diff options
1508 files changed, 128531 insertions, 73369 deletions
diff --git a/.editorconfig b/.editorconfig index 49517a5104..7743622e78 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,7 +17,8 @@ indent_size = 4 indent_style = space indent_size = 4 -[.travis.yml] +# YAML requires indentation with spaces instead of tabs. +[*.{yml,yaml}] indent_style = space indent_size = 2 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7ac70a4367..09ff2454ee 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,56 +2,181 @@ # Each line is a file pattern followed by one or more owners. # Owners can be @users, @org/teams or emails -/doc/ @godotengine/documentation -doc_classes/* @godotengine/documentation - -# Rendering -/drivers/gl_context/ @reduz -/drivers/gles2/ @reduz -/drivers/gles3/ @reduz - -# Audio -/drivers/alsa/ @marcelofg55 -/drivers/alsamidi/ @marcelofg55 -/drivers/coreaudio/ @marcelofg55 -/drivers/coremidi/ @marcelofg55 -/drivers/pulseaudio/ @marcelofg55 -/drivers/wasapi/ @marcelofg55 -/drivers/winmidi/ @marcelofg55 -/drivers/xaudio2/ @marcelofg55 - -/drivers/unix/ @hpvb -/drivers/windows/ @hpvb - -/editor/icons/ @djrm - -/misc/ @akien-mga - -/modules/bullet/ @AndreaCatania -/modules/csg/ @BastiaanOlij -/modules/enet/ @godotengine/network -/modules/gdnative/*arvr/ @BastiaanOlij -/modules/gdnative/text/ @bruvzg -/modules/gdscript/ @vnen -/modules/mbedtls/ @godotengine/network -/modules/mobile_vr/ @BastiaanOlij -/modules/mono/ @neikeq -/modules/mono/glue/GodotSharp @aaronfranke -/modules/opensimplex/ @JFonS -/modules/regex/ @LeeZH -/modules/text_server_*/ @bruvzg -/modules/upnp/ @godotengine/network -/modules/websocket/ @godotengine/network - -/platform/javascript/ @eska014 -/platform/uwp/ @vnen - -/scene/resources/font.* @bruvzg -/scene/resources/text_line.* @bruvzg -/scene/resources/text_paragraph.* @bruvzg - -/servers/physics*/ @reduz @AndreaCatania -/servers/text_server.* @bruvzg -/servers/visual*/ @reduz - -/thirdparty/ @akien-mga +# Buildsystem + +.* @godotengine/buildsystem +.github/ @godotengine/buildsystem +*.py @godotengine/buildsystem +SConstruct @godotengine/buildsystem +SCsub @godotengine/buildsystem + +# Core + +/core/ @godotengine/core +/core/crypto/ @godotengine/network +/core/debugger/ @godotengine/debugger +/core/input/ @godotengine/input + +# Doc + +/doc/ @godotengine/documentation +doc_classes/* @godotengine/documentation + +# Drivers + +## Audio +/drivers/alsa/ @godotengine/audio +/drivers/alsamidi/ @godotengine/audio +/drivers/coreaudio/ @godotengine/audio +/drivers/coremidi/ @godotengine/audio +/drivers/pulseaudio/ @godotengine/audio +/drivers/wasapi/ @godotengine/audio +/drivers/winmidi/ @godotengine/audio +/drivers/xaudio2/ @godotengine/audio + +## Rendering +/drivers/dummy/ @godotengine/rendering +/drivers/spirv-reflect/ @godotengine/rendering +/drivers/vulkan/ @godotengine/rendering + +## OS +/drivers/unix/ @godotengine/_platforms +/drivers/windows/ @godotengine/windows + +## Misc +/drivers/png/ @godotengine/import + +# Editor + +/editor/*debugger* @godotengine/debugger +/editor/icons/ @godotengine/usability +/editor/import/ @godotengine/import +/editor/plugins/*2d_*.* @godotengine/2d-editor +/editor/plugins/*3d_*.* @godotengine/3d-editor +/editor/plugins/script_*.* @godotengine/script-editor +/editor/plugins/*shader*.* @godotengine/shaders +/editor/code_editor.* @godotengine/script-editor +/editor/*dock*.* @godotengine/docks +/editor/*shader*.* @godotengine/shaders + +# Main + +/main/ @godotengine/core + +# Misc + +/misc/ @godotengine/buildsystem + +# Modules + +## Audio (+ video) +/modules/minimp3/ @godotengine/audio +/modules/ogg/ @godotengine/audio +/modules/opus/ @godotengine/audio +/modules/stb_vorbis/ @godotengine/audio +/modules/theora/ @godotengine/audio +/modules/vorbis/ @godotengine/audio +/modules/webm/ @godotengine/audio + +## Import +/modules/basis_universal/ @godotengine/import +/modules/bmp/ @godotengine/import +/modules/cvtt/ @godotengine/import +/modules/dds/ @godotengine/import +/modules/etc/ @godotengine/import +/modules/fbx/ @godotengine/import +/modules/gltf/ @godotengine/import +/modules/hdr/ @godotengine/import +/modules/jpg/ @godotengine/import +/modules/pvr/ @godotengine/import +/modules/squish/ @godotengine/import +/modules/svg/ @godotengine/import +/modules/tga/ @godotengine/import +/modules/tinyexr/ @godotengine/import +/modules/webp/ @godotengine/import + +## Network +/modules/enet/ @godotengine/network +/modules/mbedtls/ @godotengine/network +/modules/upnp/ @godotengine/network +/modules/webrtc/ @godotengine/network +/modules/websocket/ @godotengine/network + +## Rendering +/modules/denoise/ @godotengine/rendering +/modules/glslang/ @godotengine/rendering +/modules/lightmapper_rd/ @godotengine/rendering +/modules/meshoptimizer/ @godotengine/rendering +/modules/vhacd/ @godotengine/rendering +/modules/xatlas_unwrap/ @godotengine/rendering + +## Scripting +/modules/gdnative/ @godotengine/gdnative +/modules/gdscript/ @godotengine/gdscript +/modules/jsonrpc/ @godotengine/gdscript +/modules/mono/ @godotengine/mono +/modules/visual_script/ @godotengine/visualscript + +## Text +/modules/freetype/ @godotengine/buildsystem +/modules/gdnative/text/ @godotengine/gui-nodes +/modules/text_server_adv/ @godotengine/gui-nodes +/modules/text_server_fb/ @godotengine/gui-nodes + +## XR +/modules/camera/ @godotengine/xr +/modules/gdnative/xr/ @godotengine/xr +/modules/mobile_vr/ @godotengine/xr +/modules/webxr/ @godotengine/xr + +## Misc +/modules/bullet/ @godotengine/physics +/modules/csg/ @godotengine/3d-nodes +/modules/gdnavigation/ @godotengine/navigation +/modules/gridmap/ @godotengine/3d-nodes +/modules/opensimplex/ @godotengine/3d-nodes +/modules/regex/ @godotengine/core + +# Platform + +/platform/android/ @godotengine/android +/platform/iphone/ @godotengine/ios +/platform/javascript/ @godotengine/html5 +/platform/linuxbsd/ @godotengine/linux-bsd +/platform/osx/ @godotengine/macos +/platform/uwp/ @godotengine/uwp +/platform/windows/ @godotengine/windows + +# Scene + +/scene/2d/ @godotengine/2d-nodes +/scene/3d/ @godotengine/3d-nodes +/scene/animation/ @godotengine/animation +/scene/audio/ @godotengine/audio +/scene/debugger/ @godotengine/debugger +/scene/gui/ @godotengine/gui-nodes +/scene/main/ @godotengine/core +/scene/resources/default_theme/ @godotengine/gui-nodes +/scene/resources/font.* @godotengine/gui-nodes +/scene/resources/text_line.* @godotengine/gui-nodes +/scene/resources/text_paragraph.* @godotengine/gui-nodes +/scene/resources/visual_shader*.* @godotengine/shaders + +# Servers + +/servers/audio* @godotengine/audio +/servers/camera* @godotengine/xr +/servers/display_server.* @godotengine/_platforms +/servers/navigation_server*.* @godotengine/navigation +/servers/physics* @godotengine/physics +/servers/rendering* @godotengine/rendering +/servers/text_server.* @godotengine/gui-nodes +/servers/xr* @godotengine/xr + +# Tests + +/tests/ @godotengine/tests + +# Thirdparty + +/thirdparty/ @godotengine/buildsystem diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 143f3961cf..b24a36beef 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -4,8 +4,9 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes --jobs=2 module_text_server_fb_enabled=yes + SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_LIMIT: 4096 + ANDROID_NDK_VERSION: 21.1.6352462 jobs: android-template: @@ -28,6 +29,10 @@ jobs: with: java-version: 8 + - name: Install Android NDK r21 + run: | + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install 'ndk;${{env.ANDROID_NDK_VERSION}}' + # Upload cache on completion and check it out now - name: Load .scons_cache directory id: android-template-cache @@ -59,7 +64,7 @@ jobs: - name: Compilation env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ - ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk-bundle + ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/${{env.ANDROID_NDK_VERSION}}/ run: | scons target=release tools=no android_arch=armv7 scons target=release tools=no android_arch=arm64v8 diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index 73a1b2934e..c4da3cb683 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=iphone verbose=yes warnings=extra werror=yes --jobs=2 module_text_server_fb_enabled=yes + SCONSFLAGS: platform=iphone verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_LIMIT: 4096 jobs: diff --git a/.github/workflows/javascript_builds.disabled b/.github/workflows/javascript_builds.disabled index 015a1f314c..006981f3d4 100644 --- a/.github/workflows/javascript_builds.disabled +++ b/.github/workflows/javascript_builds.disabled @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=javascript verbose=yes warnings=extra werror=yes --jobs=2 + SCONSFLAGS: platform=javascript verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 SCONS_CACHE_LIMIT: 4096 EM_VERSION: 1.39.20 EM_CACHE_FOLDER: 'emsdk-cache' diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 89e8f4d146..15a7be9c4f 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -4,13 +4,13 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=linuxbsd verbose=yes warnings=extra werror=yes --jobs=2 module_text_server_fb_enabled=yes + SCONSFLAGS: platform=linuxbsd verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_LIMIT: 4096 jobs: - linux-editor-mono: + linux-editor: runs-on: "ubuntu-20.04" - name: Editor w/ Mono (target=release_debug, tools=yes, tests=yes) + name: Editor (target=release_debug, tools=yes, tests=yes) steps: - uses: actions/checkout@v2 @@ -62,13 +62,13 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons tools=yes tests=yes target=release_debug module_mono_enabled=yes mono_glue=no + scons tools=yes tests=yes target=release_debug ls -l bin/ # Execute unit tests for the editor - name: Unit Tests run: | - ./bin/godot.linuxbsd.opt.tools.64.mono --test + ./bin/godot.linuxbsd.opt.tools.64 --test - uses: actions/upload-artifact@v2 with: @@ -76,9 +76,9 @@ jobs: path: bin/* retention-days: 14 - linux-editor-sanitizers: + linux-editor-sanitizers-mono: runs-on: "ubuntu-20.04" - name: Editor with sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes) + name: Editor w/ Mono and sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes) steps: - uses: actions/checkout@v2 @@ -130,13 +130,13 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons tools=yes tests=yes target=debug use_asan=yes use_ubsan=yes + scons tools=yes tests=yes target=debug module_mono_enabled=yes mono_glue=no use_asan=yes use_ubsan=yes ls -l bin/ # Execute unit tests for the editor - name: Unit Tests run: | - ./bin/godot.linuxbsd.tools.64s --test + ./bin/godot.linuxbsd.tools.64s.mono --test linux-template-mono: runs-on: "ubuntu-20.04" @@ -191,7 +191,7 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons target=release tools=no module_mono_enabled=yes mono_glue=no debug_symbols=no + scons target=release tools=no module_mono_enabled=yes mono_glue=no ls -l bin/ - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 803c8f8ec4..a15ab92052 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=osx verbose=yes warnings=extra werror=yes --jobs=2 module_text_server_fb_enabled=yes + SCONSFLAGS: platform=osx verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_LIMIT: 4096 jobs: @@ -104,7 +104,7 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons target=release tools=no debug_symbols=no + scons target=release tools=no ls -l bin/ - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index da3327246b..30468034ff 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -18,7 +18,9 @@ jobs: - name: Install dependencies run: | - sudo apt-get install -qq dos2unix recode clang-format + sudo apt-get install -qq dos2unix recode clang-format-11 + sudo update-alternatives --remove-all clang-format + sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-11 100 sudo pip3 install black==20.8b1 pygments - name: File formatting checks (file_format.sh) @@ -33,11 +35,12 @@ jobs: run: | bash ./misc/scripts/black_format.sh - - name: JavaScript style checks via ESLint + - name: JavaScript style and documentation checks via ESLint and JSDoc run: | cd platform/javascript npm ci npm run lint + npm run docs -- -d dry-run - name: Documentation checks run: | diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index b9bf510c71..b7cc127226 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: GODOT_BASE_BRANCH: master - SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes --jobs=2 module_text_server_fb_enabled=yes + SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_MSVC_CONFIG: true SCONS_CACHE_LIMIT: 3072 @@ -24,7 +24,7 @@ jobs: # Editing this is pretty dangerous for Windows since it can break and needs to be properly tested with a fresh cache. - name: Load .scons_cache directory id: windows-editor-cache - uses: RevoluPowered/cache@v2.1 + uses: actions/cache@v2 with: path: /.scons_cache/ key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} @@ -110,7 +110,7 @@ jobs: env: SCONS_CACHE: /.scons_cache/ run: | - scons target=release tools=no debug_symbols=no + scons target=release tools=no ls -l bin/ - uses: actions/upload-artifact@v2 diff --git a/.gitignore b/.gitignore index f928c2e6ec..c1c2374bc3 100644 --- a/.gitignore +++ b/.gitignore @@ -268,9 +268,12 @@ __pycache__/ # KDE .directory -#Kdevelop project files +# Kdevelop project files *.kdev4 +# Kate swap files +*.kate-swp + # Xcode xcuserdata/ *.xcscmblueprint @@ -386,3 +389,4 @@ gcov.css # https://clangd.llvm.org/ cache folder .clangd/ +.cache/ @@ -6,6 +6,7 @@ Anish Bhobe <anishbhobe@hotmail.com> Anutrix <numaanzaheerahmed@yahoo.com> Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com> Ariel Manzur <ariel@godotengine.org> +Ariel Manzur <ariel@godotengine.org> <puntob@gmail.com> Ariel Manzur <ariel@godotengine.org> <punto@godotengine.org> Ariel Manzur <ariel@godotengine.org> <ariel@okamstudio.com> Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini.local> @@ -25,6 +26,7 @@ Daniel J. Ramirez <djrmuv@gmail.com> Dominik 'dreamsComeTrue' JasiÅ„ski <dominikjasinski@o2.pl> Emmanuel Barroga <emmanuelbarroga@gmail.com> Eric M <itsjusteza@gmail.com> +Eric Rybicki <info@ericrybicki.com> <stratos695@googlemail.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com> Fabian <supagu@gmail.com> @@ -84,6 +86,7 @@ Mateo Kuruk Miccino <mateomiccino@gmail.com> Max Hilbrunner <m.hilbrunner@gmail.com> Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com> Michael Alexsander <michaelalexsander@protonmail.com> +Nathan Franke <natfra@pm.me> <nathanwfranke@gmail.com> Nathan Lovato <nathan@gdquest.com> Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com> Nils ANDRÉ-CHANG <nils@nilsand.re> @@ -97,7 +100,7 @@ Pieter-Jan Briers <pieterjan.briers+git@gmail.com> Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com> Poommetee Ketson <poommetee@protonmail.com> PrzemysÅ‚aw Gołąb (n-pigeon) <golab.przemyslaw@gmail.com> -RafaÅ‚ Mikrut <mikrutrafal54@gmail.com> +RafaÅ‚ Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com> Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de> Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@users.noreply.github.com> Ramesh Ravone <ramesh.maran443@gmail.com> @@ -116,11 +119,13 @@ Theo Hallenius <redsymbzone@hotmail.com> Thomas Herzog <therzog@mail.de> Thomas Herzog <therzog@mail.de> <thomas.herzog@mail.com> Thomas Herzog <therzog@mail.de> <thomas.herzog@simedis.com> +Tomasz Chabora <kobewi4e@gmail.com> Twarit <wtwarit@gmail.com> V.VamsiKrishna <vk@bsb.in> <vamsikrishna.v@gmail.com> Wilhem Barbier <nounoursheureux@openmailbox.org> <wilhem.b@free.fr> Wilhem Barbier <nounoursheureux@openmailbox.org> <schtroumps31@gmail.com> Will Nations <willnationsdev@gmail.com> yg2f <yoann@terminajones.com> +Yuri Sizov <yuris@humnom.net> <pycbouh@users.noreply.github.com> Zak Stam <zakscomputers@hotmail.com> Zher Huei Lee <lee.zh.92@gmail.com> diff --git a/AUTHORS.md b/AUTHORS.md index 97c66a014c..2faaf2d2c0 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -57,7 +57,9 @@ name is available. Daniel J. Ramirez (djrm) Daniel Rakos (aqnuep) dankan1890 + Danil Alexeev (dalexeev) David Sichma (DavidSichma) + David Snopek (dsnopek) Dharkael (lupoDharkael) Dmitry Koteroff (Krakean) Dominik JasiÅ„ski (dreamsComeTrue) @@ -99,6 +101,7 @@ name is available. Jérôme Gully (Nutriz) Jia Jun Chai (SkyLucilfer) Joan Fons Sanchez (JFonS) + Johannes Witt (HaSa1002) Johan Manuel (29jm) Joshua Grams (JoshuaGrams) Juan Linietsky (reduz) @@ -111,6 +114,7 @@ name is available. Leon Krause (leonkrause) Liz Haas (27thLiz) Lucien Menassol (Kanabenki) + Lyuma m4nu3lf Maganty Rushyendra (mrushyendra) Marcel Admiraal (madmiraal) @@ -135,6 +139,7 @@ name is available. MichiRecRoom (LikeLakers2) mrezai muiroc + Nathan Franke (nathanfranke) Nathan Lovato (NathanLovato) Nathan Warden (NathanWarden) Nils André-Chang (NilsIrl) @@ -188,6 +193,7 @@ name is available. Xavier Cho (mysticfall) yg2f (SuperUserNameMan) Yuri Roubinsky (Chaosus) + Yuri Sizov (pycbouh) Zak Stam (zaksnet) Zher Huei Lee (leezh) ZuBsPaCe diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1abd76b2ff..4387750f28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,6 +72,11 @@ by drag and dropping the file in the GitHub edition field. We recommend always attaching a minimal reproduction project, even if the issue may seem simple to reproduce manually. +**Note for C# users:** If your issue is not Mono-specific, please upload a +minimal reproduction project written in GDScript or VisualScript. +This will make it easier for contributors to reproduce the issue +locally as not everyone has a Mono setup available. + **If you've been asked by a maintainer to upload a minimal reproduction project, you *must* do so within 7 days.** Otherwise, your bug report will be closed as it'll be considered too difficult to diagnose. diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 46b044a7a5..ff24d18e6f 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -30,7 +30,7 @@ # (e.g. a public domain dedication), but as far as Godot Engine is concerned # the library is considered as a whole under the Zlib license. # -# Nota: When linking dynamically against thirdparty libraries instead of +# Note: When linking dynamically against thirdparty libraries instead of # building them into the Godot binary, you may remove the corresponding # license details from this file. @@ -55,56 +55,52 @@ Comment: Godot Engine logo Copyright: 2017, Andrea Calabró License: CC-BY-4.0 -Files: ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl - ./platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml - ./platform/android/java/src/com/google/android/vending/expansion/downloader/* - ./platform/android/java/src/com/google/android/vending/licensing/* - ./platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java - ./platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java -Comment: The Android Open Source Project -Copyright: 2008-2013, The Android Open Source Project -License: Apache-2.0 +Files: ./modules/fbx/fbx_parser/ +Comment: Open Asset Import Library (FBX parser) +Copyright: 2006-2020, assimp team + 2007-2021, Juan Linietsky, Ariel Manzur. + 2014-2021, Godot Engine contributors. +License: BSD-3-clause -Files: ./platform/android/java/src/com/android/vending/licensing/util/Base64.java - ./platform/android/java/src/com/android/vending/licensing/util/Base64DecoderException.java +Files: ./platform/android/java/lib/aidl/com/android/* + ./platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml + ./platform/android/java/lib/src/com/google/android/* + ./platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java + ./platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java Comment: The Android Open Source Project -Copyright: 2002, Google Inc. +Copyright: 2008-2016, The Android Open Source Project + 2002, Google, Inc. License: Apache-2.0 -Files: ./scene/animation/tween_interpolaters.cpp -Comment: Penner Easing -Copyright: 2001, Robert Penner +Files: ./servers/physics_3d/collision_solver_3d_sat.cpp +Comment: Open Dynamics Engine +Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh License: BSD-3-clause -Files: ./servers/physics/gjk_epa.cpp - ./servers/physics/joints/generic_6dof_joint_sw.cpp - ./servers/physics/joints/generic_6dof_joint_sw.h - ./servers/physics/joints/hinge_joint_sw.cpp - ./servers/physics/joints/hinge_joint_sw.h - ./servers/physics/joints/jacobian_entry_sw.h - ./servers/physics/joints/pin_joint_sw.cpp - ./servers/physics/joints/pin_joint_sw.h - ./servers/physics/joints/slider_joint_sw.cpp - ./servers/physics/joints/slider_joint_sw.h +Files: ./servers/physics_3d/gjk_epa.cpp + ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp + ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.h + ./servers/physics_3d/joints/hinge_joint_3d_sw.cpp + ./servers/physics_3d/joints/hinge_joint_3d_sw.h + ./servers/physics_3d/joints/jacobian_entry_3d_sw.h + ./servers/physics_3d/joints/pin_joint_3d_sw.cpp + ./servers/physics_3d/joints/pin_joint_3d_sw.h + ./servers/physics_3d/joints/slider_joint_3d_sw.cpp + ./servers/physics_3d/joints/slider_joint_3d_sw.h Comment: Bullet Continuous Collision Detection and Physics Library Copyright: 2003-2008, Erwin Coumans 2007-2021, Juan Linietsky, Ariel Manzur. 2014-2021, Godot Engine contributors. License: Expat and Zlib -Files: ./servers/physics/joints/cone_twist_joint_sw.cpp - ./servers/physics/joints/cone_twist_joint_sw.h +Files: ./servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp + ./servers/physics_3d/joints/cone_twist_joint_3d_sw.h Comment: Bullet Continuous Collision Detection and Physics Library Copyright: 2007, Starbreeze Studios 2007-2021, Juan Linietsky, Ariel Manzur. 2014-2021, Godot Engine contributors. License: Expat and Zlib -Files: ./thirdparty/assimp/ -Comment: Open Asset Import Library (assimp) -Copyright: 2006-2016, assimp team -License: BSD-3-clause - Files: ./thirdparty/basis_universal/ Comment: Basis Universal Copyright: 2019, Binomial LLC. @@ -169,7 +165,7 @@ License: FTL Files: ./thirdparty/glslang/ Comment: glslang -Copyright: 2015-2020 Google, Inc. +Copyright: 2015-2020, Google, Inc. 2014-2020, The Khronos Group Inc 2002, NVIDIA Corporation. License: glslang @@ -181,19 +177,19 @@ License: MPL-2.0 Files: ./thirdparty/harfbuzz/ Comment: HarfBuzz text shaping library -Copyright: 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 Google, Inc. - 2018,2019,2020 Ebrahim Byagowi - 2019,2020 Facebook, Inc. - 2012 Mozilla Foundation - 2011 Codethink Limited - 2008,2010 Nokia Corporation and/or its subsidiary(-ies) - 2009 Keith Stribley - 2009 Martin Hosken and SIL International - 2007 Chris Wilson - 2006 Behdad Esfahbod - 2005 David Turner - 2004,2007,2008,2009,2010 Red Hat, Inc. - 1998-2004 David Turner and Werner Lemberg +Copyright: 2010-2020, Google, Inc. + 2018-2020, Ebrahim Byagowi + 2019-2020, Facebook, Inc. + 2012, Mozilla Foundation + 2011, Codethink Limited + 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) + 2009, Keith Stribley + 2009, Martin Hosken and SIL International + 2007, Chris Wilson + 2006, Behdad Esfahbod + 2005, David Turner + 2004, 2007-2010, Red Hat, Inc. + 1998-2004, David Turner and Werner Lemberg License: HarfBuzz Files: ./thirdparty/icu4c/ @@ -201,10 +197,10 @@ Comment: International Components for Unicode Copyright: 1991-2020, Unicode License: Unicode -Files: ./thirdparty/jpeg_compressor/ +Files: ./thirdparty/jpeg-compressor/ Comment: jpeg-compressor Copyright: 2012, Rich Geldreich -License: public-domain +License: public-domain or Apache-2.0 Files: ./thirdparty/libogg/ Comment: OggVorbis @@ -258,12 +254,22 @@ License: BSD-3-clause Files: ./thirdparty/mbedtls/ Comment: Mbed TLS -Copyright: 2006-2018, Arm Limited (or its affiliates) +Copyright: The Mbed TLS Contributors License: Apache-2.0 +Files: ./thirdparty/meshoptimizer/ +Comment: meshoptimizer +Copyright: 2016-2020, Arseny Kapoulkine +License: Expat + +Files: ./thirdparty/minimp3/ +Comment: MiniMP3 +Copyright: lieff +License: CC0-1.0 + Files: ./thirdparty/miniupnpc/ Comment: MiniUPnPc -Copyright: 2005-2018, Thomas Bernard +Copyright: 2005-2019, Thomas Bernard License: BSD-3-clause Files: ./thirdparty/minizip/ @@ -279,6 +285,11 @@ Comment: Clipper Copyright: 2010-2017, Angus Johnson License: BSL-1.0 +Files: ./thirdparty/misc/cubemap_coeffs.h +Comment: Fast Filtering of Reflection Probes +Copyright: 2016, Activision Publishing, Inc. +License: Expat + Files: ./thirdparty/misc/easing_equations.cpp Comment: Robert Penner's Easing Functions Copyright: 2001, Robert Penner @@ -302,23 +313,41 @@ Comment: Tangent Space Normal Maps implementation Copyright: 2011, Morten S. Mikkelsen License: Zlib +Files: ./thirdparty/misc/open-simplex-noise.c + ./thirdparty/misc/open-simplex-noise.h +Comment: OpenSimplex Noise +Copyright: 2014, Stephen M. Cameron +License: public-domain or Unlicense + Files: ./thirdparty/misc/pcg.cpp ./thirdparty/misc/pcg.h Comment: Minimal PCG32 implementation Copyright: 2014, M.E. O'Neill License: Apache-2.0 +Files: ./thirdparty/misc/polypartition.cpp + ./thirdparty/misc/polypartition.h +Comment: PolyPartition / Triangulator +Copyright: 2011-2021, Ivan Fratric and contributors +License: Expat + +Files: ./thirdparty/misc/r128.c + ./thirdparty/misc/r128.h +Comment: r128 library +Copyright: Alan Hickman +License: public-domain or Unlicense + Files: ./thirdparty/misc/smaz.c ./thirdparty/misc/smaz.h Comment: SMAZ Copyright: 2006-2009, Salvatore Sanfilippo License: BSD-3-clause -Files: ./thirdparty/misc/triangulator.cpp - ./thirdparty/misc/triangulator.h -Comment: PolyPartition -Copyright: 2011, Ivan Fratric -License: Expat +Files: ./thirdparty/misc/stb_rect_pack.h + ./thirdparty/misc/stb_vorbis.c +Comment: stb libraries +Copyright: Sean Barrett +License: public-domain or Unlicense or Expat Files: ./thirdparty/misc/yuv2rgb.h Comment: YUV2RGB @@ -345,8 +374,8 @@ License: BSD-3-clause Files: ./thirdparty/pcre2/ Comment: PCRE2 -Copyright: 1997-2019, University of Cambridge, - 2009-2019, Zoltan Herczeg +Copyright: 1997-2020, University of Cambridge + 2009-2020, Zoltan Herczeg License: BSD-3-clause Files: ./thirdparty/pvrtccompressor/ @@ -362,7 +391,12 @@ License: Zlib Files: ./thirdparty/rvo2/ Comment: RVO2 Copyright: 2016, University of North Carolina at Chapel Hill -License: Apache 2.0 +License: Apache-2.0 + +Files: ./thirdparty/spirv-reflect/ +Comment: SPIRV-Reflect +Copyright: 2017-2018, Google Inc. +License: Apache-2.0 Files: ./thirdparty/squish/ Comment: libSquish @@ -396,7 +430,7 @@ License: Expat Files: ./thirdparty/wslay/ Comment: Wslay -Copyright: 2011-2015, Tatsuhiro Tsujikawa +Copyright: 2011, 2012, 2015, Tatsuhiro Tsujikawa License: Expat Files: ./thirdparty/xatlas/ @@ -548,6 +582,121 @@ License: BSL-1.0 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +License: CC0-1.0 + CC0 1.0 Universal + . + Statement of Purpose + . + The laws of most jurisdictions throughout the world automatically confer + exclusive Copyright and Related Rights (defined below) upon the creator and + subsequent owner(s) (each and all, an "owner") of an original work of + authorship and/or a database (each, a "Work"). + . + Certain owners wish to permanently relinquish those rights to a Work for the + purpose of contributing to a commons of creative, cultural and scientific + works ("Commons") that the public can reliably and without fear of later + claims of infringement build upon, modify, incorporate in other works, reuse + and redistribute as freely as possible in any form whatsoever and for any + purposes, including without limitation commercial purposes. These owners may + contribute to the Commons to promote the ideal of a free culture and the + further production of creative, cultural and scientific works, or to gain + reputation or greater distribution for their Work in part through the use and + efforts of others. + . + For these and/or other purposes and motivations, and without any expectation + of additional consideration or compensation, the person associating CC0 with a + Work (the "Affirmer"), to the extent that he or she is an owner of Copyright + and Related Rights in the Work, voluntarily elects to apply CC0 to the Work + and publicly distribute the Work under its terms, with knowledge of his or her + Copyright and Related Rights in the Work and the meaning and intended legal + effect of CC0 on those rights. + . + 1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights ("Copyright and + Related Rights"). Copyright and Related Rights include, but are not limited + to, the following: + . + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + . + ii. moral rights retained by the original author(s) and/or performer(s); + . + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + . + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + . + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + . + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + . + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + . + 2. Waiver. To the greatest extent permitted by, but not in contravention of, + applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and + unconditionally waives, abandons, and surrenders all of Affirmer's Copyright + and Related Rights and associated claims and causes of action, whether now + known or unknown (including existing as well as future claims and causes of + action), in the Work (i) in all territories worldwide, (ii) for the maximum + duration provided by applicable law or treaty (including future time + extensions), (iii) in any current or future medium and for any number of + copies, and (iv) for any purpose whatsoever, including without limitation + commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes + the Waiver for the benefit of each member of the public at large and to the + detriment of Affirmer's heirs and successors, fully intending that such Waiver + shall not be subject to revocation, rescission, cancellation, termination, or + any other legal or equitable action to disrupt the quiet enjoyment of the Work + by the public as contemplated by Affirmer's express Statement of Purpose. + . + 3. Public License Fallback. Should any part of the Waiver for any reason be + judged legally invalid or ineffective under applicable law, then the Waiver + shall be preserved to the maximum extent permitted taking into account + Affirmer's express Statement of Purpose. In addition, to the extent the Waiver + is so judged Affirmer hereby grants to each affected person a royalty-free, + non transferable, non sublicensable, non exclusive, irrevocable and + unconditional license to exercise Affirmer's Copyright and Related Rights in + the Work (i) in all territories worldwide, (ii) for the maximum duration + provided by applicable law or treaty (including future time extensions), (iii) + in any current or future medium and for any number of copies, and (iv) for any + purpose whatsoever, including without limitation commercial, advertising or + promotional purposes (the "License"). The License shall be deemed effective as + of the date CC0 was applied by Affirmer to the Work. Should any part of the + License for any reason be judged legally invalid or ineffective under + applicable law, such partial invalidity or ineffectiveness shall not + invalidate the remainder of the License, and in such case Affirmer hereby + affirms that he or she will not (i) exercise any of his or her remaining + Copyright and Related Rights in the Work or (ii) assert any associated claims + and causes of action with respect to the Work, in either case contrary to + Affirmer's express Statement of Purpose. + . + 4. Limitations and Disclaimers. + . + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + . + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + . + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + . + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + License: CC-BY-4.0 Creative Commons Attribution 4.0 International Public License . @@ -1729,6 +1878,32 @@ License: Unicode use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. +License: Unlicense + This is free and unencumbered software released into the public domain. + . + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + . + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + . + For more information, please refer to <https://unlicense.org/> + License: Zlib This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,7 +48,6 @@ generous deed immortalized in the next stable release of Godot Engine. Digital Grows Dov Zimring Edward Flick - Franz Silva Gamechuck GameDev.net Hein-Pieter van Braam @@ -81,6 +80,7 @@ generous deed immortalized in the next stable release of Godot Engine. Acheron albinaask + Alvaro A Baena R Asher Glick Bernhard Werner Carlo Cabanilla @@ -89,6 +89,7 @@ generous deed immortalized in the next stable release of Godot Engine. Daniel James David Gehrig David Snopek + Don B Ed Morley Ellen Poe Florian Neumann @@ -103,7 +104,6 @@ generous deed immortalized in the next stable release of Godot Engine. Joan Fons Johnny IV Young Jon Woodward - Kai Klyden Karl Werf Klavdij Voncina Lex Steers @@ -136,6 +136,7 @@ generous deed immortalized in the next stable release of Godot Engine. Tom Langwaldt Tricky Fat Cat tukon + Vitaliy Sapronenko William Wold xagonist Xeno Coliseum @@ -144,17 +145,24 @@ generous deed immortalized in the next stable release of Godot Engine. Aaron Winter Adam Nakonieczny Adrian Adamiak + Aleksey Korotkevich Alexander J Maynard Alex de la Mare + Alexey Dyadchenko Alex Khayrullin alice gambrell Andreas Funke André Frélicot + Andrew Cunningham + Anm + Antanas Paskauskas Antoni Batchelli Arisaka Mayuki + Arthur S. Muszynski Aubin Detrez Barugon Ben Botwin + Caleb Sizemore Can Eris Charlie Whitfield Chase Taranto @@ -166,16 +174,19 @@ generous deed immortalized in the next stable release of Godot Engine. Conrad Curry Craig Ostrin Craig Smith + Cristopher D + dan didenko Darrian Little + Dennis Belfrage Dev To be curious Digital Denizen + Dimitri Nüscheler Donn Eddy Easypete Edgar Sun Eugenio Hugo Salgüero Jáñez flesk - Francisco Arámburo F S Gabrielius VaiÅ¡kÅ«nas Gary Hulst @@ -189,11 +200,14 @@ generous deed immortalized in the next stable release of Godot Engine. Horváth Péter Hu Hund Idilio Alfaro + Jake Burga James Couzens Jared Jared White + Jesús Chicharro Joel Fivat Joel Höglund + Johnathan Kupferer Jose Malheiro Joseph Crane Joshie Sparks @@ -208,10 +222,12 @@ generous deed immortalized in the next stable release of Godot Engine. Kelteseth kickmaniac kinfox - kuku + Kos Lachie Lain Ballard + Laszlo Kiss Leo Fidel R Liban + Liam Smyth Luc-Frédéric Langis luka duren MadScientistCarl @@ -220,17 +236,23 @@ generous deed immortalized in the next stable release of Godot Engine. Marcus Richter Marisa Clardy Mark Barrett + Mark Diaz Markus Fehr Martin Eigel Martin Kotz Martin Soucek Matt Eunson Matt Greene + Matthias Toepp + medecau Michael Michael Dürwald + Michael Noll + Michael Policastro MikadoSC MuffinManKen Nick Abousselam + Nick Barovic Oliver Dick Oscar Campos Patrick Brock @@ -245,32 +267,37 @@ generous deed immortalized in the next stable release of Godot Engine. Raymond Harris Raz A Ricardo Alcantara + Robert Larnach Robert Willes Rob McInroy Rocknight Studios Rodrigo Favarete Ronnie Ashlock Ronny Mühle - Ryan Wilson + Ryan Scott + Ryszard Sommefeldt Samuel Judd Scott Pilet Sean Morgan + Sebastian Hutter Sébastien Serban Serafimescu Sergey Minakov Shishir Tandale SKison + Song Junwoo spilldata Stephan Hennion Steven Landow Stoned Xander - TheLevelOfDetail . + TheLevelOfDetail Thomas Bjarnelöf Thomas Kurz Tim Howard + tinyBigGAMES LLC Tobias Bocanegra - Trent Fehl Turntsnaco + tweaklab Valryia Vincent Cloutier Vlad Ceru Opran @@ -287,7 +314,6 @@ generous deed immortalized in the next stable release of Godot Engine. ## Silver donors 1D_Inc - Aaron Passchier Abraham Haskins Adam Adam Brunnmeier @@ -305,24 +331,24 @@ generous deed immortalized in the next stable release of Godot Engine. AJ Austinson Aki Mimoto Alan Beauchamp + Alberto Vilches Albin Jonasson Svärdsby Alder Stefano AleMax Alessandro Senese Alexander Erlemann + Alexander Ryndin + Alexander Walter (SilvanuZ) Alexandre Beaudoin alex clavelle - Ali Al-Khalifa Allan Davis Allen Schade Ancient Phoenix Anders Marstein Kruke Andreas Krampitz - André Simões Andre Stackhouse andrew james morris Andrew Mansuetti - Andrew Rosenwinkel Andrew Thomas Ano Nim Anthony Avina @@ -330,16 +356,14 @@ generous deed immortalized in the next stable release of Godot Engine. AP Condomines Arch Toasty Arda Erol + Aria Armin Preiml Arseniy M - Arthur S. Muszynski Ashley Claymore Astier Mickael Aubrey Falconer AzulCrescent - B A Balázs Batári - Balázs Kondákor Bartosz Bielecki Bekhoucha Danyl Benedikt @@ -347,6 +371,7 @@ generous deed immortalized in the next stable release of Godot Engine. Bernd Jänichen Bjarne Voigtländer Black Block + blackjacksike Blair Allen Bobby CC Wong Borkzilla @@ -356,6 +381,7 @@ generous deed immortalized in the next stable release of Godot Engine. Brian Klein Brodie Fairhall Bronson Zgeb + Bùi Việt Thà nh Burney Waring Caleb Gartner Cameron Meyer @@ -364,7 +390,9 @@ generous deed immortalized in the next stable release of Godot Engine. Carwyn Edwards Cas Brugman Cassidy James + Cédric Givord Chad Steadman + Charles Alston Chris Chapin Chris Jagusch Chris Langford @@ -377,8 +405,9 @@ generous deed immortalized in the next stable release of Godot Engine. Christoph Woinke Chris Truebe Clay Heaton + Cody Parker Conall O - Cyrelouyea + Craig Post CzechBlueBear Daniel Cheney Daniel Johnson @@ -398,10 +427,10 @@ generous deed immortalized in the next stable release of Godot Engine. Dr.Raccoon Duobix Duodecimal + DurrDiss Eduardo Teixeira Edward Herbert Edward Swartz - Eelco F Hillenius Egon Elbre Elgenzay Elias Nykrem @@ -409,7 +438,6 @@ generous deed immortalized in the next stable release of Godot Engine. Eric Ellingson Eric Williams Erkki Seppälä - ET Garcia Evan Rose Fain Faisal Alkubaisi @@ -423,6 +451,7 @@ generous deed immortalized in the next stable release of Godot Engine. FuDiggity Gadzhi Kharkharov gamedev by Celio + Game Endeavor Gary Thomas George Marques Gerard Ruiz Torruella @@ -438,19 +467,16 @@ generous deed immortalized in the next stable release of Godot Engine. Hal A helija Heribert Hirth - Hoai Nam Tran + Hieu Thanh Hunter Jones - Hylpher Ian Williams Iiari - iKlem IndustrialRobot + Ivan Nikolaev iveks - Ivica Å imić Jackson Harmer Jacob Jaguar - Jaiden Gerig Jaime Ruiz-Borau Vizárraga Jake D Jake Huxell @@ -461,12 +487,13 @@ generous deed immortalized in the next stable release of Godot Engine. Jamiee H Jamie Massey JARKKO PARVIAINEN + Jasiek Vetulani Jason Uechi Jean-Baptiste LEPESME Jeff Hungerford Jennifer Graves Jesse Dubay - Joe Alden + Jhon Adams Joe Klemmer John Gabriel Jonas @@ -483,42 +510,41 @@ generous deed immortalized in the next stable release of Godot Engine. Jorge Javier Araya Navarro Jose C. Rubio Joseph Catrambone - Josh Mitchell Josh Taylor - Joshua Southerland + Josue David Juanfran Jueast Julian Murgia June Little - JungleRobba + Justin Hamilton Justin Oaksford Justin Spedding KaDokta Kalin - Karel NÄ›mec Kauzig Keedong Park Keinan Powers Keith Bradner Kenji Kawabata + Ken Minardo Kenneth Lee Kent Jofur + Ketafuki Kevin McPhillips Kiri Jolly - Kiyohiro Kawamura (kyorohiro) Kjetil Haugland + Konstantin Goncharov + Kridsada Thanabulpong Kristian Nygaard Jensen KsyTek Games - Kuan Cheang kycho Kyle Jacobs Kyle Szklenski Kyuppin Laurent CHEA Laurent Tréguier - Lee Meichin + Laxman Pradhan LEMMiNO - Lenny Leonardo Dimano Lin Chear Linus Lind Lundgren @@ -527,13 +553,13 @@ generous deed immortalized in the next stable release of Godot Engine. Luis Gaemperle Luis M LunaticInAHat - Lurkars Major Haul makoto asano Malcolm Marco Lardelli Mark Jad Mark Krenz + Mark Malone Markus Martin Markus Michael Egger Martin FIbik @@ -550,8 +576,10 @@ generous deed immortalized in the next stable release of Godot Engine. Maxwell Megasploot Melissa Mears + Merlyn Morgan-Graham mewin Michael + Michael Bruce-Lockhart Michael Haney MichaÅ‚ Skwarek Mikayla @@ -566,27 +594,27 @@ generous deed immortalized in the next stable release of Godot Engine. Nathaniel Natrim nee + neighty Neil Blakey-Milner Neil Wang Nerdforge Nerdyninja Nicholas - Nicholas Girga Nick Allen Nick Macholl Niclas Eriksen Nicolas Goll-Perrier - Nicolás Montaña + Nicolas Rosset Nicolas SAN AGUSTIN Nima Farid NZ + oceoh OKV Oleg Reva Oleksandr Kryvonos Olivier Omar Delarosa Oscar Domingo - Oscar Norlander Parinya Teerakasemsuk patricio lara briones Patrick Dully @@ -595,24 +623,27 @@ generous deed immortalized in the next stable release of Godot Engine. Paul Mason PaweÅ‚ Kowal PaweÅ‚ Åyczkowski - Pedro Assuncao + Peter Höglund Petrus Prinsloo Philip Cohoe + Phillip Zolla Piotr Góral + Pipo Point08 Preethi Vaidyanathan - Price Comstock pwab + pyacier + Rad Cat Rafa Laguna Raffaele Aramo + RAMupgrade Remi Rampin Rémi Verschelde Reneator - Richard Diss + Riccardo Marini Richard Ivánek Riley Robert Farr (Larington) - Robert Larnach Rob Ruana Roger Smith Roland RzÄ…sa @@ -623,19 +654,19 @@ generous deed immortalized in the next stable release of Godot Engine. Ryan Groom Sam Edson Samuele Zolfanelli - sayaks + scapegoat57 Scott D. Yelich Scott Longley - ScottMakesGames + Sean Lynch Sebastian Michailidis Sebastian Vetter SeongWan Kim Sergiy Onenko - Shaher Shane Shane Sicienski Shane Spoor Siim Raidma + simdee Simon Jonas Larsen Simon Schoenenberger Simon Wenner @@ -644,20 +675,20 @@ generous deed immortalized in the next stable release of Godot Engine. smo1704 soft circles Squirrel - Stefano Caronia Steve Cloete + summerblind Sung soo Choi Svenne Krap tadashi endo tannhauser_gate + Tarch Terry Theodore Lindsey - TheTrainDoctor TheVoiceInMyHead thomas Thomas Bechtold Thomas Detoy - Thomas Kelly + Thomas Horwath Tim Drumheller Tim Erskine Tim Gleason @@ -671,7 +702,6 @@ generous deed immortalized in the next stable release of Godot Engine. Travis O'Brien Trent Skinner tril zerobyte - Triptych Triumph263 . Troy Bonneau Tryggve Sollid @@ -684,8 +714,6 @@ generous deed immortalized in the next stable release of Godot Engine. Victor Vigilant Watch Viktor Ismagilov - Vitaliy Sapronenko - Vitor Balbio Vladimir Savin Vladislav Smirnov Výrus Hemomancer @@ -693,17 +721,15 @@ generous deed immortalized in the next stable release of Godot Engine. Wayne Haak werner mendizabal Wiley Thompson - Will William Edwards William F Siqueira William Hogben Wyatt Goodin + Xaver Fischer xenomat Yegor Smirnov - YiYin Gu Zack Yang Zak Stephens - ΒΑΣΙΛΗΣ ΓΕΩΡΓΑΚΟΠΟΥΛΟΣ è•æƒŸå… éƒæ™¨ç…œ diff --git a/SConstruct b/SConstruct index 2281b8a77f..f03fb72ff3 100644 --- a/SConstruct +++ b/SConstruct @@ -55,7 +55,7 @@ custom_tools = ["default"] platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False)) -if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)): +if os.name == "nt" and (platform_arg == "android" or methods.get_cmdline_bool("use_mingw", False)): custom_tools = ["mingw"] elif platform_arg == "javascript": # Use generic POSIX build toolchain for Emscripten. @@ -95,7 +95,7 @@ env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL)) customs = ["custom.py"] -profile = ARGUMENTS.get("profile", False) +profile = ARGUMENTS.get("profile", "") if profile: if os.path.isfile(profile): customs.append(profile) @@ -105,15 +105,14 @@ if profile: opts = Variables(customs, ARGUMENTS) # Target build options -opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "") -opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64"))) opts.Add("p", "Platform (alias for 'platform')", "") opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "") +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("optimize", "Optimization type", "speed", ("speed", "size"))) - -opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True)) -opts.Add(BoolVariable("tests", "Build the unit tests", False)) +opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) opts.Add(BoolVariable("use_lto", "Use link-time optimization", False)) # Components @@ -121,13 +120,15 @@ opts.Add(BoolVariable("deprecated", "Enable deprecated features", True)) opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True)) opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") +opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) # Advanced options -opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) +opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False)) opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True)) +opts.Add(BoolVariable("tests", "Build the unit tests", False)) +opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no"))) opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False)) -opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False)) opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "") opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False)) opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) @@ -237,8 +238,14 @@ if env_base["custom_modules"]: Exit(255) for path in module_search_paths: + if path == "modules": + # Built-in modules don't have nested modules, + # so save the time it takes to parse directories. + modules = methods.detect_modules(path, recursive=False) + else: # External. + modules = methods.detect_modules(path, env_base["custom_modules_recursive"]) # Note: custom modules can override built-in ones. - modules_detected.update(methods.detect_modules(path)) + modules_detected.update(modules) include_path = os.path.dirname(path) if include_path: env_base.Prepend(CPPPATH=[include_path]) @@ -308,7 +315,7 @@ if selected_platform in platform_list: else: env = env_base.Clone() - # Compilation DB requires SCons 3.1.1+. + # Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later. from SCons import __version__ as scons_raw_version scons_ver = env._get_major_minor_revision(scons_raw_version) @@ -317,12 +324,34 @@ if selected_platform in platform_list: env.Tool("compilation_db") env.Alias("compiledb", env.CompilationDatabase()) + # 'dev' and 'production' are aliases to set default options if they haven't been set + # manually by the user. if env["dev"]: - env["verbose"] = True - env["warnings"] = "extra" - env["werror"] = True + env["verbose"] = methods.get_cmdline_bool("verbose", True) + env["warnings"] = ARGUMENTS.get("warnings", "extra") + env["werror"] = methods.get_cmdline_bool("werror", True) if env["tools"]: - env["tests"] = True + env["tests"] = methods.get_cmdline_bool("tests", True) + if env["production"]: + env["use_static_cpp"] = methods.get_cmdline_bool("use_static_cpp", True) + env["use_lto"] = methods.get_cmdline_bool("use_lto", True) + env["debug_symbols"] = methods.get_cmdline_bool("debug_symbols", False) + if not env["tools"] and env["target"] == "debug": + print( + "WARNING: Requested `production` build with `tools=no target=debug`, " + "this will give you a full debug template (use `target=release_debug` " + "for an optimized template with debug features)." + ) + if env.msvc: + print( + "WARNING: For `production` Windows builds, you should use MinGW with GCC " + "or Clang instead of Visual Studio, as they can better optimize the " + "GDScript VM in a very significant way. MSVC LTO also doesn't work " + "reliably for our use case." + "If you want to use MSVC nevertheless for production builds, set " + "`debug_symbols=no use_lto=no` instead of the `production=yes` option." + ) + Exit(255) env.extra_suffix = "" @@ -588,7 +617,7 @@ if selected_platform in platform_list: if env["minizip"]: env.Append(CPPDEFINES=["MINIZIP_ENABLED"]) - editor_module_list = ["regex"] + editor_module_list = ["freetype", "regex"] if env["tools"] and not env.module_check_dependencies("tools", editor_module_list): print( "Build option 'module_" diff --git a/core/SCsub b/core/SCsub index c9f84a9a00..21829553a7 100644 --- a/core/SCsub +++ b/core/SCsub @@ -54,7 +54,7 @@ thirdparty_misc_sources = [ "smaz.c", # C++ sources "pcg.cpp", - "triangulator.cpp", + "polypartition.cpp", "clipper.cpp", ] thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources] diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 70e8133eaa..c872ae2162 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -32,6 +32,7 @@ #include "core/core_bind.h" #include "core/core_string_names.h" +#include "core/input/input_map.h" #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" #include "core/io/marshalls.h" @@ -124,6 +125,11 @@ void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restar props[p_name].restart_if_changed = p_restart; } +void ProjectSettings::set_as_basic(const String &p_name, bool p_basic) { + ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + props[p_name].basic = p_basic; +} + void ProjectSettings::set_ignore_value_in_docs(const String &p_name, bool p_ignore) { ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); #ifdef DEBUG_METHODS_ENABLED @@ -269,6 +275,10 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const { vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE; } + if (v->basic) { + vc.flags |= PROPERTY_USAGE_EDITOR_BASIC_SETTING; + } + if (v->restart_if_changed) { vc.flags |= PROPERTY_USAGE_RESTART_IF_CHANGED; } @@ -278,7 +288,7 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const { for (Set<_VCSort>::Element *E = vclist.front(); E; E = E->next()) { String prop_info_name = E->get().name; int dot = prop_info_name.find("."); - if (dot != -1) { + if (dot != -1 && !custom_prop_info.has(prop_info_name)) { prop_info_name = prop_info_name.substr(0, dot); } @@ -597,6 +607,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) { // If we're loading a project.godot from source code, we can operate some // ProjectSettings conversions if need be. _convert_to_last_version(config_version); + last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); return OK; } else if (err != OK) { ERR_PRINT("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted."); @@ -676,7 +687,11 @@ void ProjectSettings::clear(const String &p_name) { } Error ProjectSettings::save() { - return save_custom(get_resource_path().plus_file("project.godot")); + Error error = save_custom(get_resource_path().plus_file("project.godot")); + if (error == OK) { + last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); + } + return error; } Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) { @@ -903,7 +918,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust } } -Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed, bool p_ignore_value_in_docs) { +Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed, bool p_ignore_value_in_docs, bool p_basic) { Variant ret; if (!ProjectSettings::get_singleton()->has_setting(p_var)) { ProjectSettings::get_singleton()->set(p_var, p_default); @@ -912,6 +927,7 @@ Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restar ProjectSettings::get_singleton()->set_initial_value(p_var, p_default); ProjectSettings::get_singleton()->set_builtin_order(p_var); + ProjectSettings::get_singleton()->set_as_basic(p_var, p_basic); ProjectSettings::get_singleton()->set_restart_if_changed(p_var, p_restart_if_changed); ProjectSettings::get_singleton()->set_ignore_value_in_docs(p_var, p_ignore_value_in_docs); return ret; @@ -1042,29 +1058,47 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd); } +void ProjectSettings::_add_builtin_input_map() { + if (InputMap::get_singleton()) { + OrderedHashMap<String, List<Ref<InputEvent>>> builtins = InputMap::get_singleton()->get_builtins(); + + for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { + Array events; + + // Convert list of input events into array + for (List<Ref<InputEvent>>::Element *I = E.get().front(); I; I = I->next()) { + events.push_back(I->get()); + } + + Dictionary action; + action["deadzone"] = Variant(0.5f); + action["events"] = events; + + String action_name = "input/" + E.key(); + GLOBAL_DEF(action_name, action); + input_presets.push_back(action_name); + } + } +} + ProjectSettings::ProjectSettings() { // Initialization of engine variables should be done in the setup() method, // so that the values can be overridden from project.godot or project.binary. singleton = this; - Array events; - Dictionary action; - Ref<InputEventKey> key; - Ref<InputEventJoypadButton> joyb; - - GLOBAL_DEF("application/config/name", ""); - GLOBAL_DEF("application/config/description", ""); + GLOBAL_DEF_BASIC("application/config/name", ""); + GLOBAL_DEF_BASIC("application/config/description", ""); custom_prop_info["application/config/description"] = PropertyInfo(Variant::STRING, "application/config/description", PROPERTY_HINT_MULTILINE_TEXT); - GLOBAL_DEF("application/run/main_scene", ""); + GLOBAL_DEF_BASIC("application/run/main_scene", ""); custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res"); GLOBAL_DEF("application/run/disable_stdout", false); GLOBAL_DEF("application/run/disable_stderr", false); GLOBAL_DEF("application/config/use_custom_user_dir", false); GLOBAL_DEF("application/config/custom_user_dir_name", ""); GLOBAL_DEF("application/config/project_settings_override", ""); - GLOBAL_DEF("audio/default_bus_layout", "res://default_bus_layout.tres"); - custom_prop_info["audio/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/default_bus_layout", PROPERTY_HINT_FILE, "*.tres"); + GLOBAL_DEF_BASIC("audio/buses/default_bus_layout", "res://default_bus_layout.tres"); + custom_prop_info["audio/buses/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/buses/default_bus_layout", PROPERTY_HINT_FILE, "*.tres"); PackedStringArray extensions = PackedStringArray(); extensions.push_back("gd"); @@ -1073,174 +1107,18 @@ ProjectSettings::ProjectSettings() { } extensions.push_back("shader"); - GLOBAL_DEF("editor/search_in_file_extensions", extensions); - custom_prop_info["editor/search_in_file_extensions"] = PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/search_in_file_extensions"); - - GLOBAL_DEF("editor/script_templates_search_path", "res://script_templates"); - custom_prop_info["editor/script_templates_search_path"] = PropertyInfo(Variant::STRING, "editor/script_templates_search_path", PROPERTY_HINT_DIR); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_ENTER); - events.push_back(key); - key.instance(); - key->set_keycode(KEY_KP_ENTER); - events.push_back(key); - key.instance(); - key->set_keycode(KEY_SPACE); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_A); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_accept", action); - input_presets.push_back("input/ui_accept"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_SPACE); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_Y); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_select", action); - input_presets.push_back("input/ui_select"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_ESCAPE); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_B); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_cancel", action); - input_presets.push_back("input/ui_cancel"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_TAB); - events.push_back(key); - action["events"] = events; - GLOBAL_DEF("input/ui_focus_next", action); - input_presets.push_back("input/ui_focus_next"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_TAB); - key->set_shift(true); - events.push_back(key); - action["events"] = events; - GLOBAL_DEF("input/ui_focus_prev", action); - input_presets.push_back("input/ui_focus_prev"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_LEFT); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_DPAD_LEFT); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_left", action); - input_presets.push_back("input/ui_left"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_RIGHT); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_DPAD_RIGHT); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_right", action); - input_presets.push_back("input/ui_right"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_UP); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_DPAD_UP); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_up", action); - input_presets.push_back("input/ui_up"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_DOWN); - events.push_back(key); - joyb.instance(); - joyb->set_button_index(JOY_BUTTON_DPAD_DOWN); - events.push_back(joyb); - action["events"] = events; - GLOBAL_DEF("input/ui_down", action); - input_presets.push_back("input/ui_down"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_PAGEUP); - events.push_back(key); - action["events"] = events; - GLOBAL_DEF("input/ui_page_up", action); - input_presets.push_back("input/ui_page_up"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_PAGEDOWN); - events.push_back(key); - action["events"] = events; - GLOBAL_DEF("input/ui_page_down", action); - input_presets.push_back("input/ui_page_down"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_HOME); - events.push_back(key); - action["events"] = events; - GLOBAL_DEF("input/ui_home", action); - input_presets.push_back("input/ui_home"); - - action = Dictionary(); - action["deadzone"] = Variant(0.5f); - events = Array(); - key.instance(); - key->set_keycode(KEY_END); - events.push_back(key); - action["events"] = events; - GLOBAL_DEF("input/ui_end", action); - input_presets.push_back("input/ui_end"); + GLOBAL_DEF("editor/script/search_in_file_extensions", extensions); + custom_prop_info["editor/script/search_in_file_extensions"] = PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/script/search_in_file_extensions"); + + GLOBAL_DEF("editor/script/templates_search_path", "res://script_templates"); + custom_prop_info["editor/script/templates_search_path"] = PropertyInfo(Variant::STRING, "editor/script/templates_search_path", PROPERTY_HINT_DIR); + + _add_builtin_input_map(); custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor"); - custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); - custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); - custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects"); + custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); + GLOBAL_DEF("physics/2d/run_on_thread", false); + GLOBAL_DEF("physics/3d/run_on_thread", false); GLOBAL_DEF("debug/settings/profiler/max_functions", 16384); custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1"); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 59c56c23c2..ed8fb19fa0 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -58,6 +58,7 @@ protected: struct VariantContainer { int order = 0; bool persist = false; + bool basic = false; Variant variant; Variant initial; bool hide_from_editor = false; @@ -78,6 +79,8 @@ protected: int last_order = NO_BUILTIN_ORDER_BASE; int last_builtin_order = 0; + uint64_t last_save_time = 0; + Map<StringName, VariantContainer> props; String resource_path; Map<StringName, PropertyInfo> custom_prop_info; @@ -113,6 +116,8 @@ protected: Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false); + void _add_builtin_input_map(); + protected: static void _bind_methods(); @@ -127,6 +132,7 @@ public: String globalize_path(const String &p_path) const; void set_initial_value(const String &p_name, const Variant &p_value); + void set_as_basic(const String &p_name, bool p_basic); void set_restart_if_changed(const String &p_name, bool p_restart); void set_ignore_value_in_docs(const String &p_name, bool p_ignore); bool get_ignore_value_in_docs(const String &p_name) const; @@ -150,6 +156,7 @@ public: Error save(); void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info); const Map<StringName, PropertyInfo> &get_custom_property_info() const; + uint64_t get_last_saved_time() { return last_save_time; } Vector<String> get_optimizer_presets() const; @@ -172,11 +179,16 @@ public: }; //not a macro any longer -Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false); +Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false, bool p_basic = false); #define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value) #define GLOBAL_DEF_RST(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true) #define GLOBAL_DEF_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true) #define GLOBAL_DEF_RST_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true) #define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var) +#define GLOBAL_DEF_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, true) +#define GLOBAL_DEF_RST_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, false, true) +#define GLOBAL_DEF_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true, true) +#define GLOBAL_DEF_RST_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true, true) + #endif // PROJECT_SETTINGS_H diff --git a/core/core_bind.cpp b/core/core_bind.cpp index a84a208050..47c75cfa28 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -86,9 +86,9 @@ RES _ResourceLoader::load_threaded_get(const String &p_path) { return res; } -RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache) { +RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) { Error err = OK; - RES ret = ResourceLoader::load(p_path, p_type_hint, p_no_cache, &err); + RES ret = ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'."); return ret; @@ -135,7 +135,7 @@ void _ResourceLoader::_bind_methods() { ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get); - ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "cache_mode"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE)); ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type); ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources); ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies); @@ -146,6 +146,10 @@ void _ResourceLoader::_bind_methods() { BIND_ENUM_CONSTANT(THREAD_LOAD_IN_PROGRESS); BIND_ENUM_CONSTANT(THREAD_LOAD_FAILED); BIND_ENUM_CONSTANT(THREAD_LOAD_LOADED); + + BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE); + BIND_ENUM_CONSTANT(CACHE_MODE_REUSE); + BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE); } ////// _ResourceSaver ////// @@ -228,24 +232,32 @@ Error _OS::shell_open(String p_uri) { return OS::get_singleton()->shell_open(p_uri); } -int _OS::execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output, bool p_read_stderr) { - OS::ProcessID pid = -2; - int exitcode = 0; +int _OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr) { List<String> args; for (int i = 0; i < p_arguments.size(); i++) { args.push_back(p_arguments[i]); } String pipe; - Error err = OS::get_singleton()->execute(p_path, args, p_blocking, &pid, &pipe, &exitcode, p_read_stderr); - p_output.clear(); - p_output.push_back(pipe); + int exitcode = 0; + Error err = OS::get_singleton()->execute(p_path, args, &pipe, &exitcode, p_read_stderr); + r_output.push_back(pipe); if (err != OK) { return -1; - } else if (p_blocking) { - return exitcode; - } else { - return pid; } + return exitcode; +} + +int _OS::create_process(const String &p_path, const Vector<String> &p_arguments) { + List<String> args; + for (int i = 0; i < p_arguments.size(); i++) { + args.push_back(p_arguments[i]); + } + OS::ProcessID pid = 0; + Error err = OS::get_singleton()->create_process(p_path, args, &pid); + if (err != OK) { + return -1; + } + return pid; } Error _OS::kill(int p_pid) { @@ -264,6 +276,10 @@ String _OS::get_environment(const String &p_var) const { return OS::get_singleton()->get_environment(p_var); } +bool _OS::set_environment(const String &p_var, const String &p_value) const { + return OS::get_singleton()->set_environment(p_var, p_value); +} + String _OS::get_name() const { return OS::get_singleton()->get_name(); } @@ -290,6 +306,10 @@ Error _OS::set_thread_name(const String &p_name) { return Thread::set_name(p_name); } +Thread::ID _OS::get_thread_caller_id() const { + return Thread::get_caller_id(); +}; + bool _OS::has_feature(const String &p_feature) const { return OS::get_singleton()->has_feature(p_feature); } @@ -302,18 +322,6 @@ uint64_t _OS::get_static_memory_peak_usage() const { return OS::get_singleton()->get_static_memory_peak_usage(); } -int _OS::get_exit_code() const { - return OS::get_singleton()->get_exit_code(); -} - -void _OS::set_exit_code(int p_code) { - if (p_code < 0 || p_code > 125) { - WARN_PRINT("For portability reasons, the exit code should be set between 0 and 125 (inclusive)."); - } - - OS::get_singleton()->set_exit_code(p_code); -} - /** * Get current datetime with consideration for utc and * dst @@ -503,11 +511,19 @@ double _OS::get_unix_time() const { return OS::get_singleton()->get_unix_time(); } -void _OS::delay_usec(uint32_t p_usec) const { +/** This method uses a signed argument for better error reporting as it's used from the scripting API. */ +void _OS::delay_usec(int p_usec) const { + ERR_FAIL_COND_MSG( + p_usec < 0, + vformat("Can't sleep for %d microseconds. The delay provided must be greater than or equal to 0 microseconds.", p_usec)); OS::get_singleton()->delay_usec(p_usec); } -void _OS::delay_msec(uint32_t p_msec) const { +/** This method uses a signed argument for better error reporting as it's used from the scripting API. */ +void _OS::delay_msec(int p_msec) const { + ERR_FAIL_COND_MSG( + p_msec < 0, + vformat("Can't sleep for %d milliseconds. The delay provided must be greater than or equal to 0 milliseconds.", p_msec)); OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000); } @@ -665,22 +681,6 @@ String _OS::get_unique_id() const { return OS::get_singleton()->get_unique_id(); } -int _OS::get_tablet_driver_count() const { - return OS::get_singleton()->get_tablet_driver_count(); -} - -String _OS::get_tablet_driver_name(int p_driver) const { - return OS::get_singleton()->get_tablet_driver_name(p_driver); -} - -String _OS::get_current_tablet_driver() const { - return OS::get_singleton()->get_current_tablet_driver(); -} - -void _OS::set_current_tablet_driver(const String &p_driver) { - OS::get_singleton()->set_current_tablet_driver(p_driver); -} - _OS *_OS::singleton = nullptr; void _OS::_bind_methods() { @@ -697,13 +697,15 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_processor_count"), &_OS::get_processor_count); ClassDB::bind_method(D_METHOD("get_executable_path"), &_OS::get_executable_path); - ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "blocking", "output", "read_stderr"), &_OS::execute, DEFVAL(true), DEFVAL(Array()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr"), &_OS::execute, DEFVAL(Array()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("create_process", "path", "arguments"), &_OS::create_process); ClassDB::bind_method(D_METHOD("kill", "pid"), &_OS::kill); ClassDB::bind_method(D_METHOD("shell_open", "uri"), &_OS::shell_open); ClassDB::bind_method(D_METHOD("get_process_id"), &_OS::get_process_id); - ClassDB::bind_method(D_METHOD("get_environment", "environment"), &_OS::get_environment); - ClassDB::bind_method(D_METHOD("has_environment", "environment"), &_OS::has_environment); + ClassDB::bind_method(D_METHOD("get_environment", "variable"), &_OS::get_environment); + ClassDB::bind_method(D_METHOD("set_environment", "variable", "value"), &_OS::set_environment); + ClassDB::bind_method(D_METHOD("has_environment", "variable"), &_OS::has_environment); ClassDB::bind_method(D_METHOD("get_name"), &_OS::get_name); ClassDB::bind_method(D_METHOD("get_cmdline_args"), &_OS::get_cmdline_args); @@ -716,9 +718,6 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_datetime_from_unix_time", "unix_time_val"), &_OS::get_datetime_from_unix_time); ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime", "datetime"), &_OS::get_unix_time_from_datetime); - ClassDB::bind_method(D_METHOD("get_exit_code"), &_OS::get_exit_code); - ClassDB::bind_method(D_METHOD("set_exit_code", "code"), &_OS::set_exit_code); - ClassDB::bind_method(D_METHOD("delay_usec", "usec"), &_OS::delay_usec); ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &_OS::delay_msec); ClassDB::bind_method(D_METHOD("get_ticks_msec"), &_OS::get_ticks_msec); @@ -755,6 +754,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_file_access_save_and_swap", "enabled"), &_OS::set_use_file_access_save_and_swap); ClassDB::bind_method(D_METHOD("set_thread_name", "name"), &_OS::set_thread_name); + ClassDB::bind_method(D_METHOD("get_thread_caller_id"), &_OS::get_thread_caller_id); ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature); @@ -762,19 +762,11 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions); ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions); - ClassDB::bind_method(D_METHOD("get_tablet_driver_count"), &_OS::get_tablet_driver_count); - ClassDB::bind_method(D_METHOD("get_tablet_driver_name", "idx"), &_OS::get_tablet_driver_name); - ClassDB::bind_method(D_METHOD("get_current_tablet_driver"), &_OS::get_current_tablet_driver); - ClassDB::bind_method(D_METHOD("set_current_tablet_driver", "name"), &_OS::set_current_tablet_driver); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "tablet_driver"), "set_current_tablet_driver", "get_current_tablet_driver"); // Those default values need to be specified for the docs generator, // to avoid using values from the documentation writer's own OS instance. - ADD_PROPERTY_DEFAULT("tablet_driver", ""); ADD_PROPERTY_DEFAULT("exit_code", 0); ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false); ADD_PROPERTY_DEFAULT("low_processor_usage_mode_sleep_usec", 6900); @@ -1236,6 +1228,11 @@ Error _File::open(const String &p_path, ModeFlags p_mode_flags) { return err; } +void _File::flush() { + ERR_FAIL_COND_MSG(!f, "File must be opened before flushing."); + f->flush(); +} + void _File::close() { if (f) { memdelete(f); @@ -1529,6 +1526,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &_File::open_compressed, DEFVAL(0)); ClassDB::bind_method(D_METHOD("open", "path", "flags"), &_File::open); + ClassDB::bind_method(D_METHOD("flush"), &_File::flush); ClassDB::bind_method(D_METHOD("close"), &_File::close); ClassDB::bind_method(D_METHOD("get_path"), &_File::get_path); ClassDB::bind_method(D_METHOD("get_path_absolute"), &_File::get_path_absolute); @@ -1966,7 +1964,7 @@ void _Thread::_start_func(void *ud) { } Error _Thread::start(Object *p_instance, const StringName &p_method, const Variant &p_userdata, Priority p_priority) { - ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "Thread already started."); + ERR_FAIL_COND_V_MSG(active.is_set(), ERR_ALREADY_IN_USE, "Thread already started."); ERR_FAIL_COND_V(!p_instance, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_method == StringName(), ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_priority, PRIORITY_MAX, ERR_INVALID_PARAMETER); @@ -1975,49 +1973,33 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia target_method = p_method; target_instance = p_instance; userdata = p_userdata; - active = true; + active.set(); Ref<_Thread> *ud = memnew(Ref<_Thread>(this)); Thread::Settings s; s.priority = (Thread::Priority)p_priority; - thread = Thread::create(_start_func, ud, s); - if (!thread) { - active = false; - target_method = StringName(); - target_instance = nullptr; - userdata = Variant(); - return ERR_CANT_CREATE; - } + thread.start(_start_func, ud, s); return OK; } String _Thread::get_id() const { - if (!thread) { - return String(); - } - - return itos(thread->get_id()); + return itos(thread.get_id()); } bool _Thread::is_active() const { - return active; + return active.is_set(); } Variant _Thread::wait_to_finish() { - ERR_FAIL_COND_V_MSG(!thread, Variant(), "Thread must exist to wait for its completion."); - ERR_FAIL_COND_V_MSG(!active, Variant(), "Thread must be active to wait for its completion."); - Thread::wait_to_finish(thread); + ERR_FAIL_COND_V_MSG(!active.is_set(), Variant(), "Thread must be active to wait for its completion."); + thread.wait_to_finish(); Variant r = ret; - active = false; + active.clear(); target_method = StringName(); target_instance = nullptr; userdata = Variant(); - if (thread) { - memdelete(thread); - } - thread = nullptr; return r; } @@ -2033,10 +2015,6 @@ void _Thread::_bind_methods() { BIND_ENUM_CONSTANT(PRIORITY_HIGH); } -_Thread::~_Thread() { - ERR_FAIL_COND_MSG(active, "Reference to a Thread object was lost while the thread is still running..."); -} - ////// _ClassDB ////// PackedStringArray _ClassDB::get_class_list() const { diff --git a/core/core_bind.h b/core/core_bind.h index 30dfa2d7a8..3920116ca4 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -40,6 +40,7 @@ #include "core/os/os.h" #include "core/os/semaphore.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" class _ResourceLoader : public Object { GDCLASS(_ResourceLoader, Object); @@ -56,13 +57,19 @@ public: THREAD_LOAD_LOADED }; + enum CacheMode { + CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource. + CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available + CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk + }; + static _ResourceLoader *get_singleton() { return singleton; } Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false); ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array()); RES load_threaded_get(const String &p_path); - RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false); + RES load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE); Vector<String> get_recognized_extensions_for_type(const String &p_type); void set_abort_on_missing_resources(bool p_abort); PackedStringArray get_dependencies(const String &p_path); @@ -73,6 +80,7 @@ public: }; VARIANT_ENUM_CAST(_ResourceLoader::ThreadLoadStatus); +VARIANT_ENUM_CAST(_ResourceLoader::CacheMode); class _ResourceSaver : public Object { GDCLASS(_ResourceSaver, Object); @@ -155,8 +163,8 @@ public: int get_low_processor_usage_mode_sleep_usec() const; String get_executable_path() const; - int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking = true, Array p_output = Array(), bool p_read_stderr = false); - + int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false); + int create_process(const String &p_path, const Vector<String> &p_arguments); Error kill(int p_pid); Error shell_open(String p_uri); @@ -164,6 +172,7 @@ public: bool has_environment(const String &p_var) const; String get_environment(const String &p_var) const; + bool set_environment(const String &p_var, const String &p_value) const; String get_name() const; Vector<String> get_cmdline_args(); @@ -190,8 +199,6 @@ public: void set_use_file_access_save_and_swap(bool p_enable); - int get_exit_code() const; - void set_exit_code(int p_code); Dictionary get_date(bool utc) const; Dictionary get_time(bool utc) const; Dictionary get_datetime(bool utc) const; @@ -203,8 +210,8 @@ public: uint64_t get_static_memory_usage() const; uint64_t get_static_memory_peak_usage() const; - void delay_usec(uint32_t p_usec) const; - void delay_msec(uint32_t p_msec) const; + void delay_usec(int p_usec) const; + void delay_msec(int p_msec) const; uint32_t get_ticks_msec() const; uint64_t get_ticks_usec() const; @@ -232,6 +239,7 @@ public: String get_user_data_dir() const; Error set_thread_name(const String &p_name); + Thread::ID get_thread_caller_id() const; bool has_feature(const String &p_feature) const; @@ -239,11 +247,6 @@ public: bool request_permissions(); Vector<String> get_granted_permissions() const; - int get_tablet_driver_count() const; - String get_tablet_driver_name(int p_driver) const; - String get_current_tablet_driver() const; - void set_current_tablet_driver(const String &p_driver); - static _OS *get_singleton() { return singleton; } _OS() { singleton = this; } @@ -378,6 +381,7 @@ public: Error open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ); Error open(const String &p_path, ModeFlags p_mode_flags); // open a file. + void flush(); // Flush a file (write its buffer to disk). void close(); // Close a file. bool is_open() const; // True when file is open. @@ -550,10 +554,10 @@ class _Thread : public Reference { protected: Variant ret; Variant userdata; - volatile bool active = false; + SafeFlag active; Object *target_instance = nullptr; StringName target_method; - Thread *thread = nullptr; + Thread thread; static void _bind_methods(); static void _start_func(void *ud); @@ -569,9 +573,6 @@ public: String get_id() const; bool is_active() const; Variant wait_to_finish(); - - _Thread() {} - ~_Thread(); }; VARIANT_ENUM_CAST(_Thread::Priority); diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 3df121b9cb..f9edff1899 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -125,6 +125,9 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(VERTICAL); BIND_CORE_ENUM_CONSTANT(HORIZONTAL); + BIND_CORE_ENUM_CONSTANT(CLOCKWISE); + BIND_CORE_ENUM_CONSTANT(COUNTERCLOCKWISE); + BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT); BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER); BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT); @@ -426,6 +429,12 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MISC1); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE1); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE2); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE3); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE4); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_TOUCHPAD); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_SDL_MAX); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MAX); diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp index 18ac2a2d43..ff8569e45d 100644 --- a/core/core_string_names.cpp +++ b/core/core_string_names.cpp @@ -76,5 +76,6 @@ CoreStringNames::CoreStringNames() : bind(StaticCString::create("bind")), unbind(StaticCString::create("unbind")), emit(StaticCString::create("emit")), - notification(StaticCString::create("notification")) { + notification(StaticCString::create("notification")), + property_list_changed(StaticCString::create("property_list_changed")) { } diff --git a/core/core_string_names.h b/core/core_string_names.h index b4e386f3bc..abe751372e 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -96,6 +96,7 @@ public: StringName unbind; StringName emit; StringName notification; + StringName property_list_changed; }; #endif // CORE_STRING_NAMES_H diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index 99f4fb232d..f43f3e3290 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -141,7 +141,7 @@ void Crypto::_bind_methods() { /// Resource loader/saver -RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { String el = p_path.get_extension().to_lower(); if (el == "crt") { X509Certificate *cert = X509Certificate::create(); diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 30d2129e3d..9438fcfea5 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -116,7 +116,7 @@ public: class ResourceFormatLoaderCrypto : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index 2e388d5934..857e3af268 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/core/debugger/remote_debugger_peer.cpp @@ -65,12 +65,8 @@ int RemoteDebuggerPeerTCP::get_max_message_size() const { } void RemoteDebuggerPeerTCP::close() { - if (thread) { - running = false; - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; - } + running = false; + thread.wait_to_finish(); tcp_client->disconnect_from_host(); out_buf.resize(0); in_buf.resize(0); @@ -85,7 +81,7 @@ RemoteDebuggerPeerTCP::RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_tcp) { connected = true; #ifndef NO_THREADS running = true; - thread = Thread::create(_thread_func, this); + thread.start(_thread_func, this); #endif } else { tcp_client.instance(); @@ -188,7 +184,7 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po connected = true; #ifndef NO_THREADS running = true; - thread = Thread::create(_thread_func, this); + thread.start(_thread_func, this); #endif return OK; } diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h index c759c65568..652e2d9d20 100644 --- a/core/debugger/remote_debugger_peer.h +++ b/core/debugger/remote_debugger_peer.h @@ -58,7 +58,7 @@ class RemoteDebuggerPeerTCP : public RemoteDebuggerPeer { private: Ref<StreamPeerTCP> tcp_client; Mutex mutex; - Thread *thread = nullptr; + Thread thread; List<Array> in_queue; List<Array> out_queue; int out_left = 0; diff --git a/core/error/error_macros.h b/core/error/error_macros.h index 8eb6217ce8..f909a67d55 100644 --- a/core/error/error_macros.h +++ b/core/error/error_macros.h @@ -33,6 +33,8 @@ #include "core/typedefs.h" +#include "core/templates/safe_refcount.h" + class String; enum ErrorHandlerType { @@ -577,10 +579,10 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li */ #define WARN_DEPRECATED \ if (true) { \ - static volatile bool warning_shown = false; \ - if (!warning_shown) { \ + static SafeFlag warning_shown; \ + if (!warning_shown.is_set()) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \ - warning_shown = true; \ + warning_shown.set(); \ } \ } else \ ((void)0) @@ -590,10 +592,10 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li */ #define WARN_DEPRECATED_MSG(m_msg) \ if (true) { \ - static volatile bool warning_shown = false; \ - if (!warning_shown) { \ + static SafeFlag warning_shown; \ + if (!warning_shown.is_set()) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \ - warning_shown = true; \ + warning_shown.set(); \ } \ } else \ ((void)0) diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt index 180708cea6..668a531b1f 100644 --- a/core/input/gamecontrollerdb.txt +++ b/core/input/gamecontrollerdb.txt @@ -1,4 +1,4 @@ -# Game Controller DB for SDL in 2.0.10 format +# Game Controller DB for SDL in 2.0.9 format # Source: https://github.com/gabomdq/SDL_GameControllerDB # Windows @@ -35,7 +35,7 @@ 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, -03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, @@ -80,14 +80,15 @@ 030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows, 03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows, +030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows, 030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, -030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, -030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -98,6 +99,7 @@ 03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows, 03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows, +03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, @@ -119,6 +121,7 @@ 030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows, 03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -164,7 +167,8 @@ 030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,lefttrigger:b6,righttrigger:b7,platform:Windows, +030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows, 03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -193,6 +197,8 @@ 03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -234,6 +240,7 @@ 030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, 03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, 03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, @@ -244,7 +251,6 @@ 03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b13,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4, 03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -259,6 +265,7 @@ 030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, +03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows, 0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, 0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, 030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -271,8 +278,8 @@ 03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b0,y:b1,platform:Windows, -03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows, +03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows, +03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows, 03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, @@ -283,6 +290,8 @@ 03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows, 0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, +03000000a30c00002500000000000000,Sega Genesis Mini 3B controller,a:b2,b:b1,start:b9,dpup:-a4,dpdown:+a4,dpleft:-a3,dpright:+a3,righttrigger:b5,platform:Windows, +03000000a30c00002400000000000000,Sega Mega Drive Mini 6B controller,a:b2,b:b1,start:b9,dpup:-a4,dpdown:+a4,dpleft:-a3,dpright:+a3,rightshoulder:b4,righttrigger:b5,x:b3,y:b0,platform:Windows, 030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -328,6 +337,8 @@ 030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:+a3,righty:+a4,start:b4,x:b2,y:b3,platform:Windows, 030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000005e040000ff02000000007801,Xbox One Elite Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, @@ -338,7 +349,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, # Mac OS X -030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X, @@ -355,12 +366,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, -03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X, +03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X, @@ -427,6 +440,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -446,6 +460,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, 030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X, +030000004c050000e60c000000010000,Sony DualSense,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X, @@ -474,6 +489,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, 030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, 030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, @@ -506,12 +523,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, -03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, -05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, -030000005e0400008e02000020010000,8BitDo Wireless Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -03000000c82d00000031000011010000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +030000005e0400008e02000020010000,8BitDo Wireless Adapter (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000031000011010000,8BitDo Wireless Adapter (DInput),a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +050000005e040000e002000030110000,8BitDo Zero 2 (XInput),a:b0,b:b1,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,start:b7,x:b2,y:b3,platform:Linux, 05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, 05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, @@ -521,11 +539,16 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux, -05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, 03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -567,6 +590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -592,6 +616,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000242f00002d00000011010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, 030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, @@ -600,10 +625,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, -030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,platform:Linux, +030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, 030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +050000004d4f435554452d3035305800,M54-PC,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,platform:Linux, 05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -635,6 +660,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, 05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, @@ -642,12 +669,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux, -060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, +03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b0,y:b3,platform:Linux, 050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, @@ -666,21 +695,23 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux, 03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +05000000491900000204000000000000,PG-9118,x:b76,a:b73,b:b74,y:b77,back:b83,start:b84,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b79,lefttrigger:b81,rightshoulder:b80,righttrigger:b82,leftstick:b86,rightstick:b87,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux, 0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, @@ -709,6 +740,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, 030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, @@ -717,6 +750,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -735,14 +769,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, +03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux, 03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, 03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, 03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, 03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000a30600001005000000010000,Saitek Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, 03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, 03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, 03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -754,15 +789,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, 03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -774,11 +809,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, 03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00001431000010010000,SZMY-POWER CO. LTD. PS3 gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, 030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux, +030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux, 030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, 030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -815,6 +852,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -823,6 +864,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0, # Android 05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android, @@ -857,20 +899,27 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android, +32633532643734376632656664383733,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, +61303162353165316365336436343139,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, 050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android, 30306539356238653637313730656134,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android, +050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,platform:Android, 050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android, 34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android, 050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android, @@ -879,13 +928,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, 05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, 05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, +05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, 05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, -050000004c050000cc090000df070000,DUALSHOCK 4 Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, 4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, +050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000004c050000cc090000ff876d01,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,,platform:iOS, +050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS, 05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, +050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt index 51ddda1e4e..c43cd6c8ac 100644 --- a/core/input/godotcontrollerdb.txt +++ b/core/input/godotcontrollerdb.txt @@ -8,13 +8,26 @@ __XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftst Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android, # Javascript -Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,platform:Javascript, -c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Javascript, -303534632d303563342d576972656c65,PS4 Controller USB/Win,leftx:a0,lefty:a1,dpdown:b15,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,lefttrigger:a3,x:b0,dpup:b14,dpleft:b16,dpright:b17,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,righttrigger:b7,b:b2,platform:Javascript, -303534632d303563342d536f6e792043,PS4 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:a7,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,dpleft:a6,lefttrigger:a3,x:b0,dpup:a7,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:a6,righttrigger:a4,b:b2,platform:Javascript, -303534632d303236382d536f6e792050,PS3 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:b6,rightstick:b2,rightshoulder:b11,rightx:a2,start:b3,righty:a3,dpleft:b7,lefttrigger:b8,x:b15,dpup:b4,back:b0,leftstick:b1,leftshoulder:b10,y:b12,a:b14,dpright:b5,righttrigger:b9,b:b13,platform:Javascript, -303435652d303731392d58626f782033,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Javascript, -303435652d303238652d4d6963726f73,Wired X360 Controller,leftx:a0,lefty:a1,dpdown:a7,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:a6,lefttrigger:a2,x:b2,dpup:a7,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:a6,righttrigger:a5,b:b1,platform:Javascript, +standard,Standard Gamepad Mapping,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a6,righttrigger:a7,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftstick:b10,rightstick:b11,platform:Javascript, +Linux24c6581a,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript, +Linux0e6f0301,Logic 3 Controller (xbox compatible),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript, +Linux045e028e,Microsoft X-Box 360 pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript, +Linux045e02d1,Microsoft X-Box One pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript, +Linux045e02ea,Microsoft X-Box One S pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript, +Linux045e0b12,Microsoft X-Box Series X pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript, +Linux044fb315,Thrustmaster dual analog 3.2,a:b0,b:b2,y:b3,x:b1,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:-a5,dpleft:-a4,dpdown:+a5,dpright:+a4,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Javascript, +Linux0e8f0003,PS3 Controller,a:b2,b:b1,back:b8,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Javascript, +MacOSX24c6581a,PowerA Xbox One Cabled,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript +MacOSX045e028e,Xbox 360 Wired Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript +MacOSX045e02d1,Xbox One Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript +MacOSX045e02ea,Xbox One S Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript +MacOSX045e0b12,Xbox Series X Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript +Linux15320a14,Razer Wolverine Ultimate,a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript +Linux05832060,iBuffalo BSGP801,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +MacOSX05832060,iBuffalo BSGP801,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +Linux0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +Windows0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +MacOSX0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a4,dpleft:-a3,dpdown:+a4,dpright:+a3,platform:Javascript # UWP __UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:UWP, diff --git a/core/input/input.cpp b/core/input/input.cpp index c96884a7b3..f928ae7654 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -55,6 +55,12 @@ static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = { "dpdown", "dpleft", "dpright", + "misc1", + "paddle1", + "paddle2", + "paddle3", + "paddle4", + "touchpad", }; static const char *_joy_axes[JOY_AXIS_SDL_MAX] = { @@ -91,11 +97,11 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed); ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed); ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed); - ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed); - ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &Input::is_action_just_pressed); - ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released); - ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &Input::get_action_strength); - ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action"), &Input::get_action_strength); + ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact_match"), &Input::is_action_pressed, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact_match"), &Input::is_action_just_pressed, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact_match"), &Input::is_action_just_released, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_axis", "negative_action", "positive_action"), &Input::get_axis); ClassDB::bind_method(D_METHOD("get_vector", "negative_x", "positive_x", "negative_y", "positive_y", "deadzone"), &Input::get_vector, DEFVAL(-1.0f)); ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false)); @@ -234,16 +240,28 @@ bool Input::is_joy_button_pressed(int p_device, int p_button) const { return joy_buttons_pressed.has(_combine_device(p_button, p_device)); } -bool Input::is_action_pressed(const StringName &p_action) const { - return action_state.has(p_action) && action_state[p_action].pressed; +bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const { +#ifdef DEBUG_ENABLED + bool has_action = InputMap::get_singleton()->has_action(p_action); + ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); +#endif + return action_state.has(p_action) && action_state[p_action].pressed && (p_exact ? action_state[p_action].exact : true); } -bool Input::is_action_just_pressed(const StringName &p_action) const { +bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const { +#ifdef DEBUG_ENABLED + bool has_action = InputMap::get_singleton()->has_action(p_action); + ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); +#endif const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) { return false; } + if (p_exact && E->get().exact == false) { + return false; + } + if (Engine::get_singleton()->is_in_physics_frame()) { return E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames(); } else { @@ -251,12 +269,20 @@ bool Input::is_action_just_pressed(const StringName &p_action) const { } } -bool Input::is_action_just_released(const StringName &p_action) const { +bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const { +#ifdef DEBUG_ENABLED + bool has_action = InputMap::get_singleton()->has_action(p_action); + ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); +#endif const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) { return false; } + if (p_exact && E->get().exact == false) { + return false; + } + if (Engine::get_singleton()->is_in_physics_frame()) { return !E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames(); } else { @@ -264,21 +290,33 @@ bool Input::is_action_just_released(const StringName &p_action) const { } } -float Input::get_action_strength(const StringName &p_action) const { +float Input::get_action_strength(const StringName &p_action, bool p_exact) const { +#ifdef DEBUG_ENABLED + bool has_action = InputMap::get_singleton()->has_action(p_action); + ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); +#endif const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) { return 0.0f; } + if (p_exact && E->get().exact == false) { + return 0.0f; + } + return E->get().strength; } -float Input::get_action_raw_strength(const StringName &p_action) const { +float Input::get_action_raw_strength(const StringName &p_action, bool p_exact) const { const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) { return 0.0f; } + if (p_exact && E->get().exact == false) { + return 0.0f; + } + return E->get().raw_strength; } @@ -582,20 +620,21 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em } } - for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) { - if (InputMap::get_singleton()->event_is_action(p_event, E->key())) { - // Save the action's state - if (!p_event->is_echo() && is_action_pressed(E->key()) != p_event->is_action_pressed(E->key())) { + for (OrderedHashMap<StringName, InputMap::Action>::ConstElement E = InputMap::get_singleton()->get_action_map().front(); E; E = E.next()) { + if (InputMap::get_singleton()->event_is_action(p_event, E.key())) { + // If not echo and action pressed state has changed + if (!p_event->is_echo() && is_action_pressed(E.key(), false) != p_event->is_action_pressed(E.key())) { Action action; action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.process_frame = Engine::get_singleton()->get_process_frames(); - action.pressed = p_event->is_action_pressed(E->key()); + action.pressed = p_event->is_action_pressed(E.key()); action.strength = 0.0f; action.raw_strength = 0.0f; - action_state[E->key()] = action; + action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key(), true); + action_state[E.key()] = action; } - action_state[E->key()].strength = p_event->get_action_strength(E->key()); - action_state[E->key()].raw_strength = p_event->get_action_raw_strength(E->key()); + action_state[E.key()].strength = p_event->get_action_strength(E.key()); + action_state[E.key()].raw_strength = p_event->get_action_raw_strength(E.key()); } } @@ -886,10 +925,10 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) { jx.min = p_value.min; jx.value = p_value.value < 0.5 ? 0.6 : 0.4; joy_axis(p_device, p_axis, jx); - } else if (ABS(last) > 0.5 && last * p_value.value < 0) { + } else if (ABS(last) > 0.5 && last * p_value.value <= 0) { JoyAxis jx; jx.min = p_value.min; - jx.value = p_value.value < 0 ? 0.1 : -0.1; + jx.value = last > 0 ? 0.1 : -0.1; joy_axis(p_device, p_axis, jx); } diff --git a/core/input/input.h b/core/input/input.h index 445b7ff0cf..0e3af42381 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -116,6 +116,7 @@ private: uint64_t physics_frame; uint64_t process_frame; bool pressed; + bool exact; float strength; float raw_strength; }; @@ -261,11 +262,11 @@ public: bool is_key_pressed(int p_keycode) const; bool is_mouse_button_pressed(int p_button) const; bool is_joy_button_pressed(int p_device, int p_button) const; - bool is_action_pressed(const StringName &p_action) const; - bool is_action_just_pressed(const StringName &p_action) const; - bool is_action_just_released(const StringName &p_action) const; - float get_action_strength(const StringName &p_action) const; - float get_action_raw_strength(const StringName &p_action) const; + bool is_action_pressed(const StringName &p_action, bool p_exact = false) const; + bool is_action_just_pressed(const StringName &p_action, bool p_exact = false) const; + bool is_action_just_released(const StringName &p_action, bool p_exact = false) const; + float get_action_strength(const StringName &p_action, bool p_exact = false) const; + float get_action_raw_strength(const StringName &p_action, bool p_exact = false) const; float get_axis(const StringName &p_negative_action, const StringName &p_positive_action) const; Vector2 get_vector(const StringName &p_negative_x, const StringName &p_positive_x, const StringName &p_negative_y, const StringName &p_positive_y, float p_deadzone = -1.0f) const; diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 2771a15b80..c6910d2b1f 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -44,31 +44,31 @@ int InputEvent::get_device() const { return device; } -bool InputEvent::is_action(const StringName &p_action) const { - return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action); +bool InputEvent::is_action(const StringName &p_action, bool p_exact_match) const { + return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match); } -bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo) const { +bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo, bool p_exact_match) const { bool pressed; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed); + bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, &pressed, nullptr, nullptr); return valid && pressed && (p_allow_echo || !is_echo()); } -bool InputEvent::is_action_released(const StringName &p_action) const { +bool InputEvent::is_action_released(const StringName &p_action, bool p_exact_match) const { bool pressed; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed); + bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, &pressed, nullptr, nullptr); return valid && !pressed; } -float InputEvent::get_action_strength(const StringName &p_action) const { +float InputEvent::get_action_strength(const StringName &p_action, bool p_exact_match) const { float strength; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, nullptr, &strength); + bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, nullptr, &strength, nullptr); return valid ? strength : 0.0f; } -float InputEvent::get_action_raw_strength(const StringName &p_action) const { +float InputEvent::get_action_raw_strength(const StringName &p_action, bool p_exact_match) const { float raw_strength; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, nullptr, nullptr, &raw_strength); + bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, nullptr, nullptr, &raw_strength); return valid ? raw_strength : 0.0f; } @@ -100,10 +100,10 @@ void InputEvent::_bind_methods() { ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device); ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device); - ClassDB::bind_method(D_METHOD("is_action", "action"), &InputEvent::is_action); - ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "allow_echo"), &InputEvent::is_action_pressed, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("is_action_released", "action"), &InputEvent::is_action_released); - ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputEvent::get_action_strength); + ClassDB::bind_method(D_METHOD("is_action", "action", "exact_match"), &InputEvent::is_action, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "allow_echo", "exact_match"), &InputEvent::is_action_pressed, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_released", "action", "exact_match"), &InputEvent::is_action_released, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &InputEvent::get_action_strength, DEFVAL(false)); ClassDB::bind_method(D_METHOD("is_pressed"), &InputEvent::is_pressed); ClassDB::bind_method(D_METHOD("is_echo"), &InputEvent::is_echo); @@ -384,6 +384,31 @@ String InputEventKey::to_string() { return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", kc, mods, physical, p, e); } +Ref<InputEventKey> InputEventKey::create_reference(uint32_t p_keycode) { + Ref<InputEventKey> ie; + ie.instance(); + ie->set_keycode(p_keycode & KEY_CODE_MASK); + ie->set_unicode(p_keycode & KEY_CODE_MASK); + + if (p_keycode & KEY_MASK_SHIFT) { + ie->set_shift(true); + } + if (p_keycode & KEY_MASK_ALT) { + ie->set_alt(true); + } + if (p_keycode & KEY_MASK_CTRL) { + ie->set_control(true); + } + if (p_keycode & KEY_MASK_CMD) { + ie->set_command(true); + } + if (p_keycode & KEY_MASK_META) { + ie->set_metakey(true); + } + + return ie; +} + bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { Ref<InputEventKey> key = p_event; if (key.is_null()) { @@ -985,6 +1010,12 @@ static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = { TTRC("D-pad Down"), TTRC("D-pad Left"), TTRC("D-pad Right"), + TTRC("Xbox Share, PS5 Microphone, Nintendo Capture"), + TTRC("Xbox Paddle 1"), + TTRC("Xbox Paddle 2"), + TTRC("Xbox Paddle 3"), + TTRC("Xbox Paddle 4"), + TTRC("PS4/5 Touchpad"), }; String InputEventJoypadButton::as_text() const { @@ -1005,6 +1036,14 @@ String InputEventJoypadButton::to_string() { return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure)); } +Ref<InputEventJoypadButton> InputEventJoypadButton::create_reference(int p_btn_index) { + Ref<InputEventJoypadButton> ie; + ie.instance(); + ie->set_button_index(p_btn_index); + + return ie; +} + void InputEventJoypadButton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventJoypadButton::set_button_index); ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventJoypadButton::get_button_index); diff --git a/core/input/input_event.h b/core/input/input_event.h index 1500faa24c..df81b9fc75 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -76,7 +76,13 @@ enum JoyButtonList { JOY_BUTTON_DPAD_DOWN = 12, JOY_BUTTON_DPAD_LEFT = 13, JOY_BUTTON_DPAD_RIGHT = 14, - JOY_BUTTON_SDL_MAX = 15, + JOY_BUTTON_MISC1 = 15, + JOY_BUTTON_PADDLE1 = 16, + JOY_BUTTON_PADDLE2 = 17, + JOY_BUTTON_PADDLE3 = 18, + JOY_BUTTON_PADDLE4 = 19, + JOY_BUTTON_TOUCHPAD = 20, + JOY_BUTTON_SDL_MAX = 21, JOY_BUTTON_MAX = 36, // Android supports up to 36 buttons. }; @@ -122,11 +128,11 @@ public: void set_device(int p_device); int get_device() const; - bool is_action(const StringName &p_action) const; - bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false) const; - bool is_action_released(const StringName &p_action) const; - float get_action_strength(const StringName &p_action) const; - float get_action_raw_strength(const StringName &p_action) const; + bool is_action(const StringName &p_action, bool p_exact_match = false) const; + bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false, bool p_exact_match = false) const; + bool is_action_released(const StringName &p_action, bool p_exact_match = false) const; + float get_action_strength(const StringName &p_action, bool p_exact_match = false) const; + float get_action_raw_strength(const StringName &p_action, bool p_exact_match = false) const; // To be removed someday, since they do not make sense for all events virtual bool is_pressed() const; @@ -254,6 +260,8 @@ public: virtual String as_text() const override; virtual String to_string() override; + static Ref<InputEventKey> create_reference(uint32_t p_keycode_with_modifier_masks); + InputEventKey() {} }; @@ -400,6 +408,8 @@ public: virtual String as_text() const override; virtual String to_string() override; + static Ref<InputEventJoypadButton> create_reference(int p_btn_index); + InputEventJoypadButton() {} }; diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 53ed925c1f..e0b25fa092 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -50,7 +50,7 @@ void InputMap::_bind_methods() { ClassDB::bind_method(D_METHOD("action_erase_event", "action", "event"), &InputMap::action_erase_event); ClassDB::bind_method(D_METHOD("action_erase_events", "action"), &InputMap::action_erase_events); ClassDB::bind_method(D_METHOD("action_get_events", "action"), &InputMap::_action_get_events); - ClassDB::bind_method(D_METHOD("event_is_action", "event", "action"), &InputMap::event_is_action); + ClassDB::bind_method(D_METHOD("event_is_action", "event", "action", "exact_match"), &InputMap::event_is_action, DEFVAL(false)); ClassDB::bind_method(D_METHOD("load_from_project_settings"), &InputMap::load_from_project_settings); } @@ -88,14 +88,14 @@ List<StringName> InputMap::get_actions() const { return actions; } - for (Map<StringName, Action>::Element *E = input_map.front(); E; E = E->next()) { - actions.push_back(E->key()); + for (OrderedHashMap<StringName, Action>::Element E = input_map.front(); E; E = E.next()) { + actions.push_back(E.key()); } return actions; } -List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength) const { +List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const { ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { @@ -106,7 +106,9 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re int device = e->get_device(); if (device == ALL_DEVICES || device == p_event->get_device()) { - if (e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { + if (p_exact_match && e->shortcut_match(p_event)) { + return E; + } else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { return E; } } @@ -134,7 +136,7 @@ void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) { ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object."); ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'."); - if (_find_event(input_map[p_action], p_event)) { + if (_find_event(input_map[p_action], p_event, true)) { return; // Already addded. } @@ -143,13 +145,13 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) { ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); - return (_find_event(input_map[p_action], p_event) != nullptr); + return (_find_event(input_map[p_action], p_event, true) != nullptr); } void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) { ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'."); - List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event); + List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true); if (E) { input_map[p_action].inputs.erase(E); if (Input::get_singleton()->is_action_pressed(p_action)) { @@ -177,20 +179,20 @@ Array InputMap::_action_get_events(const StringName &p_action) { } const List<Ref<InputEvent>> *InputMap::action_get_events(const StringName &p_action) { - const Map<StringName, Action>::Element *E = input_map.find(p_action); + const OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action); if (!E) { return nullptr; } - return &E->get().inputs; + return &E.get().inputs; } -bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const { - return event_get_action_status(p_event, p_action); +bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const { + return event_get_action_status(p_event, p_action, p_exact_match); } -bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength, float *p_raw_strength) const { - Map<StringName, Action>::Element *E = input_map.find(p_action); +bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const { + OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action); ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); Ref<InputEventAction> input_event_action = p_event; @@ -207,7 +209,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str bool pressed; float strength; float raw_strength; - List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength, &raw_strength); + List<Ref<InputEvent>>::Element *event = _find_event(E.get(), p_event, p_exact_match, &pressed, &strength, &raw_strength); if (event != nullptr) { if (p_pressed != nullptr) { *p_pressed = pressed; @@ -224,7 +226,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str } } -const Map<StringName, InputMap::Action> &InputMap::get_action_map() const { +const OrderedHashMap<StringName, InputMap::Action> &InputMap::get_action_map() const { return input_map; } @@ -258,84 +260,444 @@ void InputMap::load_from_project_settings() { } } +struct _BuiltinActionDisplayName { + const char *name; + const char *display_name; +}; + +static const _BuiltinActionDisplayName _builtin_action_display_names[] = { + /* clang-format off */ + { "ui_accept", TTRC("Accept") }, + { "ui_select", TTRC("Select") }, + { "ui_cancel", TTRC("Cancel") }, + { "ui_focus_next", TTRC("Focus Next") }, + { "ui_focus_prev", TTRC("Focus Prev") }, + { "ui_left", TTRC("Left") }, + { "ui_right", TTRC("Right") }, + { "ui_up", TTRC("Up") }, + { "ui_down", TTRC("Down") }, + { "ui_page_up", TTRC("Page Up") }, + { "ui_page_down", TTRC("Page Down") }, + { "ui_home", TTRC("Home") }, + { "ui_end", TTRC("End") }, + { "ui_cut", TTRC("Cut") }, + { "ui_copy", TTRC("Copy") }, + { "ui_paste", TTRC("Paste") }, + { "ui_undo", TTRC("Undo") }, + { "ui_redo", TTRC("Redo") }, + { "ui_text_completion_query", TTRC("Completion Query") }, + { "ui_text_newline", TTRC("New Line") }, + { "ui_text_newline_blank", TTRC("New Blank Line") }, + { "ui_text_newline_above", TTRC("New Line Above") }, + { "ui_text_indent", TTRC("Indent") }, + { "ui_text_dedent", TTRC("Dedent") }, + { "ui_text_backspace", TTRC("Backspace") }, + { "ui_text_backspace_word", TTRC("Backspace Word") }, + { "ui_text_backspace_word.OSX", TTRC("Backspace Word") }, + { "ui_text_backspace_all_to_left", TTRC("Backspace all to Left") }, + { "ui_text_backspace_all_to_left.OSX", TTRC("Backspace all to Left") }, + { "ui_text_delete", TTRC("Delete") }, + { "ui_text_delete_word", TTRC("Delete Word") }, + { "ui_text_delete_word.OSX", TTRC("Delete Word") }, + { "ui_text_delete_all_to_right", TTRC("Delete all to Right") }, + { "ui_text_delete_all_to_right.OSX", TTRC("Delete all to Right") }, + { "ui_text_caret_left", TTRC("Caret Left") }, + { "ui_text_caret_word_left", TTRC("Caret Word Left") }, + { "ui_text_caret_word_left.OSX", TTRC("Caret Word Left") }, + { "ui_text_caret_right", TTRC("Caret Right") }, + { "ui_text_caret_word_right", TTRC("Caret Word Right") }, + { "ui_text_caret_word_right.OSX", TTRC("Caret Word Right") }, + { "ui_text_caret_up", TTRC("Caret Up") }, + { "ui_text_caret_down", TTRC("Caret Down") }, + { "ui_text_caret_line_start", TTRC("Caret Line Start") }, + { "ui_text_caret_line_start.OSX", TTRC("Caret Line Start") }, + { "ui_text_caret_line_end", TTRC("Caret Line End") }, + { "ui_text_caret_line_end.OSX", TTRC("Caret Line End") }, + { "ui_text_caret_page_up", TTRC("Caret Page Up") }, + { "ui_text_caret_page_down", TTRC("Caret Page Down") }, + { "ui_text_caret_document_start", TTRC("Caret Document Start") }, + { "ui_text_caret_document_start.OSX", TTRC("Caret Document Start") }, + { "ui_text_caret_document_end", TTRC("Caret Document End") }, + { "ui_text_caret_document_end.OSX", TTRC("Caret Document End") }, + { "ui_text_scroll_up", TTRC("Scroll Up") }, + { "ui_text_scroll_up.OSX", TTRC("Scroll Up") }, + { "ui_text_scroll_down", TTRC("Scroll Down") }, + { "ui_text_scroll_down.OSX", TTRC("Scroll Down") }, + { "ui_text_select_all", TTRC("Select All") }, + { "ui_text_toggle_insert_mode", TTRC("Toggle Insert Mode") }, + { "ui_graph_duplicate", TTRC("Duplicate Nodes") }, + { "ui_graph_delete", TTRC("Delete Nodes") }, + { "ui_filedialog_up_one_level", TTRC("Go Up One Level") }, + { "ui_filedialog_refresh", TTRC("Refresh") }, + { "ui_filedialog_show_hidden", TTRC("Show Hidden") }, + { "ui_swap_input_direction ", TTRC("Swap Input Direction") }, + { "", TTRC("")} + /* clang-format on */ +}; + +String InputMap::get_builtin_display_name(const String &p_name) const { + int len = sizeof(_builtin_action_display_names) / sizeof(_BuiltinActionDisplayName); + + for (int i = 0; i < len; i++) { + if (_builtin_action_display_names[i].name == p_name) { + return RTR(_builtin_action_display_names[i].display_name); + } + } + + return p_name; +} + +const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() { + // Return cache if it has already been built. + if (default_builtin_cache.size()) { + return default_builtin_cache; + } + + List<Ref<InputEvent>> inputs; + inputs.push_back(InputEventKey::create_reference(KEY_ENTER)); + inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER)); + inputs.push_back(InputEventKey::create_reference(KEY_SPACE)); + default_builtin_cache.insert("ui_accept", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_Y)); + inputs.push_back(InputEventKey::create_reference(KEY_SPACE)); + default_builtin_cache.insert("ui_select", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_ESCAPE)); + default_builtin_cache.insert("ui_cancel", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_TAB)); + default_builtin_cache.insert("ui_focus_next", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_TAB | KEY_MASK_SHIFT)); + default_builtin_cache.insert("ui_focus_prev", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_LEFT)); + inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_LEFT)); + default_builtin_cache.insert("ui_left", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_RIGHT)); + inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_RIGHT)); + default_builtin_cache.insert("ui_right", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_UP)); + inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_UP)); + default_builtin_cache.insert("ui_up", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DOWN)); + inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_DOWN)); + default_builtin_cache.insert("ui_down", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_PAGEUP)); + default_builtin_cache.insert("ui_page_up", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_PAGEDOWN)); + default_builtin_cache.insert("ui_page_down", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_HOME)); + default_builtin_cache.insert("ui_home", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_END)); + default_builtin_cache.insert("ui_end", inputs); + + // ///// UI basic Shortcuts ///// + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_X | KEY_MASK_CMD)); + inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_SHIFT)); + default_builtin_cache.insert("ui_cut", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_C | KEY_MASK_CMD)); + inputs.push_back(InputEventKey::create_reference(KEY_INSERT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_copy", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_V | KEY_MASK_CMD)); + inputs.push_back(InputEventKey::create_reference(KEY_INSERT | KEY_MASK_SHIFT)); + default_builtin_cache.insert("ui_paste", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_Z | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_undo", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_Z | KEY_MASK_CMD | KEY_MASK_SHIFT)); + inputs.push_back(InputEventKey::create_reference(KEY_Y | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_redo", inputs); + + // ///// UI Text Input Shortcuts ///// + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_SPACE | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_completion_query", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_TAB)); + default_builtin_cache.insert("ui_text_completion_accept", inputs); + + // Newlines + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_ENTER)); + inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER)); + default_builtin_cache.insert("ui_text_newline", inputs); + + inputs = List<Ref<InputEvent>>(); + + inputs.push_back(InputEventKey::create_reference(KEY_ENTER | KEY_MASK_CMD)); + inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_newline_blank", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_ENTER | KEY_MASK_SHIFT | KEY_MASK_CMD)); + inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER | KEY_MASK_SHIFT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_newline_above", inputs); + + // Indentation + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_TAB)); + default_builtin_cache.insert("ui_text_indent", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_TAB | KEY_MASK_SHIFT)); + default_builtin_cache.insert("ui_text_dedent", inputs); + + // Text Backspace and Delete + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE)); + default_builtin_cache.insert("ui_text_backspace", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_backspace_word", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_ALT)); + default_builtin_cache.insert("ui_text_backspace_word.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + default_builtin_cache.insert("ui_text_backspace_all_to_left", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_backspace_all_to_left.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DELETE)); + default_builtin_cache.insert("ui_text_delete", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_delete_word", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_ALT)); + default_builtin_cache.insert("ui_text_delete_word.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + default_builtin_cache.insert("ui_text_delete_all_to_right", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_delete_all_to_right.OSX", inputs); + + // Text Caret Movement Left/Right + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_LEFT)); + default_builtin_cache.insert("ui_text_caret_left", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_word_left", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_ALT)); + default_builtin_cache.insert("ui_text_caret_word_left.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_RIGHT)); + default_builtin_cache.insert("ui_text_caret_right", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_word_right", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_ALT)); + default_builtin_cache.insert("ui_text_caret_word_right.OSX", inputs); + + // Text Caret Movement Up/Down + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_UP)); + default_builtin_cache.insert("ui_text_caret_up", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DOWN)); + default_builtin_cache.insert("ui_text_caret_down", inputs); + + // Text Caret Movement Line Start/End + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_HOME)); + default_builtin_cache.insert("ui_text_caret_line_start", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_A | KEY_MASK_CTRL)); + inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_line_start.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_END)); + default_builtin_cache.insert("ui_text_caret_line_end", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_E | KEY_MASK_CTRL)); + inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_line_end.OSX", inputs); + // Text Caret Movement Page Up/Down + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_PAGEUP)); + default_builtin_cache.insert("ui_text_caret_page_up", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_PAGEDOWN)); + default_builtin_cache.insert("ui_text_caret_page_down", inputs); + + // Text Caret Movement Document Start/End + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_HOME | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_document_start", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_document_start.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_END | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_document_end", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_caret_document_end.OSX", inputs); + + // Text Scrolling + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_scroll_up", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD | KEY_MASK_ALT)); + default_builtin_cache.insert("ui_text_scroll_up.OSX", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_scroll_down", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD | KEY_MASK_ALT)); + default_builtin_cache.insert("ui_text_scroll_down.OSX", inputs); + + // Text Misc + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_A | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_select_all", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_INSERT)); + default_builtin_cache.insert("ui_text_toggle_insert_mode", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_MENU)); + default_builtin_cache.insert("ui_menu", inputs); + + // ///// UI Graph Shortcuts ///// + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_D | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_graph_duplicate", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_DELETE)); + default_builtin_cache.insert("ui_graph_delete", inputs); + + // ///// UI File Dialog Shortcuts ///// + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE)); + default_builtin_cache.insert("ui_filedialog_up_one_level", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_F5)); + default_builtin_cache.insert("ui_filedialog_refresh", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_H)); + default_builtin_cache.insert("ui_filedialog_show_hidden", inputs); + + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_QUOTELEFT | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_swap_input_direction", inputs); + + return default_builtin_cache; +} + void InputMap::load_default() { - Ref<InputEventKey> key; - - add_action("ui_accept"); - key.instance(); - key->set_keycode(KEY_ENTER); - action_add_event("ui_accept", key); - - key.instance(); - key->set_keycode(KEY_KP_ENTER); - action_add_event("ui_accept", key); - - key.instance(); - key->set_keycode(KEY_SPACE); - action_add_event("ui_accept", key); - - add_action("ui_select"); - key.instance(); - key->set_keycode(KEY_SPACE); - action_add_event("ui_select", key); - - add_action("ui_cancel"); - key.instance(); - key->set_keycode(KEY_ESCAPE); - action_add_event("ui_cancel", key); - - add_action("ui_focus_next"); - key.instance(); - key->set_keycode(KEY_TAB); - action_add_event("ui_focus_next", key); - - add_action("ui_focus_prev"); - key.instance(); - key->set_keycode(KEY_TAB); - key->set_shift(true); - action_add_event("ui_focus_prev", key); - - add_action("ui_left"); - key.instance(); - key->set_keycode(KEY_LEFT); - action_add_event("ui_left", key); - - add_action("ui_right"); - key.instance(); - key->set_keycode(KEY_RIGHT); - action_add_event("ui_right", key); - - add_action("ui_up"); - key.instance(); - key->set_keycode(KEY_UP); - action_add_event("ui_up", key); - - add_action("ui_down"); - key.instance(); - key->set_keycode(KEY_DOWN); - action_add_event("ui_down", key); - - add_action("ui_page_up"); - key.instance(); - key->set_keycode(KEY_PAGEUP); - action_add_event("ui_page_up", key); - - add_action("ui_page_down"); - key.instance(); - key->set_keycode(KEY_PAGEDOWN); - action_add_event("ui_page_down", key); - - add_action("ui_home"); - key.instance(); - key->set_keycode(KEY_HOME); - action_add_event("ui_home", key); - - add_action("ui_end"); - key.instance(); - key->set_keycode(KEY_END); - action_add_event("ui_end", key); - - //set("display/window/handheld/orientation", "landscape"); + OrderedHashMap<String, List<Ref<InputEvent>>> builtins = get_builtins(); + + // List of Builtins which have an override for OSX. + Vector<String> osx_builtins; + for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { + if (String(E.key()).ends_with(".OSX")) { + // Strip .OSX from name: some_input_name.OSX -> some_input_name + osx_builtins.push_back(String(E.key()).split(".")[0]); + } + } + + for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) { + String fullname = E.key(); + String name = fullname.split(".")[0]; + String override_for = fullname.split(".").size() > 1 ? fullname.split(".")[1] : ""; + +#ifdef APPLE_STYLE_KEYS + if (osx_builtins.has(name) && override_for != "OSX") { + // Name has osx builtin but this particular one is for non-osx systems - so skip. + continue; + } +#else + if (override_for == "OSX") { + // Override for OSX - not needed on non-osx platforms. + continue; + } +#endif + + add_action(name); + + List<Ref<InputEvent>> inputs = E.get(); + for (List<Ref<InputEvent>>::Element *I = inputs.front(); I; I = I->next()) { + Ref<InputEventKey> iek = I->get(); + + // For the editor, only add keyboard actions. + if (iek.is_valid()) { + action_add_event(name, I->get()); + } + } + } } InputMap::InputMap() { diff --git a/core/input/input_map.h b/core/input/input_map.h index 1646e7fadb..99c71e1e53 100644 --- a/core/input/input_map.h +++ b/core/input/input_map.h @@ -33,6 +33,8 @@ #include "core/input/input_event.h" #include "core/object/class_db.h" +#include "core/object/object.h" +#include "core/templates/ordered_hash_map.h" class InputMap : public Object { GDCLASS(InputMap, Object); @@ -52,9 +54,10 @@ public: private: static InputMap *singleton; - mutable Map<StringName, Action> input_map; + mutable OrderedHashMap<StringName, Action> input_map; + OrderedHashMap<String, List<Ref<InputEvent>>> default_builtin_cache; - List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const; + List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const; Array _action_get_events(const StringName &p_action); Array _get_actions(); @@ -78,13 +81,17 @@ public: void action_erase_events(const StringName &p_action); const List<Ref<InputEvent>> *action_get_events(const StringName &p_action); - bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const; - bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const; + bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const; + bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const; - const Map<StringName, Action> &get_action_map() const; + const OrderedHashMap<StringName, Action> &get_action_map() const; void load_from_project_settings(); void load_default(); + String get_builtin_display_name(const String &p_name) const; + // Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat. + const OrderedHashMap<String, List<Ref<InputEvent>>> &get_builtins(); + InputMap(); }; diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 1d9aa846eb..97838fd14c 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -201,7 +201,7 @@ Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const S return ERR_INVALID_PARAMETER; } - thread = Thread::create(_thread_func, this); + thread.start(_thread_func, this); return OK; } @@ -214,12 +214,9 @@ FileAccessNetworkClient::FileAccessNetworkClient() { } FileAccessNetworkClient::~FileAccessNetworkClient() { - if (thread) { - quit = true; - sem.post(); - Thread::wait_to_finish(thread); - memdelete(thread); - } + quit = true; + sem.post(); + thread.wait_to_finish(); } void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) { diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 6aec2869fc..1f5de3e5dd 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -48,7 +48,7 @@ class FileAccessNetworkClient { List<BlockRequest> block_requests; Semaphore sem; - Thread *thread = nullptr; + Thread thread; bool quit = false; Mutex mutex; Mutex blockrequest_mutex; diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 3c84e6b656..343adbe592 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -92,7 +92,7 @@ private: PathMD5() {} - PathMD5(const Vector<uint8_t> p_buf) { + PathMD5(const Vector<uint8_t> &p_buf) { a = *((uint64_t *)&p_buf[0]); b = *((uint64_t *)&p_buf[8]); } diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index a2fcf074ae..18afdc678e 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -736,14 +736,14 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { String query = ""; Array keys = p_dict.keys(); for (int i = 0; i < keys.size(); ++i) { - String encoded_key = String(keys[i]).http_escape(); + String encoded_key = String(keys[i]).uri_encode(); Variant value = p_dict[keys[i]]; switch (value.get_type()) { case Variant::ARRAY: { // Repeat the key with every values Array values = value; for (int j = 0; j < values.size(); ++j) { - query += "&" + encoded_key + "=" + String(values[j]).http_escape(); + query += "&" + encoded_key + "=" + String(values[j]).uri_encode(); } break; } @@ -754,7 +754,7 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { } default: { // Add the key-value pair - query += "&" + encoded_key + "=" + String(value).http_escape(); + query += "&" + encoded_key + "=" + String(value).uri_encode(); } } } diff --git a/core/io/image.cpp b/core/io/image.cpp index 986c29b539..5d46d75efe 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -2985,6 +2985,26 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) { _set_color_at_ofs(data.ptrw(), ofs, p_color); } +void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation) { + uint8_t *w = data.ptrw(); + uint32_t pixel_size = get_format_pixel_size(format); + uint32_t pixel_count = data.size() / pixel_size; + + for (uint32_t i = 0; i < pixel_count; i++) { + Color c = _get_color_at_ofs(w, i); + Vector3 rgb(c.r, c.g, c.b); + + rgb *= p_brightness; + rgb = Vector3(0.5, 0.5, 0.5).lerp(rgb, p_contrast); + float center = (rgb.x + rgb.y + rgb.z) / 3.0; + rgb = Vector3(center, center, center).lerp(rgb, p_saturation); + c.r = rgb.x; + c.g = rgb.y; + c.b = rgb.z; + _set_color_at_ofs(w, i, c); + } +} + Image::UsedChannels Image::detect_used_channels(CompressSource p_source) { ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA); ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA); @@ -3132,6 +3152,8 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pixelv", "point", "color"), &Image::set_pixelv); ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel); + ClassDB::bind_method(D_METHOD("adjust_bcs", "brightness", "contrast", "saturation"), &Image::adjust_bcs); + ClassDB::bind_method(D_METHOD("load_png_from_buffer", "buffer"), &Image::load_png_from_buffer); ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer); ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer); diff --git a/core/io/image.h b/core/io/image.h index b894be7df4..df8f9b35a1 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -390,6 +390,8 @@ public: void set_pixelv(const Point2i &p_point, const Color &p_color); void set_pixel(int p_x, int p_y, const Color &p_color); + void adjust_bcs(float p_brightness, float p_contrast, float p_saturation); + void set_as_black(); void copy_internals_from(const Ref<Image> &p_image) { diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 8ca1cb3beb..7de038e6fe 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -122,7 +122,7 @@ void ImageLoader::cleanup() { ///////////////// -RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index bf67e1486f..a5d588e0b5 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -72,7 +72,7 @@ public: class ResourceFormatLoaderImage : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 6fb812e78d..e1d9c19f10 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -40,13 +40,13 @@ VARIANT_ENUM_CAST(IP::ResolverStatus); struct _IP_ResolverPrivate { struct QueueItem { - volatile IP::ResolverStatus status; + SafeNumeric<IP::ResolverStatus> status; IP_Address response; String hostname; IP::Type type; void clear() { - status = IP::RESOLVER_STATUS_NONE; + status.set(IP::RESOLVER_STATUS_NONE); response = IP_Address(); type = IP::TYPE_NONE; hostname = ""; @@ -61,7 +61,7 @@ struct _IP_ResolverPrivate { IP::ResolverID find_empty_id() const { for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) { - if (queue[i].status == IP::RESOLVER_STATUS_NONE) { + if (queue[i].status.get() == IP::RESOLVER_STATUS_NONE) { return i; } } @@ -71,21 +71,21 @@ struct _IP_ResolverPrivate { Mutex mutex; Semaphore sem; - Thread *thread; + Thread thread; //Semaphore* semaphore; bool thread_abort; void resolve_queues() { for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) { - if (queue[i].status != IP::RESOLVER_STATUS_WAITING) { + if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) { continue; } queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type); if (!queue[i].response.is_valid()) { - queue[i].status = IP::RESOLVER_STATUS_ERROR; + queue[i].status.set(IP::RESOLVER_STATUS_ERROR); } else { - queue[i].status = IP::RESOLVER_STATUS_DONE; + queue[i].status.set(IP::RESOLVER_STATUS_DONE); } } } @@ -137,11 +137,11 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ resolver->queue[id].type = p_type; if (resolver->cache.has(key) && resolver->cache[key].is_valid()) { resolver->queue[id].response = resolver->cache[key]; - resolver->queue[id].status = IP::RESOLVER_STATUS_DONE; + resolver->queue[id].status.set(IP::RESOLVER_STATUS_DONE); } else { resolver->queue[id].response = IP_Address(); - resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING; - if (resolver->thread) { + resolver->queue[id].status.set(IP::RESOLVER_STATUS_WAITING); + if (resolver->thread.is_started()) { resolver->sem.post(); } else { resolver->resolve_queues(); @@ -156,12 +156,12 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const { MutexLock lock(resolver->mutex); - if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) { + if (resolver->queue[p_id].status.get() == IP::RESOLVER_STATUS_NONE) { ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE"); resolver->mutex.unlock(); return IP::RESOLVER_STATUS_NONE; } - return resolver->queue[p_id].status; + return resolver->queue[p_id].status.get(); } IP_Address IP::get_resolve_item_address(ResolverID p_id) const { @@ -169,7 +169,7 @@ IP_Address IP::get_resolve_item_address(ResolverID p_id) const { MutexLock lock(resolver->mutex); - if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) { + if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); resolver->mutex.unlock(); return IP_Address(); @@ -183,7 +183,7 @@ void IP::erase_resolve_item(ResolverID p_id) { MutexLock lock(resolver->mutex); - resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE; + resolver->queue[p_id].status.set(IP::RESOLVER_STATUS_NONE); } void IP::clear_cache(const String &p_hostname) { @@ -285,26 +285,14 @@ IP::IP() { singleton = this; resolver = memnew(_IP_ResolverPrivate); -#ifndef NO_THREADS - resolver->thread_abort = false; - - resolver->thread = Thread::create(_IP_ResolverPrivate::_thread_function, resolver); -#else - resolver->thread = nullptr; -#endif + resolver->thread.start(_IP_ResolverPrivate::_thread_function, resolver); } IP::~IP() { -#ifndef NO_THREADS - if (resolver->thread) { - resolver->thread_abort = true; - resolver->sem.post(); - Thread::wait_to_finish(resolver->thread); - memdelete(resolver->thread); - } - -#endif + resolver->thread_abort = true; + resolver->sem.post(); + resolver->thread.wait_to_finish(); memdelete(resolver); } diff --git a/core/io/json.cpp b/core/io/json.cpp index bc4527869b..0d9117fdda 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -234,6 +234,52 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to } index += 4; //will add at the end anyway + if ((res & 0xfffffc00) == 0xd800) { + if (p_str[index + 1] != '\\' || p_str[index + 2] != 'u') { + r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate"; + return ERR_PARSE_ERROR; + } + index += 2; + char32_t trail = 0; + for (int j = 0; j < 4; j++) { + char32_t c = p_str[index + j + 1]; + if (c == 0) { + r_err_str = "Unterminated String"; + return ERR_PARSE_ERROR; + } + if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { + r_err_str = "Malformed hex constant in string"; + return ERR_PARSE_ERROR; + } + char32_t v; + if (c >= '0' && c <= '9') { + v = c - '0'; + } else if (c >= 'a' && c <= 'f') { + v = c - 'a'; + v += 10; + } else if (c >= 'A' && c <= 'F') { + v = c - 'A'; + v += 10; + } else { + ERR_PRINT("Bug parsing hex constant."); + v = 0; + } + + trail <<= 4; + trail |= v; + } + if ((trail & 0xfffffc00) == 0xdc00) { + res = (res << 10UL) + trail - ((0xd800 << 10UL) + 0xdc00 - 0x10000); + index += 4; //will add at the end anyway + } else { + r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate"; + return ERR_PARSE_ERROR; + } + } else if ((res & 0xfffffc00) == 0xdc00) { + r_err_str = "Invalid UTF-16 sequence in string, unpaired trail surrogate"; + return ERR_PARSE_ERROR; + } + } break; default: { res = next; diff --git a/core/io/logger.cpp b/core/io/logger.cpp index da200f5717..8a07459a1d 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -43,6 +43,12 @@ bool Logger::should_log(bool p_err) { return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled); } +bool Logger::_flush_stdout_on_print = true; + +void Logger::set_flush_stdout_on_print(bool value) { + _flush_stdout_on_print = value; +} + void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { if (!should_log(true)) { return; @@ -207,7 +213,7 @@ void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) { Memory::free_static(buf); } - if (p_err || GLOBAL_GET("application/run/flush_stdout_on_print")) { + if (p_err || _flush_stdout_on_print) { // Don't always flush when printing stdout to avoid performance // issues when `print()` is spammed in release builds. file->flush(); @@ -228,7 +234,7 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) { vfprintf(stderr, p_format, p_list); } else { vprintf(p_format, p_list); - if (GLOBAL_GET("application/run/flush_stdout_on_print")) { + if (_flush_stdout_on_print) { // Don't always flush when printing stdout to avoid performance // issues when `print()` is spammed in release builds. fflush(stdout); diff --git a/core/io/logger.h b/core/io/logger.h index b8e615b436..a12945911c 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -41,6 +41,8 @@ class Logger { protected: bool should_log(bool p_err); + static bool _flush_stdout_on_print; + public: enum ErrorType { ERR_ERROR, @@ -49,6 +51,8 @@ public: ERR_SHADER }; + static void set_flush_stdout_on_print(bool value); + virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0; virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 716da5e395..8560e2abc7 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -52,29 +52,29 @@ void Resource::set_path(const String &p_path, bool p_take_over) { } if (path_cache != "") { - ResourceCache::lock->write_lock(); + ResourceCache::lock.write_lock(); ResourceCache::resources.erase(path_cache); - ResourceCache::lock->write_unlock(); + ResourceCache::lock.write_unlock(); } path_cache = ""; - ResourceCache::lock->read_lock(); + ResourceCache::lock.read_lock(); bool has_path = ResourceCache::resources.has(p_path); - ResourceCache::lock->read_unlock(); + ResourceCache::lock.read_unlock(); if (has_path) { if (p_take_over) { - ResourceCache::lock->write_lock(); + ResourceCache::lock.write_lock(); Resource **res = ResourceCache::resources.getptr(p_path); if (res) { (*res)->set_name(""); } - ResourceCache::lock->write_unlock(); + ResourceCache::lock.write_unlock(); } else { - ResourceCache::lock->read_lock(); + ResourceCache::lock.read_lock(); bool exists = ResourceCache::resources.has(p_path); - ResourceCache::lock->read_unlock(); + ResourceCache::lock.read_unlock(); ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion)."); } @@ -82,12 +82,11 @@ void Resource::set_path(const String &p_path, bool p_take_over) { path_cache = p_path; if (path_cache != "") { - ResourceCache::lock->write_lock(); + ResourceCache::lock.write_lock(); ResourceCache::resources[path_cache] = this; - ResourceCache::lock->write_unlock(); + ResourceCache::lock.write_unlock(); } - _change_notify("resource_path"); _resource_path_changed(); } @@ -105,7 +104,6 @@ int Resource::get_subindex() const { void Resource::set_name(const String &p_name) { name = p_name; - _change_notify("resource_name"); } String Resource::get_name() const { @@ -116,20 +114,18 @@ bool Resource::editor_can_reload_from_file() { return true; //by default yes } -void Resource::reload_from_file() { - String path = get_path(); - if (!path.is_resource_file()) { - return; +void Resource::reset_state() { +} +Error Resource::copy_from(const Ref<Resource> &p_resource) { + ERR_FAIL_COND_V(p_resource.is_null(), ERR_INVALID_PARAMETER); + if (get_class() != p_resource->get_class()) { + return ERR_INVALID_PARAMETER; } - Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true); - - if (!s.is_valid()) { - return; - } + reset_state(); //may want to reset state List<PropertyInfo> pi; - s->get_property_list(&pi); + p_resource->get_property_list(&pi); for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { @@ -139,8 +135,23 @@ void Resource::reload_from_file() { continue; //do not change path } - set(E->get().name, s->get(E->get().name)); + set(E->get().name, p_resource->get(E->get().name)); + } + return OK; +} +void Resource::reload_from_file() { + String path = get_path(); + if (!path.is_resource_file()) { + return; + } + + Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + + if (!s.is_valid()) { + return; } + + copy_from(s); } Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) { @@ -315,9 +326,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) { return; } - if (ResourceCache::lock) { - ResourceCache::lock->write_lock(); - } + ResourceCache::lock.write_lock(); if (p_remapped) { ResourceLoader::remapped_list.add(&remapped_list); @@ -325,9 +334,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) { ResourceLoader::remapped_list.remove(&remapped_list); } - if (ResourceCache::lock) { - ResourceCache::lock->write_unlock(); - } + ResourceCache::lock.write_unlock(); } bool Resource::is_translation_remapped() const { @@ -338,38 +345,24 @@ bool Resource::is_translation_remapped() const { //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored void Resource::set_id_for_path(const String &p_path, int p_id) { if (p_id == -1) { - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->write_lock(); - } + ResourceCache::path_cache_lock.write_lock(); ResourceCache::resource_path_cache[p_path].erase(get_path()); - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->write_unlock(); - } + ResourceCache::path_cache_lock.write_unlock(); } else { - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->write_lock(); - } + ResourceCache::path_cache_lock.write_lock(); ResourceCache::resource_path_cache[p_path][get_path()] = p_id; - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->write_unlock(); - } + ResourceCache::path_cache_lock.write_unlock(); } } int Resource::get_id_for_path(const String &p_path) const { - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->read_lock(); - } + ResourceCache::path_cache_lock.read_lock(); if (ResourceCache::resource_path_cache[p_path].has(get_path())) { int result = ResourceCache::resource_path_cache[p_path][get_path()]; - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->read_unlock(); - } + ResourceCache::path_cache_lock.read_unlock(); return result; } else { - if (ResourceCache::path_cache_lock) { - ResourceCache::path_cache_lock->read_unlock(); - } + ResourceCache::path_cache_lock.read_unlock(); return -1; } } @@ -386,6 +379,7 @@ void Resource::_bind_methods() { ClassDB::bind_method(D_METHOD("is_local_to_scene"), &Resource::is_local_to_scene); ClassDB::bind_method(D_METHOD("get_local_scene"), &Resource::get_local_scene); ClassDB::bind_method(D_METHOD("setup_local_to_scene"), &Resource::setup_local_to_scene); + ClassDB::bind_method(D_METHOD("emit_changed"), &Resource::emit_changed); ClassDB::bind_method(D_METHOD("duplicate", "subresources"), &Resource::duplicate, DEFVAL(false)); ADD_SIGNAL(MethodInfo("changed")); @@ -402,9 +396,9 @@ Resource::Resource() : Resource::~Resource() { if (path_cache != "") { - ResourceCache::lock->write_lock(); + ResourceCache::lock.write_lock(); ResourceCache::resources.erase(path_cache); - ResourceCache::lock->write_unlock(); + ResourceCache::lock.write_unlock(); } if (owners.size()) { WARN_PRINT("Resource is still owned."); @@ -416,18 +410,11 @@ HashMap<String, Resource *> ResourceCache::resources; HashMap<String, HashMap<String, int>> ResourceCache::resource_path_cache; #endif -RWLock *ResourceCache::lock = nullptr; +RWLock ResourceCache::lock; #ifdef TOOLS_ENABLED -RWLock *ResourceCache::path_cache_lock = nullptr; +RWLock ResourceCache::path_cache_lock; #endif -void ResourceCache::setup() { - lock = RWLock::create(); -#ifdef TOOLS_ENABLED - path_cache_lock = RWLock::create(); -#endif -} - void ResourceCache::clear() { if (resources.size()) { ERR_PRINT("Resources still in use at exit (run with --verbose for details)."); @@ -441,29 +428,25 @@ void ResourceCache::clear() { } resources.clear(); - memdelete(lock); -#ifdef TOOLS_ENABLED - memdelete(path_cache_lock); -#endif } void ResourceCache::reload_externals() { } bool ResourceCache::has(const String &p_path) { - lock->read_lock(); + lock.read_lock(); bool b = resources.has(p_path); - lock->read_unlock(); + lock.read_unlock(); return b; } Resource *ResourceCache::get(const String &p_path) { - lock->read_lock(); + lock.read_lock(); Resource **res = resources.getptr(p_path); - lock->read_unlock(); + lock.read_unlock(); if (!res) { return nullptr; @@ -473,26 +456,26 @@ Resource *ResourceCache::get(const String &p_path) { } void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) { - lock->read_lock(); + lock.read_lock(); const String *K = nullptr; while ((K = resources.next(K))) { Resource *r = resources[*K]; p_resources->push_back(Ref<Resource>(r)); } - lock->read_unlock(); + lock.read_unlock(); } int ResourceCache::get_cached_resource_count() { - lock->read_lock(); + lock.read_lock(); int rc = resources.size(); - lock->read_unlock(); + lock.read_unlock(); return rc; } void ResourceCache::dump(const char *p_file, bool p_short) { #ifdef DEBUG_ENABLED - lock->read_lock(); + lock.read_lock(); Map<String, int> type_count; @@ -529,6 +512,6 @@ void ResourceCache::dump(const char *p_file, bool p_short) { memdelete(f); } - lock->read_unlock(); + lock.read_unlock(); #endif } diff --git a/core/io/resource.h b/core/io/resource.h index eda18a8538..ae18ac0c8a 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -90,6 +90,8 @@ public: static Node *(*_get_local_scene_func)(); //used by editor virtual bool editor_can_reload_from_file(); + virtual void reset_state(); //for resources that use variable amount of properties, either via _validate_property or _get_property_list, this function needs to be implemented to correctly clear state + virtual Error copy_from(const Ref<Resource> &p_resource); virtual void reload_from_file(); void register_owner(Object *p_owner); @@ -149,16 +151,15 @@ typedef Ref<Resource> RES; class ResourceCache { friend class Resource; friend class ResourceLoader; //need the lock - static RWLock *lock; + static RWLock lock; static HashMap<String, Resource *> resources; #ifdef TOOLS_ENABLED static HashMap<String, HashMap<String, int>> resource_path_cache; // each tscn has a set of resource paths and IDs - static RWLock *path_cache_lock; + static RWLock path_cache_lock; #endif // TOOLS_ENABLED friend void unregister_core_types(); static void clear(); friend void register_core_types(); - static void setup(); public: static void reload_externals(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index ae4643a19f..fb6ad7d65e 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -261,11 +261,11 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; case VARIANT_COLOR: { - Color v; - v.r = f->get_real(); - v.g = f->get_real(); - v.b = f->get_real(); - v.a = f->get_real(); + Color v; // Colors should always be in single-precision. + v.r = f->get_float(); + v.g = f->get_float(); + v.b = f->get_float(); + v.a = f->get_float(); r_v = v; } break; @@ -313,17 +313,12 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { uint32_t index = f->get_32(); String path = res_path + "::" + itos(index); - if (use_nocache) { - if (!internal_index_cache.has(path)) { - WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data()); - } - r_v = internal_index_cache[path]; + //always use internal cache for loading internal resources + if (!internal_index_cache.has(path)) { + WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data()); + r_v = Variant(); } else { - RES res = ResourceLoader::load(path); - if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); - } - r_v = res; + r_v = internal_index_cache[path]; } } break; @@ -645,7 +640,7 @@ Error ResourceLoaderBinary::load() { } } else { - Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, local_path); + Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, ResourceFormatLoader::CACHE_MODE_REUSE, local_path); if (err != OK) { if (!ResourceLoader::get_abort_on_missing_resources()) { ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type); @@ -675,7 +670,7 @@ Error ResourceLoaderBinary::load() { path = res_path + "::" + path; } - if (!use_nocache) { + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE) { if (ResourceCache::has(path)) { //already loaded, don't do anything stage++; @@ -684,7 +679,7 @@ Error ResourceLoaderBinary::load() { } } } else { - if (!use_nocache && !ResourceCache::has(res_path)) { + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && !ResourceCache::has(res_path)) { path = res_path; } } @@ -695,26 +690,40 @@ Error ResourceLoaderBinary::load() { String t = get_unicode_string(); - Object *obj = ClassDB::instance(t); - if (!obj) { - error = ERR_FILE_CORRUPT; - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + "."); - } + RES res; - Resource *r = Object::cast_to<Resource>(obj); - if (!r) { - String obj_class = obj->get_class(); - error = ERR_FILE_CORRUPT; - memdelete(obj); //bye - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + "."); + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) { + //use the existing one + Resource *r = ResourceCache::get(path); + if (r->get_class() == t) { + r->reset_state(); + res = Ref<Resource>(r); + } } - RES res = RES(r); + if (res.is_null()) { + //did not replace - if (path != String()) { - r->set_path(path); + Object *obj = ClassDB::instance(t); + if (!obj) { + error = ERR_FILE_CORRUPT; + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + "."); + } + + Resource *r = Object::cast_to<Resource>(obj); + if (!r) { + String obj_class = obj->get_class(); + error = ERR_FILE_CORRUPT; + memdelete(obj); //bye + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + "."); + } + + res = RES(r); + if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it + } + r->set_subindex(subindex); } - r->set_subindex(subindex); if (!main) { internal_index_cache[path] = res; @@ -961,7 +970,7 @@ ResourceLoaderBinary::~ResourceLoaderBinary() { } } -RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -972,7 +981,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); ResourceLoaderBinary loader; - loader.use_nocache = p_no_cache; + loader.cache_mode = p_cache_mode; loader.use_sub_threads = p_use_sub_threads; loader.progress = r_progress; String path = p_original_path != "" ? p_original_path : p_path; diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 428725f1d2..3592bbdbc4 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -78,7 +78,7 @@ class ResourceLoaderBinary { Map<String, String> remaps; Error error = OK; - bool use_nocache = false; + ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; friend class ResourceFormatLoaderBinary; @@ -103,7 +103,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index d86877ee14..5ca0eb884a 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -116,7 +116,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy return OK; } -RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -128,7 +128,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ return RES(); } - RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress); + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress); #ifdef TOOLS_ENABLED if (res.is_valid()) { @@ -352,6 +352,12 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi } } +void ResourceFormatImporter::get_importers(List<Ref<ResourceImporter>> *r_importers) { + for (int i = 0; i < importers.size(); i++) { + r_importers->push_back(importers[i]); + } +} + Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const { Ref<ResourceImporter> importer; float priority = 0; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index d31273e3cb..91efec5534 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -57,7 +57,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { public: static ResourceFormatImporter *get_singleton() { return singleton; } - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; @@ -82,6 +82,7 @@ public: Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const; void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers); + void get_importers(List<Ref<ResourceImporter>> *r_importers); bool are_import_settings_valid(const String &p_path) const; String get_import_settings_hash() const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 821e468aee..8275dd0ad4 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -113,9 +113,9 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) } } -RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (get_script_instance() && get_script_instance()->has_method("load")) { - Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads); + Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads, p_cache_mode); if (res.get_type() == Variant::INT) { if (r_error) { @@ -164,7 +164,7 @@ Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map< void ResourceFormatLoader::_bind_methods() { { - MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path")); + MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"), PropertyInfo(Variant::BOOL, "use_sub_threads"), PropertyInfo(Variant::INT, "cache_mode")); info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; ClassDB::add_virtual_method(get_class_static(), info); } @@ -174,11 +174,15 @@ void ResourceFormatLoader::_bind_methods() { ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_resource_type", PropertyInfo(Variant::STRING, "path"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo("get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames"))); + + BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE); + BIND_ENUM_CONSTANT(CACHE_MODE_REUSE); + BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE); } /////////////////////////////////// -RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) { bool found = false; // Try all loaders and pick the first match for the type hint @@ -187,7 +191,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c continue; } found = true; - RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache); + RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); if (res.is_null()) { continue; } @@ -214,7 +218,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { //this is an actual thread, so wait for Ok fom semaphore thread_load_semaphore->wait(); //wait until its ok to start loading } - load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, false, &load_task.error, load_task.use_sub_threads, &load_task.progress); + load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, load_task.cache_mode, &load_task.error, load_task.use_sub_threads, &load_task.progress); load_task.progress = 1.0; //it was fully loaded at this point, so force progress to 1.0 @@ -267,7 +271,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { thread_load_mutex->unlock(); } -Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) { +Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) { String local_path; if (p_path.is_rel_path()) { local_path = "res://" + p_path; @@ -314,6 +318,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped); load_task.local_path = local_path; load_task.type_hint = p_type_hint; + load_task.cache_mode = p_cache_mode; load_task.use_sub_threads = p_use_sub_threads; { //must check if resource is already loaded before attempting to load it in a thread @@ -323,9 +328,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Attempted to load a resource already being loaded from this thread, cyclic reference?"); } //lock first if possible - if (ResourceCache::lock) { - ResourceCache::lock->read_lock(); - } + ResourceCache::lock.read_lock(); //get ptr Resource **rptr = ResourceCache::resources.getptr(local_path); @@ -340,9 +343,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & load_task.progress = 1.0; } } - if (ResourceCache::lock) { - ResourceCache::lock->read_unlock(); - } + ResourceCache::lock.read_unlock(); } if (p_source_resource != String()) { @@ -366,7 +367,8 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & print_lt("REQUEST: load count: " + itos(thread_loading_count) + " / wait count: " + itos(thread_waiting_count) + " / suspended count: " + itos(thread_suspended_count) + " / active: " + itos(thread_loading_count - thread_suspended_count)); - load_task.thread = Thread::create(_thread_load_function, &thread_load_tasks[local_path]); + load_task.thread = memnew(Thread); + load_task.thread->start(_thread_load_function, &thread_load_tasks[local_path]); load_task.loader_id = load_task.thread->get_id(); } @@ -493,7 +495,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { if (load_task.requests == 0) { if (load_task.thread) { //thread may not have been used - Thread::wait_to_finish(load_task.thread); + load_task.thread->wait_to_finish(); memdelete(load_task.thread); } thread_load_tasks.erase(local_path); @@ -504,7 +506,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { return resource; } -RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { +RES ResourceLoader::load(const String &p_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -516,7 +518,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p local_path = ProjectSettings::get_singleton()->localize_path(p_path); } - if (!p_no_cache) { + if (p_cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { thread_load_mutex->lock(); //Is it already being loaded? poll until done @@ -535,9 +537,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p } //Is it cached? - if (ResourceCache::lock) { - ResourceCache::lock->read_lock(); - } + ResourceCache::lock.read_lock(); Resource **rptr = ResourceCache::resources.getptr(local_path); @@ -546,9 +546,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached if (res.is_valid()) { - if (ResourceCache::lock) { - ResourceCache::lock->read_unlock(); - } + ResourceCache::lock.read_unlock(); thread_load_mutex->unlock(); if (r_error) { @@ -559,9 +557,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p } } - if (ResourceCache::lock) { - ResourceCache::lock->read_unlock(); - } + ResourceCache::lock.read_unlock(); //load using task (but this thread) ThreadLoadTask load_task; @@ -570,6 +566,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p load_task.local_path = local_path; load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped); load_task.type_hint = p_type_hint; + load_task.cache_mode = p_cache_mode; //ignore load_task.loader_id = Thread::get_caller_id(); thread_load_tasks[local_path] = load_task; @@ -590,7 +587,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p print_verbose("Loading resource: " + path); float p; - RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error, false, &p); + RES res = _load(path, local_path, p_type_hint, p_cache_mode, r_error, false, &p); if (res.is_null()) { print_verbose("Failed loading resource: " + path); @@ -955,9 +952,7 @@ String ResourceLoader::path_remap(const String &p_path) { } void ResourceLoader::reload_translation_remaps() { - if (ResourceCache::lock) { - ResourceCache::lock->read_lock(); - } + ResourceCache::lock.read_lock(); List<Resource *> to_reload; SelfList<Resource> *E = remapped_list.first(); @@ -967,9 +962,7 @@ void ResourceLoader::reload_translation_remaps() { E = E->next(); } - if (ResourceCache::lock) { - ResourceCache::lock->read_unlock(); - } + ResourceCache::lock.read_unlock(); //now just make sure to not delete any of these resources while changing locale.. while (to_reload.front()) { @@ -979,11 +972,11 @@ void ResourceLoader::reload_translation_remaps() { } void ResourceLoader::load_translation_remaps() { - if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) { + if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); List<Variant> keys; remaps.get_key_list(&keys); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index dbf6be46c5..914d988caa 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -38,11 +38,18 @@ class ResourceFormatLoader : public Reference { GDCLASS(ResourceFormatLoader, Reference); +public: + enum CacheMode { + CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource. + CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available + CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk + }; + protected: static void _bind_methods(); public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual bool exists(const String &p_path) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; @@ -59,6 +66,8 @@ public: virtual ~ResourceFormatLoader() {} }; +VARIANT_ENUM_CAST(ResourceFormatLoader::CacheMode) + typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text); typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type); @@ -99,7 +108,7 @@ private: friend class ResourceFormatImporter; friend class ResourceInteractiveLoader; //internal load function - static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress); + static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress); static ResourceLoadedCallback _loaded_callback; @@ -114,6 +123,7 @@ private: String type_hint; float progress = 0.0; ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS; + ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; Error error = OK; RES resource; bool xl_remapped = false; @@ -136,11 +146,11 @@ private: static float _dependency_get_progress(const String &p_path); public: - static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, const String &p_source_resource = String()); + static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, const String &p_source_resource = String()); static ThreadLoadStatus load_threaded_get_status(const String &p_path, float *r_progress = nullptr); static RES load_threaded_get(const String &p_path, Error *r_error = nullptr); - static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = nullptr); + static RES load(const String &p_path, const String &p_type_hint = "", ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, Error *r_error = nullptr); static bool exists(const String &p_path, const String &p_type_hint = ""); static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions); diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index ce2c3eb1cd..0e11ff514a 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -277,7 +277,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { return translation; } -RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index a524972588..36d33fcac3 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -38,7 +38,7 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: static RES load_translation(FileAccess *f, Error *r_error = nullptr); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 905be6089d..1574634aad 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -36,63 +36,6 @@ VARIANT_ENUM_CAST(XMLParser::NodeType); -static bool _equalsn(const char32_t *str1, const char32_t *str2, int len) { - int i; - for (i = 0; i < len && str1[i] && str2[i]; ++i) { - if (str1[i] != str2[i]) { - return false; - } - } - - // if one (or both) of the strings was smaller then they - // are only equal if they have the same length - return (i == len) || (str1[i] == 0 && str2[i] == 0); -} - -String XMLParser::_replace_special_characters(const String &origstr) { - int pos = origstr.find("&"); - int oldPos = 0; - - if (pos == -1) { - return origstr; - } - - String newstr; - - while (pos != -1 && pos < origstr.length() - 2) { - // check if it is one of the special characters - - int specialChar = -1; - for (int i = 0; i < (int)special_characters.size(); ++i) { - const char32_t *p = &origstr[pos] + 1; - - if (_equalsn(&special_characters[i][1], p, special_characters[i].length() - 1)) { - specialChar = i; - break; - } - } - - if (specialChar != -1) { - newstr += (origstr.substr(oldPos, pos - oldPos)); - newstr += (special_characters[specialChar][0]); - pos += special_characters[specialChar].length(); - } else { - newstr += (origstr.substr(oldPos, pos - oldPos + 1)); - pos += 1; - } - - // find next & - oldPos = pos; - pos = origstr.find("&", pos); - } - - if (oldPos < origstr.length() - 1) { - newstr += (origstr.substr(oldPos, origstr.length() - oldPos)); - } - - return newstr; -} - static inline bool _is_white_space(char c) { return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); } @@ -116,7 +59,7 @@ bool XMLParser::_set_text(char *start, char *end) { // set current text to the parsed text, and replace xml special characters String s = String::utf8(start, (int)(end - start)); - node_name = _replace_special_characters(s); + node_name = s.xml_unescape(); // current XML node type is text node_type = NODE_TEXT; @@ -292,7 +235,7 @@ void XMLParser::_parse_opening_xml_element() { String s = String::utf8(attributeValueBegin, (int)(attributeValueEnd - attributeValueBegin)); - attr.value = _replace_special_characters(s); + attr.value = s.xml_unescape(); attributes.push_back(attr); } else { // tag is closed directly @@ -555,11 +498,6 @@ int XMLParser::get_current_line() const { } XMLParser::XMLParser() { - special_characters.push_back("&"); - special_characters.push_back("<lt;"); - special_characters.push_back(">gt;"); - special_characters.push_back("\"quot;"); - special_characters.push_back("'apos;"); } XMLParser::~XMLParser() { diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 01af6a90ad..847edf958d 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -68,8 +68,6 @@ private: char *data = nullptr; char *P = nullptr; uint64_t length = 0; - void unescape(String &p_str); - Vector<String> special_characters; String node_name; bool node_empty = false; NodeType node_type = NODE_NONE; diff --git a/core/math/aabb.h b/core/math/aabb.h index 2861358e32..e16246902a 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -107,8 +107,8 @@ public: Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const; Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const; - _FORCE_INLINE_ void quantize(float p_unit); - _FORCE_INLINE_ AABB quantized(float p_unit) const; + _FORCE_INLINE_ void quantize(real_t p_unit); + _FORCE_INLINE_ AABB quantized(real_t p_unit) const; _FORCE_INLINE_ void set_end(const Vector3 &p_end) { size = p_end - position; @@ -430,7 +430,7 @@ void AABB::grow_by(real_t p_amount) { size.z += 2.0 * p_amount; } -void AABB::quantize(float p_unit) { +void AABB::quantize(real_t p_unit) { size += position; position.x -= Math::fposmodp(position.x, p_unit); @@ -448,7 +448,7 @@ void AABB::quantize(float p_unit) { size -= position; } -AABB AABB::quantized(float p_unit) const { +AABB AABB::quantized(real_t p_unit) const { AABB ret = *this; ret.quantize(p_unit); return ret; diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index 5773da9211..a5616b8d79 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -47,6 +47,9 @@ static inline float undenormalise(volatile float f) { return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f; } +static const float AUDIO_PEAK_OFFSET = 0.0000000001f; +static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear2db(AUDIO_PEAK_OFFSET) + struct AudioFrame { //left and right samples float l, r; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 26b4caba39..cbdd8a8c9f 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -790,8 +790,8 @@ Quat Basis::get_quat() const { temp[2] = ((m.elements[1][0] - m.elements[0][1]) * s); } else { int i = m.elements[0][0] < m.elements[1][1] ? - (m.elements[1][1] < m.elements[2][2] ? 2 : 1) : - (m.elements[0][0] < m.elements[2][2] ? 2 : 0); + (m.elements[1][1] < m.elements[2][2] ? 2 : 1) : + (m.elements[0][0] < m.elements[2][2] ? 2 : 0); int j = (i + 1) % 3; int k = (i + 2) % 3; diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 9ec71af57f..1066cf5e30 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -74,13 +74,22 @@ Plane CameraMatrix::xform4(const Plane &p_vec4) const { return ret; } +void CameraMatrix::adjust_perspective_znear(real_t p_new_znear) { + real_t zfar = get_z_far(); + real_t znear = p_new_znear; + + real_t deltaZ = zfar - znear; + matrix[2][2] = -(zfar + znear) / deltaZ; + matrix[3][2] = -2 * znear * zfar / deltaZ; +} + void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { if (p_flip_fov) { p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); } real_t sine, cotangent, deltaZ; - real_t radians = p_fovy_degrees / 2.0 * Math_PI / 180.0; + real_t radians = Math::deg2rad(p_fovy_degrees / 2.0); deltaZ = p_z_far - p_z_near; sine = Math::sin(radians); @@ -107,7 +116,7 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ real_t left, right, modeltranslation, ymax, xmax, frustumshift; - ymax = p_z_near * tan(p_fovy_degrees * Math_PI / 360.0f); + ymax = p_z_near * tan(Math::deg2rad(p_fovy_degrees / 2.0)); xmax = ymax * p_aspect; frustumshift = (p_intraocular_dist / 2.0) * p_z_near / p_convergence_dist; diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 03068bc7ea..3f327d3bc4 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -59,6 +59,7 @@ struct CameraMatrix { void set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov = false); void set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far); void set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false); + void adjust_perspective_znear(real_t p_new_znear); static real_t get_fovy(real_t p_fovx, real_t p_aspect) { return Math::rad2deg(Math::atan(p_aspect * Math::tan(Math::deg2rad(p_fovx) * 0.5)) * 2.0); diff --git a/core/math/color.cpp b/core/math/color.cpp index 4d58c8c84a..e1b45cac9c 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -355,6 +355,23 @@ bool Color::html_is_valid(const String &p_color) { } Color Color::named(const String &p_name) { + int idx = find_named_color(p_name); + if (idx == -1) { + ERR_FAIL_V_MSG(Color(), "Invalid color name: " + p_name + "."); + return Color(); + } + return get_named_color(idx); +} + +Color Color::named(const String &p_name, const Color &p_default) { + int idx = find_named_color(p_name); + if (idx == -1) { + return p_default; + } + return get_named_color(idx); +} + +int Color::find_named_color(const String &p_name) { String name = p_name; // Normalize name name = name.replace(" ", ""); @@ -367,14 +384,12 @@ Color Color::named(const String &p_name) { int idx = 0; while (named_colors[idx].name != nullptr) { if (name == named_colors[idx].name) { - return named_colors[idx].color; + return idx; } idx++; } - ERR_FAIL_V_MSG(Color(), "Invalid color name: " + p_name + "."); - - return Color(); + return -1; } int Color::get_named_color_count() { @@ -384,13 +399,25 @@ int Color::get_named_color_count() { } return idx; } + String Color::get_named_color_name(int p_idx) { return named_colors[p_idx].name; } + Color Color::get_named_color(int p_idx) { return named_colors[p_idx].color; } +// For a version that errors on invalid values instead of returning +// a default color, use the Color(String) constructor instead. +Color Color::from_string(const String &p_string, const Color &p_default) { + if (html_is_valid(p_string)) { + return html(p_string); + } else { + return named(p_string, p_default); + } +} + String _to_hex(float p_val) { int v = Math::round(p_val * 255); v = CLAMP(v, 0, 255); @@ -519,12 +546,12 @@ Color Color::operator*(const Color &p_color) const { a * p_color.a); } -Color Color::operator*(real_t p_rvalue) const { +Color Color::operator*(float p_scalar) const { return Color( - r * p_rvalue, - g * p_rvalue, - b * p_rvalue, - a * p_rvalue); + r * p_scalar, + g * p_scalar, + b * p_scalar, + a * p_scalar); } void Color::operator*=(const Color &p_color) { @@ -534,11 +561,11 @@ void Color::operator*=(const Color &p_color) { a = a * p_color.a; } -void Color::operator*=(real_t p_rvalue) { - r = r * p_rvalue; - g = g * p_rvalue; - b = b * p_rvalue; - a = a * p_rvalue; +void Color::operator*=(float p_scalar) { + r = r * p_scalar; + g = g * p_scalar; + b = b * p_scalar; + a = a * p_scalar; } Color Color::operator/(const Color &p_color) const { @@ -549,12 +576,12 @@ Color Color::operator/(const Color &p_color) const { a / p_color.a); } -Color Color::operator/(real_t p_rvalue) const { +Color Color::operator/(float p_scalar) const { return Color( - r / p_rvalue, - g / p_rvalue, - b / p_rvalue, - a / p_rvalue); + r / p_scalar, + g / p_scalar, + b / p_scalar, + a / p_scalar); } void Color::operator/=(const Color &p_color) { @@ -564,18 +591,11 @@ void Color::operator/=(const Color &p_color) { a = a / p_color.a; } -void Color::operator/=(real_t p_rvalue) { - if (p_rvalue == 0) { - r = 1.0; - g = 1.0; - b = 1.0; - a = 1.0; - } else { - r = r / p_rvalue; - g = g / p_rvalue; - b = b / p_rvalue; - a = a / p_rvalue; - } +void Color::operator/=(float p_scalar) { + r = r / p_scalar; + g = g / p_scalar; + b = b / p_scalar; + a = a / p_scalar; } Color Color::operator-() const { diff --git a/core/math/color.h b/core/math/color.h index c7b5ceca3d..5eb8b1119a 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -78,14 +78,14 @@ struct Color { void operator-=(const Color &p_color); Color operator*(const Color &p_color) const; - Color operator*(real_t p_rvalue) const; + Color operator*(float p_scalar) const; void operator*=(const Color &p_color); - void operator*=(real_t p_rvalue); + void operator*=(float p_scalar); Color operator/(const Color &p_color) const; - Color operator/(real_t p_rvalue) const; + Color operator/(float p_scalar) const; void operator/=(const Color &p_color); - void operator/=(real_t p_rvalue); + void operator/=(float p_scalar); bool is_equal_approx(const Color &p_color) const; @@ -182,9 +182,12 @@ struct Color { static Color html(const String &p_rgba); static bool html_is_valid(const String &p_color); static Color named(const String &p_name); + static Color named(const String &p_name, const Color &p_default); + static int find_named_color(const String &p_name); static int get_named_color_count(); static String get_named_color_name(int p_idx); static Color get_named_color(int p_idx); + static Color from_string(const String &p_string, const Color &p_default); String to_html(bool p_alpha = true) const; Color from_hsv(float p_h, float p_s, float p_v, float p_a) const; static Color from_rgbe9995(uint32_t p_rgbe); @@ -238,6 +241,19 @@ struct Color { b = p_c.b; a = p_a; } + + Color(const String &p_code) { + if (html_is_valid(p_code)) { + *this = html(p_code); + } else { + *this = named(p_code); + } + } + + Color(const String &p_code, float p_a) { + *this = Color(p_code); + a = p_a; + } }; bool Color::operator<(const Color &p_color) const { @@ -256,8 +272,8 @@ bool Color::operator<(const Color &p_color) const { } } -_FORCE_INLINE_ Color operator*(real_t p_real, const Color &p_color) { - return p_color * p_real; +_FORCE_INLINE_ Color operator*(float p_scalar, const Color &p_color) { + return p_color * p_scalar; } #endif // COLOR_H diff --git a/core/math/color_names.inc b/core/math/color_names.inc index 523c7e3c59..e5b935ea9c 100644 --- a/core/math/color_names.inc +++ b/core/math/color_names.inc @@ -156,5 +156,5 @@ static NamedColor named_colors[] = { { "whitesmoke", Color(0.96, 0.96, 0.96) }, { "yellow", Color(1.00, 1.00, 0.00) }, { "yellowgreen", Color(0.60, 0.80, 0.20) }, - { nullptr, Color(0.60, 0.80, 0.20) }, + { nullptr, Color() }, }; diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index 5d4c31088b..d67be14d33 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -31,7 +31,7 @@ #include "geometry_2d.h" #include "thirdparty/misc/clipper.hpp" -#include "thirdparty/misc/triangulator.h" +#include "thirdparty/misc/polypartition.h" #define STB_RECT_PACK_IMPLEMENTATION #include "thirdparty/misc/stb_rect_pack.h" @@ -39,16 +39,16 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> polygon) { Vector<Vector<Vector2>> decomp; - List<TriangulatorPoly> in_poly, out_poly; + List<TPPLPoly> in_poly, out_poly; - TriangulatorPoly inp; + TPPLPoly inp; inp.Init(polygon.size()); for (int i = 0; i < polygon.size(); i++) { inp.GetPoint(i) = polygon[i]; } - inp.SetOrientation(TRIANGULATOR_CCW); + inp.SetOrientation(TPPL_ORIENTATION_CCW); in_poly.push_back(inp); - TriangulatorPartition tpart; + TPPLPartition tpart; if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed. ERR_PRINT("Convex decomposing failed!"); return decomp; @@ -56,8 +56,8 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> p decomp.resize(out_poly.size()); int idx = 0; - for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { - TriangulatorPoly &tp = I->get(); + for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) { + TPPLPoly &tp = I->get(); decomp.write[idx].resize(tp.GetNumPoints()); @@ -94,6 +94,10 @@ void Geometry2D::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_re // 256x8192 atlas (won't work anywhere). ERR_FAIL_COND(p_rects.size() == 0); + for (int i = 0; i < p_rects.size(); i++) { + ERR_FAIL_COND(p_rects[i].width <= 0); + ERR_FAIL_COND(p_rects[i].height <= 0); + } Vector<_AtlasWorkRect> wrects; wrects.resize(p_rects.size()); diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index a918d1de0d..6628b760e0 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -33,7 +33,7 @@ #include "core/string/print_string.h" #include "thirdparty/misc/clipper.hpp" -#include "thirdparty/misc/triangulator.h" +#include "thirdparty/misc/polypartition.h" void Geometry3D::MeshData::optimize_vertices() { Map<int, int> vtx_remap; @@ -775,12 +775,15 @@ Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { } Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) { + ERR_FAIL_INDEX_V(p_axis, 3, Vector<Plane>()); + Vector<Plane> planes; + const double sides_step = Math_TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; - normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides); - normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides); + normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); + normal[(p_axis + 2) % 3] = Math::sin(i * sides_step); planes.push_back(Plane(normal, p_radius)); } @@ -795,6 +798,8 @@ Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height } Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) { + ERR_FAIL_INDEX_V(p_axis, 3, Vector<Plane>()); + Vector<Plane> planes; Vector3 axis; @@ -805,10 +810,11 @@ Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; + const double lon_step = Math_TAU / p_lons; for (int i = 0; i < p_lons; i++) { Vector3 normal; - normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_lons); - normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_lons); + normal[(p_axis + 1) % 3] = Math::cos(i * lon_step); + normal[(p_axis + 2) % 3] = Math::sin(i * lon_step); planes.push_back(Plane(normal, p_radius)); @@ -825,6 +831,8 @@ Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p } Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) { + ERR_FAIL_INDEX_V(p_axis, 3, Vector<Plane>()); + Vector<Plane> planes; Vector3 axis; @@ -835,10 +843,11 @@ Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; + const double sides_step = Math_TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; - normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides); - normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides); + normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); + normal[(p_axis + 2) % 3] = Math::sin(i * sides_step); planes.push_back(Plane(normal, p_radius)); diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 825817af5e..4ef9b4dbe6 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -252,27 +252,34 @@ public: return true; } - static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) { + static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr, int p_cylinder_axis = 2) { Vector3 rel = (p_to - p_from); real_t rel_l = rel.length(); if (rel_l < CMP_EPSILON) { return false; // Both points are the same. } + ERR_FAIL_COND_V(p_cylinder_axis < 0, false); + ERR_FAIL_COND_V(p_cylinder_axis > 2, false); + Vector3 cylinder_axis; + cylinder_axis[p_cylinder_axis] = 1.0; + // First check if they are parallel. Vector3 normal = (rel / rel_l); - Vector3 crs = normal.cross(Vector3(0, 0, 1)); + Vector3 crs = normal.cross(cylinder_axis); real_t crs_l = crs.length(); - Vector3 z_dir; + Vector3 axis_dir; if (crs_l < CMP_EPSILON) { - z_dir = Vector3(1, 0, 0); // Any x/y vector OK. + Vector3 side_axis; + side_axis[(p_cylinder_axis + 1) % 3] = 1.0; // Any side axis OK. + axis_dir = side_axis; } else { - z_dir = crs / crs_l; + axis_dir = crs / crs_l; } - real_t dist = z_dir.dot(p_from); + real_t dist = axis_dir.dot(p_from); if (dist >= p_radius) { return false; // Too far away. @@ -285,10 +292,10 @@ public: } Size2 size(Math::sqrt(w2), p_height * 0.5); - Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized(); + Vector3 side_dir = axis_dir.cross(cylinder_axis).normalized(); - Vector2 from2D(x_dir.dot(p_from), p_from.z); - Vector2 to2D(x_dir.dot(p_to), p_to.z); + Vector2 from2D(side_dir.dot(p_from), p_from[p_cylinder_axis]); + Vector2 to2D(side_dir.dot(p_to), p_to[p_cylinder_axis]); real_t min = 0, max = 1; @@ -335,10 +342,12 @@ public: Vector3 res_normal = result; if (axis == 0) { - res_normal.z = 0; + res_normal[p_cylinder_axis] = 0; } else { - res_normal.x = 0; - res_normal.y = 0; + int axis_side = (p_cylinder_axis + 1) % 3; + res_normal[axis_side] = 0; + axis_side = (axis_side + 1) % 3; + res_normal[axis_side] = 0; } res_normal.normalize(); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index c7d24e9c58..267f6a4fe2 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -223,11 +223,11 @@ public: return value; } - static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * Math_PI / 180.0; } - static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * Math_PI / 180.0; } + static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * (Math_PI / 180.0); } + static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * (Math_PI / 180.0); } - static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y * 180.0 / Math_PI; } - static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y * 180.0 / Math_PI; } + static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y * (180.0 / Math_PI); } + static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y * (180.0 / Math_PI); } static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; } static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; } diff --git a/core/math/quat.cpp b/core/math/quat.cpp index 4cecc20fef..a9a21a1ba3 100644 --- a/core/math/quat.cpp +++ b/core/math/quat.cpp @@ -33,32 +33,6 @@ #include "core/math/basis.h" #include "core/string/print_string.h" -// set_euler_xyz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses XYZ convention (Z is the first rotation). -void Quat::set_euler_xyz(const Vector3 &p_euler) { - real_t half_a1 = p_euler.x * 0.5; - real_t half_a2 = p_euler.y * 0.5; - real_t half_a3 = p_euler.z * 0.5; - - // R = X(a1).Y(a2).Z(a3) convention for Euler angles. - // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-2) - // a3 is the angle of the first rotation, following the notation in this reference. - - real_t cos_a1 = Math::cos(half_a1); - real_t sin_a1 = Math::sin(half_a1); - real_t cos_a2 = Math::cos(half_a2); - real_t sin_a2 = Math::sin(half_a2); - real_t cos_a3 = Math::cos(half_a3); - real_t sin_a3 = Math::sin(half_a3); - - set(sin_a1 * cos_a2 * cos_a3 + sin_a2 * sin_a3 * cos_a1, - -sin_a1 * sin_a3 * cos_a2 + sin_a2 * cos_a1 * cos_a3, - sin_a1 * sin_a2 * cos_a3 + sin_a3 * cos_a1 * cos_a2, - -sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3); -} - // get_euler_xyz returns a vector containing the Euler angles in the format // (ax,ay,az), where ax is the angle of rotation around x axis, // and similar for other axes. @@ -68,32 +42,6 @@ Vector3 Quat::get_euler_xyz() const { return m.get_euler_xyz(); } -// set_euler_yxz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses YXZ convention (Z is the first rotation). -void Quat::set_euler_yxz(const Vector3 &p_euler) { - real_t half_a1 = p_euler.y * 0.5; - real_t half_a2 = p_euler.x * 0.5; - real_t half_a3 = p_euler.z * 0.5; - - // R = Y(a1).X(a2).Z(a3) convention for Euler angles. - // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6) - // a3 is the angle of the first rotation, following the notation in this reference. - - real_t cos_a1 = Math::cos(half_a1); - real_t sin_a1 = Math::sin(half_a1); - real_t cos_a2 = Math::cos(half_a2); - real_t sin_a2 = Math::sin(half_a2); - real_t cos_a3 = Math::cos(half_a3); - real_t sin_a3 = Math::sin(half_a3); - - set(sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3, - sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3, - -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3, - sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3); -} - // get_euler_yxz returns a vector containing the Euler angles in the format // (ax,ay,az), where ax is the angle of rotation around x axis, // and similar for other axes. @@ -107,10 +55,10 @@ Vector3 Quat::get_euler_yxz() const { } void Quat::operator*=(const Quat &p_q) { - set(w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y, - w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z, - w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x, - w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z); + x = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y; + y = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z; + z = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x; + w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z; } Quat Quat::operator*(const Quat &p_q) const { @@ -233,18 +181,49 @@ Quat::operator String() const { return String::num(x) + ", " + String::num(y) + ", " + String::num(z) + ", " + String::num(w); } -void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) { +Quat::Quat(const Vector3 &p_axis, real_t p_angle) { #ifdef MATH_CHECKS - ERR_FAIL_COND_MSG(!axis.is_normalized(), "The axis Vector3 must be normalized."); + ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized."); #endif - real_t d = axis.length(); + real_t d = p_axis.length(); if (d == 0) { - set(0, 0, 0, 0); + x = 0; + y = 0; + z = 0; + w = 0; } else { - real_t sin_angle = Math::sin(angle * 0.5); - real_t cos_angle = Math::cos(angle * 0.5); + real_t sin_angle = Math::sin(p_angle * 0.5); + real_t cos_angle = Math::cos(p_angle * 0.5); real_t s = sin_angle / d; - set(axis.x * s, axis.y * s, axis.z * s, - cos_angle); + x = p_axis.x * s; + y = p_axis.y * s; + z = p_axis.z * s; + w = cos_angle; } } + +// Euler constructor expects a vector containing the Euler angles in the format +// (ax, ay, az), where ax is the angle of rotation around x axis, +// and similar for other axes. +// This implementation uses YXZ convention (Z is the first rotation). +Quat::Quat(const Vector3 &p_euler) { + real_t half_a1 = p_euler.y * 0.5; + real_t half_a2 = p_euler.x * 0.5; + real_t half_a3 = p_euler.z * 0.5; + + // R = Y(a1).X(a2).Z(a3) convention for Euler angles. + // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6) + // a3 is the angle of the first rotation, following the notation in this reference. + + real_t cos_a1 = Math::cos(half_a1); + real_t sin_a1 = Math::sin(half_a1); + real_t cos_a2 = Math::cos(half_a2); + real_t sin_a2 = Math::sin(half_a2); + real_t cos_a3 = Math::cos(half_a3); + real_t sin_a3 = Math::sin(half_a3); + + x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3; + y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3; + z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3; + w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3; +} diff --git a/core/math/quat.h b/core/math/quat.h index 423a7f8dfe..9db914fe52 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -65,19 +65,14 @@ public: Quat inverse() const; _FORCE_INLINE_ real_t dot(const Quat &p_q) const; - void set_euler_xyz(const Vector3 &p_euler); Vector3 get_euler_xyz() const; - void set_euler_yxz(const Vector3 &p_euler); Vector3 get_euler_yxz() const; - - void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); }; Vector3 get_euler() const { return get_euler_yxz(); }; Quat slerp(const Quat &p_to, const real_t &p_weight) const; Quat slerpni(const Quat &p_to, const real_t &p_weight) const; Quat cubic_slerp(const Quat &p_b, const Quat &p_pre_a, const Quat &p_post_b, const real_t &p_weight) const; - void set_axis_angle(const Vector3 &axis, const real_t &angle); _FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { r_angle = 2 * Math::acos(w); real_t r = ((real_t)1) / Math::sqrt(1 - w * w); @@ -124,23 +119,19 @@ public: operator String() const; - inline void set(real_t p_x, real_t p_y, real_t p_z, real_t p_w) { - x = p_x; - y = p_y; - z = p_z; - w = p_w; - } - _FORCE_INLINE_ Quat() {} + _FORCE_INLINE_ Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : x(p_x), y(p_y), z(p_z), w(p_w) { } - Quat(const Vector3 &axis, const real_t &angle) { set_axis_angle(axis, angle); } - Quat(const Vector3 &euler) { set_euler(euler); } + Quat(const Vector3 &p_axis, real_t p_angle); + + Quat(const Vector3 &p_euler); + Quat(const Quat &p_q) : x(p_q.x), y(p_q.y), diff --git a/core/math/transform.h b/core/math/transform.h index 60da6f5593..1c05dbe554 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -51,8 +51,8 @@ public: void rotate(const Vector3 &p_axis, real_t p_phi); void rotate_basis(const Vector3 &p_axis, real_t p_phi); - void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up); - Transform looking_at(const Vector3 &p_target, const Vector3 &p_up) const; + void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + Transform looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)) const; void scale(const Vector3 &p_scale); Transform scaled(const Vector3 &p_scale) const; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 496e29ebe4..5129ed336e 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -211,11 +211,11 @@ Vector2i Vector2i::operator*(const Vector2i &p_v1) const { return Vector2i(x * p_v1.x, y * p_v1.y); } -Vector2i Vector2i::operator*(const int &rvalue) const { +Vector2i Vector2i::operator*(const int32_t &rvalue) const { return Vector2i(x * rvalue, y * rvalue); } -void Vector2i::operator*=(const int &rvalue) { +void Vector2i::operator*=(const int32_t &rvalue) { x *= rvalue; y *= rvalue; } @@ -224,11 +224,11 @@ Vector2i Vector2i::operator/(const Vector2i &p_v1) const { return Vector2i(x / p_v1.x, y / p_v1.y); } -Vector2i Vector2i::operator/(const int &rvalue) const { +Vector2i Vector2i::operator/(const int32_t &rvalue) const { return Vector2i(x / rvalue, y / rvalue); } -void Vector2i::operator/=(const int &rvalue) { +void Vector2i::operator/=(const int32_t &rvalue) { x /= rvalue; y /= rvalue; } @@ -237,11 +237,11 @@ Vector2i Vector2i::operator%(const Vector2i &p_v1) const { return Vector2i(x % p_v1.x, y % p_v1.y); } -Vector2i Vector2i::operator%(const int &rvalue) const { +Vector2i Vector2i::operator%(const int32_t &rvalue) const { return Vector2i(x % rvalue, y % rvalue); } -void Vector2i::operator%=(const int &rvalue) { +void Vector2i::operator%=(const int32_t &rvalue) { x %= rvalue; y %= rvalue; } diff --git a/core/math/vector2.h b/core/math/vector2.h index 24795857a3..81bc71d590 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -265,18 +265,18 @@ struct Vector2i { }; union { - int x = 0; - int width; + int32_t x = 0; + int32_t width; }; union { - int y = 0; - int height; + int32_t y = 0; + int32_t height; }; - _FORCE_INLINE_ int &operator[](int p_idx) { + _FORCE_INLINE_ int32_t &operator[](int p_idx) { return p_idx ? y : x; } - _FORCE_INLINE_ const int &operator[](int p_idx) const { + _FORCE_INLINE_ const int32_t &operator[](int p_idx) const { return p_idx ? y : x; } @@ -286,16 +286,16 @@ struct Vector2i { void operator-=(const Vector2i &p_v); Vector2i operator*(const Vector2i &p_v1) const; - Vector2i operator*(const int &rvalue) const; - void operator*=(const int &rvalue); + Vector2i operator*(const int32_t &rvalue) const; + void operator*=(const int32_t &rvalue); Vector2i operator/(const Vector2i &p_v1) const; - Vector2i operator/(const int &rvalue) const; - void operator/=(const int &rvalue); + Vector2i operator/(const int32_t &rvalue) const; + void operator/=(const int32_t &rvalue); Vector2i operator%(const Vector2i &p_v1) const; - Vector2i operator%(const int &rvalue) const; - void operator%=(const int &rvalue); + Vector2i operator%(const int32_t &rvalue) const; + void operator%=(const int32_t &rvalue); Vector2i operator-() const; bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } @@ -317,10 +317,10 @@ struct Vector2i { inline Vector2i() {} inline Vector2i(const Vector2 &p_vec2) { - x = (int)p_vec2.x; - y = (int)p_vec2.y; + x = (int32_t)p_vec2.x; + y = (int32_t)p_vec2.y; } - inline Vector2i(int p_x, int p_y) { + inline Vector2i(int32_t p_x, int32_t p_y) { x = p_x; y = p_y; } diff --git a/core/math/vector3.h b/core/math/vector3.h index 3fdb944729..377581bb45 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -110,6 +110,7 @@ struct Vector3 { _FORCE_INLINE_ Vector3 project(const Vector3 &p_to) const; _FORCE_INLINE_ real_t angle_to(const Vector3 &p_to) const; + _FORCE_INLINE_ real_t signed_angle_to(const Vector3 &p_to, const Vector3 &p_axis) const; _FORCE_INLINE_ Vector3 direction_to(const Vector3 &p_to) const; _FORCE_INLINE_ Vector3 slide(const Vector3 &p_normal) const; @@ -230,6 +231,13 @@ real_t Vector3::angle_to(const Vector3 &p_to) const { return Math::atan2(cross(p_to).length(), dot(p_to)); } +real_t Vector3::signed_angle_to(const Vector3 &p_to, const Vector3 &p_axis) const { + Vector3 cross_to = cross(p_to); + real_t unsigned_angle = Math::atan2(cross_to.length(), dot(p_to)); + real_t sign = cross_to.dot(p_axis); + return (sign < 0) ? -unsigned_angle : unsigned_angle; +} + Vector3 Vector3::direction_to(const Vector3 &p_to) const { Vector3 ret(p_to.x - x, p_to.y - y, p_to.z - z); ret.normalize(); @@ -324,48 +332,40 @@ bool Vector3::operator<(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z < p_v.z; - } else { - return y < p_v.y; } - } else { - return x < p_v.x; + return y < p_v.y; } + return x < p_v.x; } bool Vector3::operator>(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z > p_v.z; - } else { - return y > p_v.y; } - } else { - return x > p_v.x; + return y > p_v.y; } + return x > p_v.x; } bool Vector3::operator<=(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z <= p_v.z; - } else { - return y < p_v.y; } - } else { - return x < p_v.x; + return y < p_v.y; } + return x < p_v.x; } bool Vector3::operator>=(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z >= p_v.z; - } else { - return y > p_v.y; } - } else { - return x > p_v.x; + return y > p_v.y; } + return x > p_v.x; } _FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) { diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 6bc6d653d1..375ad8fae1 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -983,9 +983,9 @@ void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, co // NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end. void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { - lock->read_lock(); + lock.read_lock(); ClassInfo *type = classes.getptr(p_class); - lock->read_unlock(); + lock.read_unlock(); ERR_FAIL_COND(!type); @@ -1541,11 +1541,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con return var; } -RWLock *ClassDB::lock = nullptr; - -void ClassDB::init() { - lock = RWLock::create(); -} +RWLock ClassDB::lock; void ClassDB::cleanup_defaults() { default_values.clear(); @@ -1568,8 +1564,6 @@ void ClassDB::cleanup() { classes.clear(); resource_base_extensions.clear(); compat_classes.clear(); - - memdelete(lock); } // diff --git a/core/object/class_db.h b/core/object/class_db.h index 0591676b92..6fd5748dbb 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -146,7 +146,7 @@ public: return memnew(T); } - static RWLock *lock; + static RWLock lock; static HashMap<StringName, ClassInfo> classes; static HashMap<StringName, StringName> resource_base_extensions; static HashMap<StringName, StringName> compat_classes; @@ -387,7 +387,6 @@ public: static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions); static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback); - static void init(); static void set_current_api(APIType p_api); static APIType get_current_api(); diff --git a/core/object/object.cpp b/core/object/object.cpp index 171bc4dc2c..1a9cce49d8 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -808,21 +808,6 @@ String Object::to_string() { return "[" + get_class() + ":" + itos(get_instance_id()) + "]"; } -void Object::_changed_callback(Object *p_changed, const char *p_prop) { -} - -void Object::add_change_receptor(Object *p_receptor) { - change_receptors.insert(p_receptor); -} - -void Object::remove_change_receptor(Object *p_receptor) { - change_receptors.erase(p_receptor); -} - -void Object::property_list_changed_notify() { - _change_notify(); -} - void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) { //this function is not meant to be used in any of these ways ERR_FAIL_COND(p_script.is_null()); @@ -856,7 +841,7 @@ void Object::set_script(const Variant &p_script) { } } - _change_notify(); //scripts may add variables, so refresh is desired + notify_property_list_changed(); //scripts may add variables, so refresh is desired emit_signal(CoreStringNames::get_singleton()->script_changed); } @@ -1496,6 +1481,10 @@ void Object::clear_internal_resource_paths() { } } +void Object::notify_property_list_changed() { + emit_signal(CoreStringNames::get_singleton()->property_list_changed); +} + void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_class"), &Object::get_class); ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class); @@ -1562,7 +1551,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals); ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals); - ClassDB::bind_method(D_METHOD("property_list_changed_notify"), &Object::property_list_changed_notify); + ClassDB::bind_method(D_METHOD("notify_property_list_changed"), &Object::notify_property_list_changed); ClassDB::bind_method(D_METHOD("set_message_translation", "enable"), &Object::set_message_translation); ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages); @@ -1574,6 +1563,7 @@ void Object::_bind_methods() { ClassDB::add_virtual_method("Object", MethodInfo("free"), false); ADD_SIGNAL(MethodInfo("script_changed")); + ADD_SIGNAL(MethodInfo("property_list_changed")); BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what"))); BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value"))); @@ -1737,7 +1727,7 @@ void *Object::get_script_instance_binding(int p_script_language_index) { if (!_script_instance_bindings[p_script_language_index]) { void *script_data = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this); if (script_data) { - atomic_increment(&instance_binding_count); + instance_binding_count.increment(); _script_instance_bindings[p_script_language_index] = script_data; } } diff --git a/core/object/object.h b/core/object/object.h index 7e460462cf..029478873d 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -37,6 +37,7 @@ #include "core/templates/hash_map.h" #include "core/templates/list.h" #include "core/templates/map.h" +#include "core/templates/safe_refcount.h" #include "core/templates/set.h" #include "core/templates/vmap.h" #include "core/variant/callable_bind.h" @@ -125,6 +126,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 27, // For Object properties, instantiate them when creating in editor. + PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 28, //for project or editor settings, show when basic settings are selected PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED, @@ -454,7 +456,6 @@ private: #endif bool _block_signals = false; int _predelete_ok = 0; - Set<Object *> change_receptors; ObjectID _instance_id; bool _predelete(); void _postinitialize(); @@ -486,7 +487,7 @@ private: friend class Reference; bool type_is_reference = false; - uint32_t instance_binding_count = 0; + SafeNumeric<uint32_t> instance_binding_count; void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; Object(bool p_reference); @@ -523,9 +524,6 @@ protected: static void get_valid_parents_static(List<String> *p_parents); static void _get_valid_parents_static(List<String> *p_parents); - void property_list_changed_notify(); - virtual void _changed_callback(Object *p_changed, const char *p_prop); - //Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant()); //void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant()); @@ -555,16 +553,8 @@ public: //should be protected, but bug in clang++ _FORCE_INLINE_ static void register_custom_data_to_otdb() {} public: -#ifdef TOOLS_ENABLED - _FORCE_INLINE_ void _change_notify(const char *p_property = "") { - _edited = true; - for (Set<Object *>::Element *E = change_receptors.front(); E; E = E->next()) { - ((Object *)(E->get()))->_changed_callback(this, p_property); - } - } -#else - _FORCE_INLINE_ void _change_notify(const char *p_what = "") {} -#endif + void notify_property_list_changed(); + static void *get_class_ptr_static() { static int ptr; return &ptr; @@ -574,10 +564,6 @@ public: _FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; } - // this is used for editors - void add_change_receptor(Object *p_receptor); - void remove_change_receptor(Object *p_receptor); - template <class T> static T *cast_to(Object *p_object) { #ifndef NO_SAFE_CAST diff --git a/core/object/reference.cpp b/core/object/reference.cpp index 71a52a9ba5..22e4e8a336 100644 --- a/core/object/reference.cpp +++ b/core/object/reference.cpp @@ -62,7 +62,7 @@ bool Reference::reference() { if (get_script_instance()) { get_script_instance()->refcount_incremented(); } - if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) { + if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { ScriptServer::get_language(i)->refcount_incremented_instance_binding(this); @@ -83,7 +83,7 @@ bool Reference::unreference() { bool script_ret = get_script_instance()->refcount_decremented(); die = die && script_ret; } - if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) { + if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this); diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index c3f109a147..42fb0a0caf 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -275,6 +275,14 @@ void ScriptServer::save_global_classes() { gcarr.push_back(d); } + Array old; + if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) { + old = ProjectSettings::get_singleton()->get("_global_script_classes"); + } + if ((!old.is_empty() || gcarr.is_empty()) && gcarr.hash() == old.hash()) { + return; + } + if (gcarr.is_empty()) { if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) { ProjectSettings::get_singleton()->clear("_global_script_classes"); @@ -515,7 +523,7 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c } if (owner && owner->get_script_instance() == this) { - owner->_change_notify(); + owner->notify_property_list_changed(); } //change notify diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index c699820e75..e8735e335c 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -53,6 +53,23 @@ void UndoRedo::_discard_redo() { actions.resize(current_action + 1); } +bool UndoRedo::_redo(bool p_execute) { + ERR_FAIL_COND_V(action_level > 0, false); + + if ((current_action + 1) >= actions.size()) { + return false; //nothing to redo + } + + current_action++; + if (p_execute) { + _process_operation_list(actions.write[current_action].do_ops.front()); + } + version++; + emit_signal("version_changed"); + + return true; +} + void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { uint32_t ticks = OS::get_singleton()->get_ticks_msec(); @@ -242,7 +259,7 @@ bool UndoRedo::is_committing_action() const { return committing > 0; } -void UndoRedo::commit_action() { +void UndoRedo::commit_action(bool p_execute) { ERR_FAIL_COND(action_level <= 0); action_level--; if (action_level > 0) { @@ -255,8 +272,9 @@ void UndoRedo::commit_action() { } committing++; - redo(); // perform action + _redo(p_execute); // perform action committing--; + if (callback && actions.size() > 0) { callback(callback_ud, actions[actions.size() - 1].name); } @@ -323,19 +341,7 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) { } bool UndoRedo::redo() { - ERR_FAIL_COND_V(action_level > 0, false); - - if ((current_action + 1) >= actions.size()) { - return false; //nothing to redo - } - - current_action++; - - _process_operation_list(actions.write[current_action].do_ops.front()); - version++; - emit_signal("version_changed"); - - return true; + return _redo(true); } bool UndoRedo::undo() { @@ -351,6 +357,24 @@ bool UndoRedo::undo() { return true; } +int UndoRedo::get_history_count() { + ERR_FAIL_COND_V(action_level > 0, -1); + + return actions.size(); +} + +int UndoRedo::get_current_action() { + ERR_FAIL_COND_V(action_level > 0, -1); + + return current_action; +} + +String UndoRedo::get_action_name(int p_id) { + ERR_FAIL_INDEX_V(p_id, actions.size(), ""); + + return actions[p_id].name; +} + void UndoRedo::clear_history(bool p_increase_version) { ERR_FAIL_COND(action_level > 0); _discard_redo(); @@ -480,7 +504,7 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla void UndoRedo::_bind_methods() { ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE)); - ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action); + ClassDB::bind_method(D_METHOD("commit_action", "execute"), &UndoRedo::commit_action, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_committing_action"), &UndoRedo::is_committing_action); { @@ -505,8 +529,14 @@ void UndoRedo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_undo_property", "object", "property", "value"), &UndoRedo::add_undo_property); ClassDB::bind_method(D_METHOD("add_do_reference", "object"), &UndoRedo::add_do_reference); ClassDB::bind_method(D_METHOD("add_undo_reference", "object"), &UndoRedo::add_undo_reference); + + ClassDB::bind_method(D_METHOD("get_history_count"), &UndoRedo::get_history_count); + ClassDB::bind_method(D_METHOD("get_current_action"), &UndoRedo::get_current_action); + ClassDB::bind_method(D_METHOD("get_action_name", "id"), &UndoRedo::get_action_name); ClassDB::bind_method(D_METHOD("clear_history", "increase_version"), &UndoRedo::clear_history, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_current_action_name"), &UndoRedo::get_current_action_name); + ClassDB::bind_method(D_METHOD("has_undo"), &UndoRedo::has_undo); ClassDB::bind_method(D_METHOD("has_redo"), &UndoRedo::has_redo); ClassDB::bind_method(D_METHOD("get_version"), &UndoRedo::get_version); diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index 7b28b138c1..a08ca7792f 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -84,6 +84,7 @@ private: void _pop_history_tail(); void _process_operation_list(List<Operation>::Element *E); void _discard_redo(); + bool _redo(bool p_execute); CommitNotifyCallback callback = nullptr; void *callback_ud = nullptr; @@ -109,11 +110,15 @@ public: void add_undo_reference(Object *p_object); bool is_committing_action() const; - void commit_action(); + void commit_action(bool p_execute = true); bool redo(); bool undo(); String get_current_action_name() const; + + int get_history_count(); + int get_current_action(); + String get_action_name(int p_id); void clear_history(bool p_increase_version = true); bool has_undo(); diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index fb9da9fbed..b7c3a17ba9 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -170,7 +170,7 @@ Error DirAccess::make_dir_recursive(String p_dir) { curpath = curpath.plus_file(subdirs[i]); Error err = make_dir(curpath); if (err != OK && err != ERR_ALREADY_EXISTS) { - ERR_FAIL_V(err); + ERR_FAIL_V_MSG(err, "Could not create directory: " + curpath); } } diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 14808c2ce6..5910cb0e7b 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -60,11 +60,11 @@ void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_d #endif #ifdef DEBUG_ENABLED -uint64_t Memory::mem_usage = 0; -uint64_t Memory::max_usage = 0; +SafeNumeric<uint64_t> Memory::mem_usage; +SafeNumeric<uint64_t> Memory::max_usage; #endif -uint64_t Memory::alloc_count = 0; +SafeNumeric<uint64_t> Memory::alloc_count; void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { #ifdef DEBUG_ENABLED @@ -77,7 +77,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { ERR_FAIL_COND_V(!mem, nullptr); - atomic_increment(&alloc_count); + alloc_count.increment(); if (prepad) { uint64_t *s = (uint64_t *)mem; @@ -86,8 +86,8 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { uint8_t *s8 = (uint8_t *)mem; #ifdef DEBUG_ENABLED - atomic_add(&mem_usage, p_bytes); - atomic_exchange_if_greater(&max_usage, mem_usage); + uint64_t new_mem_usage = mem_usage.add(p_bytes); + max_usage.exchange_if_greater(new_mem_usage); #endif return s8 + PAD_ALIGN; } else { @@ -114,10 +114,10 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { #ifdef DEBUG_ENABLED if (p_bytes > *s) { - atomic_add(&mem_usage, p_bytes - *s); - atomic_exchange_if_greater(&max_usage, mem_usage); + uint64_t new_mem_usage = mem_usage.add(p_bytes - *s); + max_usage.exchange_if_greater(new_mem_usage); } else { - atomic_sub(&mem_usage, *s - p_bytes); + mem_usage.sub(*s - p_bytes); } #endif @@ -156,14 +156,14 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) { bool prepad = p_pad_align; #endif - atomic_decrement(&alloc_count); + alloc_count.decrement(); if (prepad) { mem -= PAD_ALIGN; #ifdef DEBUG_ENABLED uint64_t *s = (uint64_t *)mem; - atomic_sub(&mem_usage, *s); + mem_usage.sub(*s); #endif free(mem); @@ -178,7 +178,7 @@ uint64_t Memory::get_mem_available() { uint64_t Memory::get_mem_usage() { #ifdef DEBUG_ENABLED - return mem_usage; + return mem_usage.get(); #else return 0; #endif @@ -186,7 +186,7 @@ uint64_t Memory::get_mem_usage() { uint64_t Memory::get_mem_max_usage() { #ifdef DEBUG_ENABLED - return max_usage; + return max_usage.get(); #else return 0; #endif diff --git a/core/os/memory.h b/core/os/memory.h index c2ae3f4ae7..10e678103d 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -43,11 +43,11 @@ class Memory { Memory(); #ifdef DEBUG_ENABLED - static uint64_t mem_usage; - static uint64_t max_usage; + static SafeNumeric<uint64_t> mem_usage; + static SafeNumeric<uint64_t> max_usage; #endif - static uint64_t alloc_count; + static SafeNumeric<uint64_t> alloc_count; public: static void *alloc_static(size_t p_bytes, bool p_pad_align = false); diff --git a/core/os/os.h b/core/os/os.h index ed3c6ddc94..e41d788e12 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -40,6 +40,7 @@ #include "core/templates/vector.h" #include <stdarg.h> +#include <stdlib.h> class OS { static OS *singleton; @@ -53,7 +54,7 @@ class OS { bool _debug_stdout = false; String _local_clipboard; bool _no_window = false; - int _exit_code = 0; + int _exit_code = EXIT_FAILURE; // unexpected exit is marked as failure int _orientation; bool _allow_hidpi = false; bool _allow_layered = false; @@ -129,7 +130,8 @@ public: virtual int get_low_processor_usage_mode_sleep_usec() const; virtual String get_executable_path() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0; + virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0; + virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) = 0; virtual Error kill(const ProcessID &p_pid) = 0; virtual int get_process_id() const; virtual void vibrate_handheld(int p_duration_ms = 500); @@ -148,11 +150,6 @@ public: bool is_layered_allowed() const { return _allow_layered; } bool is_hidpi_allowed() const { return _allow_hidpi; } - virtual int get_tablet_driver_count() const { return 0; }; - virtual String get_tablet_driver_name(int p_driver) const { return ""; }; - virtual String get_current_tablet_driver() const { return ""; }; - virtual void set_current_tablet_driver(const String &p_driver){}; - void ensure_user_data_dir(); virtual MainLoop *get_main_loop() const = 0; diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h index ff6ad3cc4a..560ec57a5f 100644 --- a/core/os/rw_lock.h +++ b/core/os/rw_lock.h @@ -33,55 +33,83 @@ #include "core/error/error_list.h" +#if !defined(NO_THREADS) + +#include <shared_mutex> + class RWLock { -protected: - static RWLock *(*create_func)(); + mutable std::shared_timed_mutex mutex; public: - virtual void read_lock() = 0; ///< Lock the rwlock, block if locked by someone else - virtual void read_unlock() = 0; ///< Unlock the rwlock, let other threads continue - virtual Error read_try_lock() = 0; ///< Attempt to lock the rwlock, OK on success, ERROR means it can't lock. + // Lock the rwlock, block if locked by someone else + void read_lock() const { + mutex.lock_shared(); + } - virtual void write_lock() = 0; ///< Lock the rwlock, block if locked by someone else - virtual void write_unlock() = 0; ///< Unlock the rwlock, let other thwrites continue - virtual Error write_try_lock() = 0; ///< Attempt to lock the rwlock, OK on success, ERROR means it can't lock. + // Unlock the rwlock, let other threads continue + void read_unlock() const { + mutex.unlock_shared(); + } - static RWLock *create(); ///< Create a rwlock + // Attempt to lock the rwlock, OK on success, ERR_BUSY means it can't lock. + Error read_try_lock() const { + return mutex.try_lock_shared() ? OK : ERR_BUSY; + } + + // Lock the rwlock, block if locked by someone else + void write_lock() { + mutex.lock(); + } + + // Unlock the rwlock, let other thwrites continue + void write_unlock() { + mutex.unlock(); + } - virtual ~RWLock() {} + // Attempt to lock the rwlock, OK on success, ERR_BUSY means it can't lock. + Error write_try_lock() { + return mutex.try_lock() ? OK : ERR_BUSY; + } +}; + +#else + +class RWLock { +public: + void read_lock() const {} + void read_unlock() const {} + Error read_try_lock() const { return OK; } + + void write_lock() {} + void write_unlock() {} + Error write_try_lock() { return OK; } }; +#endif + class RWLockRead { - RWLock *lock; + const RWLock &lock; public: - RWLockRead(const RWLock *p_lock) { - lock = const_cast<RWLock *>(p_lock); - if (lock) { - lock->read_lock(); - } + RWLockRead(const RWLock &p_lock) : + lock(p_lock) { + lock.read_lock(); } ~RWLockRead() { - if (lock) { - lock->read_unlock(); - } + lock.read_unlock(); } }; class RWLockWrite { - RWLock *lock; + RWLock &lock; public: - RWLockWrite(RWLock *p_lock) { - lock = p_lock; - if (lock) { - lock->write_lock(); - } + RWLockWrite(RWLock &p_lock) : + lock(p_lock) { + lock.write_lock(); } ~RWLockWrite() { - if (lock) { - lock->write_unlock(); - } + lock.write_unlock(); } }; diff --git a/core/os/thread.cpp b/core/os/thread.cpp index 0ed8825452..aea370787d 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -30,30 +30,73 @@ #include "thread.h" -Thread *(*Thread::create_func)(ThreadCreateCallback, void *, const Settings &) = nullptr; -Thread::ID (*Thread::get_thread_id_func)() = nullptr; -void (*Thread::wait_to_finish_func)(Thread *) = nullptr; +#include "core/object/script_language.h" + +#if !defined(NO_THREADS) + +#include "core/templates/safe_refcount.h" + Error (*Thread::set_name_func)(const String &) = nullptr; +void (*Thread::set_priority_func)(Thread::Priority) = nullptr; +void (*Thread::init_func)() = nullptr; +void (*Thread::term_func)() = nullptr; -Thread::ID Thread::_main_thread_id = 0; +Thread::ID Thread::main_thread_id = 1; +SafeNumeric<Thread::ID> Thread::last_thread_id{ 1 }; +thread_local Thread::ID Thread::caller_id = 1; -Thread::ID Thread::get_caller_id() { - if (get_thread_id_func) { - return get_thread_id_func(); +void Thread::_set_platform_funcs( + Error (*p_set_name_func)(const String &), + void (*p_set_priority_func)(Thread::Priority), + void (*p_init_func)(), + void (*p_term_func)()) { + Thread::set_name_func = p_set_name_func; + Thread::set_priority_func = p_set_priority_func; + Thread::init_func = p_init_func; + Thread::term_func = p_term_func; +} + +void Thread::callback(Thread *p_self, const Settings &p_settings, Callback p_callback, void *p_userdata) { + Thread::caller_id = p_self->id; + if (set_priority_func) { + set_priority_func(p_settings.priority); + } + if (init_func) { + init_func(); + } + ScriptServer::thread_enter(); //scripts may need to attach a stack + p_callback(p_userdata); + ScriptServer::thread_exit(); + if (term_func) { + term_func(); } - return 0; } -Thread *Thread::create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings) { - if (create_func) { - return create_func(p_callback, p_user, p_settings); +void Thread::start(Thread::Callback p_callback, void *p_user, const Settings &p_settings) { + if (id != 0) { +#ifdef DEBUG_ENABLED + WARN_PRINT("A Thread object has been re-started without wait_to_finish() having been called on it. Please do so to ensure correct cleanup of the thread."); +#endif + thread.detach(); + std::thread empty_thread; + thread.swap(empty_thread); } - return nullptr; + id = last_thread_id.increment(); + std::thread new_thread(&Thread::callback, this, p_settings, p_callback, p_user); + thread.swap(new_thread); } -void Thread::wait_to_finish(Thread *p_thread) { - if (wait_to_finish_func) { - wait_to_finish_func(p_thread); +bool Thread::is_started() const { + return id != 0; +} + +void Thread::wait_to_finish() { + if (id != 0) { + ERR_FAIL_COND_MSG(id == get_caller_id(), "A Thread can't wait for itself to finish."); + thread.join(); + std::thread empty_thread; + thread.swap(empty_thread); + id = 0; } } @@ -64,3 +107,14 @@ Error Thread::set_name(const String &p_name) { return ERR_UNAVAILABLE; } + +Thread::~Thread() { + if (id != 0) { +#ifdef DEBUG_ENABLED + WARN_PRINT("A Thread object has been destroyed without wait_to_finish() having been called on it. Please do so to ensure correct cleanup of the thread."); +#endif + thread.detach(); + } +} + +#endif diff --git a/core/os/thread.h b/core/os/thread.h index 993c7ad33d..76f5be182e 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -31,13 +31,21 @@ #ifndef THREAD_H #define THREAD_H -#include "core/string/ustring.h" #include "core/typedefs.h" -typedef void (*ThreadCreateCallback)(void *p_userdata); +#if !defined(NO_THREADS) +#include "core/templates/safe_refcount.h" +#include <thread> +#endif + +class String; class Thread { public: + typedef void (*Callback)(void *p_userdata); + + typedef uint64_t ID; + enum Priority { PRIORITY_LOW, PRIORITY_NORMAL, @@ -49,30 +57,60 @@ public: Settings() { priority = PRIORITY_NORMAL; } }; - typedef uint64_t ID; +private: +#if !defined(NO_THREADS) + friend class Main; -protected: - static Thread *(*create_func)(ThreadCreateCallback p_callback, void *, const Settings &); - static ID (*get_thread_id_func)(); - static void (*wait_to_finish_func)(Thread *); - static Error (*set_name_func)(const String &); + static ID main_thread_id; + static SafeNumeric<Thread::ID> last_thread_id; - friend class Main; + ID id = 0; + static thread_local ID caller_id; + std::thread thread; - static ID _main_thread_id; + static void callback(Thread *p_self, const Settings &p_settings, Thread::Callback p_callback, void *p_userdata); - Thread() {} + static Error (*set_name_func)(const String &); + static void (*set_priority_func)(Thread::Priority); + static void (*init_func)(); + static void (*term_func)(); +#endif public: - virtual ID get_id() const = 0; + static void _set_platform_funcs( + Error (*p_set_name_func)(const String &), + void (*p_set_priority_func)(Thread::Priority), + void (*p_init_func)() = nullptr, + void (*p_term_func)() = nullptr); + +#if !defined(NO_THREADS) + _FORCE_INLINE_ ID get_id() const { return id; } + // get the ID of the caller thread + _FORCE_INLINE_ static ID get_caller_id() { return caller_id; } + // get the ID of the main thread + _FORCE_INLINE_ static ID get_main_id() { return main_thread_id; } static Error set_name(const String &p_name); - _FORCE_INLINE_ static ID get_main_id() { return _main_thread_id; } ///< get the ID of the main thread - static ID get_caller_id(); ///< get the ID of the caller function ID - static void wait_to_finish(Thread *p_thread); ///< waits until thread is finished, and deallocates it. - static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings()); ///< Static function to create a thread, will call p_callback - virtual ~Thread() {} + void start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings()); + bool is_started() const; + ///< waits until thread is finished, and deallocates it. + void wait_to_finish(); + + ~Thread(); +#else + _FORCE_INLINE_ ID get_id() const { return 0; } + // get the ID of the caller thread + _FORCE_INLINE_ static ID get_caller_id() { return 0; } + // get the ID of the main thread + _FORCE_INLINE_ static ID get_main_id() { return 0; } + + static Error set_name(const String &p_name) { return ERR_UNAVAILABLE; } + + void start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings()) {} + bool is_started() const { return false; } + void wait_to_finish() {} +#endif }; #endif // THREAD_H diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h deleted file mode 100644 index 35e19732bf..0000000000 --- a/core/os/thread_dummy.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* thread_dummy.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef THREAD_DUMMY_H -#define THREAD_DUMMY_H - -#include "core/os/rw_lock.h" -#include "core/os/semaphore.h" -#include "core/os/thread.h" - -class ThreadDummy : public Thread { - static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings()); - -public: - virtual ID get_id() const { return 0; }; - - static void make_default(); -}; - -class RWLockDummy : public RWLock { - static RWLock *create(); - -public: - virtual void read_lock() {} - virtual void read_unlock() {} - virtual Error read_try_lock() { return OK; } - - virtual void write_lock() {} - virtual void write_unlock() {} - virtual Error write_try_lock() { return OK; } - - static void make_default(); -}; - -#endif // THREAD_DUMMY_H diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h index 57f3de20bf..fec6473589 100644 --- a/core/os/threaded_array_processor.h +++ b/core/os/threaded_array_processor.h @@ -40,7 +40,7 @@ template <class C, class U> struct ThreadArrayProcessData { uint32_t elements; - uint32_t index; + SafeNumeric<uint32_t> index; C *instance; U userdata; void (C::*method)(uint32_t, U); @@ -56,7 +56,7 @@ template <class T> void process_array_thread(void *ud) { T &data = *(T *)ud; while (true) { - uint32_t index = atomic_increment(&data.index); + uint32_t index = data.index.increment(); if (index >= data.elements) { break; } @@ -70,22 +70,21 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us data.method = p_method; data.instance = p_instance; data.userdata = p_userdata; - data.index = 0; + data.index.set(0); data.elements = p_elements; - data.process(data.index); //process first, let threads increment for next + data.process(0); //process first, let threads increment for next - Vector<Thread *> threads; + int thread_count = OS::get_singleton()->get_processor_count(); + Thread *threads = memnew_arr(Thread, thread_count); - threads.resize(OS::get_singleton()->get_processor_count()); - - for (int i = 0; i < threads.size(); i++) { - threads.write[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U>>, &data); + for (int i = 0; i < thread_count; i++) { + threads[i].start(process_array_thread<ThreadArrayProcessData<C, U>>, &data); } - for (int i = 0; i < threads.size(); i++) { - Thread::wait_to_finish(threads[i]); - memdelete(threads[i]); + for (int i = 0; i < thread_count; i++) { + threads[i].wait_to_finish(); } + memdelete_arr(threads); } #else @@ -96,7 +95,7 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us data.method = p_method; data.instance = p_instance; data.userdata = p_userdata; - data.index = 0; + data.index.set(0); data.elements = p_elements; for (uint32_t i = 0; i < p_elements; i++) { data.process(i); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 9eef7700f9..b58abc81d1 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -103,7 +103,6 @@ void register_core_types() { static_assert(sizeof(Callable) <= 16); ObjectDB::setup(); - ResourceCache::setup(); StringName::setup(); ResourceLoader::initialize(); diff --git a/core/string/translation.cpp b/core/string/translation.cpp index 5337d46aa3..9cee218735 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -39,13 +39,14 @@ #include "main/main.h" #endif -// ISO 639-1 language codes, with the addition of glibc locales with their -// regional identifiers. This list must match the language names (in English) -// of locale_names. +// ISO 639-1 language codes (and a couple of three-letter ISO 639-2 codes), +// with the addition of glibc locales with their regional identifiers. +// This list must match the language names (in English) of locale_names. // // References: // - https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes // - https://lh.2xlibre.net/locales/ +// - https://iso639-3.sil.org/ static const char *locale_list[] = { "aa", // Afar @@ -100,6 +101,7 @@ static const char *locale_list[] = { "bo", // Tibetan "bo_CN", // Tibetan (China) "bo_IN", // Tibetan (India) + "br", // Breton "br_FR", // Breton (France) "brx_IN", // Bodo (India) "bs_BA", // Bosnian (Bosnia and Herzegovina) @@ -201,6 +203,7 @@ static const char *locale_list[] = { "gd_GB", // Scottish Gaelic (United Kingdom) "gez_ER", // Geez (Eritrea) "gez_ET", // Geez (Ethiopia) + "gl", // Galician "gl_ES", // Galician (Spain) "gu_IN", // Gujarati (India) "gv_GB", // Manx (United Kingdom) @@ -273,6 +276,7 @@ static const char *locale_list[] = { "ml_IN", // Malayalam (India) "mni_IN", // Manipuri (India) "mn_MN", // Mongolian (Mongolia) + "mr", // Marathi "mr_IN", // Marathi (India) "ms", // Malay "ms_MY", // Malay (Malaysia) @@ -302,6 +306,7 @@ static const char *locale_list[] = { "om", // Oromo "om_ET", // Oromo (Ethiopia) "om_KE", // Oromo (Kenya) + "or", // Oriya "or_IN", // Oriya (India) "os_RU", // Ossetian (Russia) "pa_IN", // Panjabi (India) @@ -386,6 +391,8 @@ static const char *locale_list[] = { "tr_TR", // Turkish (Turkey) "ts_ZA", // Tsonga (South Africa) "tt_RU", // Tatar (Russia) + "tzm", // Central Atlas Tamazight + "tzm_MA", // Central Atlas Tamazight (Marrocos) "ug_CN", // Uighur (China) "uk", // Ukrainian "uk_UA", // Ukrainian (Ukraine) @@ -468,6 +475,7 @@ static const char *locale_names[] = { "Tibetan", "Tibetan (China)", "Tibetan (India)", + "Breton", "Breton (France)", "Bodo (India)", "Bosnian (Bosnia and Herzegovina)", @@ -569,6 +577,7 @@ static const char *locale_names[] = { "Scottish Gaelic (United Kingdom)", "Geez (Eritrea)", "Geez (Ethiopia)", + "Galician", "Galician (Spain)", "Gujarati (India)", "Manx (United Kingdom)", @@ -641,6 +650,7 @@ static const char *locale_names[] = { "Malayalam (India)", "Manipuri (India)", "Mongolian (Mongolia)", + "Marathi", "Marathi (India)", "Malay", "Malay (Malaysia)", @@ -670,6 +680,7 @@ static const char *locale_names[] = { "Oromo", "Oromo (Ethiopia)", "Oromo (Kenya)", + "Oriya", "Oriya (India)", "Ossetian (Russia)", "Panjabi (India)", @@ -754,6 +765,8 @@ static const char *locale_names[] = { "Turkish (Turkey)", "Tsonga (South Africa)", "Tatar (Russia)", + "Central Atlas Tamazight", + "Central Atlas Tamazight (Marrocos)", "Uighur (China)", "Ukrainian", "Ukrainian (Ukraine)", @@ -1191,14 +1204,14 @@ bool TranslationServer::_load_translations(const String &p_from) { } void TranslationServer::setup() { - String test = GLOBAL_DEF("locale/test", ""); + String test = GLOBAL_DEF("internationalization/locale/test", ""); test = test.strip_edges(); if (test != "") { set_locale(test); } else { set_locale(OS::get_singleton()->get_locale()); } - fallback = GLOBAL_DEF("locale/fallback", "en"); + fallback = GLOBAL_DEF("internationalization/locale/fallback", "en"); #ifdef TOOLS_ENABLED { String options = ""; @@ -1210,7 +1223,7 @@ void TranslationServer::setup() { options += locale_list[idx]; idx++; } - ProjectSettings::get_singleton()->set_custom_property_info("locale/fallback", PropertyInfo(Variant::STRING, "locale/fallback", PROPERTY_HINT_ENUM, options)); + ProjectSettings::get_singleton()->set_custom_property_info("internationalization/locale/fallback", PropertyInfo(Variant::STRING, "internationalization/locale/fallback", PROPERTY_HINT_ENUM, options)); } #endif } @@ -1307,11 +1320,11 @@ void TranslationServer::_bind_methods() { void TranslationServer::load_translations() { String locale = get_locale(); - _load_translations("locale/translations"); //all - _load_translations("locale/translations_" + locale.substr(0, 2)); + _load_translations("internationalization/locale/translations"); //all + _load_translations("internationalization/locale/translations_" + locale.substr(0, 2)); if (locale.substr(0, 2) != locale) { - _load_translations("locale/translations_" + locale); + _load_translations("internationalization/locale/translations_" + locale); } } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 21336a99ec..a57c7b2504 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1409,8 +1409,9 @@ String String::num(double p_num, int p_decimals) { if (digit == MAX_DIGITS) //no point in going to infinite break; - if ((dec - (double)((int)dec)) < 1e-6) + if (dec - (double)((int)dec) < 1e-6) { break; + } } if (digit == p_decimals) @@ -2096,8 +2097,9 @@ String::String(const StrRange &p_range) { copy_from(p_range.c_str, p_range.len); } -int64_t String::hex_to_int(bool p_with_prefix) const { - if (p_with_prefix && length() < 3) { +int64_t String::hex_to_int() const { + int len = length(); + if (len == 0) { return 0; } @@ -2109,10 +2111,7 @@ int64_t String::hex_to_int(bool p_with_prefix) const { s++; } - if (p_with_prefix) { - if (s[0] != '0' || s[1] != 'x') { - return 0; - } + if (len > 2 && s[0] == '0' && s[1] == 'x') { s += 2; } @@ -2139,8 +2138,9 @@ int64_t String::hex_to_int(bool p_with_prefix) const { return hex * sign; } -int64_t String::bin_to_int(bool p_with_prefix) const { - if (p_with_prefix && length() < 3) { +int64_t String::bin_to_int() const { + int len = length(); + if (len == 0) { return 0; } @@ -2152,10 +2152,7 @@ int64_t String::bin_to_int(bool p_with_prefix) const { s++; } - if (p_with_prefix) { - if (s[0] != '0' || s[1] != 'b') { - return 0; - } + if (len > 2 && s[0] == '0' && s[1] == 'b') { s += 2; } @@ -3074,35 +3071,47 @@ int String::rfindn(const String &p_str, int p_from) const { } bool String::ends_with(const String &p_string) const { - int pos = rfind(p_string); - if (pos == -1) { + int l = p_string.length(); + if (l > length()) { return false; } - return pos + p_string.length() == length(); + + if (l == 0) { + return true; + } + + const char32_t *p = &p_string[0]; + const char32_t *s = &operator[](length() - l); + + for (int i = 0; i < l; i++) { + if (p[i] != s[i]) { + return false; + } + } + + return true; } bool String::begins_with(const String &p_string) const { - if (p_string.length() > length()) { + int l = p_string.length(); + if (l > length()) { return false; } - int l = p_string.length(); if (l == 0) { return true; } - const char32_t *src = &p_string[0]; - const char32_t *str = &operator[](0); + const char32_t *p = &p_string[0]; + const char32_t *s = &operator[](0); - int i = 0; - for (; i < l; i++) { - if (src[i] != str[i]) { + for (int i = 0; i < l; i++) { + if (p[i] != s[i]) { return false; } } - // only if i == l the p_string matches the beginning - return i == l; + return true; } bool String::begins_with(const char *p_string) const { @@ -3250,8 +3259,8 @@ float String::similarity(const String &p_string) const { int src_size = src_bigrams.size(); int tgt_size = tgt_bigrams.size(); - double sum = src_size + tgt_size; - double inter = 0; + int sum = src_size + tgt_size; + int inter = 0; for (int i = 0; i < src_size; i++) { for (int j = 0; j < tgt_size; j++) { if (src_bigrams[i] == tgt_bigrams[j]) { @@ -3478,7 +3487,7 @@ String String::right(int p_pos) const { return substr(p_pos, (length() - p_pos)); } -char32_t String::ord_at(int p_idx) const { +char32_t String::unicode_at(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, length(), 0); return operator[](p_idx); } @@ -3750,7 +3759,7 @@ bool String::is_valid_string() const { return valid; } -String String::http_escape() const { +String String::uri_encode() const { const CharString temp = utf8(); String res; for (int i = 0; i < temp.length(); ++i) { @@ -3774,23 +3783,25 @@ String String::http_escape() const { return res; } -String String::http_unescape() const { +String String::uri_decode() const { String res; for (int i = 0; i < length(); ++i) { - if (ord_at(i) == '%' && i + 2 < length()) { - char32_t ord1 = ord_at(i + 1); + if (unicode_at(i) == '%' && i + 2 < length()) { + char32_t ord1 = unicode_at(i + 1); if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) { - char32_t ord2 = ord_at(i + 2); + char32_t ord2 = unicode_at(i + 2); if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) { char bytes[3] = { (char)ord1, (char)ord2, 0 }; res += (char)strtol(bytes, nullptr, 16); i += 2; } } else { - res += ord_at(i); + res += unicode_at(i); } + } else if (unicode_at(i) == '+') { + res += ' '; } else { - res += ord_at(i); + res += unicode_at(i); } } return String::utf8(res.ascii()); @@ -3877,25 +3888,55 @@ static _FORCE_INLINE_ int _xml_unescape(const char32_t *p_src, int p_src_len, ch if (p_src_len >= 4 && p_src[1] == '#') { char32_t c = 0; - - for (int i = 2; i < p_src_len; i++) { - eat = i + 1; - char32_t ct = p_src[i]; - if (ct == ';') { - break; - } else if (ct >= '0' && ct <= '9') { - ct = ct - '0'; - } else if (ct >= 'a' && ct <= 'f') { - ct = (ct - 'a') + 10; - } else if (ct >= 'A' && ct <= 'F') { - ct = (ct - 'A') + 10; - } else { - continue; + bool overflow = false; + if (p_src[2] == 'x') { + // Hex entity &#x<num>; + for (int i = 3; i < p_src_len; i++) { + eat = i + 1; + char32_t ct = p_src[i]; + if (ct == ';') { + break; + } else if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = (ct - 'a') + 10; + } else if (ct >= 'A' && ct <= 'F') { + ct = (ct - 'A') + 10; + } else { + break; + } + if (c > (UINT32_MAX >> 4)) { + overflow = true; + break; + } + c <<= 4; + c |= ct; + } + } else { + // Decimal entity &#<num>; + for (int i = 2; i < p_src_len; i++) { + eat = i + 1; + char32_t ct = p_src[i]; + if (ct == ';' || ct < '0' || ct > '9') { + break; + } + } + if (p_src[eat - 1] == ';') { + int64_t val = String::to_int(p_src + 2, eat - 3); + if (val > 0 && val <= UINT32_MAX) { + c = (char32_t)val; + } else { + overflow = true; + } } - c <<= 4; - c |= ct; } + // Value must be non-zero, in the range of char32_t, + // actually end with ';'. If invalid, leave the entity as-is + if (c == '\0' || overflow || p_src[eat - 1] != ';') { + eat = 1; + c = *p_src; + } if (p_dst) { *p_dst = c; } @@ -4245,7 +4286,7 @@ bool String::is_valid_ip_address() const { continue; } if (n.is_valid_hex_number(false)) { - int64_t nint = n.hex_to_int(false); + int64_t nint = n.hex_to_int(); if (nint < 0 || nint > 0xffff) { return false; } @@ -4340,63 +4381,6 @@ String String::plus_file(const String &p_file) const { return *this + "/" + p_file; } -String String::percent_encode() const { - CharString cs = utf8(); - String encoded; - for (int i = 0; i < cs.length(); i++) { - uint8_t c = cs[i]; - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '~' || c == '.') { - char p[2] = { (char)c, 0 }; - encoded += p; - } else { - char p[4] = { '%', 0, 0, 0 }; - static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - - p[1] = hex[c >> 4]; - p[2] = hex[c & 0xF]; - encoded += p; - } - } - - return encoded; -} - -String String::percent_decode() const { - CharString pe; - - CharString cs = utf8(); - for (int i = 0; i < cs.length(); i++) { - uint8_t c = cs[i]; - if (c == '%' && i < length() - 2) { - uint8_t a = LOWERCASE(cs[i + 1]); - uint8_t b = LOWERCASE(cs[i + 2]); - - if (a >= '0' && a <= '9') { - c = (a - '0') << 4; - } else if (a >= 'a' && a <= 'f') { - c = (a - 'a' + 10) << 4; - } else { - continue; - } - - uint8_t d = 0; - - if (b >= '0' && b <= '9') { - d = (b - '0'); - } else if (b >= 'a' && b <= 'f') { - d = (b - 'a' + 10); - } else { - continue; - } - c += d; - i += 2; - } - pe += c; - } - - return String::utf8(pe.ptr()); -} - String String::property_name_encode() const { // Escape and quote strings with extended ASCII or further Unicode characters // as well as '"', '=' or ' ' (32) diff --git a/core/string/ustring.h b/core/string/ustring.h index 654e327320..821941036f 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -318,8 +318,8 @@ public: bool is_numeric() const; double to_float() const; - int64_t hex_to_int(bool p_with_prefix = true) const; - int64_t bin_to_int(bool p_with_prefix = true) const; + int64_t hex_to_int() const; + int64_t bin_to_int() const; int64_t to_int() const; static int64_t to_int(const char *p_str, int p_len = -1); @@ -366,7 +366,7 @@ public: String get_extension() const; String get_basename() const; String plus_file(const String &p_file) const; - char32_t ord_at(int p_idx) const; + char32_t unicode_at(int p_idx) const; void erase(int p_pos, int p_chars); @@ -409,17 +409,14 @@ public: String xml_escape(bool p_escape_quotes = false) const; String xml_unescape() const; - String http_escape() const; - String http_unescape() const; + String uri_encode() const; + String uri_decode() const; String c_escape() const; String c_escape_multiline() const; String c_unescape() const; String json_escape() const; String word_wrap(int p_chars_per_line) const; - String percent_encode() const; - String percent_decode() const; - String property_name_encode() const; bool is_valid_identifier() const; diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h index 7861c76153..0012cea72d 100644 --- a/core/templates/command_queue_mt.h +++ b/core/templates/command_queue_mt.h @@ -498,6 +498,11 @@ public: flush_one(); } + _FORCE_INLINE_ void flush_if_pending() { + if (unlikely(read_ptr_and_epoch != write_ptr_and_epoch)) { + flush_all(); + } + } void flush_all() { //ERR_FAIL_COND(sync); lock(); diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index 4becb1be59..c985593473 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -45,6 +45,10 @@ class CharString; template <class T, class V> class VMap; +#if !defined(NO_THREADS) +SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t) +#endif + template <class T> class CowData { template <class TV> @@ -60,12 +64,12 @@ private: // internal helpers - _FORCE_INLINE_ uint32_t *_get_refcount() const { + _FORCE_INLINE_ SafeNumeric<uint32_t> *_get_refcount() const { if (!_ptr) { return nullptr; } - return reinterpret_cast<uint32_t *>(_ptr) - 2; + return reinterpret_cast<SafeNumeric<uint32_t> *>(_ptr) - 2; } _FORCE_INLINE_ uint32_t *_get_size() const { @@ -111,7 +115,7 @@ private: void _unref(void *p_data); void _ref(const CowData *p_from); void _ref(const CowData &p_from); - void _copy_on_write(); + uint32_t _copy_on_write(); public: void operator=(const CowData<T> &p_from) { _ref(p_from); } @@ -138,7 +142,7 @@ public: _FORCE_INLINE_ bool is_empty() const { return _ptr == nullptr; } _FORCE_INLINE_ void set(int p_index, const T &p_elem) { - CRASH_BAD_INDEX(p_index, size()); + ERR_FAIL_INDEX(p_index, size()); _copy_on_write(); _get_data()[p_index] = p_elem; } @@ -192,9 +196,9 @@ void CowData<T>::_unref(void *p_data) { return; } - uint32_t *refc = _get_refcount(); + SafeNumeric<uint32_t> *refc = _get_refcount(); - if (atomic_decrement(refc) > 0) { + if (refc->decrement() > 0) { return; // still in use } // clean up @@ -214,20 +218,21 @@ void CowData<T>::_unref(void *p_data) { } template <class T> -void CowData<T>::_copy_on_write() { +uint32_t CowData<T>::_copy_on_write() { if (!_ptr) { - return; + return 0; } - uint32_t *refc = _get_refcount(); + SafeNumeric<uint32_t> *refc = _get_refcount(); - if (unlikely(*refc > 1)) { + uint32_t rc = refc->get(); + if (unlikely(rc > 1)) { /* in use by more than me */ uint32_t current_size = *_get_size(); uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true); - *(mem_new - 2) = 1; //refcount + new (mem_new - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount *(mem_new - 1) = current_size; //size T *_data = (T *)(mem_new); @@ -244,7 +249,10 @@ void CowData<T>::_copy_on_write() { _unref(_ptr); _ptr = _data; + + rc = 1; } + return rc; } template <class T> @@ -265,7 +273,7 @@ Error CowData<T>::resize(int p_size) { } // possibly changing size, copy on write - _copy_on_write(); + uint32_t rc = _copy_on_write(); size_t current_alloc_size = _get_alloc_size(current_size); size_t alloc_size; @@ -278,13 +286,15 @@ Error CowData<T>::resize(int p_size) { uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true); ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY); *(ptr - 1) = 0; //size, currently none - *(ptr - 2) = 1; //refcount + new (ptr - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount _ptr = (T *)ptr; } else { - void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true); + uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true); ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY); + new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount + _ptr = (T *)(_ptrnew); } } @@ -311,8 +321,9 @@ Error CowData<T>::resize(int p_size) { } if (alloc_size != current_alloc_size) { - void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true); + uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true); ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY); + new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount _ptr = (T *)(_ptrnew); } @@ -359,7 +370,7 @@ void CowData<T>::_ref(const CowData &p_from) { return; //nothing to do } - if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference + if (p_from._get_refcount()->conditional_increment() > 0) { // could reference _ptr = p_from._ptr; } } diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 4ffb93b2ad..ffd17b7ee9 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -82,6 +82,19 @@ public: } } + /// Removes the item copying the last value into the position of the one to + /// remove. It's generally faster than `remove`. + void remove_unordered(U p_index) { + ERR_FAIL_INDEX(p_index, count); + count--; + if (count > p_index) { + data[p_index] = data[count]; + } + if (!__has_trivial_destructor(T) && !force_trivial) { + data[count].~T(); + } + } + void erase(const T &p_val) { int64_t idx = find(p_val); if (idx >= 0) { @@ -105,6 +118,7 @@ public: } } _FORCE_INLINE_ bool is_empty() const { return count == 0; } + _FORCE_INLINE_ U get_capacity() const { return capacity; } _FORCE_INLINE_ void reserve(U p_size) { p_size = nearest_power_of_2_templated(p_size); if (p_size > capacity) { diff --git a/core/templates/rid_owner.cpp b/core/templates/rid_owner.cpp index f75a2eb9df..56f39ab779 100644 --- a/core/templates/rid_owner.cpp +++ b/core/templates/rid_owner.cpp @@ -30,4 +30,4 @@ #include "rid_owner.h" -volatile uint64_t RID_AllocBase::base_id = 1; +SafeNumeric<uint64_t> RID_AllocBase::base_id{ 1 }; diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index d26c445eb4..c4aa93c394 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -44,7 +44,7 @@ #include <typeinfo> class RID_AllocBase { - static volatile uint64_t base_id; + static SafeNumeric<uint64_t> base_id; protected: static RID _make_from_id(uint64_t p_id) { @@ -54,7 +54,7 @@ protected: } static uint64_t _gen_id() { - return atomic_increment(&base_id); + return base_id.increment(); } static RID _gen_rid() { @@ -79,8 +79,7 @@ class RID_Alloc : public RID_AllocBase { SpinLock spin_lock; -public: - RID make_rid(const T &p_value) { + _FORCE_INLINE_ RID _allocate_rid(const T *p_initializer) { if (THREAD_SAFE) { spin_lock.lock(); } @@ -115,15 +114,22 @@ public: uint32_t free_chunk = free_index / elements_in_chunk; uint32_t free_element = free_index % elements_in_chunk; - T *ptr = &chunks[free_chunk][free_element]; - memnew_placement(ptr, T(p_value)); + if (p_initializer) { + T *ptr = &chunks[free_chunk][free_element]; + memnew_placement(ptr, T(*p_initializer)); + } - uint32_t validator = (uint32_t)(_gen_id() & 0xFFFFFFFF); + uint32_t validator = (uint32_t)(_gen_id() & 0x7FFFFFFF); uint64_t id = validator; id <<= 32; id |= free_index; validator_chunks[free_chunk][free_element] = validator; + + if (!p_initializer) { + validator_chunks[free_chunk][free_element] |= 0x80000000; //mark uninitialized bit + } + alloc_count++; if (THREAD_SAFE) { @@ -133,7 +139,20 @@ public: return _make_from_id(id); } - _FORCE_INLINE_ T *getornull(const RID &p_rid) { +public: + RID make_rid(const T &p_value) { + return _allocate_rid(&p_value); + } + + //allocate but don't initialize, use initialize_rid afterwards + RID allocate_rid() { + return _allocate_rid(nullptr); + } + + _FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) { + if (p_rid == RID()) { + return nullptr; + } if (THREAD_SAFE) { spin_lock.lock(); } @@ -151,10 +170,32 @@ public: uint32_t idx_element = idx % elements_in_chunk; uint32_t validator = uint32_t(id >> 32); - if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { + + if (unlikely(p_initialize)) { + if (unlikely(!(validator_chunks[idx_chunk][idx_element] & 0x80000000))) { + if (THREAD_SAFE) { + spin_lock.unlock(); + } + ERR_FAIL_V_MSG(nullptr, "Initializing already initialized RID"); + } + + if (unlikely((validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) != validator)) { + if (THREAD_SAFE) { + spin_lock.unlock(); + } + ERR_FAIL_V_MSG(nullptr, "Attempting to initialize the wrong RID"); + return nullptr; + } + + validator_chunks[idx_chunk][idx_element] &= 0x7FFFFFFF; //initialized + + } else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { if (THREAD_SAFE) { spin_lock.unlock(); } + if (validator_chunks[idx_chunk][idx_element] & 0x80000000) { + ERR_FAIL_V_MSG(nullptr, "Attempting to use an uninitialized RID"); + } return nullptr; } @@ -166,6 +207,11 @@ public: return ptr; } + void initialize_rid(RID p_rid, const T &p_value) { + T *mem = getornull(p_rid, true); + ERR_FAIL_COND(!mem); + memnew_placement(mem, T(p_value)); + } _FORCE_INLINE_ bool owns(const RID &p_rid) { if (THREAD_SAFE) { @@ -186,7 +232,7 @@ public: uint32_t validator = uint32_t(id >> 32); - bool owned = validator_chunks[idx_chunk][idx_element] == validator; + bool owned = (validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) == validator; if (THREAD_SAFE) { spin_lock.unlock(); @@ -213,7 +259,12 @@ public: uint32_t idx_element = idx % elements_in_chunk; uint32_t validator = uint32_t(id >> 32); - if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { + if (unlikely(validator_chunks[idx_chunk][idx_element] & 0x80000000)) { + if (THREAD_SAFE) { + spin_lock.unlock(); + } + ERR_FAIL_MSG("Attempted to free an uninitialized or invalid RID"); + } else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { if (THREAD_SAFE) { spin_lock.unlock(); } @@ -330,6 +381,14 @@ public: return alloc.make_rid(p_ptr); } + _FORCE_INLINE_ RID allocate_rid() { + return alloc.allocate_rid(); + } + + _FORCE_INLINE_ void initialize_rid(RID p_rid, T *p_ptr) { + alloc.initialize_rid(p_rid, p_ptr); + } + _FORCE_INLINE_ T *getornull(const RID &p_rid) { T **ptr = alloc.getornull(p_rid); if (unlikely(!ptr)) { @@ -338,6 +397,12 @@ public: return *ptr; } + _FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) { + T **ptr = alloc.getornull(p_rid); + ERR_FAIL_COND(!ptr); + *ptr = p_new_ptr; + } + _FORCE_INLINE_ bool owns(const RID &p_rid) { return alloc.owns(p_rid); } @@ -379,6 +444,14 @@ public: return alloc.make_rid(p_ptr); } + _FORCE_INLINE_ RID allocate_rid() { + return alloc.allocate_rid(); + } + + _FORCE_INLINE_ void initialize_rid(RID p_rid, const T &p_ptr) { + alloc.initialize_rid(p_rid, p_ptr); + } + _FORCE_INLINE_ T *getornull(const RID &p_rid) { return alloc.getornull(p_rid); } diff --git a/core/templates/safe_refcount.cpp b/core/templates/safe_refcount.cpp deleted file mode 100644 index a915ee662f..0000000000 --- a/core/templates/safe_refcount.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/*************************************************************************/ -/* safe_refcount.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "safe_refcount.h" - -#if defined(_MSC_VER) - -/* Implementation for MSVC-Windows */ - -// don't pollute my namespace! -#include <windows.h> - -#define ATOMIC_CONDITIONAL_INCREMENT_BODY(m_pw, m_win_type, m_win_cmpxchg, m_cpp_type) \ - /* try to increment until it actually works */ \ - /* taken from boost */ \ - while (true) { \ - m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \ - if (tmp == 0) { \ - return 0; /* if zero, can't add to it anymore */ \ - } \ - if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) { \ - return tmp + 1; \ - } \ - } - -#define ATOMIC_EXCHANGE_IF_GREATER_BODY(m_pw, m_val, m_win_type, m_win_cmpxchg, m_cpp_type) \ - while (true) { \ - m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \ - if (tmp >= m_val) { \ - return tmp; /* already greater, or equal */ \ - } \ - if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) { \ - return m_val; \ - } \ - } - -_ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(volatile uint32_t *pw) { - ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t); -} - -_ALWAYS_INLINE_ uint32_t _atomic_decrement_impl(volatile uint32_t *pw) { - return InterlockedDecrement((LONG volatile *)pw); -} - -_ALWAYS_INLINE_ uint32_t _atomic_increment_impl(volatile uint32_t *pw) { - return InterlockedIncrement((LONG volatile *)pw); -} - -_ALWAYS_INLINE_ uint32_t _atomic_sub_impl(volatile uint32_t *pw, volatile uint32_t val) { - return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val; -} - -_ALWAYS_INLINE_ uint32_t _atomic_add_impl(volatile uint32_t *pw, volatile uint32_t val) { - return InterlockedAdd((LONG volatile *)pw, val); -} - -_ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(volatile uint32_t *pw, volatile uint32_t val) { - ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t); -} - -_ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(volatile uint64_t *pw) { - ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t); -} - -_ALWAYS_INLINE_ uint64_t _atomic_decrement_impl(volatile uint64_t *pw) { - return InterlockedDecrement64((LONGLONG volatile *)pw); -} - -_ALWAYS_INLINE_ uint64_t _atomic_increment_impl(volatile uint64_t *pw) { - return InterlockedIncrement64((LONGLONG volatile *)pw); -} - -_ALWAYS_INLINE_ uint64_t _atomic_sub_impl(volatile uint64_t *pw, volatile uint64_t val) { - return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val; -} - -_ALWAYS_INLINE_ uint64_t _atomic_add_impl(volatile uint64_t *pw, volatile uint64_t val) { - return InterlockedAdd64((LONGLONG volatile *)pw, val); -} - -_ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(volatile uint64_t *pw, volatile uint64_t val) { - ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t); -} - -// The actual advertised functions; they'll call the right implementation - -uint32_t atomic_conditional_increment(volatile uint32_t *pw) { - return _atomic_conditional_increment_impl(pw); -} - -uint32_t atomic_decrement(volatile uint32_t *pw) { - return _atomic_decrement_impl(pw); -} - -uint32_t atomic_increment(volatile uint32_t *pw) { - return _atomic_increment_impl(pw); -} - -uint32_t atomic_sub(volatile uint32_t *pw, volatile uint32_t val) { - return _atomic_sub_impl(pw, val); -} - -uint32_t atomic_add(volatile uint32_t *pw, volatile uint32_t val) { - return _atomic_add_impl(pw, val); -} - -uint32_t atomic_exchange_if_greater(volatile uint32_t *pw, volatile uint32_t val) { - return _atomic_exchange_if_greater_impl(pw, val); -} - -uint64_t atomic_conditional_increment(volatile uint64_t *pw) { - return _atomic_conditional_increment_impl(pw); -} - -uint64_t atomic_decrement(volatile uint64_t *pw) { - return _atomic_decrement_impl(pw); -} - -uint64_t atomic_increment(volatile uint64_t *pw) { - return _atomic_increment_impl(pw); -} - -uint64_t atomic_sub(volatile uint64_t *pw, volatile uint64_t val) { - return _atomic_sub_impl(pw, val); -} - -uint64_t atomic_add(volatile uint64_t *pw, volatile uint64_t val) { - return _atomic_add_impl(pw, val); -} - -uint64_t atomic_exchange_if_greater(volatile uint64_t *pw, volatile uint64_t val) { - return _atomic_exchange_if_greater_impl(pw, val); -} -#endif diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h index d94444fad6..91a34ecd54 100644 --- a/core/templates/safe_refcount.h +++ b/core/templates/safe_refcount.h @@ -31,167 +31,291 @@ #ifndef SAFE_REFCOUNT_H #define SAFE_REFCOUNT_H -#include "core/os/mutex.h" #include "core/typedefs.h" -#include "platform_config.h" -// Atomic functions, these are used for multithread safe reference counters! +#if !defined(NO_THREADS) -#ifdef NO_THREADS +#include <atomic> -/* Bogus implementation unaware of multiprocessing */ +// Design goals for these classes: +// - No automatic conversions or arithmetic operators, +// to keep explicit the use of atomics everywhere. +// - Using acquire-release semantics, even to set the first value. +// The first value may be set relaxedly in many cases, but adding the distinction +// between relaxed and unrelaxed operation to the interface would make it needlessly +// flexible. There's negligible waste in having release semantics for the initial +// value and, as an important benefit, you can be sure the value is properly synchronized +// even with threads that are already running. + +// This is used in very specific areas of the engine where it's critical that these guarantees are held +#define SAFE_NUMERIC_TYPE_PUN_GUARANTEES(m_type) \ + static_assert(sizeof(SafeNumeric<m_type>) == sizeof(m_type)); \ + static_assert(alignof(SafeNumeric<m_type>) == alignof(m_type)); \ + static_assert(std::is_trivially_destructible<std::atomic<m_type>>::value); template <class T> -static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) { - if (*pw == 0) { - return 0; +class SafeNumeric { + std::atomic<T> value; + + static_assert(std::atomic<T>::is_always_lock_free); + +public: + _ALWAYS_INLINE_ void set(T p_value) { + value.store(p_value, std::memory_order_release); } - (*pw)++; + _ALWAYS_INLINE_ T get() const { + return value.load(std::memory_order_acquire); + } - return *pw; -} + _ALWAYS_INLINE_ T increment() { + return value.fetch_add(1, std::memory_order_acq_rel) + 1; + } -template <class T> -static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) { - (*pw)--; + // Returns the original value instead of the new one + _ALWAYS_INLINE_ T postincrement() { + return value.fetch_add(1, std::memory_order_acq_rel); + } - return *pw; -} + _ALWAYS_INLINE_ T decrement() { + return value.fetch_sub(1, std::memory_order_acq_rel) - 1; + } -template <class T> -static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) { - (*pw)++; + // Returns the original value instead of the new one + _ALWAYS_INLINE_ T postdecrement() { + return value.fetch_sub(1, std::memory_order_acq_rel); + } - return *pw; -} + _ALWAYS_INLINE_ T add(T p_value) { + return value.fetch_add(p_value, std::memory_order_acq_rel) + p_value; + } -template <class T, class V> -static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) { - (*pw) -= val; + // Returns the original value instead of the new one + _ALWAYS_INLINE_ T postadd(T p_value) { + return value.fetch_add(p_value, std::memory_order_acq_rel); + } - return *pw; -} + _ALWAYS_INLINE_ T sub(T p_value) { + return value.fetch_sub(p_value, std::memory_order_acq_rel) - p_value; + } -template <class T, class V> -static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) { - (*pw) += val; + // Returns the original value instead of the new one + _ALWAYS_INLINE_ T postsub(T p_value) { + return value.fetch_sub(p_value, std::memory_order_acq_rel); + } - return *pw; -} + _ALWAYS_INLINE_ T exchange_if_greater(T p_value) { + while (true) { + T tmp = value.load(std::memory_order_acquire); + if (tmp >= p_value) { + return tmp; // already greater, or equal + } + if (value.compare_exchange_weak(tmp, p_value, std::memory_order_release)) { + return p_value; + } + } + } -template <class T, class V> -static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V val) { - if (val > *pw) { - *pw = val; + _ALWAYS_INLINE_ T conditional_increment() { + while (true) { + T c = value.load(std::memory_order_acquire); + if (c == 0) { + return 0; + } + if (value.compare_exchange_weak(c, c + 1, std::memory_order_release)) { + return c + 1; + } + } } - return *pw; -} + _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) { + set(p_value); + } +}; -#elif defined(__GNUC__) +class SafeFlag { + std::atomic_bool flag; -/* Implementation for GCC & Clang */ + static_assert(std::atomic_bool::is_always_lock_free); -// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes. -// Clang states it supports GCC atomic builtins. +public: + _ALWAYS_INLINE_ bool is_set() const { + return flag.load(std::memory_order_acquire); + } -template <class T> -static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) { - while (true) { - T tmp = static_cast<T const volatile &>(*pw); - if (tmp == 0) { - return 0; // if zero, can't add to it anymore - } - if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp) { - return tmp + 1; - } + _ALWAYS_INLINE_ void set() { + flag.store(true, std::memory_order_release); } -} -template <class T> -static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) { - return __sync_sub_and_fetch(pw, 1); -} + _ALWAYS_INLINE_ void clear() { + flag.store(false, std::memory_order_release); + } + + _ALWAYS_INLINE_ void set_to(bool p_value) { + flag.store(p_value, std::memory_order_release); + } + + _ALWAYS_INLINE_ explicit SafeFlag(bool p_value = false) { + set_to(p_value); + } +}; + +class SafeRefCount { + SafeNumeric<uint32_t> count; + +public: + _ALWAYS_INLINE_ bool ref() { // true on success + return count.conditional_increment() != 0; + } + + _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success + return count.conditional_increment(); + } + + _ALWAYS_INLINE_ bool unref() { // true if must be disposed of + return count.decrement() == 0; + } + + _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of + return count.decrement(); + } + + _ALWAYS_INLINE_ uint32_t get() const { + return count.get(); + } + + _ALWAYS_INLINE_ void init(uint32_t p_value = 1) { + count.set(p_value); + } +}; + +#else template <class T> -static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) { - return __sync_add_and_fetch(pw, 1); -} - -template <class T, class V> -static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) { - return __sync_sub_and_fetch(pw, val); -} - -template <class T, class V> -static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) { - return __sync_add_and_fetch(pw, val); -} - -template <class T, class V> -static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V val) { - while (true) { - T tmp = static_cast<T const volatile &>(*pw); - if (tmp >= val) { - return tmp; // already greater, or equal +class SafeNumeric { +protected: + T value; + +public: + _ALWAYS_INLINE_ void set(T p_value) { + value = p_value; + } + + _ALWAYS_INLINE_ T get() const { + return value; + } + + _ALWAYS_INLINE_ T increment() { + return ++value; + } + + _ALWAYS_INLINE_ T postincrement() { + return value++; + } + + _ALWAYS_INLINE_ T decrement() { + return --value; + } + + _ALWAYS_INLINE_ T postdecrement() { + return value--; + } + + _ALWAYS_INLINE_ T add(T p_value) { + return value += p_value; + } + + _ALWAYS_INLINE_ T postadd(T p_value) { + T old = value; + value += p_value; + return old; + } + + _ALWAYS_INLINE_ T sub(T p_value) { + return value -= p_value; + } + + _ALWAYS_INLINE_ T postsub(T p_value) { + T old = value; + value -= p_value; + return old; + } + + _ALWAYS_INLINE_ T exchange_if_greater(T p_value) { + if (value < p_value) { + value = p_value; } - if (__sync_val_compare_and_swap(pw, tmp, val) == tmp) { - return val; + return value; + } + + _ALWAYS_INLINE_ T conditional_increment() { + if (value == 0) { + return 0; + } else { + return ++value; } } -} - -#elif defined(_MSC_VER) -// For MSVC use a separate compilation unit to prevent windows.h from polluting -// the global namespace. -uint32_t atomic_conditional_increment(volatile uint32_t *pw); -uint32_t atomic_decrement(volatile uint32_t *pw); -uint32_t atomic_increment(volatile uint32_t *pw); -uint32_t atomic_sub(volatile uint32_t *pw, volatile uint32_t val); -uint32_t atomic_add(volatile uint32_t *pw, volatile uint32_t val); -uint32_t atomic_exchange_if_greater(volatile uint32_t *pw, volatile uint32_t val); - -uint64_t atomic_conditional_increment(volatile uint64_t *pw); -uint64_t atomic_decrement(volatile uint64_t *pw); -uint64_t atomic_increment(volatile uint64_t *pw); -uint64_t atomic_sub(volatile uint64_t *pw, volatile uint64_t val); -uint64_t atomic_add(volatile uint64_t *pw, volatile uint64_t val); -uint64_t atomic_exchange_if_greater(volatile uint64_t *pw, volatile uint64_t val); -#else -//no threads supported? -#error Must provide atomic functions for this platform or compiler! -#endif + _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) : + value(p_value) { + } +}; -struct SafeRefCount { - uint32_t count = 0; +class SafeFlag { +protected: + bool flag; public: - // destroy() is called when weak_count_ drops to zero. - - _ALWAYS_INLINE_ bool ref() { // true on success + _ALWAYS_INLINE_ bool is_set() const { + return flag; + } - return atomic_conditional_increment(&count) != 0; + _ALWAYS_INLINE_ void set() { + flag = true; } - _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success + _ALWAYS_INLINE_ void clear() { + flag = false; + } - return atomic_conditional_increment(&count); + _ALWAYS_INLINE_ void set_to(bool p_value) { + flag = p_value; } - _ALWAYS_INLINE_ bool unref() { // true if must be disposed of + _ALWAYS_INLINE_ explicit SafeFlag(bool p_value = false) : + flag(p_value) {} +}; + +class SafeRefCount { + uint32_t count = 0; - return atomic_decrement(&count) == 0; +public: + _ALWAYS_INLINE_ bool ref() { // true on success + if (count != 0) { + ++count; + return true; + } else { + return false; + } } - _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of + _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success + if (count != 0) { + return ++count; + } else { + return 0; + } + } - return atomic_decrement(&count); + _ALWAYS_INLINE_ bool unref() { // true if must be disposed of + return --count == 0; } - _ALWAYS_INLINE_ uint32_t get() const { // nothrow + _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of + return --count; + } + _ALWAYS_INLINE_ uint32_t get() const { return count; } @@ -200,4 +324,6 @@ public: } }; +#endif + #endif // SAFE_REFCOUNT_H diff --git a/core/templates/thread_work_pool.cpp b/core/templates/thread_work_pool.cpp index ea784e510c..17969a2c90 100644 --- a/core/templates/thread_work_pool.cpp +++ b/core/templates/thread_work_pool.cpp @@ -32,14 +32,15 @@ #include "core/os/os.h" -void ThreadWorkPool::_thread_function(ThreadData *p_thread) { +void ThreadWorkPool::_thread_function(void *p_user) { + ThreadData *thread = static_cast<ThreadData *>(p_user); while (true) { - p_thread->start.wait(); - if (p_thread->exit.load()) { + thread->start.wait(); + if (thread->exit.load()) { break; } - p_thread->work->work(); - p_thread->completed.post(); + thread->work->work(); + thread->completed.post(); } } @@ -54,7 +55,7 @@ void ThreadWorkPool::init(int p_thread_count) { for (uint32_t i = 0; i < thread_count; i++) { threads[i].exit.store(false); - threads[i].thread = memnew(std::thread(ThreadWorkPool::_thread_function, &threads[i])); + threads[i].thread.start(&ThreadWorkPool::_thread_function, &threads[i]); } } @@ -68,8 +69,7 @@ void ThreadWorkPool::finish() { threads[i].start.post(); } for (uint32_t i = 0; i < thread_count; i++) { - threads[i].thread->join(); - memdelete(threads[i].thread); + threads[i].thread.wait_to_finish(); } memdelete_arr(threads); diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h index 7c3508814f..19ab1dda3a 100644 --- a/core/templates/thread_work_pool.h +++ b/core/templates/thread_work_pool.h @@ -33,9 +33,9 @@ #include "core/os/memory.h" #include "core/os/semaphore.h" +#include "core/os/thread.h" #include <atomic> -#include <thread> class ThreadWorkPool { std::atomic<uint32_t> index; @@ -64,7 +64,7 @@ class ThreadWorkPool { }; struct ThreadData { - std::thread *thread; + Thread thread; Semaphore start; Semaphore completed; std::atomic<bool> exit; @@ -75,7 +75,7 @@ class ThreadWorkPool { uint32_t thread_count = 0; BaseWork *current_work = nullptr; - static void _thread_function(ThreadData *p_thread); + static void _thread_function(void *p_user); public: template <class C, class M, class U> diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 48916f941e..9a2922a777 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -35,6 +35,7 @@ #include "core/object/script_language.h" #include "core/templates/hashfuncs.h" #include "core/templates/vector.h" +#include "core/variant/callable.h" #include "core/variant/variant.h" class ArrayPrivate { @@ -371,25 +372,22 @@ void Array::sort() { } struct _ArrayVariantSortCustom { - Object *obj = nullptr; - StringName func; + Callable func; _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { const Variant *args[2] = { &p_l, &p_r }; Callable::CallError err; - bool res = obj->call(func, args, 2, err); - if (err.error != Callable::CallError::CALL_OK) { - res = false; - } + Variant res; + func.call(args, 2, res, err); + ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false, + "Error calling sorting method: " + Variant::get_callable_error_text(func, args, 1, err)); return res; } }; -void Array::sort_custom(Object *p_obj, const StringName &p_function) { - ERR_FAIL_NULL(p_obj); +void Array::sort_custom(Callable p_callable) { SortArray<Variant, _ArrayVariantSortCustom, true> avs; - avs.compare.obj = p_obj; - avs.compare.func = p_function; + avs.compare.func = p_callable; avs.sort(_p->array.ptrw(), _p->array.size()); } @@ -438,13 +436,11 @@ int Array::bsearch(const Variant &p_value, bool p_before) { return bisect(_p->array, p_value, p_before, _ArrayVariantSort()); } -int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { +int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) { ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); - ERR_FAIL_NULL_V(p_obj, 0); _ArrayVariantSortCustom less; - less.obj = p_obj; - less.func = p_function; + less.func = p_callable; return bisect(_p->array, p_value, p_before, less); } diff --git a/core/variant/array.h b/core/variant/array.h index 26de5477b4..d8f2402330 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -37,6 +37,7 @@ class Variant; class ArrayPrivate; class Object; class StringName; +class Callable; class Array { mutable ArrayPrivate *_p; @@ -78,10 +79,10 @@ public: Variant back() const; void sort(); - void sort_custom(Object *p_obj, const StringName &p_function); + void sort_custom(Callable p_callable); void shuffle(); int bsearch(const Variant &p_value, bool p_before = true); - int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true); + int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true); void invert(); int find(const Variant &p_value, int p_from = 0) const; diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 9d8e262cc9..490bd45b7b 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -88,6 +88,7 @@ VARIANT_ENUM_CAST(Vector3::Axis); VARIANT_ENUM_CAST(Error); VARIANT_ENUM_CAST(Side); +VARIANT_ENUM_CAST(ClockDirection); VARIANT_ENUM_CAST(Corner); VARIANT_ENUM_CAST(Orientation); VARIANT_ENUM_CAST(HAlign); diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 7824776fdb..015cee09a7 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -2023,7 +2023,7 @@ Variant::operator Color() const { if (type == COLOR) { return *reinterpret_cast<const Color *>(_data._mem); } else if (type == STRING) { - return Color::html(operator String()); + return Color(operator String()); } else if (type == INT) { return Color::hex(operator int()); } else { diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 85e3b29279..54ca1a911d 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -929,7 +929,7 @@ static void _register_variant_builtin_methods() { bind_method(String, get_extension, sarray(), varray()); bind_method(String, get_basename, sarray(), varray()); bind_method(String, plus_file, sarray("file"), varray()); - bind_method(String, ord_at, sarray("at"), varray()); + bind_method(String, unicode_at, sarray("at"), varray()); bind_method(String, dedent, sarray(), varray()); // FIXME: String needs to be immutable when binding //bind_method(String, erase, sarray("position", "chars"), varray()); @@ -950,13 +950,11 @@ static void _register_variant_builtin_methods() { bind_method(String, get_file, sarray(), varray()); bind_method(String, xml_escape, sarray("escape_quotes"), varray(false)); bind_method(String, xml_unescape, sarray(), varray()); - bind_method(String, http_escape, sarray(), varray()); - bind_method(String, http_unescape, sarray(), varray()); + bind_method(String, uri_encode, sarray(), varray()); + bind_method(String, uri_decode, sarray(), varray()); bind_method(String, c_escape, sarray(), varray()); bind_method(String, c_unescape, sarray(), varray()); bind_method(String, json_escape, sarray(), varray()); - bind_method(String, percent_encode, sarray(), varray()); - bind_method(String, percent_decode, sarray(), varray()); bind_method(String, is_valid_identifier, sarray(), varray()); bind_method(String, is_valid_integer, sarray(), varray()); @@ -968,8 +966,8 @@ static void _register_variant_builtin_methods() { bind_method(String, to_int, sarray(), varray()); bind_method(String, to_float, sarray(), varray()); - bind_method(String, hex_to_int, sarray("with_prefix"), varray(true)); - bind_method(String, bin_to_int, sarray("with_prefix"), varray(true)); + bind_method(String, hex_to_int, sarray(), varray()); + bind_method(String, bin_to_int, sarray(), varray()); bind_method(String, lpad, sarray("min_length", "character"), varray(" ")); bind_method(String, rpad, sarray("min_length", "character"), varray(" ")); @@ -1061,6 +1059,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3, min_axis, sarray(), varray()); bind_method(Vector3, max_axis, sarray(), varray()); bind_method(Vector3, angle_to, sarray("to"), varray()); + bind_method(Vector3, signed_angle_to, sarray("to", "axis"), varray()); bind_method(Vector3, direction_to, sarray("b"), varray()); bind_method(Vector3, distance_to, sarray("b"), varray()); bind_method(Vector3, distance_squared_to, sarray("b"), varray()); @@ -1126,10 +1125,6 @@ static void _register_variant_builtin_methods() { bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray()); bind_method(Quat, get_euler, sarray(), varray()); - // FIXME: Quat is atomic, this should be done via construcror - //ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray()); - //ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray()); - /* Color */ bind_method(Color, to_argb32, sarray(), varray()); @@ -1216,7 +1211,7 @@ static void _register_variant_builtin_methods() { bind_method(Basis, transposed, sarray(), varray()); bind_method(Basis, orthonormalized, sarray(), varray()); bind_method(Basis, determinant, sarray(), varray()); - bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, float) const>(&Basis::rotated), sarray("axis", "phi"), varray()); + bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "phi"), varray()); bind_method(Basis, scaled, sarray("scale"), varray()); bind_method(Basis, get_scale, sarray(), varray()); bind_method(Basis, get_euler, sarray(), varray()); @@ -1262,7 +1257,7 @@ static void _register_variant_builtin_methods() { bind_method(Transform, rotated, sarray("axis", "phi"), varray()); bind_method(Transform, scaled, sarray("scale"), varray()); bind_method(Transform, translated, sarray("offset"), varray()); - bind_method(Transform, looking_at, sarray("target", "up"), varray()); + bind_method(Transform, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform, is_equal_approx, sarray("xform"), varray()); @@ -1304,10 +1299,10 @@ static void _register_variant_builtin_methods() { bind_method(Array, pop_back, sarray(), varray()); bind_method(Array, pop_front, sarray(), varray()); bind_method(Array, sort, sarray(), varray()); - bind_method(Array, sort_custom, sarray("obj", "func"), varray()); + bind_method(Array, sort_custom, sarray("func"), varray()); bind_method(Array, shuffle, sarray(), varray()); bind_method(Array, bsearch, sarray("value", "before"), varray(true)); - bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true)); + bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true)); bind_method(Array, invert, sarray(), varray()); bind_method(Array, duplicate, sarray("deep"), varray(false)); bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 9835734583..52f9f6060e 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -688,6 +688,8 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Color, Color, double>>(sarray("from", "alpha")); add_constructor<VariantConstructor<Color, double, double, double>>(sarray("r", "g", "b")); add_constructor<VariantConstructor<Color, double, double, double, double>>(sarray("r", "g", "b", "a")); + add_constructor<VariantConstructor<Color, String>>(sarray("code")); + add_constructor<VariantConstructor<Color, String, double>>(sarray("code", "alpha")); add_constructor<VariantConstructNoArgs<StringName>>(sarray()); add_constructor<VariantConstructor<StringName, StringName>>(sarray("from")); diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index e9c817bc9f..e0a3cf4215 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -318,6 +318,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right); } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { diff --git a/doc/Makefile b/doc/Makefile index 9534da9bd5..d4bc53bcf9 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,6 +2,7 @@ BASEDIR = $(CURDIR) CLASSES = $(BASEDIR)/classes/ $(BASEDIR)/../modules/ OUTPUTDIR = $(BASEDIR)/_build TOOLSDIR = $(BASEDIR)/tools +JSDIR = $(BASEDIR)/../platform/javascript .ONESHELL: @@ -16,6 +17,10 @@ doxygen: rst: rm -rf $(OUTPUTDIR)/rst mkdir -p $(OUTPUTDIR)/rst - pushd $(OUTPUTDIR)/rst - python3 $(TOOLSDIR)/makerst.py $(CLASSES) - popd + python3 $(TOOLSDIR)/makerst.py -o $(OUTPUTDIR)/rst $(CLASSES) + +rstjs: + rm -rf $(OUTPUTDIR)/rstjs + mkdir -p $(OUTPUTDIR)/rstjs + npm --prefix $(JSDIR) ci + npm --prefix $(JSDIR) run docs -- --destination $(OUTPUTDIR)/rstjs/html5_shell_classref.rst diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index bf81362e79..3ca7e0716b 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -935,7 +935,7 @@ <description> Returns the result of smoothly interpolating the value of [code]x[/code] between [code]0[/code] and [code]1[/code], based on the where [code]x[/code] lies with respect to the edges [code]from[/code] and [code]to[/code]. The return value is [code]0[/code] if [code]x <= from[/code], and [code]1[/code] if [code]x >= to[/code]. If [code]x[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]x[/code] between [code]0[/code] and [code]1[/code]. - This S-shaped curve is the cubic Hermite interpolator, given by [code]f(x) = 3*x^2 - 2*x^3[/code]. + This S-shaped curve is the cubic Hermite interpolator, given by [code]f(y) = 3*y^2 - 2*y^3[/code] where [code]y = (x-from) / (to-from)[/code]. [codeblock] smoothstep(0, 2, -5.0) # Returns 0.0 smoothstep(0, 2, 0.5) # Returns 0.15625 @@ -2147,7 +2147,25 @@ <constant name="JOY_BUTTON_DPAD_RIGHT" value="14" enum="JoyButtonList"> Game controller D-pad right button. </constant> - <constant name="JOY_BUTTON_SDL_MAX" value="15" enum="JoyButtonList"> + <constant name="JOY_BUTTON_MISC1" value="15" enum="JoyButtonList"> + Game controller SDL miscellaneous button. Corresponds to Xbox share button, PS5 microphone button, Nintendo capture button. + </constant> + <constant name="JOY_BUTTON_PADDLE1" value="16" enum="JoyButtonList"> + Game controller SDL paddle 1 button. + </constant> + <constant name="JOY_BUTTON_PADDLE2" value="17" enum="JoyButtonList"> + Game controller SDL paddle 2 button. + </constant> + <constant name="JOY_BUTTON_PADDLE3" value="18" enum="JoyButtonList"> + Game controller SDL paddle 3 button. + </constant> + <constant name="JOY_BUTTON_PADDLE4" value="19" enum="JoyButtonList"> + Game controller SDL paddle 4 button. + </constant> + <constant name="JOY_BUTTON_TOUCHPAD" value="20" enum="JoyButtonList"> + Game controller SDL touchpad button. + </constant> + <constant name="JOY_BUTTON_SDL_MAX" value="21" enum="JoyButtonList"> The number of SDL game controller buttons. </constant> <constant name="JOY_BUTTON_MAX" value="36" enum="JoyButtonList"> diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml index e1fb78e5b5..02ccab4e05 100644 --- a/doc/classes/AnimatedSprite3D.xml +++ b/doc/classes/AnimatedSprite3D.xml @@ -49,6 +49,11 @@ </member> </members> <signals> + <signal name="animation_finished"> + <description> + Emitted when the animation is finished (when it plays the last frame). If the animation is looping, this signal is emitted every time the last frame is drawn. + </description> + </signal> <signal name="frame_changed"> <description> Emitted when [member frame] changed. diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index d26c0e8605..9720405ffd 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -168,7 +168,7 @@ <argument index="2" name="stream" type="Resource"> </argument> <description> - Sets the stream of the key identified by [code]key_idx[/code] to value [code]offset[/code]. The [code]track_idx[/code] must be the index of an Audio Track. + Sets the stream of the key identified by [code]key_idx[/code] to value [code]stream[/code]. The [code]track_idx[/code] must be the index of an Audio Track. </description> </method> <method name="bezier_track_get_key_in_handle" qualifiers="const"> diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index bebff61671..e5ba1d58f7 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -254,7 +254,7 @@ <member name="playback_default_blend_time" type="float" setter="set_default_blend_time" getter="get_default_blend_time" default="0.0"> The default time in which to blend animations. Ranges from 0 to 4096 with 0.01 precision. </member> - <member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" enum="AnimationPlayer.AnimationProcessMode" default="1"> + <member name="playback_process_mode" type="int" setter="set_process_callback" getter="get_process_callback" enum="AnimationPlayer.AnimationProcessCallback" default="1"> The process notification in which to update animations. </member> <member name="playback_speed" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> @@ -299,13 +299,13 @@ </signal> </signals> <constants> - <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessMode"> + <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessCallback"> Process animation during the physics process. This is especially useful when animating physics bodies. </constant> - <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessMode"> + <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessCallback"> Process animation during the idle process. </constant> - <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessMode"> + <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessCallback"> Do not process animation. Use [method advance] to process the animation manually. </constant> <constant name="ANIMATION_METHOD_CALL_DEFERRED" value="0" enum="AnimationMethodCallMode"> diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index 262b5addb7..2517941133 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -45,8 +45,8 @@ <member name="anim_player" type="NodePath" setter="set_animation_player" getter="get_animation_player" default="NodePath("")"> The path to the [AnimationPlayer] used for animating. </member> - <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="AnimationTree.AnimationProcessMode" default="1"> - The process mode of this [AnimationTree]. See [enum AnimationProcessMode] for available modes. + <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="AnimationTree.AnimationProcessCallback" default="1"> + The process mode of this [AnimationTree]. See [enum AnimationProcessCallback] for available modes. </member> <member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath("")"> The path to the Animation track used for root motion. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. To specify a track that controls properties or bones, append its name after the path, separated by [code]":"[/code]. For example, [code]"character/skeleton:ankle"[/code] or [code]"character/mesh:transform/local"[/code]. @@ -57,13 +57,13 @@ </member> </members> <constants> - <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessMode"> + <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessCallback"> The animations will progress during the physics frame (i.e. [method Node._physics_process]). </constant> - <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessMode"> + <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessCallback"> The animations will progress during the idle frame (i.e. [method Node._process]). </constant> - <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessMode"> + <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessCallback"> The animations will only progress manually (see [method advance]). </constant> </constants> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index 72c40478bb..9711a2a35b 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -140,14 +140,16 @@ <argument index="0" name="area" type="Area2D"> </argument> <description> - Emitted when another area enters. + Emitted when another Area2D enters this Area2D. Requires [member monitoring] to be set to [code]true[/code]. + [code]area[/code] the other Area2D. </description> </signal> <signal name="area_exited"> <argument index="0" name="area" type="Area2D"> </argument> <description> - Emitted when another area exits. + Emitted when another Area2D exits this Area2D. Requires [member monitoring] to be set to [code]true[/code]. + [code]area[/code] the other Area2D. </description> </signal> <signal name="area_shape_entered"> @@ -157,10 +159,14 @@ </argument> <argument index="2" name="area_shape" type="int"> </argument> - <argument index="3" name="self_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when another area enters, reporting which shapes overlapped. [code]shape_owner_get_owner(shape_find_owner(shape))[/code] returns the parent object of the owner of the [code]shape[/code]. + Emitted when one of another Area2D's [Shape2D]s enters one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. + [code]area_id[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D]. + [code]area[/code] the other Area2D. + [code]area_shape[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D]. + [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. </description> </signal> <signal name="area_shape_exited"> @@ -170,54 +176,64 @@ </argument> <argument index="2" name="area_shape" type="int"> </argument> - <argument index="3" name="self_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when another area exits, reporting which shapes were overlapping. + Emitted when one of another Area2D's [Shape2D]s exits one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. + [code]area_id[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D]. + [code]area[/code] the other Area2D. + [code]area_shape[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D]. + [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. </description> </signal> <signal name="body_entered"> - <argument index="0" name="body" type="Node"> + <argument index="0" name="body" type="Node2D"> </argument> <description> - Emitted when a physics body enters. - The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when a [PhysicsBody2D] or [TileMap] enters this Area2D. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap]. </description> </signal> <signal name="body_exited"> - <argument index="0" name="body" type="Node"> + <argument index="0" name="body" type="Node2D"> </argument> <description> - Emitted when a physics body exits. - The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when a [PhysicsBody2D] or [TileMap] exits this Area2D. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap]. </description> </signal> <signal name="body_shape_entered"> <argument index="0" name="body_id" type="int"> </argument> - <argument index="1" name="body" type="Node"> + <argument index="1" name="body" type="Node2D"> </argument> <argument index="2" name="body_shape" type="int"> </argument> - <argument index="3" name="area_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a physics body enters, reporting which shapes overlapped. - The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when one of a [PhysicsBody2D] or [TileMap]'s [Shape2D]s enters one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body_id[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D]. + [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody2D] or [TileMap]. + [code]body_shape[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. + [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. </description> </signal> <signal name="body_shape_exited"> <argument index="0" name="body_id" type="int"> </argument> - <argument index="1" name="body" type="Node"> + <argument index="1" name="body" type="Node2D"> </argument> <argument index="2" name="body_shape" type="int"> </argument> - <argument index="3" name="area_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a physics body exits, reporting which shapes were overlapping. - The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when one of a [PhysicsBody2D] or [TileMap]'s [Shape2D]s exits one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body_id[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D]. + [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody2D] or [TileMap]. + [code]body_shape[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. + [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. </description> </signal> </signals> diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml index 2f8042bb1e..4271769155 100644 --- a/doc/classes/Area3D.xml +++ b/doc/classes/Area3D.xml @@ -150,14 +150,16 @@ <argument index="0" name="area" type="Area3D"> </argument> <description> - Emitted when another area enters. + Emitted when another Area3D enters this Area3D. Requires [member monitoring] to be set to [code]true[/code]. + [code]area[/code] the other Area3D. </description> </signal> <signal name="area_exited"> <argument index="0" name="area" type="Area3D"> </argument> <description> - Emitted when another area exits. + Emitted when another Area3D exits this Area3D. Requires [member monitoring] to be set to [code]true[/code]. + [code]area[/code] the other Area3D. </description> </signal> <signal name="area_shape_entered"> @@ -167,10 +169,14 @@ </argument> <argument index="2" name="area_shape" type="int"> </argument> - <argument index="3" name="self_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when another area enters, reporting which areas overlapped. [code]shape_owner_get_owner(shape_find_owner(shape))[/code] returns the parent object of the owner of the [code]shape[/code]. + Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. + [code]area_id[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D]. + [code]area[/code] the other Area3D. + [code]area_shape[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D]. + [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. </description> </signal> <signal name="area_shape_exited"> @@ -180,54 +186,64 @@ </argument> <argument index="2" name="area_shape" type="int"> </argument> - <argument index="3" name="self_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when another area exits, reporting which areas were overlapping. + Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. + [code]area_id[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D]. + [code]area[/code] the other Area3D. + [code]area_shape[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D]. + [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. </description> </signal> <signal name="body_entered"> - <argument index="0" name="body" type="Node"> + <argument index="0" name="body" type="Node3D"> </argument> <description> - Emitted when a physics body enters. - The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when a [PhysicsBody3D] or [GridMap] enters this Area3D. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap]. </description> </signal> <signal name="body_exited"> - <argument index="0" name="body" type="Node"> + <argument index="0" name="body" type="Node3D"> </argument> <description> - Emitted when a physics body exits. - The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when a [PhysicsBody3D] or [GridMap] exits this Area3D. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap]. </description> </signal> <signal name="body_shape_entered"> <argument index="0" name="body_id" type="int"> </argument> - <argument index="1" name="body" type="Node"> + <argument index="1" name="body" type="Node3D"> </argument> <argument index="2" name="body_shape" type="int"> </argument> - <argument index="3" name="area_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a physics body enters, reporting which shapes overlapped. - The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when one of a [PhysicsBody3D] or [GridMap]'s [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body_id[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. + [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody3D] or [GridMap]. + [code]body_shape[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. + [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. </description> </signal> <signal name="body_shape_exited"> <argument index="0" name="body_id" type="int"> </argument> - <argument index="1" name="body" type="Node"> + <argument index="1" name="body" type="Node3D"> </argument> <argument index="2" name="body_shape" type="int"> </argument> - <argument index="3" name="area_shape" type="int"> + <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a physics body exits, reporting which shapes were overlapping. - The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). + Emitted when one of a [PhysicsBody3D] or [GridMap]'s [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body_id[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. + [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody3D] or [GridMap]. + [code]body_shape[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. + [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. </description> </signal> </signals> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index db5d377c62..8fb688a8ae 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -191,15 +191,13 @@ </return> <argument index="0" name="value" type="Variant"> </argument> - <argument index="1" name="obj" type="Object"> + <argument index="1" name="func" type="Callable"> </argument> - <argument index="2" name="func" type="StringName"> - </argument> - <argument index="3" name="before" type="bool" default="true"> + <argument index="2" name="before" type="bool" default="true"> </argument> <description> Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise. - [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + [b]Note:[/b] Calling [method bsearch_custom] on an unsorted array results in unexpected behavior. </description> </method> <method name="clear"> @@ -234,7 +232,9 @@ <argument index="0" name="value" type="Variant"> </argument> <description> - Removes the first occurrence of a value from the array. + Removes the first occurrence of a value from the array. To remove an element by index, use [method remove] instead. + [b]Note:[/b] This method acts in-place and doesn't return a value. + [b]Note:[/b] On large arrays, this method will be slower if the removed element is close to the beginning of the array (index 0). This is because all elements placed after the removed element have to be reindexed. </description> </method> <method name="find"> @@ -311,7 +311,8 @@ <return type="int"> </return> <description> - Returns a hashed integer value representing the array contents. + Returns a hashed integer value representing the array and its contents. + [b]Note:[/b] Arrays with equal contents can still produce different hashes. Only the exact same arrays will produce the same hashed integer value. </description> </method> <method name="insert"> @@ -323,6 +324,8 @@ </argument> <description> Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]pos == size()[/code]). + [b]Note:[/b] This method acts in-place and doesn't return a value. + [b]Note:[/b] On large arrays, this method will be slower if the inserted element is close to the beginning of the array (index 0). This is because all elements placed after the newly inserted element have to be reindexed. </description> </method> <method name="invert"> @@ -421,14 +424,15 @@ <return type="Variant"> </return> <description> - Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. + Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. See also [method pop_front]. </description> </method> <method name="pop_front"> <return type="Variant"> </return> <description> - Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. + Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. See also [method pop_back]. + [b]Note:[/b] On large arrays, this method is much slower than [method pop_back] as it will reindex all the array's elements every time it's called. The larger the array, the slower [method pop_front] will be. </description> </method> <method name="push_back"> @@ -437,7 +441,7 @@ <argument index="0" name="value" type="Variant"> </argument> <description> - Appends an element at the end of the array. + Appends an element at the end of the array. See also [method push_front]. </description> </method> <method name="push_front"> @@ -446,7 +450,8 @@ <argument index="0" name="value" type="Variant"> </argument> <description> - Adds an element at the beginning of the array. + Adds an element at the beginning of the array. See also [method push_back]. + [b]Note:[/b] On large arrays, this method is much slower than [method push_back] as it will reindex all the array's elements every time it's called. The larger the array, the slower [method push_front] will be. </description> </method> <method name="remove"> @@ -455,7 +460,9 @@ <argument index="0" name="position" type="int"> </argument> <description> - Removes an element from the array by index. If the index does not exist in the array, nothing happens. + Removes an element from the array by index. If the index does not exist in the array, nothing happens. To remove an element by searching for its value, use [method erase] instead. + [b]Note:[/b] This method acts in-place and doesn't return a value. + [b]Note:[/b] On large arrays, this method will be slower if the removed element is close to the beginning of the array (index 0). This is because all elements placed after the removed element have to be reindexed. </description> </method> <method name="resize"> @@ -528,12 +535,10 @@ <method name="sort_custom"> <return type="void"> </return> - <argument index="0" name="obj" type="Object"> - </argument> - <argument index="1" name="func" type="StringName"> + <argument index="0" name="func" type="Callable"> </argument> <description> - Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. + Sorts the array using a custom method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. [b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior. [codeblocks] [gdscript] @@ -544,7 +549,7 @@ return false var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]] - my_items.sort_custom(MyCustomSorter, "sort_ascending") + my_items.sort_custom(MyCustomSorter.sort_ascending) print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]]. [/gdscript] [csharp] diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 1f532f4843..e2c4ed1430 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -215,6 +215,8 @@ <member name="custom_aabb" type="AABB" setter="set_custom_aabb" getter="get_custom_aabb" default="AABB( 0, 0, 0, 0, 0, 0 )"> Overrides the [AABB] with one defined by user for use with frustum culling. Especially useful to avoid unexpected culling when using a shader to offset vertices. </member> + <member name="shadow_mesh" type="ArrayMesh" setter="set_shadow_mesh" getter="get_shadow_mesh"> + </member> </members> <constants> </constants> diff --git a/doc/classes/AudioEffectCapture.xml b/doc/classes/AudioEffectCapture.xml new file mode 100644 index 0000000000..cf3d87c2e4 --- /dev/null +++ b/doc/classes/AudioEffectCapture.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="AudioEffectCapture" inherits="AudioEffect" version="4.0"> + <brief_description> + Captures audio from an audio bus in real-time. + </brief_description> + <description> + AudioEffectCapture is an AudioEffect which copies all audio frames from the attached audio effect bus into its internal ring buffer. + Application code should consume these audio frames from this ring buffer using [method get_buffer] and process it as needed, for example to capture data from a microphone, implement application defined effects, or to transmit audio over the network. + </description> + <tutorials> + </tutorials> + <methods> + <method name="can_get_buffer" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="frames" type="int"> + </argument> + <description> + Returns [code]true[/code] if at least [code]frames[/code] audio frames are available to read in the internal ring buffer. + </description> + </method> + <method name="clear_buffer"> + <return type="void"> + </return> + <description> + Clears the internal ring buffer. + </description> + </method> + <method name="get_buffer"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="frames" type="int"> + </argument> + <description> + Gets the next [code]frames[/code] audio samples from the internal ring buffer. + Returns a [PackedVector2Array] containing exactly [code]frames[/code] audio samples if available, or an empty [PackedVector2Array] if insufficient data was available. + </description> + </method> + <method name="get_buffer_length_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the total size of the internal ring buffer in frames. + </description> + </method> + <method name="get_discarded_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of audio frames discarded from the audio bus due to full buffer. + </description> + </method> + <method name="get_frames_available" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of frames available to read using [method get_buffer]. + </description> + </method> + <method name="get_pushed_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of audio frames inserted from the audio bus. + </description> + </method> + </methods> + <members> + <member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="0.1"> + Length of the internal ring buffer, in seconds. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/BakedLightmapData.xml b/doc/classes/BakedLightmapData.xml index 026477782a..904555c48e 100644 --- a/doc/classes/BakedLightmapData.xml +++ b/doc/classes/BakedLightmapData.xml @@ -12,11 +12,11 @@ </return> <argument index="0" name="path" type="NodePath"> </argument> - <argument index="1" name="lightmap" type="Rect2"> + <argument index="1" name="uv_scale" type="Rect2"> </argument> - <argument index="2" name="offset" type="int"> + <argument index="2" name="slice_index" type="int"> </argument> - <argument index="3" name="arg3" type="int"> + <argument index="3" name="sub_instance" type="int"> </argument> <description> </description> diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index e47198a381..51c35b15ce 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -34,6 +34,7 @@ [/codeblocks] Buttons (like all Control nodes) can also be created in the editor, but some situations may require creating them from code. See also [BaseButton] which contains common properties and methods associated with this node. + [b]Note:[/b] Buttons do not interpret touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions, as [TouchScreenButton] supports multitouch. </description> <tutorials> <link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link> @@ -118,17 +119,20 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Default text [Color] of the [Button]. </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> Text [Color] used when the [Button] is disabled. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> Text [Color] used when the [Button] is being hovered. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> - Text [Color] used when the [Button] is being pressed. + <theme_item name="font_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Text [Color] used when the [Button] is being hovered and pressed. + </theme_item> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [Button]. </theme_item> - <theme_item name="font_outline_modulate" type="Color" default="Color( 1, 1, 1, 1 )"> - Text oubline [Color] of the [Button]. + <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Text [Color] used when the [Button] is being pressed. </theme_item> <theme_item name="font_size" type="int"> Font size of the [Button]'s text. @@ -139,11 +143,26 @@ <theme_item name="hseparation" type="int" default="2"> The horizontal space between [Button]'s icon and text. </theme_item> + <theme_item name="icon_disabled_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Icon modulate [Color] used when the [Button] is disabled. + </theme_item> + <theme_item name="icon_hover_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Icon modulate [Color] used when the [Button] is being hovered. + </theme_item> + <theme_item name="icon_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Icon modulate [Color] used when the [Button] is being hovered and pressed. + </theme_item> + <theme_item name="icon_normal_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Default icon modulate [Color] of the [Button]. + </theme_item> + <theme_item name="icon_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> + Icon modulate [Color] used when the [Button] is being pressed. + </theme_item> <theme_item name="normal" type="StyleBox"> Default [StyleBox] for the [Button]. </theme_item> <theme_item name="outline_size" type="int" default="0"> - Size of the [Button]'s text outline. + The size of the text outline. </theme_item> <theme_item name="pressed" type="StyleBox"> [StyleBox] used when the [Button] is being pressed. diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index f137ede90f..9b8993e45d 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -18,7 +18,7 @@ callable.call("invalid") # Invalid call, should have at least 2 arguments. [/gdscript] [csharp] - Callable callable = new Callable(this, "print_args"); + Callable callable = new Callable(this, nameof("printArgs")); public void PrintArgs(object arg1, object arg2, object arg3 = "") { GD.PrintS(arg1, arg2, arg3); @@ -67,6 +67,7 @@ <return type="Callable"> </return> <description> + Returns a copy of this [Callable] with the arguments bound. Bound arguments are passed after the arguments supplied by [method call]. </description> </method> <method name="call" qualifiers="vararg"> @@ -108,24 +109,28 @@ <return type="int"> </return> <description> + Returns the hash value of this [Callable]'s object. </description> </method> <method name="is_custom"> <return type="bool"> </return> <description> + Returns [code]true[/code] if this [Callable] is a custom callable whose behavior differs based on implementation details. Custom callables are used in the engine for various reasons. If [code]true[/code], you can't use [method get_method]. </description> </method> <method name="is_null"> <return type="bool"> </return> <description> + Returns [code]true[/code] if this [Callable] has no target to call the method on. </description> </method> <method name="is_standard"> <return type="bool"> </return> <description> + Returns [code]true[/code] if this [Callable] is a standard callable, referencing an object and a method using a [StringName]. </description> </method> <method name="operator !=" qualifiers="operator"> @@ -134,6 +139,7 @@ <argument index="0" name="right" type="Callable"> </argument> <description> + Returns [code]true[/code] if both [Callable]s invoke different targets. </description> </method> <method name="operator ==" qualifiers="operator"> @@ -142,6 +148,7 @@ <argument index="0" name="right" type="Callable"> </argument> <description> + Returns [code]true[/code] if both [Callable]s invoke the same custom target. </description> </method> <method name="unbind"> @@ -150,6 +157,7 @@ <argument index="0" name="argcount" type="int"> </argument> <description> + Returns a copy of this [Callable] with the arguments unbound. Calling the returned [Callable] will call the method without the extra arguments that are supplied in the [Callable] on which you are calling this method. </description> </method> </methods> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index 2a4e726d43..d40567bdcb 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -168,8 +168,8 @@ <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> The camera's offset, useful for looking around or camera shake animations. </member> - <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Camera2D.Camera2DProcessMode" default="1"> - The camera's process callback. See [enum Camera2DProcessMode]. + <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="Camera2D.Camera2DProcessCallback" default="1"> + The camera's process callback. See [enum Camera2DProcessCallback]. </member> <member name="rotating" type="bool" setter="set_rotating" getter="is_rotating" default="false"> If [code]true[/code], the camera rotates with the target. @@ -191,10 +191,10 @@ <constant name="ANCHOR_MODE_DRAG_CENTER" value="1" enum="AnchorMode"> The camera's position takes into account vertical/horizontal offsets and the screen size. </constant> - <constant name="CAMERA2D_PROCESS_PHYSICS" value="0" enum="Camera2DProcessMode"> + <constant name="CAMERA2D_PROCESS_PHYSICS" value="0" enum="Camera2DProcessCallback"> The camera updates with the [code]_physics_process[/code] callback. </constant> - <constant name="CAMERA2D_PROCESS_IDLE" value="1" enum="Camera2DProcessMode"> + <constant name="CAMERA2D_PROCESS_IDLE" value="1" enum="Camera2DProcessCallback"> The camera updates with the [code]_process[/code] callback. </constant> </constants> diff --git a/doc/classes/CharFXTransform.xml b/doc/classes/CharFXTransform.xml index b4cb110337..850098f741 100644 --- a/doc/classes/CharFXTransform.xml +++ b/doc/classes/CharFXTransform.xml @@ -17,7 +17,7 @@ The color the character will be drawn with. </member> <member name="elapsed_time" type="float" setter="set_elapsed_time" getter="get_elapsed_time" default="0.0"> - The time elapsed since the [RichTextLabel] was added to the scene tree (in seconds). Time stops when the project is paused, unless the [RichTextLabel]'s [member Node.pause_mode] is set to [constant Node.PAUSE_MODE_PROCESS]. + The time elapsed since the [RichTextLabel] was added to the scene tree (in seconds). Time stops when the project is paused depending on the value of the [RichTextLabel]'s [member Node.process_mode]. [b]Note:[/b] Time still passes while the [RichTextLabel] is hidden. </member> <member name="env" type="Dictionary" setter="set_environment" getter="get_environment" default="{}"> diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml index 89fb960e88..80febfbfe7 100644 --- a/doc/classes/CheckBox.xml +++ b/doc/classes/CheckBox.xml @@ -36,16 +36,19 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> The [CheckBox] text's font color. </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> The [CheckBox] text's font color when it's disabled. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> The [CheckBox] text's font color when it's hovered. </theme_item> - <theme_item name="font_color_hover_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> The [CheckBox] text's font color when it's hovered and pressed. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [CheckBox]. + </theme_item> + <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> The [CheckBox] text's font color when it's pressed. </theme_item> <theme_item name="font_size" type="int"> @@ -63,6 +66,9 @@ <theme_item name="normal" type="StyleBox"> The [StyleBox] to display as a background. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="pressed" type="StyleBox"> The [StyleBox] to display as a background when the [CheckBox] is pressed. </theme_item> diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml index 882f1c69f3..46e590a115 100644 --- a/doc/classes/CheckButton.xml +++ b/doc/classes/CheckButton.xml @@ -33,16 +33,19 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> The [CheckButton] text's font color. </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> The [CheckButton] text's font color when it's disabled. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> The [CheckButton] text's font color when it's hovered. </theme_item> - <theme_item name="font_color_hover_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> The [CheckButton] text's font color when it's hovered and pressed. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [CheckButton]. + </theme_item> + <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> The [CheckButton] text's font color when it's pressed. </theme_item> <theme_item name="font_size" type="int"> @@ -84,6 +87,9 @@ <theme_item name="on_mirrored" type="Texture2D"> The icon to display when the [CheckButton] is checked (for right-to-left layouts). </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="pressed" type="StyleBox"> The [StyleBox] to display as a background when the [CheckButton] is pressed. </theme_item> diff --git a/doc/classes/ClippedCamera3D.xml b/doc/classes/ClippedCamera3D.xml index de90247536..9116af19c3 100644 --- a/doc/classes/ClippedCamera3D.xml +++ b/doc/classes/ClippedCamera3D.xml @@ -95,15 +95,15 @@ <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0"> The camera's collision margin. The camera can't get closer than this distance to a colliding object. </member> - <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="ClippedCamera3D.ProcessMode" default="0"> - The camera's process callback. See [enum ProcessMode]. + <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="ClippedCamera3D.ClipProcessCallback" default="0"> + The camera's process callback. See [enum ClipProcessCallback]. </member> </members> <constants> - <constant name="CLIP_PROCESS_PHYSICS" value="0" enum="ProcessMode"> + <constant name="CLIP_PROCESS_PHYSICS" value="0" enum="ClipProcessCallback"> The camera updates with the [code]_physics_process[/code] callback. </constant> - <constant name="CLIP_PROCESS_IDLE" value="1" enum="ProcessMode"> + <constant name="CLIP_PROCESS_IDLE" value="1" enum="ClipProcessCallback"> The camera updates with the [code]_process[/code] callback. </constant> </constants> diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml index 8834ff82c6..d1483ac88e 100644 --- a/doc/classes/CodeEdit.xml +++ b/doc/classes/CodeEdit.xml @@ -179,9 +179,12 @@ </theme_item> <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> - <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [CodeEdit]. </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> + <theme_item name="font_readonly_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )"> </theme_item> <theme_item name="font_size" type="int"> Font size of the [CodeEdit]'s text. @@ -194,6 +197,9 @@ </theme_item> <theme_item name="normal" type="StyleBox"> </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="read_only" type="StyleBox"> </theme_item> <theme_item name="safe_line_number_color" type="Color" default="Color( 0.67, 0.78, 0.67, 0.6 )"> diff --git a/doc/classes/CodeHighlighter.xml b/doc/classes/CodeHighlighter.xml index 7a1dad547b..f078e4e5b0 100644 --- a/doc/classes/CodeHighlighter.xml +++ b/doc/classes/CodeHighlighter.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CodeHighlighter" inherits="SyntaxHighlighter" version="4.0"> <brief_description> + A syntax highlighter for code. </brief_description> <description> + A syntax highlighter for code. </description> <tutorials> </tutorials> @@ -10,15 +12,18 @@ <method name="add_color_region"> <return type="void"> </return> - <argument index="0" name="p_start_key" type="String"> + <argument index="0" name="start_key" type="String"> </argument> - <argument index="1" name="p_end_key" type="String"> + <argument index="1" name="end_key" type="String"> </argument> - <argument index="2" name="p_color" type="Color"> + <argument index="2" name="color" type="Color"> </argument> - <argument index="3" name="p_line_only" type="bool" default="false"> + <argument index="3" name="line_only" type="bool" default="false"> </argument> <description> + Adds a color region such as comments or strings. + Both the start and end keys must be symbols. Only the start key has to be unique. + Line only denotes if the region should continue until the end of the line or carry over on to the next line. If the end key is blank this is automatically set to [code]true[/code]. </description> </method> <method name="add_keyword_color"> @@ -29,6 +34,8 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color for a keyword. + The keyword cannot contain any symbols except '_'. </description> </method> <method name="add_member_keyword_color"> @@ -39,24 +46,30 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color for a member keyword. + The member keyword cannot contain any symbols except '_'. + It will not be highlighted if preceded by a '.'. </description> </method> <method name="clear_color_regions"> <return type="void"> </return> <description> + Removes all color regions. </description> </method> <method name="clear_keyword_colors"> <return type="void"> </return> <description> + Removes all keywords. </description> </method> <method name="clear_member_keyword_colors"> <return type="void"> </return> <description> + Removes all member keywords. </description> </method> <method name="get_keyword_color" qualifiers="const"> @@ -65,6 +78,7 @@ <argument index="0" name="keyword" type="String"> </argument> <description> + Returns the color for a keyword. </description> </method> <method name="get_member_keyword_color" qualifiers="const"> @@ -73,14 +87,16 @@ <argument index="0" name="member_keyword" type="String"> </argument> <description> + Returns the color for a member keyword. </description> </method> <method name="has_color_region" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="p_start_key" type="String"> + <argument index="0" name="start_key" type="String"> </argument> <description> + Return [code]true[/code] if the start key exists, else [code]false[/code]. </description> </method> <method name="has_keyword_color" qualifiers="const"> @@ -89,6 +105,7 @@ <argument index="0" name="keyword" type="String"> </argument> <description> + Return [code]true[/code] if the keyword exists, else [code]false[/code]. </description> </method> <method name="has_member_keyword_color" qualifiers="const"> @@ -97,14 +114,16 @@ <argument index="0" name="member_keyword" type="String"> </argument> <description> + Return [code]true[/code] if the member keyword exists, else [code]false[/code]. </description> </method> <method name="remove_color_region"> <return type="void"> </return> - <argument index="0" name="p_start_key" type="String"> + <argument index="0" name="start_key" type="String"> </argument> <description> + Removes the color region that uses that start key. </description> </method> <method name="remove_keyword_color"> @@ -113,6 +132,7 @@ <argument index="0" name="keyword" type="String"> </argument> <description> + Removes the keyword. </description> </method> <method name="remove_member_keyword_color"> @@ -121,23 +141,31 @@ <argument index="0" name="member_keyword" type="String"> </argument> <description> + Removes the member keyword. </description> </method> </methods> <members> <member name="color_regions" type="Dictionary" setter="set_color_regions" getter="get_color_regions" default="{}"> + Sets the color regions. All existing regions will be removed. The [Dictionary] key is the region start and end key, separated by a space. The value is the region color. </member> <member name="function_color" type="Color" setter="set_function_color" getter="get_function_color" default="Color( 0, 0, 0, 1 )"> + Sets color for functions. A function is a non-keyword string followed by a '('. </member> <member name="keyword_colors" type="Dictionary" setter="set_keyword_colors" getter="get_keyword_colors" default="{}"> + Sets the keyword colors. All existing keywords will be removed. The [Dictionary] key is the keyword. The value is the keyword color. </member> <member name="member_keyword_colors" type="Dictionary" setter="set_member_keyword_colors" getter="get_member_keyword_colors" default="{}"> + Sets the member keyword colors. All existing member keyword will be removed. The [Dictionary] key is the member keyword. The value is the member keyword color. </member> <member name="member_variable_color" type="Color" setter="set_member_variable_color" getter="get_member_variable_color" default="Color( 0, 0, 0, 1 )"> + Sets color for member variables. A member variable is non-keyword, non-function string proceeded with a '.'. </member> <member name="number_color" type="Color" setter="set_number_color" getter="get_number_color" default="Color( 0, 0, 0, 1 )"> + Sets the color for numbers. </member> <member name="symbol_color" type="Color" setter="set_symbol_color" getter="get_symbol_color" default="Color( 0, 0, 0, 1 )"> + Sets the color for symbols. </member> </members> <constants> diff --git a/doc/classes/CollisionPolygon3D.xml b/doc/classes/CollisionPolygon3D.xml index dd3c57d1d0..38f4c5fe5c 100644 --- a/doc/classes/CollisionPolygon3D.xml +++ b/doc/classes/CollisionPolygon3D.xml @@ -17,6 +17,9 @@ <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" default="false"> If [code]true[/code], no collision will be produced. </member> + <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.04"> + The collision margin for the generated [Shape3D]. See [member Shape3D.margin] for more details. + </member> <member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array( )"> Array of vertices which define the polygon. [b]Note:[/b] The returned value is a copy of the original. Methods which mutate the size or properties of the return value will not impact the original polygon. To change properties of the polygon, assign it to a temporary variable and make changes before reassigning the [code]polygon[/code] member. diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 8af5f29b65..ce88e0ae88 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -5,7 +5,7 @@ </brief_description> <description> A color represented by red, green, blue, and alpha (RGBA) components. The alpha component is often used for transparency. Values are in floating-point and usually range from 0 to 1. Some properties (such as CanvasItem.modulate) may accept values greater than 1 (overbright or HDR colors). - You can also create a color from standardized color names by using [code]ColorN[/code] ([b]FIXME:[/b] No longer true, a Color(String) constructor should be re-implemented for that) or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url]. + You can also create a color from standardized color names by using the string constructor or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url]. If you want to supply values in a range of 0 to 255, you should use [method @GDScript.Color8]. [b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it's equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code]. [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/color_constants.png]Color constants cheatsheet[/url] @@ -54,6 +54,26 @@ <method name="Color" qualifiers="constructor"> <return type="Color"> </return> + <argument index="0" name="code" type="String"> + </argument> + <argument index="1" name="alpha" type="float"> + </argument> + <description> + Constructs a [Color] either from an HTML color code or from a standardized color name, with [code]alpha[/code] on the range of 0 to 1. Supported color names are the same as the constants. + </description> + </method> + <method name="Color" qualifiers="constructor"> + <return type="Color"> + </return> + <argument index="0" name="code" type="String"> + </argument> + <description> + Constructs a [Color] either from an HTML color code or from a standardized color name. Supported color names are the same as the constants. + </description> + </method> + <method name="Color" qualifiers="constructor"> + <return type="Color"> + </return> <argument index="0" name="r" type="float"> </argument> <argument index="1" name="g" type="float"> diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index c04e8b9ea0..e49027e61d 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -73,13 +73,16 @@ <theme_item name="font_color" type="Color" default="Color( 1, 1, 1, 1 )"> Default text [Color] of the [ColorPickerButton]. </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.3 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.3 )"> Text [Color] used when the [ColorPickerButton] is disabled. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 1, 1, 1, 1 )"> Text [Color] used when the [ColorPickerButton] is being hovered. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 0.8, 0.8, 0.8, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [ColorPickerButton]. + </theme_item> + <theme_item name="font_pressed_color" type="Color" default="Color( 0.8, 0.8, 0.8, 1 )"> Text [Color] used when the [ColorPickerButton] is being pressed. </theme_item> <theme_item name="font_size" type="int"> @@ -94,6 +97,9 @@ <theme_item name="normal" type="StyleBox"> Default [StyleBox] for the [ColorPickerButton]. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="pressed" type="StyleBox"> [StyleBox] used when the [ColorPickerButton] is being pressed. </theme_item> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 533748aced..c5e820e9fe 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -16,8 +16,9 @@ [b]Note:[/b] Theme items are [i]not[/i] [Object] properties. This means you can't access their values using [method Object.get] and [method Object.set]. Instead, use the [code]get_theme_*[/code] and [code]add_theme_*_override[/code] methods provided by this class. </description> <tutorials> - <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/gui/index.html</link> + <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/ui/index.html</link> <link title="Custom drawing in 2D">https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link> + <link title="Control node gallery">https://docs.godotengine.org/en/latest/tutorials/ui/control_node_gallery.html</link> <link title="All GUI Demos">https://github.com/godotengine/godot-demo-projects/tree/master/gui</link> </tutorials> <methods> @@ -306,6 +307,20 @@ [/codeblocks] </description> </method> + <method name="find_next_valid_focus" qualifiers="const"> + <return type="Control"> + </return> + <description> + Finds the next (below in the tree) [Control] that can receive the focus. + </description> + </method> + <method name="find_prev_valid_focus" qualifiers="const"> + <return type="Control"> + </return> + <description> + Finds the previous (above in the tree) [Control] that can receive the focus. + </description> + </method> <method name="force_drag"> <return type="void"> </return> @@ -854,7 +869,7 @@ <argument index="0" name="control" type="Control"> </argument> <description> - Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. The control must not be in the scene tree. + Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. The control must not be in the scene tree. You should not free the control, and you should not keep a reference to the control beyond the duration of the drag. It will be deleted automatically after the drag has ended. [codeblocks] [gdscript] export (Color, RGBA) var color = Color(1, 0, 0, 1) diff --git a/doc/classes/Curve2D.xml b/doc/classes/Curve2D.xml index 2d50d98a74..b33f3b4ffc 100644 --- a/doc/classes/Curve2D.xml +++ b/doc/classes/Curve2D.xml @@ -63,7 +63,7 @@ <argument index="0" name="to_point" type="Vector2"> </argument> <description> - Returns the closest point (in curve's local space) to [code]to_point[/code]. + Returns the closest baked point (in curve's local space) to [code]to_point[/code]. [code]to_point[/code] must be in this curve's local space. </description> </method> diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml index bda04f010b..fcd150ad57 100644 --- a/doc/classes/Curve3D.xml +++ b/doc/classes/Curve3D.xml @@ -78,7 +78,7 @@ <argument index="0" name="to_point" type="Vector3"> </argument> <description> - Returns the closest point (in curve's local space) to [code]to_point[/code]. + Returns the closest baked point (in curve's local space) to [code]to_point[/code]. [code]to_point[/code] must be in this curve's local space. </description> </method> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index d91ea6528a..91e90d051d 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -492,7 +492,7 @@ </argument> <argument index="3" name="subtitle_track" type="String"> </argument> - <argument index="4" name="arg4" type="int"> + <argument index="4" name="screen" type="int"> </argument> <description> </description> @@ -635,6 +635,42 @@ <description> </description> </method> + <method name="tablet_get_current_driver" qualifiers="const"> + <return type="String"> + </return> + <description> + Returns current active tablet driver name. + [b]Note:[/b] This method is implemented on Windows. + </description> + </method> + <method name="tablet_get_driver_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the total number of available tablet drivers. + [b]Note:[/b] This method is implemented on Windows. + </description> + </method> + <method name="tablet_get_driver_name" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Returns the tablet driver name for the given index. + [b]Note:[/b] This method is implemented on Windows. + </description> + </method> + <method name="tablet_set_current_driver"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Set active tablet driver name. + [b]Note:[/b] This method is implemented on Windows. + </description> + </method> <method name="virtual_keyboard_get_height" qualifiers="const"> <return type="int"> </return> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index e5401134bf..aa64ab4043 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -16,7 +16,7 @@ return "my.special.plugin" func get_visible_name(): - return "Special Mesh Importer" + return "Special Mesh" func get_recognized_extensions(): return ["special", "spec"] @@ -44,8 +44,7 @@ # Fill the Mesh with data read in "file", left as an exercise to the reader. var filename = save_path + "." + get_save_extension() - ResourceSaver.save(filename, mesh) - return OK + return ResourceSaver.save(filename, mesh) [/gdscript] [csharp] using Godot; @@ -60,7 +59,7 @@ public override String GetVisibleName() { - return "Special Mesh Importer"; + return "Special Mesh"; } public override Godot.Collections.Array GetRecognizedExtensions() @@ -104,8 +103,7 @@ var mesh = new ArrayMesh(); // Fill the Mesh with data read in "file", left as an exercise to the reader. String filename = savePath + "." + GetSaveExtension(); - ResourceSaver.Save(filename, mesh); - return (int)Error.Ok; + return (int)ResourceSaver.Save(filename, mesh); } } [/csharp] @@ -220,7 +218,7 @@ <return type="String"> </return> <description> - Gets the name to display in the import window. + Gets the name to display in the import window. You should choose this name as a continuation to "Import as", e.g. "Import as Special Mesh". </description> </method> <method name="import" qualifiers="virtual"> diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml index 6f03165a97..d85f95baff 100644 --- a/doc/classes/EditorInspector.xml +++ b/doc/classes/EditorInspector.xml @@ -10,14 +10,6 @@ <tutorials> </tutorials> <methods> - <method name="refresh"> - <return type="void"> - </return> - <description> - Refreshes the inspector. - [b]Note:[/b] To save on CPU resources, calling this method will do nothing if the time specified in [code]docks/property_editor/auto_refresh_interval[/code] editor setting hasn't passed yet since this method was last called. (By default, this interval is set to 0.3 seconds.) - </description> - </method> </methods> <members> <member name="scroll_horizontal_enabled" type="bool" setter="set_enable_h_scroll" getter="is_h_scroll_enabled" override="true" default="false" /> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index be21ad65c5..a24e4bbdc5 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -169,6 +169,8 @@ <return type="bool"> </return> <description> + This method is called when the editor is about to run the project. The plugin can then perform required operations before the project runs. + This method must return a boolean. If this method returns [code]false[/code], the project will not run. The run is aborted immediately, so this also prevents all other plugins' [method build] methods from running. </description> </method> <method name="clear" qualifiers="virtual"> @@ -675,6 +677,10 @@ Emitted when user changes the workspace ([b]2D[/b], [b]3D[/b], [b]Script[/b], [b]AssetLib[/b]). Also works with custom screens defined by plugins. </description> </signal> + <signal name="project_settings_changed"> + <description> + </description> + </signal> <signal name="resource_saved"> <argument index="0" name="resource" type="Resource"> </argument> diff --git a/doc/classes/EditorSceneImporterMesh.xml b/doc/classes/EditorSceneImporterMesh.xml index 1c903bd889..58b7104667 100644 --- a/doc/classes/EditorSceneImporterMesh.xml +++ b/doc/classes/EditorSceneImporterMesh.xml @@ -29,7 +29,7 @@ </argument> <argument index="4" name="material" type="Material" default="null"> </argument> - <argument index="5" name="arg5" type="String" default=""""> + <argument index="5" name="name" type="String" default=""""> </argument> <description> </description> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 6088ae7a43..016d0128eb 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -160,6 +160,16 @@ Returns the default value of the setting specified by [code]name[/code]. This is the value that would be applied when clicking the Revert button in the Editor Settings. </description> </method> + <method name="set_builtin_action_override"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="actions_list" type="Array"> + </argument> + <description> + </description> + </method> <method name="set_favorites"> <return type="void"> </return> diff --git a/doc/classes/EditorSyntaxHighlighter.xml b/doc/classes/EditorSyntaxHighlighter.xml index 103d95e1d6..b80e81928f 100644 --- a/doc/classes/EditorSyntaxHighlighter.xml +++ b/doc/classes/EditorSyntaxHighlighter.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorSyntaxHighlighter" inherits="SyntaxHighlighter" version="4.0"> <brief_description> + Base Syntax highlighter resource for the [ScriptEditor]. </brief_description> <description> + Base syntax highlighter resource all editor syntax highlighters extend from, it is used in the [ScriptEditor]. + Add a syntax highlighter to an individual script by calling [method ScriptEditorBase.add_syntax_highlighter]. To apply to all scripts on open, call [method ScriptEditor.register_syntax_highlighter] </description> <tutorials> </tutorials> @@ -11,18 +14,21 @@ <return type="String"> </return> <description> + Virtual method which can be overridden to return the syntax highlighter name. </description> </method> <method name="_get_supported_extentions" qualifiers="virtual"> <return type="Array"> </return> <description> + Virtual method which can be overridden to return the supported file extensions. </description> </method> <method name="_get_supported_languages" qualifiers="virtual"> <return type="Array"> </return> <description> + Virtual method which can be overridden to return the supported language names. </description> </method> </methods> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 9dd4ecc37b..821aa91d21 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -169,6 +169,8 @@ </member> <member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0"> </member> + <member name="sdfgi_bounce_feedback" type="float" setter="set_sdfgi_bounce_feedback" getter="get_sdfgi_bounce_feedback" default="0.0"> + </member> <member name="sdfgi_cascade0_distance" type="float" setter="set_sdfgi_cascade0_distance" getter="get_sdfgi_cascade0_distance" default="12.8"> </member> <member name="sdfgi_cascades" type="int" setter="set_sdfgi_cascades" getter="get_sdfgi_cascades" enum="Environment.SDFGICascades" default="1"> @@ -187,8 +189,6 @@ </member> <member name="sdfgi_read_sky_light" type="bool" setter="set_sdfgi_read_sky_light" getter="is_sdfgi_reading_sky_light" default="false"> </member> - <member name="sdfgi_use_multi_bounce" type="bool" setter="set_sdfgi_use_multi_bounce" getter="is_sdfgi_using_multi_bounce" default="false"> - </member> <member name="sdfgi_use_occlusion" type="bool" setter="set_sdfgi_use_occlusion" getter="is_sdfgi_using_occlusion" default="false"> </member> <member name="sdfgi_y_scale" type="int" setter="set_sdfgi_y_scale" getter="get_sdfgi_y_scale" enum="Environment.SDFGIYScale" default="0"> @@ -265,12 +265,14 @@ </member> <member name="volumetric_fog_light_energy" type="float" setter="set_volumetric_fog_light_energy" getter="get_volumetric_fog_light_energy" default="1.0"> </member> - <member name="volumetric_fog_shadow_filter" type="int" setter="set_volumetric_fog_shadow_filter" getter="get_volumetric_fog_shadow_filter" enum="Environment.VolumetricFogShadowFilter" default="1"> + <member name="volumetric_fog_temporal_reprojection_amount" type="float" setter="set_volumetric_fog_temporal_reprojection_amount" getter="get_volumetric_fog_temporal_reprojection_amount" default="0.9"> + </member> + <member name="volumetric_fog_temporal_reprojection_enabled" type="bool" setter="set_volumetric_fog_temporal_reprojection_enabled" getter="is_volumetric_fog_temporal_reprojection_enabled" default="true"> </member> </members> <constants> <constant name="BG_CLEAR_COLOR" value="0" enum="BGMode"> - Clears the background using the clear color defined in [member ProjectSettings.rendering/environment/default_clear_color]. + Clears the background using the clear color defined in [member ProjectSettings.rendering/environment/defaults/default_clear_color]. </constant> <constant name="BG_COLOR" value="1" enum="BGMode"> Clears the background using a custom clear color. diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 2f7ac551cf..e0781e807f 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -42,6 +42,7 @@ [/codeblocks] In the example above, the file will be saved in the user data folder as specified in the [url=https://docs.godotengine.org/en/latest/tutorials/io/data_paths.html]Data paths[/url] documentation. [b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of the [File] API, as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package. + [b]Note:[/b] Files are automatically closed only if the process exits "normally" (such as by clicking the window manager's close button or pressing [b]Alt + F4[/b]). If you stop the project execution by pressing [b]F8[/b] while the project is running, the file won't be closed as the game process will be killed. You can work around this by calling [method flush] at regular intervals. </description> <tutorials> <link title="File system">https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link> @@ -52,7 +53,7 @@ <return type="void"> </return> <description> - Closes the currently opened file. + Closes the currently opened file and prevents subsequent read/write operations. Use [method flush] to persist the data to disk without closing the file. </description> </method> <method name="eof_reached" qualifiers="const"> @@ -73,6 +74,14 @@ [b]Note:[/b] Many resources types are imported (e.g. textures or sound files), and their source asset will not be included in the exported game, as only the imported version is used. See [method ResourceLoader.exists] for an alternative approach that takes resource remapping into account. </description> </method> + <method name="flush"> + <return type="void"> + </return> + <description> + Writes the file's buffer to disk. Flushing is automatically performed when the file is closed. This means you don't need to call [method flush] manually before closing a file using [method close]. Still, calling [method flush] can be used to ensure the data is safe even if the project crashes instead of being closed gracefully. + [b]Note:[/b] Only call [method flush] when you actually need it. Otherwise, it will decrease performance due to constant disk writes. + </description> + </method> <method name="get_16" qualifiers="const"> <return type="int"> </return> @@ -481,8 +490,9 @@ </methods> <members> <member name="endian_swap" type="bool" setter="set_endian_swap" getter="get_endian_swap" default="false"> - If [code]true[/code], the file's endianness is swapped. Use this if you're dealing with files written on big-endian machines. - [b]Note:[/b] This is about the file format, not CPU type. This is always reset to [code]false[/code] whenever you open the file. + If [code]true[/code], the file is read with big-endian [url=https://en.wikipedia.org/wiki/Endianness]endianness[/url]. If [code]false[/code], the file is read with little-endian endianness. If in doubt, leave this to [code]false[/code] as most files are written with little-endian endianness. + [b]Note:[/b] [member endian_swap] is only about the file format, not the CPU type. The CPU endianness doesn't affect the default endianness for files written. + [b]Note:[/b] This is always reset to [code]false[/code] whenever you open the file. Therefore, you must set [member endian_swap] [i]after[/i] opening the file, not before. </member> </members> <constants> diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index edd2bd137f..409e405551 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -329,10 +329,10 @@ </methods> <members> <member name="extra_spacing_bottom" type="int" setter="set_spacing" getter="get_spacing" default="0"> - Extra spacing at the bottom in pixels. + Extra spacing at the bottom of the line in pixels. </member> <member name="extra_spacing_top" type="int" setter="set_spacing" getter="get_spacing" default="0"> - Extra character spacing in pixels. + Extra spacing at the top of the line in pixels. </member> </members> <constants> diff --git a/doc/classes/FontData.xml b/doc/classes/FontData.xml index e2c35f9ce7..6c54af05cd 100644 --- a/doc/classes/FontData.xml +++ b/doc/classes/FontData.xml @@ -11,6 +11,45 @@ <tutorials> </tutorials> <methods> + <method name="bitmap_add_char"> + <return type="void"> + </return> + <argument index="0" name="char" type="int"> + </argument> + <argument index="1" name="texture_idx" type="int"> + </argument> + <argument index="2" name="rect" type="Rect2"> + </argument> + <argument index="3" name="align" type="Vector2"> + </argument> + <argument index="4" name="advance" type="float"> + </argument> + <description> + Adds a character to the font, where [code]character[/code] is the Unicode value, [code]texture[/code] is the texture index, [code]rect[/code] is the region in the texture (in pixels!), [code]align[/code] is the (optional) alignment for the character and [code]advance[/code] is the (optional) advance. + </description> + </method> + <method name="bitmap_add_kerning_pair"> + <return type="void"> + </return> + <argument index="0" name="A" type="int"> + </argument> + <argument index="1" name="B" type="int"> + </argument> + <argument index="2" name="kerning" type="int"> + </argument> + <description> + Adds a kerning pair to the bitmap font as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character. + </description> + </method> + <method name="bitmap_add_texture"> + <return type="void"> + </return> + <argument index="0" name="texture" type="Texture"> + </argument> + <description> + Adds a texture to the bitmap font. + </description> + </method> <method name="draw_glyph" qualifiers="const"> <return type="Vector2"> </return> @@ -154,6 +193,15 @@ Returns list of script support overrides. </description> </method> + <method name="get_spacing" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="type" type="int"> + </argument> + <description> + Returns the spacing for the given [code]type[/code] (see [enum SpacingType]). + </description> + </method> <method name="get_supported_chars" qualifiers="const"> <return type="String"> </return> @@ -256,6 +304,19 @@ Note: For non-scalable fonts [code]base_size[/code] is ignored, use [method get_base_size] to check actual font size. </description> </method> + <method name="new_bitmap"> + <return type="void"> + </return> + <argument index="0" name="height" type="float"> + </argument> + <argument index="1" name="ascent" type="float"> + </argument> + <argument index="2" name="base_size" type="int"> + </argument> + <description> + Creates new, empty bitmap font. + </description> + </method> <method name="remove_language_support_override"> <return type="void"> </return> @@ -296,6 +357,17 @@ Adds override for [method is_script_supported]. </description> </method> + <method name="set_spacing"> + <return type="void"> + </return> + <argument index="0" name="type" type="int"> + </argument> + <argument index="1" name="value" type="int"> + </argument> + <description> + Sets the spacing for [code]type[/code] (see [enum SpacingType]) to [code]value[/code] in pixels (not relative to the font size). + </description> + </method> <method name="set_variation"> <return type="void"> </return> @@ -318,6 +390,14 @@ <member name="distance_field_hint" type="bool" setter="set_distance_field_hint" getter="get_distance_field_hint" default="false"> If [code]true[/code], distance field hint is enabled. </member> + <member name="extra_spacing_glyph" type="int" setter="set_spacing" getter="get_spacing" default="0"> + Extra spacing for each glyphs in pixels. + This can be a negative number to make the distance between glyphs smaller. + </member> + <member name="extra_spacing_space" type="int" setter="set_spacing" getter="get_spacing" default="0"> + Extra spacing for the space character in pixels. + This can be a negative number to make the distance between words smaller. + </member> <member name="force_autohinter" type="bool" setter="set_force_autohinter" getter="get_force_autohinter" default="false"> If [code]true[/code], default autohinter is used for font hinting. </member> @@ -326,5 +406,11 @@ </member> </members> <constants> + <constant name="SPACING_GLYPH" value="0" enum="SpacingType"> + Spacing for each glyph. + </constant> + <constant name="SPACING_SPACE" value="1" enum="SpacingType"> + Spacing for the space character. + </constant> </constants> </class> diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml index 52d3698201..dd51248fd9 100644 --- a/doc/classes/GIProbe.xml +++ b/doc/classes/GIProbe.xml @@ -5,7 +5,7 @@ </brief_description> <description> [GIProbe]s are used to provide high-quality real-time indirect light to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. [GIProbe]s need to be baked before using, however, once baked, dynamic objects will receive light from them. Further, lights can be fully dynamic or baked. - Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/quality/gi_probes/quality]. + Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/global_illumination/gi_probes/quality]. </description> <tutorials> <link title="GI probes">https://docs.godotengine.org/en/latest/tutorials/3d/gi_probes.html</link> diff --git a/doc/classes/GLTFSkeleton.xml b/doc/classes/GLTFSkeleton.xml index e27c838648..9680c27705 100644 --- a/doc/classes/GLTFSkeleton.xml +++ b/doc/classes/GLTFSkeleton.xml @@ -10,7 +10,7 @@ <method name="get_bone_attachment"> <return type="BoneAttachment3D"> </return> - <argument index="0" name="arg0" type="int"> + <argument index="0" name="idx" type="int"> </argument> <description> </description> diff --git a/doc/classes/GLTFState.xml b/doc/classes/GLTFState.xml index f7763efdb1..a8e96ec8a9 100644 --- a/doc/classes/GLTFState.xml +++ b/doc/classes/GLTFState.xml @@ -16,7 +16,7 @@ <method name="get_animation_player"> <return type="AnimationPlayer"> </return> - <argument index="0" name="arg0" type="int"> + <argument index="0" name="idx" type="int"> </argument> <description> </description> @@ -24,7 +24,7 @@ <method name="get_animation_players_count"> <return type="int"> </return> - <argument index="0" name="arg0" type="int"> + <argument index="0" name="idx" type="int"> </argument> <description> </description> @@ -80,7 +80,7 @@ <method name="get_scene_node"> <return type="Node"> </return> - <argument index="0" name="arg0" type="int"> + <argument index="0" name="idx" type="int"> </argument> <description> </description> diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index c09151405a..ebe4e3b00d 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -71,7 +71,8 @@ Particle texture. If [code]null[/code], particles will be squares. </member> <member name="visibility_rect" type="Rect2" setter="set_visibility_rect" getter="get_visibility_rect" default="Rect2( -100, -100, 200, 200 )"> - Editor visibility helper. + The [Rect2] that determines the node's region which needs to be visible on screen for the particle system to be active. + Grow the rect if particles suddenly appear/disappear when the node enters/exits the screen. The [Rect2] can be grown via code or with the [b]Particles → Generate Visibility Rect[/b] editor tool. </member> </members> <constants> diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index d1296c3418..aea106af50 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -123,7 +123,8 @@ <member name="sub_emitter" type="NodePath" setter="set_sub_emitter" getter="get_sub_emitter" default="NodePath("")"> </member> <member name="visibility_aabb" type="AABB" setter="set_visibility_aabb" getter="get_visibility_aabb" default="AABB( -4, -4, -4, 8, 8, 8 )"> - The [AABB] that determines the area of the world part of which needs to be visible on screen for the particle system to be active. + The [AABB] that determines the node's region which needs to be visible on screen for the particle system to be active. + Grow the box if particles suddenly appear/disappear when the node enters/exits the screen. The [AABB] can be grown via code or with the [b]Particles → Generate AABB[/b] editor tool. </member> </members> <constants> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 4b0ea4dcb1..279c4c4c94 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -272,6 +272,13 @@ Emitted when the GraphNode is requested to be resized. Happens on dragging the resizer handle (see [member resizable]). </description> </signal> + <signal name="slot_updated"> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Emitted when any GraphNode's slot is updated. + </description> + </signal> </signals> <constants> <constant name="OVERLAY_DISABLED" value="0" enum="Overlay"> diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index b6594aac39..9ff682f79d 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -175,7 +175,7 @@ var result = new HTTPClient().Request(HTTPClient.Method.Post, "index.php", headers, queryString); [/csharp] [/codeblocks] - [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example. + [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.uri_encode] for an example. </description> </method> <method name="request_raw"> diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index f2ab93033a..a65f66c72a 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -203,7 +203,7 @@ <description> Creates request on the underlying [HTTPClient]. If there is no configuration errors, it tries to connect using [method HTTPClient.connect_to_host] and passes parameters onto [method HTTPClient.request]. Returns [constant OK] if request is successfully created. (Does not imply that the server has responded), [constant ERR_UNCONFIGURED] if not in the tree, [constant ERR_BUSY] if still processing previous request, [constant ERR_INVALID_PARAMETER] if given string is not a valid URL format, or [constant ERR_CANT_CONNECT] if not using thread and the [HTTPClient] cannot connect to host. - [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example. + [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.uri_encode] for an example. </description> </method> <method name="request_raw"> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 3dba5d13aa..bad8127c03 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -12,6 +12,18 @@ <link title="Importing images">https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_images.html</link> </tutorials> <methods> + <method name="adjust_bcs"> + <return type="void"> + </return> + <argument index="0" name="brightness" type="float"> + </argument> + <argument index="1" name="contrast" type="float"> + </argument> + <argument index="2" name="saturation" type="float"> + </argument> + <description> + </description> + </method> <method name="blend_rect"> <return type="void"> </return> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index cfb3e8d981..1f872db6c6 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -59,6 +59,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns a value between 0 and 1 representing the raw intensity of the given action, ignoring the action's deadzone. In most cases, you should use [method get_action_strength] instead. </description> @@ -68,6 +70,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns a value between 0 and 1 representing the intensity of the given action. In a joypad, for example, the further away the axis (analog sticks or L2, R2 triggers) is from the dead zone, the closer the value will be to 1. If the action is mapped to a control that has no axis as the keyboard, the value returned will be 0 or 1. </description> @@ -214,6 +218,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] when the user starts pressing the action event, meaning it's [code]true[/code] only on the frame that the user pressed down the button. This is useful for code that needs to run only once when an action is pressed, instead of every frame while it's pressed. @@ -224,6 +230,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] when the user stops pressing the action event, meaning it's [code]true[/code] only on the frame that the user released the button. </description> @@ -233,6 +241,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] if you are pressing the action event. Note that if an action has multiple buttons assigned and more than one of them is pressed, releasing one button will release the action, even if some other button assigned to this action is still pressed. </description> diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml index 8c6063bd67..28c4773f51 100644 --- a/doc/classes/InputEvent.xml +++ b/doc/classes/InputEvent.xml @@ -35,6 +35,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns a value between 0.0 and 1.0 depending on the given actions' state. Useful for getting the value of events of type [InputEventJoypadMotion]. </description> @@ -44,6 +46,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] if this input event matches a pre-defined action of any type. </description> @@ -55,6 +59,8 @@ </argument> <argument index="1" name="allow_echo" type="bool" default="false"> </argument> + <argument index="2" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] if the given action is being pressed (and is not an echo event for [InputEventKey] events, unless [code]allow_echo[/code] is [code]true[/code]). Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag]. </description> @@ -64,6 +70,8 @@ </return> <argument index="0" name="action" type="StringName"> </argument> + <argument index="1" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] if the given action is released (i.e. not pressed). Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag]. </description> diff --git a/doc/classes/InputMap.xml b/doc/classes/InputMap.xml index 49d29b3a53..0fb18d8e81 100644 --- a/doc/classes/InputMap.xml +++ b/doc/classes/InputMap.xml @@ -100,6 +100,8 @@ </argument> <argument index="1" name="action" type="StringName"> </argument> + <argument index="2" name="exact_match" type="bool" default="false"> + </argument> <description> Returns [code]true[/code] if the given event is part of an existing action. This method ignores keyboard modifiers if the given [InputEvent] is not pressed (for proper release detection). See [method action_has_event] if you don't want this behavior. </description> diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 6e5ff83a35..ffeb45907d 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -12,18 +12,18 @@ </tutorials> <methods> <method name="add_icon_item"> - <return type="void"> + <return type="int"> </return> <argument index="0" name="icon" type="Texture2D"> </argument> <argument index="1" name="selectable" type="bool" default="true"> </argument> <description> - Adds an item to the item list with no text, only an icon. + Adds an item to the item list with no text, only an icon. Returns the index of an added item. </description> </method> <method name="add_item"> - <return type="void"> + <return type="int"> </return> <argument index="0" name="text" type="String"> </argument> @@ -32,7 +32,8 @@ <argument index="2" name="selectable" type="bool" default="true"> </argument> <description> - Adds an item to the item list with specified text. Specify an [code]icon[/code], or use [code]null[/code] as the [code]icon[/code] for a list item with no icon. + Adds an item to the item list with specified text. Returns the index of an added item. + Specify an [code]icon[/code], or use [code]null[/code] as the [code]icon[/code] for a list item with no icon. If selectable is [code]true[/code], the list item will be selectable. </description> </method> @@ -614,7 +615,10 @@ <theme_item name="font_color" type="Color" default="Color( 0.63, 0.63, 0.63, 1 )"> Default text [Color] of the item. </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the item. + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 1, 1, 1, 1 )"> Text [Color] used when the item is selected. </theme_item> <theme_item name="font_size" type="int"> @@ -632,6 +636,9 @@ <theme_item name="line_separation" type="int" default="2"> The vertical spacing between each line of text. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the item text outline. + </theme_item> <theme_item name="selected" type="StyleBox"> [StyleBox] for the selected items, used when the [ItemList] is not being focused. </theme_item> diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index 1edf31de4a..8574ff9836 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -150,12 +150,12 @@ <theme_item name="font_color" type="Color" default="Color( 1, 1, 1, 1 )"> Default text [Color] of the [Label]. </theme_item> - <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 0 )"> - [Color] of the text's shadow effect. - </theme_item> - <theme_item name="font_outline_modulate" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> The tint of [Font]'s outline. </theme_item> + <theme_item name="font_shadow_color" type="Color" default="Color( 0, 0, 0, 0 )"> + [Color] of the text's shadow effect. + </theme_item> <theme_item name="font_size" type="int"> Font size of the [Label]'s text. </theme_item> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 6c008e4f7e..111473e098 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -78,7 +78,7 @@ <member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false"> If [code]true[/code], the light will cast shadows. </member> - <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="1.0"> + <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="0.1"> </member> <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="2.0"> Offsets the lookup into the shadow map by the object's normal. This can be used to reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible. diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index f05121d48c..360f5c451e 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -380,21 +380,27 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Default font color. </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> - Font color for selected text (inside the selection rectangle). + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [LineEdit]. </theme_item> - <theme_item name="font_color_uneditable" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> - Font color when editing is disabled. + <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )"> + Font color for selected text (inside the selection rectangle). </theme_item> <theme_item name="font_size" type="int"> Font size of the [LineEdit]'s text. </theme_item> - <theme_item name="minimum_spaces" type="int" default="12"> - Minimum horizontal space for the text (not counting the clear button and content margins). This value is measured in count of space characters (i.e. this amount of space characters can be displayed without scrolling). + <theme_item name="font_uneditable_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> + Font color when editing is disabled. + </theme_item> + <theme_item name="minimum_character_width" type="int" default="4"> + Minimum horizontal space for the text (not counting the clear button and content margins). This value is measured in count of 'M' characters (i.e. this amount of 'M' characters can be displayed without scrolling). </theme_item> <theme_item name="normal" type="StyleBox"> Default background for the [LineEdit]. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="read_only" type="StyleBox"> Background used when [LineEdit] is in read-only mode ([member editable] is set to [code]false[/code]). </theme_item> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index 93384843de..6e2f4399b3 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -81,15 +81,21 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Default text [Color] of the [LinkButton]. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> Text [Color] used when the [LinkButton] is being hovered. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [LinkButton]. + </theme_item> + <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> Text [Color] used when the [LinkButton] is being pressed. </theme_item> <theme_item name="font_size" type="int"> Font size of the [LinkButton]'s text. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="underline_spacing" type="int" default="2"> The vertical space between the baseline of text and the underline. </theme_item> diff --git a/doc/classes/Material.xml b/doc/classes/Material.xml index 10a7061bef..0d287a5d1d 100644 --- a/doc/classes/Material.xml +++ b/doc/classes/Material.xml @@ -11,6 +11,12 @@ <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> </tutorials> <methods> + <method name="inspect_native_shader_code"> + <return type="void"> + </return> + <description> + </description> + </method> </methods> <members> <member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass"> diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index a002ce636b..481b737eee 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -59,13 +59,16 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Default text [Color] of the [MenuButton]. </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 1, 1, 1, 0.3 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 1, 1, 1, 0.3 )"> Text [Color] used when the [MenuButton] is disabled. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> Text [Color] used when the [MenuButton] is being hovered. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [MenuButton]. + </theme_item> + <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> Text [Color] used when the [MenuButton] is being pressed. </theme_item> <theme_item name="font_size" type="int"> @@ -80,6 +83,9 @@ <theme_item name="normal" type="StyleBox"> Default [StyleBox] for the [MenuButton]. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="pressed" type="StyleBox"> [StyleBox] used when the [MenuButton] is being pressed. </theme_item> diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index fcc259fb44..c168695d61 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -4,9 +4,10 @@ High-level multiplayer API. </brief_description> <description> - This class implements most of the logic behind the high-level multiplayer API. + This class implements most of the logic behind the high-level multiplayer API. See also [NetworkedMultiplayerPeer]. By default, [SceneTree] has a reference to this class that is used to provide multiplayer capabilities (i.e. RPC/RSET) across the whole scene. It is possible to override the MultiplayerAPI instance used by specific Nodes by setting the [member Node.custom_multiplayer] property, effectively allowing to run both client and server in the same scene. + [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. </description> <tutorials> </tutorials> diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml index 954d31794a..06ea46f023 100644 --- a/doc/classes/NetworkedMultiplayerPeer.xml +++ b/doc/classes/NetworkedMultiplayerPeer.xml @@ -4,7 +4,8 @@ A high-level network interface to simplify multiplayer interactions. </brief_description> <description> - Manages the connection to network peers. Assigns unique IDs to each client connected to the server. + Manages the connection to network peers. Assigns unique IDs to each client connected to the server. See also [MultiplayerAPI]. + [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. </description> <tutorials> <link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index e8913f2623..7ee6860dfc 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -179,7 +179,7 @@ <return type="bool"> </return> <description> - Returns [code]true[/code] if the node can process while the scene tree is paused (see [member pause_mode]). Always returns [code]true[/code] if the scene tree is not paused, and [code]false[/code] if the node is not in the tree. + Returns [code]true[/code] if the node can process while the scene tree is paused (see [member process_mode]). Always returns [code]true[/code] if the scene tree is not paused, and [code]false[/code] if the node is not in the tree. </description> </method> <method name="duplicate" qualifiers="const"> @@ -245,6 +245,12 @@ Returns an array of references to node's children. </description> </method> + <method name="get_editor_description" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> <method name="get_groups" qualifiers="const"> <return type="Array"> </return> @@ -623,10 +629,11 @@ </return> <argument index="0" name="node" type="Node"> </argument> - <argument index="1" name="keep_data" type="bool" default="false"> + <argument index="1" name="keep_groups" type="bool" default="false"> </argument> <description> Replaces a node in a scene by the given one. Subscriptions that pass through this node will be lost. + If [code]keep_groups[/code] is [code]true[/code], the [code]node[/code] is added to the same groups that the replaced node is in. </description> </method> <method name="request_ready"> @@ -756,6 +763,14 @@ Sets the folded state of the node in the Scene dock. </description> </method> + <method name="set_editor_description"> + <return type="void"> + </return> + <argument index="0" name="editor_description" type="String"> + </argument> + <description> + </description> + </method> <method name="set_network_master"> <return type="void"> </return> @@ -867,8 +882,8 @@ <member name="owner" type="Node" setter="set_owner" getter="get_owner"> The node owner. A node can have any other node as owner (as long as it is a valid parent, grandparent, etc. ascending in the tree). When saving a node (using [PackedScene]), all the nodes it owns will be saved with it. This allows for the creation of complex [SceneTree]s, with instancing and subinstancing. </member> - <member name="pause_mode" type="int" setter="set_pause_mode" getter="get_pause_mode" enum="Node.PauseMode" default="0"> - Pause mode. How the node will behave if the [SceneTree] is paused. + <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Node.ProcessMode" default="0"> + Can be used to pause or unpause the node, or make the node paused based on the [SceneTree], or make it inherit the process mode from its parent (default). </member> <member name="process_priority" type="int" setter="set_process_priority" getter="get_process_priority" default="0"> The node's priority in the execution order of the enabled processing callbacks (i.e. [constant NOTIFICATION_PROCESS], [constant NOTIFICATION_PHYSICS_PROCESS] and their internal counterparts). Nodes whose process priority value is [i]lower[/i] will have their processing callbacks executed first. @@ -1016,14 +1031,20 @@ <constant name="NOTIFICATION_TEXT_SERVER_CHANGED" value="2018"> Notification received when text server is changed. </constant> - <constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode"> - Inherits pause mode from the node's parent. For the root node, it is equivalent to [constant PAUSE_MODE_STOP]. Default. + <constant name="PROCESS_MODE_INHERIT" value="0" enum="ProcessMode"> + Inherits process mode from the node's parent. For the root node, it is equivalent to [constant PROCESS_MODE_PAUSABLE]. Default. + </constant> + <constant name="PROCESS_MODE_PAUSABLE" value="1" enum="ProcessMode"> + Stops processing when the [SceneTree] is paused (process when unpaused). This is the inverse of [constant PROCESS_MODE_WHEN_PAUSED]. + </constant> + <constant name="PROCESS_MODE_WHEN_PAUSED" value="2" enum="ProcessMode"> + Only process when the [SceneTree] is paused (don't process when unpaused). This is the inverse of [constant PROCESS_MODE_PAUSABLE]. </constant> - <constant name="PAUSE_MODE_STOP" value="1" enum="PauseMode"> - Stops processing when the [SceneTree] is paused. + <constant name="PROCESS_MODE_ALWAYS" value="3" enum="ProcessMode"> + Always process. Continue processing always, ignoring the [SceneTree]'s paused property. This is the inverse of [constant PROCESS_MODE_DISABLED]. </constant> - <constant name="PAUSE_MODE_PROCESS" value="2" enum="PauseMode"> - Continue to process regardless of the [SceneTree] pause state. + <constant name="PROCESS_MODE_DISABLED" value="4" enum="ProcessMode"> + Never process. Completely disables processing, ignoring the [SceneTree]'s paused property. This is the inverse of [constant PROCESS_MODE_ALWAYS]. </constant> <constant name="DUPLICATE_SIGNALS" value="1" enum="DuplicateFlags"> Duplicate the node's signals. diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index fe3a9c5d39..5c29c0d48f 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -103,7 +103,7 @@ </return> <argument index="0" name="target" type="Vector3"> </argument> - <argument index="1" name="up" type="Vector3"> + <argument index="1" name="up" type="Vector3" default="Vector3( 0, 1, 0 )"> </argument> <description> Rotates itself so that the local -Z axis points towards the [code]target[/code] position. @@ -118,7 +118,7 @@ </argument> <argument index="1" name="target" type="Vector3"> </argument> - <argument index="2" name="up" type="Vector3"> + <argument index="2" name="up" type="Vector3" default="Vector3( 0, 1, 0 )"> </argument> <description> Moves the node to the specified [code]position[/code], and then rotates itself to point toward the [code]target[/code] as per [method look_at]. Operations take place in global space. @@ -229,7 +229,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Sets whether the node notifies about its global and local transformation changes. [Node3D] will not propagate this by default. + Sets whether the node notifies about its global and local transformation changes. [Node3D] will not propagate this by default, unless it is in the editor context and it has a valid gizmo. </description> </method> <method name="show"> @@ -324,7 +324,7 @@ <constants> <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="2000"> Node3D nodes receives this notification when their global transform changes. This means that either the current or a parent node changed its transform. - In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. + In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. The notification is also sent if the node is in the editor context and it has a valid gizmo. </constant> <constant name="NOTIFICATION_ENTER_WORLD" value="41"> Node3D nodes receives this notification when they are registered to new [World3D] resource. diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 65a815a603..057a2b8d1a 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -25,13 +25,36 @@ [b]Note:[/b] This method is implemented on Linux, macOS and Windows. </description> </method> + <method name="create_process"> + <return type="int"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <argument index="1" name="arguments" type="PackedStringArray"> + </argument> + <description> + Creates a new process that runs independently of Godot. It will not terminate if Godot terminates. The file specified in [code]path[/code] must exist and be executable. Platform path resolution will be used. The [code]arguments[/code] are used in the given order and separated by a space. + If the process creation succeeds, the method will return the new process ID, which you can use to monitor the process (and potentially terminate it with [method kill]). If the process creation fails, the method will return [code]-1[/code]. + For example, running another instance of the project: + [codeblocks] + [gdscript] + var pid = OS.create_process(OS.get_executable_path(), []) + [/gdscript] + [csharp] + var pid = OS.CreateProcess(OS.GetExecutablePath(), new string[] {}); + [/csharp] + [/codeblocks] + See [method execute] if you wish to run an external command and retrieve the results. + [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows. + </description> + </method> <method name="delay_msec" qualifiers="const"> <return type="void"> </return> <argument index="0" name="msec" type="int"> </argument> <description> - Delay execution of the current thread by [code]msec[/code] milliseconds. + Delay execution of the current thread by [code]msec[/code] milliseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_msec] will do nothing and will print an error message. </description> </method> <method name="delay_usec" qualifiers="const"> @@ -40,7 +63,7 @@ <argument index="0" name="usec" type="int"> </argument> <description> - Delay execution of the current thread by [code]usec[/code] microseconds. + Delay execution of the current thread by [code]usec[/code] microseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_usec] will do nothing and will print an error message. </description> </method> <method name="dump_memory_to_file"> @@ -71,48 +94,34 @@ </argument> <argument index="1" name="arguments" type="PackedStringArray"> </argument> - <argument index="2" name="blocking" type="bool" default="true"> - </argument> - <argument index="3" name="output" type="Array" default="[ ]"> + <argument index="2" name="output" type="Array" default="[ ]"> </argument> - <argument index="4" name="read_stderr" type="bool" default="false"> + <argument index="3" name="read_stderr" type="bool" default="false"> </argument> <description> - Execute the file at the given path with the arguments passed as an array of strings. Platform path resolution will take place. The resolved file must exist and be executable. - The arguments are used in the given order and separated by a space, so [code]OS.execute("ping", ["-w", "3", "godotengine.org"], false)[/code] will resolve to [code]ping -w 3 godotengine.org[/code] in the system's shell. - This method has slightly different behavior based on whether the [code]blocking[/code] mode is enabled. - If [code]blocking[/code] is [code]true[/code], the Godot thread will pause its execution while waiting for the process to terminate. The shell output of the process will be written to the [code]output[/code] array as a single string. When the process terminates, the Godot thread will resume execution. - If [code]blocking[/code] is [code]false[/code], the Godot thread will continue while the new process runs. It is not possible to retrieve the shell output in non-blocking mode, so [code]output[/code] will be empty. - The return value also depends on the blocking mode. When blocking, the method will return an exit code of the process. When non-blocking, the method returns a process ID, which you can use to monitor the process (and potentially terminate it with [method kill]). If the process forking (non-blocking) or opening (blocking) fails, the method will return [code]-1[/code] or another exit code. - Example of blocking mode and retrieving the shell output: + Executes a command. The file specified in [code]path[/code] must exist and be executable. Platform path resolution will be used. The [code]arguments[/code] are used in the given order and separated by a space. If an [code]output[/code] [Array] is provided, the complete shell output of the process will be appended as a single [String] element in [code]output[/code]. If [code]read_stderr[/code] is [code]true[/code], the output to the standard error stream will be included too. + If the command is successfully executed, the method will return the exit code of the command, or [code]-1[/code] if it fails. + [b]Note:[/b] The Godot thread will pause its execution until the executed command terminates. Use [Thread] to create a separate thread that will not pause the Godot thread, or use [method create_process] to create a completely independent process. + For example, to retrieve a list of the working directory's contents: [codeblocks] [gdscript] var output = [] - var exit_code = OS.execute("ls", ["-l", "/tmp"], true, output) + var exit_code = OS.execute("ls", ["-l", "/tmp"], output) [/gdscript] [csharp] var output = new Godot.Collections.Array(); - int exitCode = OS.Execute("ls", new string[] {"-l", "/tmp"}, true, output); - [/csharp] - [/codeblocks] - Example of non-blocking mode, running another instance of the project and storing its process ID: - [codeblocks] - [gdscript] - var pid = OS.execute(OS.get_executable_path(), [], false) - [/gdscript] - [csharp] - var pid = OS.Execute(OS.GetExecutablePath(), new string[] {}, false); + int exitCode = OS.Execute("ls", new string[] {"-l", "/tmp"}, output); [/csharp] [/codeblocks] - If you wish to access a shell built-in or perform a composite command, a platform-specific shell can be invoked. For example: + To execute a composite command, a platform-specific shell can be invoked. For example: [codeblocks] [gdscript] var output = [] - OS.execute("CMD.exe", ["/C", "cd %TEMP% && dir"], true, output) + OS.execute("CMD.exe", ["/C", "cd %TEMP% && dir"], output) [/gdscript] [csharp] var output = new Godot.Collections.Array(); - OS.Execute("CMD.exe", new string[] {"/C", "cd %TEMP% && dir"}, true, output); + OS.Execute("CMD.exe", new string[] {"/C", "cd %TEMP% && dir"}, output); [/csharp] [/codeblocks] [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows. @@ -198,10 +207,11 @@ <method name="get_environment" qualifiers="const"> <return type="String"> </return> - <argument index="0" name="environment" type="String"> + <argument index="0" name="variable" type="String"> </argument> <description> - Returns an environment variable. + Returns the value of an environment variable. Returns an empty string if the environment variable doesn't exist. + [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows. </description> </method> <method name="get_executable_path" qualifiers="const"> @@ -295,22 +305,12 @@ [b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows. </description> </method> - <method name="get_tablet_driver_count" qualifiers="const"> + <method name="get_thread_caller_id" qualifiers="const"> <return type="int"> </return> <description> - Returns the total number of available tablet drivers. - [b]Note:[/b] This method is implemented on Windows. - </description> - </method> - <method name="get_tablet_driver_name" qualifiers="const"> - <return type="String"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the tablet driver name for the given index. - [b]Note:[/b] This method is implemented on Windows. + Returns the ID of the current thread. This can be used in logs to ease debugging of multi-threaded applications. + [b]Note:[/b] Thread IDs are not deterministic and may be reused across application restarts. </description> </method> <method name="get_ticks_msec" qualifiers="const"> @@ -384,10 +384,11 @@ <method name="has_environment" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="environment" type="String"> + <argument index="0" name="variable" type="String"> </argument> <description> - Returns [code]true[/code] if an environment variable exists. + Returns [code]true[/code] if the environment variable with the name [code]variable[/code] exists. + [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows. </description> </method> <method name="has_feature" qualifiers="const"> @@ -502,6 +503,18 @@ [b]Note:[/b] This method is implemented on Android. </description> </method> + <method name="set_environment" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="variable" type="String"> + </argument> + <argument index="1" name="value" type="String"> + </argument> + <description> + Sets the value of the environment variable [code]variable[/code] to [code]value[/code]. The environment variable will be set for the Godot process and any process executed with [method execute] after running [method set_environment]. The environment variable will [i]not[/i] persist to processes run after the Godot process was terminated. + [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows. + </description> + </method> <method name="set_thread_name"> <return type="int" enum="Error"> </return> @@ -536,19 +549,12 @@ </method> </methods> <members> - <member name="exit_code" type="int" setter="set_exit_code" getter="get_exit_code" default="0"> - The exit code passed to the OS when the main loop exits. By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error. For portability reasons, the exit code should be set between 0 and 125 (inclusive). - [b]Note:[/b] This value will be ignored if using [method SceneTree.quit] with an [code]exit_code[/code] argument passed. - </member> <member name="low_processor_usage_mode" type="bool" setter="set_low_processor_usage_mode" getter="is_in_low_processor_usage_mode" default="false"> If [code]true[/code], the engine optimizes for low processor usage by only refreshing the screen if needed. Can improve battery consumption on mobile. </member> <member name="low_processor_usage_mode_sleep_usec" type="int" setter="set_low_processor_usage_mode_sleep_usec" getter="get_low_processor_usage_mode_sleep_usec" default="6900"> The amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU usage. </member> - <member name="tablet_driver" type="String" setter="set_current_tablet_driver" getter="get_current_tablet_driver" default=""""> - The current tablet driver in use. - </member> </members> <constants> <constant name="VIDEO_DRIVER_GLES2" value="0" enum="VideoDriver"> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 6ff7e34194..ad3ce8e93e 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -10,11 +10,20 @@ Some classes that extend Object add memory management. This is the case of [Reference], which counts references and deletes itself automatically when no longer referenced. [Node], another fundamental type, deletes all its children when freed from memory. Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them. Property membership can be tested directly in GDScript using [code]in[/code]: - [codeblock] + [codeblocks] + [gdscript] var n = Node2D.new() print("position" in n) # Prints "True". print("other_property" in n) # Prints "False". - [/codeblock] + [/gdscript] + [csharp] + var node = new Node2D(); + // C# has no direct equivalent to GDScript's `in` operator here, but we + // can achieve the same behavior by performing `Get` with a null check. + GD.Print(node.Get("position") != null); // Prints "True". + GD.Print(node.Get("other_property") != null); // Prints "False". + [/csharp] + [/codeblocks] The [code]in[/code] operator will evaluate to [code]true[/code] as long as the key exists, even if the value is [code]null[/code]. Objects also receive notifications. Notifications are a simple way to notify the object about different events, so they can all be handled together. See [method _notification]. [b]Note:[/b] Unlike references to a [Reference], references to an Object stored in a variable can become invalid without warning. Therefore, it's recommended to use [Reference] for data classes instead of [Object]. @@ -96,9 +105,16 @@ </argument> <description> Calls the [code]method[/code] on the object and returns the result. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example: - [codeblock] - call("set", "position", Vector2(42.0, 0.0)) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.call("set", "position", Vector2(42, 0)) + [/gdscript] + [csharp] + var node = new Node2D(); + node.Call("set", "position", new Vector2(42, 0)); + [/csharp] + [/codeblocks] [b]Note:[/b] In C#, the method name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined methods where you should use the same convention as in the C# source (typically PascalCase). </description> </method> @@ -109,9 +125,16 @@ </argument> <description> Calls the [code]method[/code] on the object during idle time. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example: - [codeblock] - call_deferred("set", "position", Vector2(42.0, 0.0)) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.call_deferred("set", "position", Vector2(42, 0)) + [/gdscript] + [csharp] + var node = new Node2D(); + node.CallDeferred("set", "position", new Vector2(42, 0)); + [/csharp] + [/codeblocks] [b]Note:[/b] In C#, the method name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined methods where you should use the same convention as in the C# source (typically PascalCase). </description> </method> @@ -124,9 +147,16 @@ </argument> <description> Calls the [code]method[/code] on the object and returns the result. Contrarily to [method call], this method does not support a variable number of arguments but expects all parameters to be via a single [Array]. - [codeblock] - callv("set", [ "position", Vector2(42.0, 0.0) ]) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.callv("set", ["position", Vector2(42, 0)]) + [/gdscript] + [csharp] + var node = new Node2D(); + node.Callv("set", new Godot.Collections.Array { "position", new Vector2(42, 0) }); + [/csharp] + [/codeblocks] </description> </method> <method name="can_translate_messages" qualifiers="const"> @@ -148,23 +178,140 @@ <argument index="3" name="flags" type="int" default="0"> </argument> <description> - [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated. - Connects a [code]signal[/code] to a [code]method[/code] on a [code]target[/code] object. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. - A [code]signal[/code] can only be connected once to a [code]method[/code]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. - If the [code]target[/code] is destroyed in the game's lifecycle, the connection will be lost. - Examples: - [codeblock] - connect("pressed", self, "_on_Button_pressed") # BaseButton signal - connect("text_entered", self, "_on_LineEdit_text_entered") # LineEdit signal - connect("hit", self, "_on_Player_hit", [ weapon_type, damage ]) # User-defined signal - [/codeblock] - An example of the relationship between [code]binds[/code] passed to [method connect] and parameters used when calling [method emit_signal]: - [codeblock] - connect("hit", self, "_on_Player_hit", [ weapon_type, damage ]) # weapon_type and damage are passed last - emit_signal("hit", "Dark lord", 5) # "Dark lord" and 5 are passed first - func _on_Player_hit(hit_by, level, weapon_type, damage): - print("Hit by %s (lvl %d) with weapon %s for %d damage" % [hit_by, level, weapon_type, damage]) - [/codeblock] + Connects a [code]signal[/code] to a [code]callable[/code]. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the [Callable]'s method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. + [b]Note:[/b] This method is the legacy implementation for connecting signals. The recommend modern approach is to use [method Signal.connect] and to use [method Callable.bind] to add and validate parameter binds. Both syntaxes are shown below. + A signal can only be connected once to a [Callable]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. + If the callable's target is destroyed in the game's lifecycle, the connection will be lost. + [b]Examples with recommended syntax:[/b] + Connecting signals is one of the most common operations in Godot and the API gives many options to do so, which are described further down. The code block below shows the recommended approach for both GDScript and C#. + [codeblocks] + [gdscript] + func _ready(): + var button = Button.new() + # `button_down` here is a Signal object, and we thus call the Signal.connect() method, + # not Object.connect(). See discussion below for a more in-depth overview of the API. + button.button_down.connect(_on_button_down) + + # This assumes that a `Player` class exists which defines a `hit` signal. + var player = Player.new() + # We use Signal.connect() again, and we also use the Callable.bind() method which + # returns a new Callable with the parameter binds. + player.hit.connect(_on_player_hit.bind("sword", 100)) + + func _on_button_down(): + print("Button down!") + + func _on_player_hit(weapon_type, damage): + print("Hit with weapon %s for %d damage." % [weapon_type, damage]) + [/gdscript] + [csharp] + public override void _Ready() + { + var button = new Button(); + // C# supports passing signals as events, so we can use this idiomatic construct: + button.ButtonDown += OnButtonDown; + + // This assumes that a `Player` class exists which defines a `Hit` signal. + var player = new Player(); + // Signals as events (`player.Hit += OnPlayerHit;`) do not support argument binding. You have to use: + player.Hit.Connect(OnPlayerHit, new Godot.Collections.Array {"sword", 100 }); + } + + private void OnButtonDown() + { + GD.Print("Button down!"); + } + + private void OnPlayerHit(string weaponType, int damage) + { + GD.Print(String.Format("Hit with weapon {0} for {1} damage.", weaponType, damage)); + } + [/csharp] + [/codeblocks] + [b][code]Object.connect()[/code] or [code]Signal.connect()[/code]?[/b] + As seen above, the recommended method to connect signals is not [method Object.connect]. The code block below shows the four options for connecting signals, using either this legacy method or the recommended [method Signal.connect], and using either an implicit [Callable] or a manually defined one. + [codeblocks] + [gdscript] + func _ready(): + var button = Button.new() + # Option 1: Object.connect() with an implicit Callable for the defined function. + button.connect("button_down", _on_button_down) + # Option 2: Object.connect() with a constructed Callable using a target object and method name. + button.connect("button_down", Callable(self, "_on_button_down")) + # Option 3: Signal.connect() with an implicit Callable for the defined function. + button.button_down.connect(_on_button_down) + # Option 4: Signal.connect() with a constructed Callable using a target object and method name. + button.button_down.connect(Callable(self, "_on_button_down")) + + func _on_button_down(): + print("Button down!") + [/gdscript] + [csharp] + public override void _Ready() + { + var button = new Button(); + // Option 1: Object.Connect() with an implicit Callable for the defined function. + button.Connect("button_down", OnButtonDown); + // Option 2: Object.connect() with a constructed Callable using a target object and method name. + button.Connect("button_down", new Callable(self, nameof(OnButtonDown))); + // Option 3: Signal.connect() with an implicit Callable for the defined function. + button.ButtonDown.Connect(OnButtonDown); + // Option 3b: In C#, we can use signals as events and connect with this more idiomatic syntax: + button.ButtonDown += OnButtonDown; + // Option 4: Signal.connect() with a constructed Callable using a target object and method name. + button.ButtonDown.Connect(new Callable(self, nameof(OnButtonDown))); + } + + private void OnButtonDown() + { + GD.Print("Button down!"); + } + [/csharp] + [/codeblocks] + While all options have the same outcome ([code]button[/code]'s [signal BaseButton.button_down] signal will be connected to [code]_on_button_down[/code]), option 3 offers the best validation: it will throw a compile-time error if either the [code]button_down[/code] signal or the [code]_on_button_down[/code] callable are undefined. On the other hand, option 2 only relies on string names and will only be able to validate either names at runtime: it will throw a runtime error if [code]"button_down"[/code] doesn't correspond to a signal, or if [code]"_on_button_down"[/code] is not a registered method in the object [code]self[/code]. The main reason for using options 1, 2, or 4 would be if you actually need to use strings (e.g. to connect signals programmatically based on strings read from a configuration file). Otherwise, option 3 is the recommended (and fastest) method. + [b]Parameter bindings and passing:[/b] + For legacy or language-specific reasons, there are also several ways to bind parameters to signals. One can pass a [code]binds[/code] [Array] to [method Object.connect] or [method Signal.connect], or use the recommended [method Callable.bind] method to create a new callable from an existing one, with the given parameter binds. + One can also pass additional parameters when emitting the signal with [method emit_signal]. The examples below show the relationship between those two types of parameters. + [codeblocks] + [gdscript] + func _ready(): + # This assumes that a `Player` class exists which defines a `hit` signal. + var player = Player.new() + # Option 1: Using Callable.bind(). + player.hit.connect(_on_player_hit.bind("sword", 100)) + # Option 2: Using a `binds` Array in Signal.connect() (same syntax for Object.connect()). + player.hit.connect(_on_player_hit, ["sword", 100]) + + # Parameters added when emitting the signal are passed first. + player.emit_signal("hit", "Dark lord", 5) + + # Four arguments, since we pass two when emitting (hit_by, level) + # and two when connecting (weapon_type, damage). + func _on_player_hit(hit_by, level, weapon_type, damage): + print("Hit by %s (level %d) with weapon %s for %d damage." % [hit_by, level, weapon_type, damage]) + [/gdscript] + [csharp] + public override void _Ready() + { + // This assumes that a `Player` class exists which defines a `Hit` signal. + var player = new Player(); + // Option 1: Using Callable.Bind(). This way we can still use signals as events. + player.Hit += OnPlayerHit.Bind("sword", 100); + // Option 2: Using a `binds` Array in Signal.Connect() (same syntax for Object.Connect()). + player.Hit.Connect(OnPlayerHit, new Godot.Collections.Array{ "sword", 100 }); + + // Parameters added when emitting the signal are passed first. + player.EmitSignal("hit", "Dark lord", 5); + } + + // Four arguments, since we pass two when emitting (hitBy, level) + // and two when connecting (weaponType, damage). + private void OnPlayerHit(string hitBy, int level, string weaponType, int damage) + { + GD.Print(String.Format("Hit by {0} (level {1}) with weapon {2} for {3} damage.", hitBy, level, weaponType, damage)); + } + [/csharp] + [/codeblocks] </description> </method> <method name="disconnect"> @@ -175,8 +322,7 @@ <argument index="1" name="callable" type="Callable"> </argument> <description> - [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated. - Disconnects a [code]signal[/code] from a [code]method[/code] on the given [code]target[/code]. + Disconnects a [code]signal[/code] from a given [code]callable[/code]. If you try to disconnect a connection that does not exist, the method will throw an error. Use [method is_connected] to ensure that the connection exists. </description> </method> @@ -187,10 +333,16 @@ </argument> <description> Emits the given [code]signal[/code]. The signal must exist, so it should be a built-in signal of this class or one of its parent classes, or a user-defined signal. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example: - [codeblock] - emit_signal("hit", weapon_type, damage) + [codeblocks] + [gdscript] + emit_signal("hit", "sword", 100) emit_signal("game_over") - [/codeblock] + [/gdscript] + [csharp] + EmitSignal("hit", "sword", 100); + EmitSignal("game_over"); + [/csharp] + [/codeblocks] </description> </method> <method name="free"> @@ -359,8 +511,7 @@ <argument index="1" name="callable" type="Callable"> </argument> <description> - [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated. - Returns [code]true[/code] if a connection exists for a given [code]signal[/code], [code]target[/code], and [code]method[/code]. + Returns [code]true[/code] if a connection exists for a given [code]signal[/code] and [code]callable[/code]. </description> </method> <method name="is_queued_for_deletion" qualifiers="const"> @@ -382,11 +533,11 @@ If [code]reversed[/code] is [code]true[/code], [method _notification] is called first on the object's own class, and then up to its successive parent classes. If [code]reversed[/code] is [code]false[/code], [method _notification] is called first on the highest ancestor ([Object] itself), and then down to its successive inheriting classes. </description> </method> - <method name="property_list_changed_notify"> + <method name="notify_property_list_changed"> <return type="void"> </return> <description> - Notify the editor that the property list has changed, so that editor plugins can take the new values into account. Does nothing on export builds. + Notify the editor that the property list has changed by emitting the [signal property_list_changed] signal, so that editor plugins can take the new values into account. </description> </method> <method name="remove_meta"> @@ -440,11 +591,20 @@ </argument> <description> Assigns a new value to the property identified by the [NodePath]. The node path should be relative to the current object and can use the colon character ([code]:[/code]) to access nested properties. Example: - [codeblock] - set_indexed("position", Vector2(42, 0)) - set_indexed("position:y", -10) - print(position) # (42, -10) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.set_indexed("position", Vector2(42, 0)) + node.set_indexed("position:y", -10) + print(node.position) # (42, -10) + [/gdscript] + [csharp] + var node = new Node2D(); + node.SetIndexed("position", new Vector2(42, 0)); + node.SetIndexed("position:y", -10); + GD.Print(node.Position); // (42, -10) + [/csharp] + [/codeblocks] </description> </method> <method name="set_message_translation"> @@ -520,6 +680,10 @@ </method> </methods> <signals> + <signal name="property_list_changed"> + <description> + </description> + </signal> <signal name="script_changed"> <description> Emitted whenever the object's script is changed. diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index 53309bae96..52da08c02f 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -253,13 +253,16 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Default text [Color] of the [OptionButton]. </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> Text [Color] used when the [OptionButton] is disabled. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> Text [Color] used when the [OptionButton] is being hovered. </theme_item> - <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [OptionButton]. + </theme_item> + <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )"> Text [Color] used when the [OptionButton] is being pressed. </theme_item> <theme_item name="font_size" type="int"> @@ -280,6 +283,9 @@ <theme_item name="normal_mirrored" type="StyleBox"> Default [StyleBox] for the [OptionButton] (for right-to-left layouts). </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="pressed" type="StyleBox"> [StyleBox] used when the [OptionButton] is being pressed (for left-to-right layouts). </theme_item> diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index d15bcfd114..1d9be7f165 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -5,7 +5,7 @@ </brief_description> <description> A simplified interface to a scene file. Provides access to operations and checks that can be performed on the scene resource itself. - Can be used to save a node to a file. When saving, the node as well as all the node it owns get saved (see [code]owner[/code] property on [Node]). + Can be used to save a node to a file. When saving, the node as well as all the nodes it owns get saved (see [code]owner[/code] property on [Node]). [b]Note:[/b] The node doesn't need to own itself. [b]Example of loading a saved scene:[/b] [codeblocks] diff --git a/doc/classes/PhysicsDirectSpaceState2D.xml b/doc/classes/PhysicsDirectSpaceState2D.xml index c26cf0514c..b6f95305ed 100644 --- a/doc/classes/PhysicsDirectSpaceState2D.xml +++ b/doc/classes/PhysicsDirectSpaceState2D.xml @@ -16,8 +16,9 @@ <argument index="0" name="shape" type="PhysicsShapeQueryParameters2D"> </argument> <description> - Checks how far the shape can travel toward a point. If the shape can not move, the array will be empty. - [b]Note:[/b] Both the shape and the motion are supplied through a [PhysicsShapeQueryParameters2D] object. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [code][1, 1][/code]. + Checks how far a [Shape2D] can move without colliding. All the parameters for the query, including the shape and the motion, are supplied through a [PhysicsShapeQueryParameters2D] object. + Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned. + [b]Note:[/b] Any [Shape2D]s that the shape is already colliding with e.g. inside of, will be ignored. Use [method collide_shape] to determine the [Shape2D]s that the shape is already colliding with. </description> </method> <method name="collide_shape"> diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml index 789e8cc731..243d071c56 100644 --- a/doc/classes/PhysicsDirectSpaceState3D.xml +++ b/doc/classes/PhysicsDirectSpaceState3D.xml @@ -18,8 +18,9 @@ <argument index="1" name="motion" type="Vector3"> </argument> <description> - Checks whether the shape can travel to a point. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [code][1, 1][/code]. - If the shape can not move, the returned array will be [code][0, 0][/code] under Bullet, and empty under GodotPhysics3D. + Checks how far a [Shape3D] can move without colliding. All the parameters for the query, including the shape, are supplied through a [PhysicsShapeQueryParameters3D] object. + Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned. + [b]Note:[/b] Any [Shape3D]s that the shape is already colliding with e.g. inside of, will be ignored. Use [method collide_shape] to determine the [Shape3D]s that the shape is already colliding with. </description> </method> <method name="collide_shape"> diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 6a1508b0e3..1fa82adb7a 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -850,21 +850,6 @@ <description> </description> </method> - <method name="damped_spring_joint_create"> - <return type="RID"> - </return> - <argument index="0" name="anchor_a" type="Vector2"> - </argument> - <argument index="1" name="anchor_b" type="Vector2"> - </argument> - <argument index="2" name="body_a" type="RID"> - </argument> - <argument index="3" name="body_b" type="RID"> - </argument> - <description> - Creates a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself. - </description> - </method> <method name="damped_spring_joint_get_param" qualifiers="const"> <return type="float"> </return> @@ -907,21 +892,18 @@ Returns information about the current state of the 2D physics engine. See [enum ProcessInfo] for a list of available states. </description> </method> - <method name="groove_joint_create"> - <return type="RID"> + <method name="joint_clear"> + <return type="void"> </return> - <argument index="0" name="groove1_a" type="Vector2"> - </argument> - <argument index="1" name="groove2_a" type="Vector2"> - </argument> - <argument index="2" name="anchor_b" type="Vector2"> - </argument> - <argument index="3" name="body_a" type="RID"> - </argument> - <argument index="4" name="body_b" type="RID"> + <argument index="0" name="joint" type="RID"> </argument> <description> - Creates a groove joint between two bodies. If not specified, the bodies are assumed to be the joint itself. + </description> + </method> + <method name="joint_create"> + <return type="RID"> + </return> + <description> </description> </method> <method name="joint_get_param" qualifiers="const"> @@ -944,36 +926,71 @@ Returns a joint's type (see [enum JointType]). </description> </method> - <method name="joint_set_param"> + <method name="joint_make_damped_spring"> <return type="void"> </return> <argument index="0" name="joint" type="RID"> </argument> - <argument index="1" name="param" type="int" enum="PhysicsServer2D.JointParam"> + <argument index="1" name="anchor_a" type="Vector2"> </argument> - <argument index="2" name="value" type="float"> + <argument index="2" name="anchor_b" type="Vector2"> + </argument> + <argument index="3" name="body_a" type="RID"> + </argument> + <argument index="4" name="body_b" type="RID"> </argument> <description> - Sets a joint parameter. See [enum JointParam] for a list of available parameters. </description> </method> - <method name="line_shape_create"> - <return type="RID"> + <method name="joint_make_groove"> + <return type="void"> </return> + <argument index="0" name="joint" type="RID"> + </argument> + <argument index="1" name="groove1_a" type="Vector2"> + </argument> + <argument index="2" name="groove2_a" type="Vector2"> + </argument> + <argument index="3" name="anchor_b" type="Vector2"> + </argument> + <argument index="4" name="body_a" type="RID"> + </argument> + <argument index="5" name="body_b" type="RID"> + </argument> <description> </description> </method> - <method name="pin_joint_create"> - <return type="RID"> + <method name="joint_make_pin"> + <return type="void"> </return> - <argument index="0" name="anchor" type="Vector2"> + <argument index="0" name="joint" type="RID"> </argument> - <argument index="1" name="body_a" type="RID"> + <argument index="1" name="anchor" type="Vector2"> </argument> - <argument index="2" name="body_b" type="RID"> + <argument index="2" name="body_a" type="RID"> + </argument> + <argument index="3" name="body_b" type="RID"> </argument> <description> - Creates a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself. + </description> + </method> + <method name="joint_set_param"> + <return type="void"> + </return> + <argument index="0" name="joint" type="RID"> + </argument> + <argument index="1" name="param" type="int" enum="PhysicsServer2D.JointParam"> + </argument> + <argument index="2" name="value" type="float"> + </argument> + <description> + Sets a joint parameter. See [enum JointParam] for a list of available parameters. + </description> + </method> + <method name="line_shape_create"> + <return type="RID"> + </return> + <description> </description> </method> <method name="ray_shape_create"> @@ -1233,15 +1250,18 @@ <constant name="BODY_STATE_CAN_SLEEP" value="4" enum="BodyState"> Constant to set/get whether the body can sleep. </constant> - <constant name="JOINT_PIN" value="0" enum="JointType"> + <constant name="JOINT_TYPE_PIN" value="0" enum="JointType"> Constant to create pin joints. </constant> - <constant name="JOINT_GROOVE" value="1" enum="JointType"> + <constant name="JOINT_TYPE_GROOVE" value="1" enum="JointType"> Constant to create groove joints. </constant> - <constant name="JOINT_DAMPED_SPRING" value="2" enum="JointType"> + <constant name="JOINT_TYPE_DAMPED_SPRING" value="2" enum="JointType"> Constant to create damped spring joints. </constant> + <constant name="JOINT_TYPE_MAX" value="3" enum="JointType"> + Represents the size of the [enum JointType] enum. + </constant> <constant name="JOINT_PARAM_BIAS" value="0" enum="JointParam"> </constant> <constant name="JOINT_PARAM_MAX_BIAS" value="1" enum="JointParam"> diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index 5fd3ef5db2..9a7926e937 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -129,15 +129,6 @@ Returns the transform matrix for an area. </description> </method> - <method name="area_is_ray_pickable" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="area" type="RID"> - </argument> - <description> - If [code]true[/code], area collides with rays. - </description> - </method> <method name="area_remove_shape"> <return type="void"> </return> @@ -421,12 +412,7 @@ <method name="body_create"> <return type="RID"> </return> - <argument index="0" name="mode" type="int" enum="PhysicsServer3D.BodyMode" default="2"> - </argument> - <argument index="1" name="init_sleeping" type="bool" default="false"> - </argument> <description> - Creates a physics body. The first parameter can be any value from [enum BodyMode] constants, for the type of body created. Additionally, the body can be created in sleeping state to save processing time. </description> </method> <method name="body_get_collision_layer" qualifiers="const"> @@ -582,15 +568,6 @@ Returns whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]). </description> </method> - <method name="body_is_ray_pickable" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="body" type="RID"> - </argument> - <description> - If [code]true[/code], the body can be detected by rays. - </description> - </method> <method name="body_remove_collision_exception"> <return type="void"> </return> @@ -815,6 +792,24 @@ Sets a body state (see [enum BodyState] constants). </description> </method> + <method name="box_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> + <method name="capsule_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> + <method name="concave_polygon_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> <method name="cone_twist_joint_get_param" qualifiers="const"> <return type="float"> </return> @@ -839,6 +834,24 @@ Sets a cone_twist_joint parameter (see [enum ConeTwistJointParam] constants). </description> </method> + <method name="convex_polygon_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> + <method name="custom_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> + <method name="cylinder_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> <method name="free_rid"> <return type="void"> </return> @@ -848,7 +861,7 @@ Destroys any of the objects created by PhysicsServer3D. If the [RID] passed is not one of the objects that can be created by PhysicsServer3D, an error will be sent to the console. </description> </method> - <method name="generic_6dof_joint_get_flag"> + <method name="generic_6dof_joint_get_flag" qualifiers="const"> <return type="bool"> </return> <argument index="0" name="joint" type="RID"> @@ -861,7 +874,7 @@ Gets a generic_6_DOF_joint flag (see [enum G6DOFJointAxisFlag] constants). </description> </method> - <method name="generic_6dof_joint_get_param"> + <method name="generic_6dof_joint_get_param" qualifiers="const"> <return type="float"> </return> <argument index="0" name="joint" type="RID"> @@ -913,6 +926,12 @@ Returns an Info defined by the [enum ProcessInfo] input given. </description> </method> + <method name="heightmap_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> <method name="hinge_joint_get_flag" qualifiers="const"> <return type="bool"> </return> @@ -961,97 +980,116 @@ Sets a hinge_joint parameter (see [enum HingeJointParam] constants). </description> </method> - <method name="joint_create_cone_twist"> - <return type="RID"> + <method name="joint_clear"> + <return type="void"> </return> - <argument index="0" name="body_A" type="RID"> - </argument> - <argument index="1" name="local_ref_A" type="Transform"> - </argument> - <argument index="2" name="body_B" type="RID"> - </argument> - <argument index="3" name="local_ref_B" type="Transform"> + <argument index="0" name="joint" type="RID"> </argument> <description> - Creates a [ConeTwistJoint3D]. </description> </method> - <method name="joint_create_generic_6dof"> + <method name="joint_create"> <return type="RID"> </return> - <argument index="0" name="body_A" type="RID"> - </argument> - <argument index="1" name="local_ref_A" type="Transform"> - </argument> - <argument index="2" name="body_B" type="RID"> + <description> + </description> + </method> + <method name="joint_get_solver_priority" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="joint" type="RID"> </argument> - <argument index="3" name="local_ref_B" type="Transform"> + <description> + Gets the priority value of the Joint3D. + </description> + </method> + <method name="joint_get_type" qualifiers="const"> + <return type="int" enum="PhysicsServer3D.JointType"> + </return> + <argument index="0" name="joint" type="RID"> </argument> <description> - Creates a [Generic6DOFJoint3D]. + Returns the type of the Joint3D. </description> </method> - <method name="joint_create_hinge"> - <return type="RID"> + <method name="joint_make_cone_twist"> + <return type="void"> </return> - <argument index="0" name="body_A" type="RID"> + <argument index="0" name="joint" type="RID"> </argument> - <argument index="1" name="hinge_A" type="Transform"> + <argument index="1" name="body_A" type="RID"> </argument> - <argument index="2" name="body_B" type="RID"> + <argument index="2" name="local_ref_A" type="Transform"> </argument> - <argument index="3" name="hinge_B" type="Transform"> + <argument index="3" name="body_B" type="RID"> + </argument> + <argument index="4" name="local_ref_B" type="Transform"> </argument> <description> - Creates a [HingeJoint3D]. </description> </method> - <method name="joint_create_pin"> - <return type="RID"> + <method name="joint_make_generic_6dof"> + <return type="void"> </return> - <argument index="0" name="body_A" type="RID"> + <argument index="0" name="joint" type="RID"> </argument> - <argument index="1" name="local_A" type="Vector3"> + <argument index="1" name="body_A" type="RID"> + </argument> + <argument index="2" name="local_ref_A" type="Transform"> </argument> - <argument index="2" name="body_B" type="RID"> + <argument index="3" name="body_B" type="RID"> </argument> - <argument index="3" name="local_B" type="Vector3"> + <argument index="4" name="local_ref_B" type="Transform"> </argument> <description> - Creates a [PinJoint3D]. </description> </method> - <method name="joint_create_slider"> - <return type="RID"> + <method name="joint_make_hinge"> + <return type="void"> </return> - <argument index="0" name="body_A" type="RID"> + <argument index="0" name="joint" type="RID"> + </argument> + <argument index="1" name="body_A" type="RID"> </argument> - <argument index="1" name="local_ref_A" type="Transform"> + <argument index="2" name="hinge_A" type="Transform"> </argument> - <argument index="2" name="body_B" type="RID"> + <argument index="3" name="body_B" type="RID"> </argument> - <argument index="3" name="local_ref_B" type="Transform"> + <argument index="4" name="hinge_B" type="Transform"> </argument> <description> - Creates a [SliderJoint3D]. </description> </method> - <method name="joint_get_solver_priority" qualifiers="const"> - <return type="int"> + <method name="joint_make_pin"> + <return type="void"> </return> <argument index="0" name="joint" type="RID"> </argument> + <argument index="1" name="body_A" type="RID"> + </argument> + <argument index="2" name="local_A" type="Vector3"> + </argument> + <argument index="3" name="body_B" type="RID"> + </argument> + <argument index="4" name="local_B" type="Vector3"> + </argument> <description> - Gets the priority value of the Joint3D. </description> </method> - <method name="joint_get_type" qualifiers="const"> - <return type="int" enum="PhysicsServer3D.JointType"> + <method name="joint_make_slider"> + <return type="void"> </return> <argument index="0" name="joint" type="RID"> </argument> + <argument index="1" name="body_A" type="RID"> + </argument> + <argument index="2" name="local_ref_A" type="Transform"> + </argument> + <argument index="3" name="body_B" type="RID"> + </argument> + <argument index="4" name="local_ref_B" type="Transform"> + </argument> <description> - Returns the type of the Joint3D. </description> </method> <method name="joint_set_solver_priority"> @@ -1129,22 +1167,25 @@ Sets a pin_joint parameter (see [enum PinJointParam] constants). </description> </method> - <method name="set_active"> - <return type="void"> + <method name="plane_shape_create"> + <return type="RID"> </return> - <argument index="0" name="active" type="bool"> - </argument> <description> - Activates or deactivates the 3D physics engine. </description> </method> - <method name="shape_create"> + <method name="ray_shape_create"> <return type="RID"> </return> - <argument index="0" name="type" type="int" enum="PhysicsServer3D.ShapeType"> + <description> + </description> + </method> + <method name="set_active"> + <return type="void"> + </return> + <argument index="0" name="active" type="bool"> </argument> <description> - Creates a shape of a type from [enum ShapeType]. Does not assign it to a body or an area. To do so, you must use [method area_set_shape] or [method body_set_shape]. + Activates or deactivates the 3D physics engine. </description> </method> <method name="shape_get_data" qualifiers="const"> @@ -1260,23 +1301,32 @@ Sets the value for a space parameter. A list of available parameters is on the [enum SpaceParameter] constants. </description> </method> + <method name="sphere_shape_create"> + <return type="RID"> + </return> + <description> + </description> + </method> </methods> <constants> - <constant name="JOINT_PIN" value="0" enum="JointType"> + <constant name="JOINT_TYPE_PIN" value="0" enum="JointType"> The [Joint3D] is a [PinJoint3D]. </constant> - <constant name="JOINT_HINGE" value="1" enum="JointType"> + <constant name="JOINT_TYPE_HINGE" value="1" enum="JointType"> The [Joint3D] is a [HingeJoint3D]. </constant> - <constant name="JOINT_SLIDER" value="2" enum="JointType"> + <constant name="JOINT_TYPE_SLIDER" value="2" enum="JointType"> The [Joint3D] is a [SliderJoint3D]. </constant> - <constant name="JOINT_CONE_TWIST" value="3" enum="JointType"> + <constant name="JOINT_TYPE_CONE_TWIST" value="3" enum="JointType"> The [Joint3D] is a [ConeTwistJoint3D]. </constant> - <constant name="JOINT_6DOF" value="4" enum="JointType"> + <constant name="JOINT_TYPE_6DOF" value="4" enum="JointType"> The [Joint3D] is a [Generic6DOFJoint3D]. </constant> + <constant name="JOINT_TYPE_MAX" value="5" enum="JointType"> + Represents the size of the [enum JointType] enum. + </constant> <constant name="PIN_JOINT_BIAS" value="0" enum="PinJointParam"> The strength with which the pinned objects try to stay in positional relation to each other. The higher, the stronger. diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 2532af9a0c..51ec509a14 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -717,19 +717,22 @@ <theme_item name="font" type="Font"> [Font] used for the menu items. </theme_item> + <theme_item name="font_accelerator_color" type="Color" default="Color( 0.7, 0.7, 0.7, 0.8 )"> + The text [Color] used for shortcuts and accelerators that show next to the menu item name when defined. See [method get_item_accelerator] for more info on accelerators. + </theme_item> <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> The default text [Color] for menu items' names. </theme_item> - <theme_item name="font_color_accel" type="Color" default="Color( 0.7, 0.7, 0.7, 0.8 )"> - The text [Color] used for shortcuts and accelerators that show next to the menu item name when defined. See [method get_item_accelerator] for more info on accelerators. - </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.4, 0.4, 0.4, 0.8 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.4, 0.4, 0.4, 0.8 )"> [Color] used for disabled menu items' text. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> + <theme_item name="font_hover_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> [Color] used for the hovered text. </theme_item> - <theme_item name="font_color_separator" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the menu item. + </theme_item> + <theme_item name="font_separator_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> [Color] used for labeled separators' text. See [method add_separator]. </theme_item> <theme_item name="font_size" type="int"> @@ -741,12 +744,19 @@ <theme_item name="hseparation" type="int" default="4"> The horizontal space between the item's name and the shortcut text/submenu arrow. </theme_item> + <theme_item name="item_end_padding" type="int" default="2"> + </theme_item> + <theme_item name="item_start_padding" type="int" default="2"> + </theme_item> <theme_item name="labeled_separator_left" type="StyleBox"> [StyleBox] for the left side of labeled separator. See [method add_separator]. </theme_item> <theme_item name="labeled_separator_right" type="StyleBox"> [StyleBox] for the right side of labeled separator. See [method add_separator]. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the item text outline. + </theme_item> <theme_item name="panel" type="StyleBox"> Default [StyleBox] of the [PopupMenu] items. </theme_item> diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index c05cbf4413..160b61c720 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -32,11 +32,17 @@ <theme_item name="font_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> The color of the text. </theme_item> - <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [ProgressBar]. + </theme_item> + <theme_item name="font_shadow_color" type="Color" default="Color( 0, 0, 0, 1 )"> The color of the text's shadow. </theme_item> <theme_item name="font_size" type="int"> Font size used to draw the fill percentage if [member percent_visible] is [code]true[/code]. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> </theme_items> </class> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index a82cf9a2a9..a1e5e60b4a 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -273,9 +273,11 @@ If [code]true[/code], flushes the standard output stream every time a line is printed. This affects both terminal logging and file logging. When running a project, this setting must be enabled if you want logs to be collected by service managers such as systemd/journalctl. This setting is disabled by default on release builds, since flushing on every printed line will negatively affect performance if lots of lines are printed in a rapid succession. Also, if this setting is enabled, logged files will still be written successfully if the application crashes or is otherwise killed by the user (without being closed "normally"). [b]Note:[/b] Regardless of this setting, the standard error stream ([code]stderr[/code]) is always flushed when a line is printed to it. + Changes to this setting will only be applied upon restarting the application. </member> <member name="application/run/flush_stdout_on_print.debug" type="bool" setter="" getter="" default="true"> Debug build override for [member application/run/flush_stdout_on_print], as performance is less important during debugging. + Changes to this setting will only be applied upon restarting the application. </member> <member name="application/run/frame_delay_msec" type="int" setter="" getter="" default="0"> Forces a delay between frames in the main loop (in milliseconds). This may be useful if you plan to disable vertical synchronization. @@ -289,31 +291,31 @@ <member name="application/run/main_scene" type="String" setter="" getter="" default=""""> Path to the main scene file that will be loaded when the project runs. </member> - <member name="audio/channel_disable_threshold_db" type="float" setter="" getter="" default="-60.0"> + <member name="audio/buses/channel_disable_threshold_db" type="float" setter="" getter="" default="-60.0"> Audio buses will disable automatically when sound goes below a given dB threshold for a given time. This saves CPU as effects assigned to that bus will no longer do any processing. </member> - <member name="audio/channel_disable_time" type="float" setter="" getter="" default="2.0"> + <member name="audio/buses/channel_disable_time" type="float" setter="" getter="" default="2.0"> Audio buses will disable automatically when sound goes below a given dB threshold for a given time. This saves CPU as effects assigned to that bus will no longer do any processing. </member> - <member name="audio/default_bus_layout" type="String" setter="" getter="" default=""res://default_bus_layout.tres""> + <member name="audio/buses/default_bus_layout" type="String" setter="" getter="" default=""res://default_bus_layout.tres""> Default [AudioBusLayout] resource file to use in the project, unless overridden by the scene. </member> - <member name="audio/driver" type="String" setter="" getter=""> + <member name="audio/driver/driver" type="String" setter="" getter=""> Specifies the audio driver to use. This setting is platform-dependent as each platform supports different audio drivers. If left empty, the default audio driver will be used. </member> - <member name="audio/enable_audio_input" type="bool" setter="" getter="" default="false"> + <member name="audio/driver/enable_input" type="bool" setter="" getter="" default="false"> If [code]true[/code], microphone input will be allowed. This requires appropriate permissions to be set when exporting to Android or iOS. </member> - <member name="audio/mix_rate" type="int" setter="" getter="" default="44100"> + <member name="audio/driver/mix_rate" type="int" setter="" getter="" default="44100"> Mixing rate used for audio. In general, it's better to not touch this and leave it to the host operating system. </member> - <member name="audio/output_latency" type="int" setter="" getter="" default="15"> + <member name="audio/driver/output_latency" type="int" setter="" getter="" default="15"> Output latency in milliseconds for audio. Lower values will result in lower audio latency at the cost of increased CPU usage. Low values may result in audible cracking on slower hardware. </member> - <member name="audio/output_latency.web" type="int" setter="" getter="" default="50"> - Safer override for [member audio/output_latency] in the Web platform, to avoid audio issues especially on mobile devices. + <member name="audio/driver/output_latency.web" type="int" setter="" getter="" default="50"> + Safer override for [member audio/driver/output_latency] in the Web platform, to avoid audio issues especially on mobile devices. </member> - <member name="audio/video_delay_compensation_ms" type="int" setter="" getter="" default="0"> + <member name="audio/video/video_delay_compensation_ms" type="int" setter="" getter="" default="0"> Setting to hardcode audio delay when playing video. Best to leave this untouched unless you know what you are doing. </member> <member name="compression/formats/gzip/compression_level" type="int" setter="" getter="" default="-1"> @@ -331,6 +333,18 @@ <member name="compression/formats/zstd/window_log_size" type="int" setter="" getter="" default="27"> Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard. Higher values can result in better compression, but will require more memory when compressing and decompressing. </member> + <member name="debug/file_logging/enable_file_logging" type="bool" setter="" getter="" default="false"> + If [code]true[/code], logs all output to files. + </member> + <member name="debug/file_logging/enable_file_logging.pc" type="bool" setter="" getter="" default="true"> + Desktop override for [member debug/file_logging/enable_file_logging], as log files are not readily accessible on mobile/Web platforms. + </member> + <member name="debug/file_logging/log_path" type="String" setter="" getter="" default=""user://logs/godot.log""> + Path to logs within the project. Using an [code]user://[/code] path is recommended. + </member> + <member name="debug/file_logging/max_log_files" type="int" setter="" getter="" default="5"> + Specifies the maximum amount of log files allowed (used for rotation). + </member> <member name="debug/gdscript/completion/autocomplete_setters_and_getters" type="bool" setter="" getter="" default="false"> If [code]true[/code], displays getters and setters in autocompletion results in the script editor. This setting is meant to be used when porting old projects (Godot 2), as using member variables is the preferred style from Godot 3 onwards. </member> @@ -448,6 +462,9 @@ <member name="debug/shapes/collision/contact_color" type="Color" setter="" getter="" default="Color( 1, 0.2, 0.1, 0.8 )"> Color of the contact points between collision shapes, visible when "Visible Collision Shapes" is enabled in the Debug menu. </member> + <member name="debug/shapes/collision/draw_2d_outlines" type="bool" setter="" getter="" default="true"> + Sets whether 2D physics will display collision outlines in game when "Visible Collision Shapes" is enabled in the Debug menu. + </member> <member name="debug/shapes/collision/max_contacts_displayed" type="int" setter="" getter="" default="10000"> Maximum number of contact points between collision shapes to display when "Visible Collision Shapes" is enabled in the Debug menu. </member> @@ -475,9 +492,6 @@ <member name="display/window/energy_saving/keep_screen_on" type="bool" setter="" getter="" default="true"> If [code]true[/code], keeps the screen on (even in case of inactivity), so the screensaver does not take over. Works on desktop and mobile platforms. </member> - <member name="display/window/force_right_to_left_layout_direction" type="bool" setter="" getter="" default="false"> - Force layout direction and text writing direction to RTL for all locales. - </member> <member name="display/window/handheld/orientation" type="String" setter="" getter="" default=""landscape""> Default orientation on mobile devices. </member> @@ -513,12 +527,6 @@ <member name="display/window/size/width" type="int" setter="" getter="" default="1024"> Sets the game's main viewport width. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled. </member> - <member name="display/window/tablet_driver" type="String" setter="" getter=""> - Specifies the tablet driver to use. If left empty, the default driver will be used. - </member> - <member name="display/window/text_name" type="String" setter="" getter="" default=""""> - Specifies the [TextServer] to use. If left empty, the default will be used. - </member> <member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true"> If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5). </member> @@ -526,12 +534,18 @@ If [code]Use Vsync[/code] is enabled and this setting is [code]true[/code], enables vertical synchronization via the operating system's window compositor when in windowed mode and the compositor is enabled. This will prevent stutter in certain situations. (Windows only.) [b]Note:[/b] This option is experimental and meant to alleviate stutter experienced by some users. However, some users have experienced a Vsync framerate halving (e.g. from 60 FPS to 30 FPS) when using it. </member> - <member name="editor/script_templates_search_path" type="String" setter="" getter="" default=""res://script_templates""> - Search path for project-specific script templates. Godot will search for script templates both in the editor-specific path and in this project-specific path. + <member name="editor/node_naming/name_casing" type="int" setter="" getter="" default="0"> + When creating node names automatically, set the type of casing in this project. This is mostly an editor setting. </member> - <member name="editor/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray( "gd", "shader" )"> + <member name="editor/node_naming/name_num_separator" type="int" setter="" getter="" default="0"> + What to use to separate node name from number. This is mostly an editor setting. + </member> + <member name="editor/script/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray( "gd", "shader" )"> Text-based file extensions to include in the script editor's "Find in Files" feature. You can add e.g. [code]tscn[/code] if you wish to also parse your scene files, especially if you use built-in scripts which are serialized in the scene files. </member> + <member name="editor/script/templates_search_path" type="String" setter="" getter="" default=""res://script_templates""> + Search path for project-specific script templates. Godot will search for script templates both in the editor-specific path and in this project-specific path. + </member> <member name="gui/common/default_scroll_deadzone" type="int" setter="" getter="" default="0"> Default value for [member ScrollContainer.scroll_deadzone], which will be used for all [ScrollContainer]s unless overridden. </member> @@ -566,6 +580,10 @@ Default [InputEventAction] to discard a modal or pending input. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input/ui_copy" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_cut" type="Dictionary" setter="" getter=""> + </member> <member name="input/ui_down" type="Dictionary" setter="" getter=""> Default [InputEventAction] to move down in the UI. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. @@ -574,6 +592,12 @@ Default [InputEventAction] to go to the end position of a [Control] (e.g. last item in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_END] on typical desktop UI systems. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input/ui_filedialog_refresh" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_filedialog_show_hidden" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_filedialog_up_one_level" type="Dictionary" setter="" getter=""> + </member> <member name="input/ui_focus_next" type="Dictionary" setter="" getter=""> Default [InputEventAction] to focus the next [Control] in the scene. The focus behavior can be configured via [member Control.focus_next]. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. @@ -582,6 +606,10 @@ Default [InputEventAction] to focus the previous [Control] in the scene. The focus behavior can be configured via [member Control.focus_previous]. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input/ui_graph_delete" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_graph_duplicate" type="Dictionary" setter="" getter=""> + </member> <member name="input/ui_home" type="Dictionary" setter="" getter=""> Default [InputEventAction] to go to the start position of a [Control] (e.g. first item in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_HOME] on typical desktop UI systems. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. @@ -590,6 +618,8 @@ Default [InputEventAction] to move left in the UI. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input/ui_menu" type="Dictionary" setter="" getter=""> + </member> <member name="input/ui_page_down" type="Dictionary" setter="" getter=""> Default [InputEventAction] to go down a page in a [Control] (e.g. in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEDOWN] on typical desktop UI systems. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. @@ -598,6 +628,10 @@ Default [InputEventAction] to go up a page in a [Control] (e.g. in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEUP] on typical desktop UI systems. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input/ui_paste" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_redo" type="Dictionary" setter="" getter=""> + </member> <member name="input/ui_right" type="Dictionary" setter="" getter=""> Default [InputEventAction] to move right in the UI. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. @@ -606,10 +640,102 @@ Default [InputEventAction] to select an item in a [Control] (e.g. in an [ItemList] or a [Tree]). [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input/ui_swap_input_direction" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_backspace" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_backspace_all_to_left" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_backspace_all_to_left.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_backspace_word" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_backspace_word.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_document_end" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_document_end.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_document_start" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_document_start.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_down" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_left" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_line_end" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_line_end.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_line_start" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_line_start.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_page_down" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_page_up" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_right" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_up" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_word_left" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_word_left.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_word_right" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_caret_word_right.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_completion_accept" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_completion_query" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_dedent" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_delete" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_delete_all_to_right" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_delete_all_to_right.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_delete_word" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_delete_word.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_indent" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_newline" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_newline_above" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_newline_blank" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_scroll_down" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_scroll_down.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_scroll_up" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_scroll_up.OSX" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_select_all" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_text_toggle_insert_mode" type="Dictionary" setter="" getter=""> + </member> + <member name="input/ui_undo" type="Dictionary" setter="" getter=""> + </member> <member name="input/ui_up" type="Dictionary" setter="" getter=""> Default [InputEventAction] to move up in the UI. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input_devices/pen_tablet/driver" type="String" setter="" getter=""> + Specifies the tablet driver to use. If left empty, the default driver will be used. + </member> + <member name="input_devices/pen_tablet/driver.windows" type="String" setter="" getter=""> + Override for [member input_devices/pen_tablet/driver] on Windows. + </member> <member name="input_devices/pointing/emulate_mouse_from_touch" type="bool" setter="" getter="" default="true"> If [code]true[/code], sends mouse input events when tapping or swiping on the touchscreen. </member> @@ -619,6 +745,18 @@ <member name="input_devices/pointing/ios/touch_delay" type="float" setter="" getter="" default="0.15"> Default delay for touch events. This only affects iOS devices. </member> + <member name="internationalization/locale/fallback" type="String" setter="" getter="" default=""en""> + The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used. + </member> + <member name="internationalization/locale/test" type="String" setter="" getter="" default=""""> + If non-empty, this locale will be used when running the project from the editor. + </member> + <member name="internationalization/rendering/force_right_to_left_layout_direction" type="bool" setter="" getter="" default="false"> + Force layout direction and text writing direction to RTL for all locales. + </member> + <member name="internationalization/rendering/text_driver" type="String" setter="" getter="" default=""""> + Specifies the [TextServer] to use. If left empty, the default will be used. + </member> <member name="layer_names/2d_physics/layer_0" type="String" setter="" getter="" default=""""> Optional name for the 2D physics layer 0. If left empty, the layer will display as "Layer 0". </member> @@ -859,24 +997,6 @@ <member name="layer_names/3d_render/layer_9" type="String" setter="" getter="" default=""""> Optional name for the 3D render layer 9. If left empty, the layer will display as "Layer 9". </member> - <member name="locale/fallback" type="String" setter="" getter="" default=""en""> - The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used. - </member> - <member name="locale/test" type="String" setter="" getter="" default=""""> - If non-empty, this locale will be used when running the project from the editor. - </member> - <member name="logging/file_logging/enable_file_logging" type="bool" setter="" getter="" default="false"> - If [code]true[/code], logs all output to files. - </member> - <member name="logging/file_logging/enable_file_logging.pc" type="bool" setter="" getter="" default="true"> - Desktop override for [member logging/file_logging/enable_file_logging], as log files are not readily accessible on mobile/Web platforms. - </member> - <member name="logging/file_logging/log_path" type="String" setter="" getter="" default=""user://logs/godot.log""> - Path to logs within the project. Using an [code]user://[/code] path is recommended. - </member> - <member name="logging/file_logging/max_log_files" type="int" setter="" getter="" default="5"> - Specifies the maximum amount of log files allowed (used for rotation). - </member> <member name="memory/limits/command_queue/multithreading_queue_size_kb" type="int" setter="" getter="" default="256"> </member> <member name="memory/limits/message_queue/max_size_kb" type="int" setter="" getter="" default="4096"> @@ -930,12 +1050,6 @@ The CA certificates bundle to use for SSL connections. If this is set to a non-empty value, this will [i]override[/i] Godot's default [url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-certificates.crt]Mozilla certificate bundle[/url]. If left empty, the default certificate bundle will be used. If in doubt, leave this setting empty. </member> - <member name="node/name_casing" type="int" setter="" getter="" default="0"> - When creating node names automatically, set the type of casing in this project. This is mostly an editor setting. - </member> - <member name="node/name_num_separator" type="int" setter="" getter="" default="0"> - What to use to separate node name from number. This is mostly an editor setting. - </member> <member name="physics/2d/bp_hash_table_size" type="int" setter="" getter="" default="4096"> Size of the hash table used for the broad-phase 2D hash grid algorithm. </member> @@ -985,22 +1099,18 @@ Sets which physics engine to use for 2D physics. "DEFAULT" and "GodotPhysics2D" are the same, as there is currently no alternative 2D physics server implemented. </member> + <member name="physics/2d/run_on_thread" type="bool" setter="" getter="" default="false"> + Sets whether 2D physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process. + </member> <member name="physics/2d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626"> Threshold angular velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD]. </member> <member name="physics/2d/sleep_threshold_linear" type="float" setter="" getter="" default="2.0"> Threshold linear velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD]. </member> - <member name="physics/2d/thread_model" type="int" setter="" getter="" default="1"> - Sets whether physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process. - [b]Warning:[/b] As of Godot 3.2, there are mixed reports about the use of a Multi-Threaded thread model for physics. Be sure to assess whether it does give you extra performance and no regressions when using it. - </member> <member name="physics/2d/time_before_sleep" type="float" setter="" getter="" default="0.5"> Time (in seconds) of inactivity before which a 2D physics body will put to sleep. See [constant PhysicsServer2D.SPACE_PARAM_BODY_TIME_TO_SLEEP]. </member> - <member name="physics/3d/active_soft_world" type="bool" setter="" getter="" default="true"> - Sets whether the 3D physics world will be created with support for [SoftBody3D] physics. Only applies to the Bullet physics engine. - </member> <member name="physics/3d/default_angular_damp" type="float" setter="" getter="" default="0.1"> The default angular damp in 3D. [b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration. @@ -1041,6 +1151,15 @@ Sets which physics engine to use for 3D physics. "DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics3D" engine is still supported as an alternative. </member> + <member name="physics/3d/run_on_thread" type="bool" setter="" getter="" default="false"> + Sets whether 3D physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process. + </member> + <member name="physics/3d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626"> + </member> + <member name="physics/3d/sleep_threshold_linear" type="float" setter="" getter="" default="0.1"> + </member> + <member name="physics/3d/time_before_sleep" type="float" setter="" getter="" default="0.5"> + </member> <member name="physics/common/enable_object_picking" type="bool" setter="" getter="" default="true"> Enables [member Viewport.physics_object_picking] on the root viewport. </member> @@ -1052,273 +1171,269 @@ Fix to improve physics jitter, specially on monitors where refresh rate is different than the physics FPS. [b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead. </member> - <member name="rendering/environment/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )"> - Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method RenderingServer.set_default_clear_color]. + <member name="rendering/2d/sdf/oversize" type="int" setter="" getter="" default="1"> </member> - <member name="rendering/environment/default_environment" type="String" setter="" getter="" default=""""> - [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here. + <member name="rendering/2d/sdf/scale" type="int" setter="" getter="" default="1"> </member> - <member name="rendering/forward_renderer/threaded_render_minimum_instances" type="int" setter="" getter="" default="500"> + <member name="rendering/2d/shadow_atlas/size" type="int" setter="" getter="" default="2048"> </member> - <member name="rendering/gpu_lightmapper/performance/max_rays_per_pass" type="int" setter="" getter="" default="32"> + <member name="rendering/2d/snap/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false"> </member> - <member name="rendering/gpu_lightmapper/performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64"> + <member name="rendering/2d/snap/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false"> </member> - <member name="rendering/gpu_lightmapper/performance/region_size" type="int" setter="" getter="" default="512"> + <member name="rendering/anti_aliasing/quality/msaa" type="int" setter="" getter="" default="0"> + Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. </member> - <member name="rendering/gpu_lightmapper/quality/high_quality_probe_ray_count" type="int" setter="" getter="" default="512"> + <member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0"> + Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. + Another way to combat specular aliasing is to enable [member rendering/anti_aliasing/screen_space_roughness_limiter/enabled]. </member> - <member name="rendering/gpu_lightmapper/quality/high_quality_ray_count" type="int" setter="" getter="" default="256"> + <member name="rendering/anti_aliasing/quality/use_debanding" type="bool" setter="" getter="" default="false"> </member> - <member name="rendering/gpu_lightmapper/quality/low_quality_probe_ray_count" type="int" setter="" getter="" default="64"> + <member name="rendering/anti_aliasing/screen_space_roughness_limiter/amount" type="float" setter="" getter="" default="0.25"> </member> - <member name="rendering/gpu_lightmapper/quality/low_quality_ray_count" type="int" setter="" getter="" default="16"> + <member name="rendering/anti_aliasing/screen_space_roughness_limiter/enabled" type="bool" setter="" getter="" default="true"> </member> - <member name="rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count" type="int" setter="" getter="" default="256"> + <member name="rendering/anti_aliasing/screen_space_roughness_limiter/limit" type="float" setter="" getter="" default="0.18"> </member> - <member name="rendering/gpu_lightmapper/quality/medium_quality_ray_count" type="int" setter="" getter="" default="64"> + <member name="rendering/camera/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> + Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother. </member> - <member name="rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count" type="int" setter="" getter="" default="2048"> + <member name="rendering/camera/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1"> + Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute. </member> - <member name="rendering/gpu_lightmapper/quality/ultra_quality_ray_count" type="int" setter="" getter="" default="1024"> + <member name="rendering/camera/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false"> + If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples. </member> - <member name="rendering/high_end/global_shader_variables_buffer_size" type="int" setter="" getter="" default="65536"> + <member name="rendering/driver/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default=""PowerVR,Mali,Adreno,Apple""> + Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this. </member> - <member name="rendering/lightmapper/probe_capture_update_speed" type="float" setter="" getter="" default="15"> + <member name="rendering/driver/depth_prepass/enable" type="bool" setter="" getter="" default="true"> + If [code]true[/code], performs a previous depth pass before rendering materials. This increases performance in scenes with high overdraw, when complex materials and lighting are used. </member> - <member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000"> - Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves. + <member name="rendering/driver/driver_name" type="String" setter="" getter="" default=""Vulkan""> + The video driver to use (currently only "Vulkan" is implemented). + [b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument. + [b]FIXME:[/b] No longer valid after DisplayServer split: + In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time. </member> - <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600"> + <member name="rendering/driver/rd_renderer/use_low_end_renderer" type="bool" setter="" getter="" default="false"> </member> - <member name="rendering/quality/2d/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false"> + <member name="rendering/driver/rd_renderer/use_low_end_renderer.mobile" type="bool" setter="" getter="" default="true"> </member> - <member name="rendering/quality/2d/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false"> + <member name="rendering/driver/threads/thread_model" type="int" setter="" getter="" default="1"> + Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter. </member> - <member name="rendering/quality/2d_sdf/oversize" type="int" setter="" getter="" default="1"> + <member name="rendering/environment/defaults/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )"> + Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method RenderingServer.set_default_clear_color]. </member> - <member name="rendering/quality/2d_sdf/scale" type="int" setter="" getter="" default="1"> + <member name="rendering/environment/defaults/default_environment" type="String" setter="" getter="" default=""""> + [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here. </member> - <member name="rendering/quality/2d_shadow_atlas/size" type="int" setter="" getter="" default="2048"> + <member name="rendering/environment/glow/upscale_mode" type="int" setter="" getter="" default="1"> + Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth. </member> - <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> - Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother. + <member name="rendering/environment/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/environment/glow/upscale_mode] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1"> - Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute. + <member name="rendering/environment/glow/use_high_quality" type="bool" setter="" getter="" default="false"> + Takes more samples during downsample pass of glow. This ensures that single pixels are captured by glow which makes the glow look smoother and more stable during movement. However, it is very expensive and makes the glow post process take twice as long. </member> - <member name="rendering/quality/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false"> - If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples. + <member name="rendering/environment/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> + Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. </member> - <member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default=""PowerVR,Mali,Adreno,Apple""> - Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this. + <member name="rendering/environment/ssao/adaptive_target" type="float" setter="" getter="" default="0.5"> + Quality target to use when [member rendering/environment/ssao/quality] is set to [code]ULTRA[/code]. A value of [code]0.0[/code] provides a quality and speed similar to [code]MEDIUM[/code] while a value of [code]1.0[/code] provides much higher quality than any of the other settings at the cost of performance. </member> - <member name="rendering/quality/depth_prepass/enable" type="bool" setter="" getter="" default="true"> - If [code]true[/code], performs a previous depth pass before rendering materials. This increases performance in scenes with high overdraw, when complex materials and lighting are used. + <member name="rendering/environment/ssao/blur_passes" type="int" setter="" getter="" default="2"> + Number of blur passes to use when computing screen-space ambient occlusion. A higher number will result in a smoother look, but will be slower to compute and will have less high-frequency detail. </member> - <member name="rendering/quality/directional_shadow/size" type="int" setter="" getter="" default="4096"> - The directional shadow's size in pixels. Higher values will result in sharper shadows, at the cost of performance. The value will be rounded up to the nearest power of 2. + <member name="rendering/environment/ssao/fadeout_from" type="float" setter="" getter="" default="50.0"> + Distance at which the screen-space ambient occlusion effect starts to fade out. Use this hide ambient occlusion at great distances. </member> - <member name="rendering/quality/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048"> - Lower-end override for [member rendering/quality/directional_shadow/size] on mobile devices, due to performance concerns or driver support. + <member name="rendering/environment/ssao/fadeout_to" type="float" setter="" getter="" default="300.0"> + Distance at which the screen-space ambient occlusion is fully faded out. Use this hide ambient occlusion at great distances. </member> - <member name="rendering/quality/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2"> - Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. + <member name="rendering/environment/ssao/half_size" type="bool" setter="" getter="" default="false"> + If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details. </member> - <member name="rendering/quality/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> - Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. + <member name="rendering/environment/ssao/half_size.mobile" type="bool" setter="" getter="" default="true"> + Lower-end override for [member rendering/environment/ssao/half_size] on mobile devices, due to performance concerns. </member> - <member name="rendering/quality/driver/driver_name" type="String" setter="" getter="" default=""Vulkan""> - The video driver to use ("GLES2" or "Vulkan"). - [b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument. - [b]FIXME:[/b] No longer valid after DisplayServer split: - In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time. + <member name="rendering/environment/ssao/quality" type="int" setter="" getter="" default="2"> + Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance. Setting to [code]ULTRA[/code] will use the [member rendering/environment/ssao/adaptive_target] setting. </member> - <member name="rendering/quality/gi_probes/anisotropic" type="bool" setter="" getter="" default="false"> - If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction. + <member name="rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01"> + Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth. </member> - <member name="rendering/quality/gi_probes/quality" type="int" setter="" getter="" default="1"> - Sets the number of cone samples taken when rendering objects affected by [GIProbe]s. + <member name="rendering/environment/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1"> + Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer. </member> - <member name="rendering/quality/glow/upscale_mode" type="int" setter="" getter="" default="1"> - Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth. + <member name="rendering/environment/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05"> + Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light. </member> - <member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0"> - Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support. + <member name="rendering/environment/volumetric_fog/use_filter" type="int" setter="" getter="" default="1"> </member> - <member name="rendering/quality/glow/use_high_quality" type="bool" setter="" getter="" default="false"> - Takes more samples during downsample pass of glow. This ensures that single pixels are captured by glow which makes the glow look smoother and more stable during movement. However, it is very expensive and makes the glow post process take twice as long. + <member name="rendering/environment/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128"> </member> - <member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2"> - Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment]. + <member name="rendering/environment/volumetric_fog/volume_size" type="int" setter="" getter="" default="64"> </member> - <member name="rendering/quality/intended_usage/framebuffer_allocation.mobile" type="int" setter="" getter="" default="3"> - Lower-end override for [member rendering/quality/intended_usage/framebuffer_allocation] on mobile devices, due to performance concerns or driver support. + <member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false"> </member> - <member name="rendering/quality/mesh_lod/threshold_pixels" type="float" setter="" getter="" default="1.0"> + <member name="rendering/global_illumination/gi_probes/anisotropic" type="bool" setter="" getter="" default="false"> + If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction. </member> - <member name="rendering/quality/rd_renderer/use_low_end_renderer" type="bool" setter="" getter="" default="false"> + <member name="rendering/global_illumination/gi_probes/quality" type="int" setter="" getter="" default="1"> + Sets the number of cone samples taken when rendering objects affected by [GIProbe]s. </member> - <member name="rendering/quality/rd_renderer/use_low_end_renderer.mobile" type="bool" setter="" getter="" default="true"> + <member name="rendering/global_illumination/sdfgi/frames_to_converge" type="int" setter="" getter="" default="4"> </member> - <member name="rendering/quality/reflection_atlas/reflection_count" type="int" setter="" getter="" default="64"> - Number of cubemaps to store in the reflection atlas. The number of [ReflectionProbe]s in a scene will be limited by this amount. A higher number requires more VRAM. + <member name="rendering/global_illumination/sdfgi/frames_to_update_lights" type="int" setter="" getter="" default="2"> </member> - <member name="rendering/quality/reflection_atlas/reflection_size" type="int" setter="" getter="" default="256"> - Size of cubemap faces for [ReflectionProbe]s. A higher number requires more VRAM and may make reflection probe updating slower. + <member name="rendering/global_illumination/sdfgi/probe_ray_count" type="int" setter="" getter="" default="1"> </member> - <member name="rendering/quality/reflection_atlas/reflection_size.mobile" type="int" setter="" getter="" default="128"> - Lower-end override for [member rendering/quality/reflection_atlas/reflection_size] on mobile devices, due to performance concerns or driver support. + <member name="rendering/lightmapping/bake_performance/max_rays_per_pass" type="int" setter="" getter="" default="32"> </member> - <member name="rendering/quality/reflections/fast_filter_high_quality" type="bool" setter="" getter="" default="false"> - Use a higher quality variant of the fast filtering algorithm. Significantly slower than using default quality, but results in smoother reflections. Should only be used when the scene is especially detailed. + <member name="rendering/lightmapping/bake_performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64"> </member> - <member name="rendering/quality/reflections/ggx_samples" type="int" setter="" getter="" default="1024"> - Sets the number of samples to take when using importance sampling for [Sky]s and [ReflectionProbe]s. A higher value will result in smoother, higher quality reflections, but increases time to calculate radiance maps. In general, fewer samples are needed for simpler, low dynamic range environments while more samples are needed for HDR environments and environments with a high level of detail. + <member name="rendering/lightmapping/bake_performance/region_size" type="int" setter="" getter="" default="512"> </member> - <member name="rendering/quality/reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128"> - Lower-end override for [member rendering/quality/reflections/ggx_samples] on mobile devices, due to performance concerns or driver support. + <member name="rendering/lightmapping/bake_quality/high_quality_probe_ray_count" type="int" setter="" getter="" default="512"> </member> - <member name="rendering/quality/reflections/roughness_layers" type="int" setter="" getter="" default="8"> - Limits the number of layers to use in radiance maps when using importance sampling. A lower number will be slightly faster and take up less VRAM. + <member name="rendering/lightmapping/bake_quality/high_quality_ray_count" type="int" setter="" getter="" default="256"> </member> - <member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter="" default="true"> - If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise and upscaling artifacts on reflections, but is significantly slower to compute and uses [member rendering/quality/reflections/roughness_layers] times more memory. + <member name="rendering/lightmapping/bake_quality/low_quality_probe_ray_count" type="int" setter="" getter="" default="64"> </member> - <member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> - Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. + <member name="rendering/lightmapping/bake_quality/low_quality_ray_count" type="int" setter="" getter="" default="16"> </member> - <member name="rendering/quality/screen_filters/msaa" type="int" setter="" getter="" default="0"> - Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. - [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend. + <member name="rendering/lightmapping/bake_quality/medium_quality_probe_ray_count" type="int" setter="" getter="" default="256"> </member> - <member name="rendering/quality/screen_filters/screen_space_aa" type="int" setter="" getter="" default="0"> - Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. - Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter_enabled]. + <member name="rendering/lightmapping/bake_quality/medium_quality_ray_count" type="int" setter="" getter="" default="64"> </member> - <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_amount" type="float" setter="" getter="" default="0.25"> + <member name="rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count" type="int" setter="" getter="" default="2048"> </member> - <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_enabled" type="bool" setter="" getter="" default="true"> + <member name="rendering/lightmapping/bake_quality/ultra_quality_ray_count" type="int" setter="" getter="" default="1024"> </member> - <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_limit" type="float" setter="" getter="" default="0.18"> + <member name="rendering/lightmapping/probe_capture/update_speed" type="float" setter="" getter="" default="15"> </member> - <member name="rendering/quality/screen_filters/use_debanding" type="bool" setter="" getter="" default="false"> + <member name="rendering/limits/cluster_builder/max_clustered_elements" type="float" setter="" getter="" default="512"> </member> - <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> - Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. + <member name="rendering/limits/forward_renderer/threaded_render_minimum_instances" type="int" setter="" getter="" default="500"> </member> - <member name="rendering/quality/shading/force_blinn_over_ggx" type="bool" setter="" getter="" default="false"> - If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model. + <member name="rendering/limits/global_shader_variables/buffer_size" type="int" setter="" getter="" default="65536"> </member> - <member name="rendering/quality/shading/force_blinn_over_ggx.mobile" type="bool" setter="" getter="" default="true"> - Lower-end override for [member rendering/quality/shading/force_blinn_over_ggx] on mobile devices, due to performance concerns or driver support. + <member name="rendering/limits/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000"> </member> - <member name="rendering/quality/shading/force_lambert_over_burley" type="bool" setter="" getter="" default="false"> - If [code]true[/code], uses faster but lower-quality Lambert material lighting model instead of Burley. + <member name="rendering/limits/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10"> </member> - <member name="rendering/quality/shading/force_lambert_over_burley.mobile" type="bool" setter="" getter="" default="true"> - Lower-end override for [member rendering/quality/shading/force_lambert_over_burley] on mobile devices, due to performance concerns or driver support. + <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600"> </member> - <member name="rendering/quality/shading/force_vertex_shading" type="bool" setter="" getter="" default="false"> - If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices. + <member name="rendering/mesh_lod/lod_change/threshold_pixels" type="float" setter="" getter="" default="1.0"> </member> - <member name="rendering/quality/shading/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true"> - Lower-end override for [member rendering/quality/shading/force_vertex_shading] on mobile devices, due to performance concerns or driver support. + <member name="rendering/reflections/reflection_atlas/reflection_count" type="int" setter="" getter="" default="64"> + Number of cubemaps to store in the reflection atlas. The number of [ReflectionProbe]s in a scene will be limited by this amount. A higher number requires more VRAM. </member> - <member name="rendering/quality/shadow_atlas/quadrant_0_subdiv" type="int" setter="" getter="" default="1"> - Subdivision quadrant size for shadow mapping. See shadow mapping documentation. + <member name="rendering/reflections/reflection_atlas/reflection_size" type="int" setter="" getter="" default="256"> + Size of cubemap faces for [ReflectionProbe]s. A higher number requires more VRAM and may make reflection probe updating slower. </member> - <member name="rendering/quality/shadow_atlas/quadrant_1_subdiv" type="int" setter="" getter="" default="2"> - Subdivision quadrant size for shadow mapping. See shadow mapping documentation. + <member name="rendering/reflections/reflection_atlas/reflection_size.mobile" type="int" setter="" getter="" default="128"> + Lower-end override for [member rendering/reflections/reflection_atlas/reflection_size] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/shadow_atlas/quadrant_2_subdiv" type="int" setter="" getter="" default="3"> - Subdivision quadrant size for shadow mapping. See shadow mapping documentation. + <member name="rendering/reflections/sky_reflections/fast_filter_high_quality" type="bool" setter="" getter="" default="false"> + Use a higher quality variant of the fast filtering algorithm. Significantly slower than using default quality, but results in smoother reflections. Should only be used when the scene is especially detailed. </member> - <member name="rendering/quality/shadow_atlas/quadrant_3_subdiv" type="int" setter="" getter="" default="4"> - Subdivision quadrant size for shadow mapping. See shadow mapping documentation. + <member name="rendering/reflections/sky_reflections/ggx_samples" type="int" setter="" getter="" default="1024"> + Sets the number of samples to take when using importance sampling for [Sky]s and [ReflectionProbe]s. A higher value will result in smoother, higher quality reflections, but increases time to calculate radiance maps. In general, fewer samples are needed for simpler, low dynamic range environments while more samples are needed for HDR environments and environments with a high level of detail. </member> - <member name="rendering/quality/shadow_atlas/size" type="int" setter="" getter="" default="4096"> - Size for shadow atlas (used for OmniLights and SpotLights). See documentation. + <member name="rendering/reflections/sky_reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128"> + Lower-end override for [member rendering/reflections/sky_reflections/ggx_samples] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048"> - Lower-end override for [member rendering/quality/shadow_atlas/size] on mobile devices, due to performance concerns or driver support. + <member name="rendering/reflections/sky_reflections/roughness_layers" type="int" setter="" getter="" default="8"> + Limits the number of layers to use in radiance maps when using importance sampling. A lower number will be slightly faster and take up less VRAM. </member> - <member name="rendering/quality/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2"> - Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. + <member name="rendering/reflections/sky_reflections/texture_array_reflections" type="bool" setter="" getter="" default="true"> + If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise and upscaling artifacts on reflections, but is significantly slower to compute and uses [member rendering/reflections/sky_reflections/roughness_layers] times more memory. </member> - <member name="rendering/quality/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> - Lower-end override for [member rendering/quality/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. + <member name="rendering/reflections/sky_reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> + Lower-end override for [member rendering/reflections/sky_reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/ssao/adaptive_target" type="float" setter="" getter="" default="0.5"> - Quality target to use when [member rendering/quality/ssao/quality] is set to [code]ULTRA[/code]. A value of [code]0.0[/code] provides a quality and speed similar to [code]MEDIUM[/code] while a value of [code]1.0[/code] provides much higher quality than any of the other settings at the cost of performance. + <member name="rendering/shading/overrides/force_blinn_over_ggx" type="bool" setter="" getter="" default="false"> + If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model. </member> - <member name="rendering/quality/ssao/blur_passes" type="int" setter="" getter="" default="2"> - Number of blur passes to use when computing screen-space ambient occlusion. A higher number will result in a smoother look, but will be slower to compute and will have less high-frequency detail. + <member name="rendering/shading/overrides/force_blinn_over_ggx.mobile" type="bool" setter="" getter="" default="true"> + Lower-end override for [member rendering/shading/overrides/force_blinn_over_ggx] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/ssao/fadeout_from" type="float" setter="" getter="" default="50.0"> - Distance at which the screen-space ambient occlusion effect starts to fade out. Use this hide ambient occlusion at great distances. + <member name="rendering/shading/overrides/force_lambert_over_burley" type="bool" setter="" getter="" default="false"> + If [code]true[/code], uses faster but lower-quality Lambert material lighting model instead of Burley. </member> - <member name="rendering/quality/ssao/fadeout_to" type="float" setter="" getter="" default="300.0"> - Distance at which the screen-space ambient occlusion is fully faded out. Use this hide ambient occlusion at great distances. + <member name="rendering/shading/overrides/force_lambert_over_burley.mobile" type="bool" setter="" getter="" default="true"> + Lower-end override for [member rendering/shading/overrides/force_lambert_over_burley] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/ssao/half_size" type="bool" setter="" getter="" default="false"> - If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details. + <member name="rendering/shading/overrides/force_vertex_shading" type="bool" setter="" getter="" default="false"> + If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices. </member> - <member name="rendering/quality/ssao/half_size.mobile" type="bool" setter="" getter="" default="true"> - Lower-end override for [member rendering/quality/ssao/half_size] on mobile devices, due to performance concerns. + <member name="rendering/shading/overrides/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true"> + Lower-end override for [member rendering/shading/overrides/force_vertex_shading] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/ssao/quality" type="int" setter="" getter="" default="2"> - Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance. Setting to [code]ULTRA[/code] will use the [member rendering/quality/ssao/adaptive_target] setting. + <member name="rendering/shadows/directional_shadow/16_bits" type="bool" setter="" getter="" default="true"> </member> - <member name="rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01"> - Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth. + <member name="rendering/shadows/directional_shadow/size" type="int" setter="" getter="" default="4096"> + The directional shadow's size in pixels. Higher values will result in sharper shadows, at the cost of performance. The value will be rounded up to the nearest power of 2. </member> - <member name="rendering/quality/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1"> - Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer. + <member name="rendering/shadows/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048"> + Lower-end override for [member rendering/shadows/directional_shadow/size] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05"> - Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light. + <member name="rendering/shadows/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2"> + Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. </member> - <member name="rendering/quality/texture_filters/anisotropic_filtering_level" type="int" setter="" getter="" default="2"> - Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled. + <member name="rendering/shadows/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/shadows/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/texture_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> - If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. + <member name="rendering/shadows/shadow_atlas/16_bits" type="bool" setter="" getter="" default="true"> </member> - <member name="rendering/sdfgi/frames_to_converge" type="int" setter="" getter="" default="1"> + <member name="rendering/shadows/shadow_atlas/quadrant_0_subdiv" type="int" setter="" getter="" default="2"> + Subdivision quadrant size for shadow mapping. See shadow mapping documentation. </member> - <member name="rendering/sdfgi/probe_ray_count" type="int" setter="" getter="" default="2"> + <member name="rendering/shadows/shadow_atlas/quadrant_1_subdiv" type="int" setter="" getter="" default="2"> + Subdivision quadrant size for shadow mapping. See shadow mapping documentation. </member> - <member name="rendering/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000"> + <member name="rendering/shadows/shadow_atlas/quadrant_2_subdiv" type="int" setter="" getter="" default="3"> + Subdivision quadrant size for shadow mapping. See shadow mapping documentation. </member> - <member name="rendering/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10"> + <member name="rendering/shadows/shadow_atlas/quadrant_3_subdiv" type="int" setter="" getter="" default="4"> + Subdivision quadrant size for shadow mapping. See shadow mapping documentation. </member> - <member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1"> - Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter. + <member name="rendering/shadows/shadow_atlas/size" type="int" setter="" getter="" default="4096"> + Size for shadow atlas (used for OmniLights and SpotLights). See documentation. </member> - <member name="rendering/volumetric_fog/directional_shadow_shrink" type="int" setter="" getter="" default="512"> + <member name="rendering/shadows/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048"> + Lower-end override for [member rendering/shadows/shadow_atlas/size] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/volumetric_fog/positional_shadow_shrink" type="int" setter="" getter="" default="512"> + <member name="rendering/shadows/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2"> + Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. </member> - <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="0"> + <member name="rendering/shadows/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/shadows/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128"> + <member name="rendering/textures/default_filters/anisotropic_filtering_level" type="int" setter="" getter="" default="2"> + Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled. </member> - <member name="rendering/volumetric_fog/volume_size" type="int" setter="" getter="" default="64"> + <member name="rendering/textures/default_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> + If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. </member> - <member name="rendering/vram_compression/import_bptc" type="bool" setter="" getter="" default="false"> + <member name="rendering/textures/vram_compression/import_bptc" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the Vulkan renderer. </member> - <member name="rendering/vram_compression/import_etc" type="bool" setter="" getter="" default="false"> + <member name="rendering/textures/vram_compression/import_etc" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression algorithm. This algorithm doesn't support alpha channels in textures. </member> - <member name="rendering/vram_compression/import_etc2" type="bool" setter="" getter="" default="true"> + <member name="rendering/textures/vram_compression/import_etc2" type="bool" setter="" getter="" default="true"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression 2 algorithm. This texture compression algorithm is only supported when using the Vulkan renderer. </member> - <member name="rendering/vram_compression/import_pvrtc" type="bool" setter="" getter="" default="false"> + <member name="rendering/textures/vram_compression/import_pvrtc" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the PowerVR Texture Compression algorithm. This texture compression algorithm is only supported on iOS. </member> - <member name="rendering/vram_compression/import_s3tc" type="bool" setter="" getter="" default="true"> + <member name="rendering/textures/vram_compression/import_s3tc" type="bool" setter="" getter="" default="true"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles. </member> <member name="rendering/vulkan/descriptor_pools/max_descriptors_per_pool" type="int" setter="" getter="" default="64"> diff --git a/doc/classes/Reference.xml b/doc/classes/Reference.xml index 44ee6fbda1..724d2db924 100644 --- a/doc/classes/Reference.xml +++ b/doc/classes/Reference.xml @@ -5,7 +5,7 @@ </brief_description> <description> Base class for any object that keeps a reference count. [Resource] and many other helper objects inherit this class. - Unlike [Object]s, References keep an internal reference counter so that they are automatically released when no longer in use, and only then. References therefore do not need to be freed manually with [method Object.free]. + Unlike other [Object] types, References keep an internal reference counter so that they are automatically released when no longer in use, and only then. References therefore do not need to be freed manually with [method Object.free]. In the vast majority of use cases, instantiating and using [Reference]-derived types is all you need to do. The methods provided in this class are only for advanced users, and can cause issues if misused. [b]Note:[/b] In C#, references will not be freed instantly after they are no longer in use. Instead, garbage collection will run periodically and will free references that are no longer in use. This means that unused references will linger on for a while before being removed. </description> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 7cdc9ffaca..841d2bde72 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -7,6 +7,30 @@ <tutorials> </tutorials> <methods> + <method name="barrier"> + <return type="void"> + </return> + <argument index="0" name="from" type="int" default="7"> + </argument> + <argument index="1" name="to" type="int" default="7"> + </argument> + <description> + </description> + </method> + <method name="buffer_clear"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="buffer" type="RID"> + </argument> + <argument index="1" name="offset" type="int"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <argument index="3" name="post_barrier" type="int" default="7"> + </argument> + <description> + </description> + </method> <method name="buffer_get_data"> <return type="PackedByteArray"> </return> @@ -26,7 +50,7 @@ </argument> <argument index="3" name="data" type="PackedByteArray"> </argument> - <argument index="4" name="sync_with_draw" type="bool" default="true"> + <argument index="4" name="post_barrier" type="int" default="7"> </argument> <description> </description> @@ -36,8 +60,6 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="sync_to_draw" type="bool"> - </argument> <description> </description> </method> @@ -52,6 +74,8 @@ <method name="compute_list_begin"> <return type="int"> </return> + <argument index="0" name="allow_draw_overlap" type="bool" default="false"> + </argument> <description> </description> </method> @@ -94,6 +118,8 @@ <method name="compute_list_end"> <return type="void"> </return> + <argument index="0" name="post_barrier" type="int" default="7"> + </argument> <description> </description> </method> @@ -131,6 +157,32 @@ <description> </description> </method> + <method name="draw_command_begin_label"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="color" type="Color"> + </argument> + <description> + </description> + </method> + <method name="draw_command_end_label"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="draw_command_insert_label"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="color" type="Color"> + </argument> + <description> + </description> + </method> <method name="draw_list_begin"> <return type="int"> </return> @@ -272,6 +324,8 @@ <method name="draw_list_end"> <return type="void"> </return> + <argument index="0" name="post_barrier" type="int" default="7"> + </argument> <description> </description> </method> @@ -302,7 +356,9 @@ </return> <argument index="0" name="size" type="Vector2i"> </argument> - <argument index="1" name="validate_with_format" type="int" default="-1"> + <argument index="1" name="samples" type="int" enum="RenderingDevice.TextureSamples" default="0"> + </argument> + <argument index="2" name="validate_with_format" type="int" default="-1"> </argument> <description> </description> @@ -318,7 +374,7 @@ <method name="framebuffer_format_create_empty"> <return type="int"> </return> - <argument index="0" name="size" type="Vector2i"> + <argument index="0" name="samples" type="int" enum="RenderingDevice.TextureSamples" default="0"> </argument> <description> </description> @@ -347,6 +403,12 @@ <description> </description> </method> + <method name="full_barrier"> + <return type="void"> + </return> + <description> + </description> + </method> <method name="get_captured_timestamp_cpu_time" qualifiers="const"> <return type="int"> </return> @@ -383,6 +445,24 @@ <description> </description> </method> + <method name="get_device_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_device_pipeline_cache_uuid" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_device_vendor_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> <method name="get_frame_delay" qualifiers="const"> <return type="int"> </return> @@ -410,7 +490,7 @@ </argument> <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )"> </argument> - <argument index="3" name="arg3" type="bool" default="false"> + <argument index="3" name="use_restart_indices" type="bool" default="false"> </argument> <description> </description> @@ -485,6 +565,16 @@ <description> </description> </method> + <method name="set_resource_name"> + <return type="void"> + </return> + <argument index="0" name="id" type="RID"> + </argument> + <argument index="1" name="name" type="String"> + </argument> + <description> + </description> + </method> <method name="shader_compile_from_source"> <return type="RDShaderBytecode"> </return> @@ -562,7 +652,7 @@ </argument> <argument index="5" name="layer_count" type="int"> </argument> - <argument index="6" name="sync_with_draw" type="bool" default="false"> + <argument index="6" name="post_barrier" type="int" default="7"> </argument> <description> </description> @@ -588,7 +678,7 @@ </argument> <argument index="8" name="dst_layer" type="int"> </argument> - <argument index="9" name="sync_with_draw" type="bool" default="false"> + <argument index="9" name="post_barrier" type="int" default="7"> </argument> <description> </description> @@ -674,7 +764,7 @@ </argument> <argument index="1" name="to_texture" type="RID"> </argument> - <argument index="2" name="sync_with_draw" type="bool" default="false"> + <argument index="2" name="post_barrier" type="int" default="7"> </argument> <description> </description> @@ -688,7 +778,7 @@ </argument> <argument index="2" name="data" type="PackedByteArray"> </argument> - <argument index="3" name="sync_with_draw" type="bool" default="false"> + <argument index="3" name="post_barrier" type="int" default="7"> </argument> <description> </description> @@ -745,6 +835,16 @@ </method> </methods> <constants> + <constant name="BARRIER_MASK_RASTER" value="1"> + </constant> + <constant name="BARRIER_MASK_COMPUTE" value="2"> + </constant> + <constant name="BARRIER_MASK_TRANSFER" value="4"> + </constant> + <constant name="BARRIER_MASK_ALL" value="7"> + </constant> + <constant name="BARRIER_MASK_NO_BARRIER" value="8"> + </constant> <constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat"> </constant> <constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat"> @@ -1507,13 +1607,17 @@ </constant> <constant name="INITIAL_ACTION_CLEAR" value="0" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_KEEP" value="1" enum="InitialAction"> + <constant name="INITIAL_ACTION_CLEAR_REGION" value="1" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="2" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_KEEP" value="3" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction"> + <constant name="INITIAL_ACTION_DROP" value="4" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_CONTINUE" value="3" enum="InitialAction"> + <constant name="INITIAL_ACTION_CONTINUE" value="5" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_MAX" value="4" enum="InitialAction"> + <constant name="INITIAL_ACTION_MAX" value="6" enum="InitialAction"> </constant> <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction"> </constant> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 4be97b7d3d..dfd4a5c2d5 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1802,7 +1802,7 @@ Updates a specific region of a vertex buffer for the specified surface. Warning: this function alters the vertex buffer directly with no safety mechanisms, you can easily corrupt your mesh. </description> </method> - <method name="multimesh_allocate"> + <method name="multimesh_allocate_data"> <return type="void"> </return> <argument index="0" name="multimesh" type="RID"> @@ -2549,7 +2549,7 @@ Sets a shader's default texture. Overwrites the texture given by name. </description> </method> - <method name="skeleton_allocate"> + <method name="skeleton_allocate_data"> <return type="void"> </return> <argument index="0" name="skeleton" type="RID"> @@ -2559,7 +2559,6 @@ <argument index="2" name="is_2d_skeleton" type="bool" default="false"> </argument> <description> - Allocates the GPU buffers for this skeleton. </description> </method> <method name="skeleton_bone_get_transform" qualifiers="const"> @@ -2949,6 +2948,8 @@ </argument> <argument index="1" name="size" type="int"> </argument> + <argument index="2" name="use_16_bits" type="bool" default="false"> + </argument> <description> Sets the size of the shadow atlas's images (used for omni and spot lights). The value will be rounded up to the nearest power of 2. </description> @@ -3451,7 +3452,7 @@ <constant name="VIEWPORT_DEBUG_DRAW_GI_BUFFER" value="17" enum="ViewportDebugDraw"> </constant> <constant name="SKY_MODE_QUALITY" value="1" enum="SkyMode"> - Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/reflections/sky_reflections/ggx_samples]. </constant> <constant name="SKY_MODE_REALTIME" value="3" enum="SkyMode"> Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 54984b7785..2548f8d911 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -4,7 +4,7 @@ Base class for all resources. </brief_description> <description> - Resource is the base class for all Godot-specific resource types, serving primarily as data containers. Unlike [Object]s, they are reference-counted and freed when no longer in use. They are also cached once loaded from disk, so that any further attempts to load a resource from a given path will return the same reference (all this in contrast to a [Node], which is not reference-counted and can be instanced from disk as many times as desired). Resources can be saved externally on disk or bundled into another object, such as a [Node] or another resource. + Resource is the base class for all Godot-specific resource types, serving primarily as data containers. Since they inherit from [Reference], resources are reference-counted and freed when no longer in use. They are also cached once loaded from disk, so that any further attempts to load a resource from a given path will return the same reference (all this in contrast to a [Node], which is not reference-counted and can be instanced from disk as many times as desired). Resources can be saved externally on disk or bundled into another object, such as a [Node] or another resource. [b]Note:[/b] In C#, resources will not be freed instantly after they are no longer in use. Instead, garbage collection will run periodically and will free resources that are no longer in use. This means that unused resources will linger on for a while before being removed. </description> <tutorials> @@ -29,6 +29,19 @@ [b]Note:[/b] If [code]subresources[/code] is [code]true[/code], this method will only perform a shallow copy. Nested resources within subresources will not be duplicated and will still be shared. </description> </method> + <method name="emit_changed"> + <return type="void"> + </return> + <description> + Emits the [signal changed] signal. + If external objects which depend on this resource should be updated, this method must be called manually whenever the state of this resource has changed (such as modification of properties). + The method is equivalent to: + [codeblock] + emit_signal("changed") + [/codeblock] + [b]Note:[/b] This method is called automatically for built-in resources. + </description> + </method> <method name="get_local_scene" qualifiers="const"> <return type="Node"> </return> @@ -66,7 +79,7 @@ If [code]true[/code], the resource will be made unique in each instance of its local scene. It can thus be modified in a scene instance without impacting other instances of that same scene. </member> <member name="resource_name" type="String" setter="set_name" getter="get_name" default=""""> - The name of the resource. This is an optional identifier. + The name of the resource. This is an optional identifier. If [member resource_name] is not empty, its value will be displayed to represent the current resource in the editor inspector. For built-in scripts, the [member resource_name] will be displayed as the tab name in the script editor. </member> <member name="resource_path" type="String" setter="set_path" getter="get_path" default=""""> The path to the resource. In case it has its own file, it will return its filepath. If it's tied to the scene, it will return the scene's path, followed by the resource's index. diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml index ad0c438f98..2683156ec5 100644 --- a/doc/classes/ResourceFormatLoader.xml +++ b/doc/classes/ResourceFormatLoader.xml @@ -57,8 +57,13 @@ </argument> <argument index="1" name="original_path" type="String"> </argument> + <argument index="2" name="use_sub_threads" type="bool"> + </argument> + <argument index="3" name="cache_mode" type="int"> + </argument> <description> Loads a resource when the engine finds this loader to be compatible. If the loaded resource is the result of an import, [code]original_path[/code] will target the source file. Returns a [Resource] object on success, or an [enum Error] constant in case of failure. + The [code]cache_mode[/code] property defines whether and how the cache should be used or updated when loading the resource. See [enum CacheMode] for details. </description> </method> <method name="rename_dependencies" qualifiers="virtual"> @@ -75,5 +80,11 @@ </method> </methods> <constants> + <constant name="CACHE_MODE_IGNORE" value="0" enum="CacheMode"> + </constant> + <constant name="CACHE_MODE_REUSE" value="1" enum="CacheMode"> + </constant> + <constant name="CACHE_MODE_REPLACE" value="2" enum="CacheMode"> + </constant> </constants> </class> diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index c55a51c7ae..c81b21333f 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -58,13 +58,13 @@ </argument> <argument index="1" name="type_hint" type="String" default=""""> </argument> - <argument index="2" name="no_cache" type="bool" default="false"> + <argument index="2" name="cache_mode" type="int" enum="ResourceLoader.CacheMode" default="1"> </argument> <description> Loads a resource at the given [code]path[/code], caching the result for further access. The registered [ResourceFormatLoader]s are queried sequentially to find the first one which can handle the file's extension, and then attempt loading. If loading fails, the remaining ResourceFormatLoaders are also attempted. An optional [code]type_hint[/code] can be used to further specify the [Resource] type that should be handled by the [ResourceFormatLoader]. Anything that inherits from [Resource] can be used as a type hint, for example [Image]. - If [code]no_cache[/code] is [code]true[/code], the resource cache will be bypassed and the resource will be loaded anew. Otherwise, the cached resource will be returned if it exists. + The [code]cache_mode[/code] property defines whether and how the cache should be used or updated when loading the resource. See [enum CacheMode] for details. Returns an empty resource if no [ResourceFormatLoader] could handle the file. GDScript has a simplified [method @GDScript.load] built-in method which can be used in most situations, leaving the use of [ResourceLoader] for more advanced scenarios. </description> @@ -127,5 +127,11 @@ <constant name="THREAD_LOAD_LOADED" value="3" enum="ThreadLoadStatus"> The resource was loaded successfully and can be accessed via [method load_threaded_get]. </constant> + <constant name="CACHE_MODE_IGNORE" value="0" enum="CacheMode"> + </constant> + <constant name="CACHE_MODE_REUSE" value="1" enum="CacheMode"> + </constant> + <constant name="CACHE_MODE_REPLACE" value="2" enum="CacheMode"> + </constant> </constants> </class> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 147e41bf1b..7ca70f5a7a 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -70,7 +70,35 @@ <return type="int"> </return> <description> - Returns the total number of newlines in the tag stack's text tags. Considers wrapped text as one line. + Returns the total number of lines in the text. Wrapped text is counted as multiple lines. + </description> + </method> + <method name="get_paragraph_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the total number of paragraphs (newlines or [code]p[/code] tags in the tag stack's text tags). Considers wrapped text as one paragraph. + </description> + </method> + <method name="get_selected_text" qualifiers="const"> + <return type="String"> + </return> + <description> + Returns the current selection text. Does not include BBCodes. + </description> + </method> + <method name="get_selection_from" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the current selection first character index if a selection is active, [code]-1[/code] otherwise. Does not include BBCodes. + </description> + </method> + <method name="get_selection_to" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the current selection last character index if a selection is active, [code]-1[/code] otherwise. Does not include BBCodes. </description> </method> <method name="get_total_character_count" qualifiers="const"> @@ -94,6 +122,13 @@ Returns the number of visible lines. </description> </method> + <method name="get_visible_paragraph_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of visible paragraphs. A paragraph is considered visible if at least one of its lines is visible. + </description> + </method> <method name="install_effect"> <return type="void"> </return> @@ -342,6 +377,15 @@ Scrolls the window's top line to match [code]line[/code]. </description> </method> + <method name="scroll_to_paragraph"> + <return type="void"> + </return> + <argument index="0" name="paragraph" type="int"> + </argument> + <description> + Scrolls the window's top line to match first line of the [code]paragraph[/code]. + </description> + </method> <method name="set_cell_border_color"> <return type="void"> </return> @@ -455,6 +499,7 @@ </member> <member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1"> The restricted number of characters to display in the label. If [code]-1[/code], all characters will be displayed. + [b]Note:[/b] Setting this property updates [member percent_visible] based on current [method get_total_character_count]. </member> </members> <signals> @@ -573,10 +618,13 @@ <theme_item name="focus" type="StyleBox"> The background The background used when the [RichTextLabel] is focused. </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The default tint of text outline. + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )"> The color of selected text, used when [member selection_enabled] is [code]true[/code]. </theme_item> - <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 0 )"> + <theme_item name="font_shadow_color" type="Color" default="Color( 0, 0, 0, 0 )"> The color of the font's shadow. </theme_item> <theme_item name="italics_font" type="Font"> @@ -603,6 +651,9 @@ <theme_item name="normal_font_size" type="int"> The default text font size. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="selection_color" type="Color" default="Color( 0.1, 0.1, 1, 0.8 )"> The color of the selection box. </theme_item> diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index 2a0b44f3f3..6b27c77f26 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -180,14 +180,16 @@ <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a body enters into contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. + Emitted when a collision with another [PhysicsBody2D] or [TileMap] occurs. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap]. </description> </signal> <signal name="body_exited"> <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a body exits contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. + Emitted when the collision with another [PhysicsBody2D] or [TileMap] ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap]. </description> </signal> <signal name="body_shape_entered"> @@ -200,7 +202,11 @@ <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a body enters into contact with this one. Reports colliding shape information. See [CollisionObject2D] for shape index information. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. + Emitted when one of this RigidBody2D's [Shape2D]s collides with another [PhysicsBody2D] or [TileMap]'s [Shape2D]s. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body_id[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D]. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap]. + [code]body_shape[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. + [code]local_shape[/code] the index of the [Shape2D] of this RigidBody2D used by the [PhysicsServer2D]. </description> </signal> <signal name="body_shape_exited"> @@ -213,7 +219,11 @@ <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a body shape exits contact with this one. Reports colliding shape information. See [CollisionObject2D] for shape index information. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. + Emitted when the collision between one of this RigidBody2D's [Shape2D]s and another [PhysicsBody2D] or [TileMap]'s [Shape2D]s ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s. + [code]body_id[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D]. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap]. + [code]body_shape[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. + [code]local_shape[/code] the index of the [Shape2D] of this RigidBody2D used by the [PhysicsServer2D]. </description> </signal> <signal name="sleeping_state_changed"> diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml index b4171d36fc..1c6c8852a9 100644 --- a/doc/classes/RigidBody3D.xml +++ b/doc/classes/RigidBody3D.xml @@ -204,14 +204,16 @@ <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a body enters into contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. + Emitted when a collision with another [PhysicsBody3D] or [GridMap] occurs. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap]. </description> </signal> <signal name="body_exited"> <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a body shape exits contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. + Emitted when the collision with another [PhysicsBody3D] or [GridMap] ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap]. </description> </signal> <signal name="body_shape_entered"> @@ -224,8 +226,11 @@ <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a body enters into contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. - This signal not only receives the body that collided with this one, but also its [RID] ([code]body_id[/code]), the shape index from the colliding body ([code]body_shape[/code]), and the shape index from this body ([code]local_shape[/code]) the other body collided with. + Emitted when one of this RigidBody3D's [Shape3D]s collides with another [PhysicsBody3D] or [GridMap]'s [Shape3D]s. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body_id[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap]. + [code]body_shape[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. + [code]local_shape[/code] the index of the [Shape3D] of this RigidBody3D used by the [PhysicsServer3D]. [b]Note:[/b] Bullet physics cannot identify the shape index when using a [ConcavePolygonShape3D]. Don't use multiple [CollisionShape3D]s when using a [ConcavePolygonShape3D] with Bullet physics if you need shape indices. </description> </signal> @@ -239,8 +244,11 @@ <argument index="3" name="local_shape" type="int"> </argument> <description> - Emitted when a body shape exits contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. - This signal not only receives the body that stopped colliding with this one, but also its [RID] ([code]body_id[/code]), the shape index from the colliding body ([code]body_shape[/code]), and the shape index from this body ([code]local_shape[/code]) the other body stopped colliding with. + Emitted when the collision between one of this RigidBody3D's [Shape3D]s and another [PhysicsBody3D] or [GridMap]'s [Shape3D]s ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s. + [code]body_id[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. [GridMap]s are detected if the Meshes have [Shape3D]s. + [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap]. + [code]body_shape[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. + [code]local_shape[/code] the index of the [Shape3D] of this RigidBody3D used by the [PhysicsServer3D]. [b]Note:[/b] Bullet physics cannot identify the shape index when using a [ConcavePolygonShape3D]. Don't use multiple [CollisionShape3D]s when using a [ConcavePolygonShape3D] with Bullet physics if you need shape indices. </description> </signal> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 2c99815abf..c54e2f4b88 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -64,10 +64,10 @@ </return> <argument index="0" name="time_sec" type="float"> </argument> - <argument index="1" name="pause_mode_process" type="bool" default="true"> + <argument index="1" name="process_always" type="bool" default="true"> </argument> <description> - Returns a [SceneTreeTimer] which will [signal SceneTreeTimer.timeout] after the given time in seconds elapsed in this [SceneTree]. If [code]pause_mode_process[/code] is set to [code]false[/code], pausing the [SceneTree] will also pause the timer. + Returns a [SceneTreeTimer] which will [signal SceneTreeTimer.timeout] after the given time in seconds elapsed in this [SceneTree]. If [code]process_always[/code] is set to [code]false[/code], pausing the [SceneTree] will also pause the timer. Commonly used to create a one-shot delay timer as in the following example: [codeblock] func some_function(): @@ -75,6 +75,7 @@ yield(get_tree().create_timer(1.0), "timeout") print("end") [/codeblock] + The timer will be automatically freed after its time elapses. </description> </method> <method name="get_frame" qualifiers="const"> @@ -180,10 +181,12 @@ <method name="quit"> <return type="void"> </return> - <argument index="0" name="exit_code" type="int" default="-1"> + <argument index="0" name="exit_code" type="int" default="0"> </argument> <description> - Quits the application at the end of the current iteration. A process [code]exit_code[/code] can optionally be passed as an argument. If this argument is [code]0[/code] or greater, it will override the [member OS.exit_code] defined before quitting the application. + Quits the application at the end of the current iteration. Argument [code]exit_code[/code] can optionally be given (defaulting to 0) to customize the exit status code. + By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error. + For portability reasons, the exit code should be set between 0 and 125 (inclusive). </description> </method> <method name="reload_current_scene"> @@ -360,6 +363,11 @@ Emitted whenever the [SceneTree] hierarchy changed (children being moved or renamed, etc.). </description> </signal> + <signal name="tree_process_mode_changed"> + <description> + This signal is only emitted in the editor, it allows the editor to update the visibility of disabled nodes. Emitted whenever any node's [member Node.process_mode] is changed. + </description> + </signal> </signals> <constants> <constant name="GROUP_CALL_DEFAULT" value="0" enum="GroupCallFlags"> diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index d5a32dd20c..28620bd29b 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -37,6 +37,7 @@ <return type="ScriptEditorBase"> </return> <description> + Returns the [ScriptEditorBase] object that the user is currently editing. </description> </method> <method name="get_current_script"> @@ -60,6 +61,7 @@ <return type="Array"> </return> <description> + Returns an array with all [ScriptEditorBase] objects which are currently open in editor. </description> </method> <method name="get_open_scripts" qualifiers="const"> @@ -95,6 +97,8 @@ <argument index="0" name="syntax_highlighter" type="EditorSyntaxHighlighter"> </argument> <description> + Registers the [EditorSyntaxHighlighter] to the editor, the [EditorSyntaxHighlighter] will be available on all open scripts. + [b]Note:[/b] Does not apply to scripts that are already opened. </description> </method> <method name="unregister_syntax_highlighter"> @@ -103,6 +107,8 @@ <argument index="0" name="syntax_highlighter" type="EditorSyntaxHighlighter"> </argument> <description> + Unregisters the [EditorSyntaxHighlighter] from the editor. + [b]Note:[/b] The [EditorSyntaxHighlighter] will still be applied to scripts that are already opened. </description> </method> </methods> diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml index 9968ae06c3..ee498de302 100644 --- a/doc/classes/ScriptEditorBase.xml +++ b/doc/classes/ScriptEditorBase.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ScriptEditorBase" inherits="VBoxContainer" version="4.0"> <brief_description> + Base editor for editing scripts in the [ScriptEditor]. </brief_description> <description> + Base editor for editing scripts in the [ScriptEditor], this does not include documentation items. </description> <tutorials> </tutorials> @@ -13,34 +15,40 @@ <argument index="0" name="highlighter" type="Object"> </argument> <description> + Adds a [EditorSyntaxHighlighter] to the open script. </description> </method> </methods> <signals> <signal name="edited_script_changed"> <description> + Emitted after script validation. For visual scripts on modification. </description> </signal> <signal name="go_to_help"> <argument index="0" name="what" type="String"> </argument> <description> + Emitted when the user requests a specific documentation page. </description> </signal> <signal name="name_changed"> <description> + Emitted after script validation or when the edited resource has changed. Not used by visual scripts. </description> </signal> <signal name="replace_in_files_requested"> <argument index="0" name="text" type="String"> </argument> <description> + Emitted when the user request to find and replace text in the file system. Not used by visual scripts. </description> </signal> <signal name="request_help"> <argument index="0" name="topic" type="String"> </argument> <description> + Emitted when the user requests contextual help. </description> </signal> <signal name="request_open_script_at_line"> @@ -49,16 +57,19 @@ <argument index="1" name="line" type="int"> </argument> <description> + Emitted when the user requests a script. </description> </signal> <signal name="request_save_history"> <description> + Emitted when the user contextual goto and the item is in the same script. </description> </signal> <signal name="search_in_files_requested"> <argument index="0" name="text" type="String"> </argument> <description> + Emitted when the user request to search text in the file system. Not used by visual scripts. </description> </signal> </signals> diff --git a/doc/classes/Shape3D.xml b/doc/classes/Shape3D.xml index 2d8bb5d051..f3e62175c6 100644 --- a/doc/classes/Shape3D.xml +++ b/doc/classes/Shape3D.xml @@ -13,7 +13,8 @@ </methods> <members> <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.04"> - The collision margin for the shape. + The collision margin for the shape. Used in Bullet Physics only. + Collision margins allows collision detection to be more efficient by adding an extra shell around shapes. Collision algorithms are more expensive when objects overlap by more than their margin, so a higher value for margins is better for performance, at the cost of accuracy around edges as it makes them less sharp. </member> </members> <constants> diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml index a77515b3e6..d9553a3be3 100644 --- a/doc/classes/Sky.xml +++ b/doc/classes/Sky.xml @@ -52,13 +52,13 @@ Automatically selects the appropriate process mode based on your sky shader. If your shader uses [code]TIME[/code] or [code]POSITION[/code], this will use [constant PROCESS_MODE_REALTIME]. If your shader uses any of the [code]LIGHT_*[/code] variables or any custom uniforms, this uses [constant PROCESS_MODE_INCREMENTAL]. Otherwise, this defaults to [constant PROCESS_MODE_QUALITY]. </constant> <constant name="PROCESS_MODE_QUALITY" value="1" enum="ProcessMode"> - Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/reflections/sky_reflections/ggx_samples]. </constant> <constant name="PROCESS_MODE_INCREMENTAL" value="2" enum="ProcessMode"> - Uses the same high quality importance sampling to process the radiance map as [constant PROCESS_MODE_QUALITY], but updates over several frames. The number of frames is determined by [member ProjectSettings.rendering/quality/reflections/roughness_layers]. Use this when you need highest quality radiance maps, but have a sky that updates slowly. + Uses the same high quality importance sampling to process the radiance map as [constant PROCESS_MODE_QUALITY], but updates over several frames. The number of frames is determined by [member ProjectSettings.rendering/reflections/sky_reflections/roughness_layers]. Use this when you need highest quality radiance maps, but have a sky that updates slowly. </constant> <constant name="PROCESS_MODE_REALTIME" value="3" enum="ProcessMode"> - Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. If you need better quality, but still need to update the sky every frame, consider turning on [member ProjectSettings.rendering/quality/reflections/fast_filter_high_quality]. + Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. If you need better quality, but still need to update the sky every frame, consider turning on [member ProjectSettings.rendering/reflections/sky_reflections/fast_filter_high_quality]. [b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member radiance_size] must be set to [constant RADIANCE_SIZE_256]. </constant> </constants> diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml index d3ab955570..04e201e1bd 100644 --- a/doc/classes/SoftBody3D.xml +++ b/doc/classes/SoftBody3D.xml @@ -77,7 +77,7 @@ </method> </methods> <members> - <member name="areaAngular_stiffness" type="float" setter="set_areaAngular_stiffness" getter="get_areaAngular_stiffness" default="0.5"> + <member name="angular_stiffness" type="float" setter="set_angular_stiffness" getter="get_angular_stiffness" default="0.0"> </member> <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1"> The physics layers this SoftBody3D is in. @@ -87,11 +87,11 @@ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> The physics layers this SoftBody3D scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> - <member name="damping_coefficient" type="float" setter="set_damping_coefficient" getter="get_damping_coefficient" default="0.01"> + <member name="damping_coefficient" type="float" setter="set_damping_coefficient" getter="get_damping_coefficient" default="0.0"> </member> <member name="drag_coefficient" type="float" setter="set_drag_coefficient" getter="get_drag_coefficient" default="0.0"> </member> - <member name="linear_stiffness" type="float" setter="set_linear_stiffness" getter="get_linear_stiffness" default="0.5"> + <member name="linear_stiffness" type="float" setter="set_linear_stiffness" getter="get_linear_stiffness" default="0.0"> </member> <member name="parent_collision_ignore" type="NodePath" setter="set_parent_collision_ignore" getter="get_parent_collision_ignore" default="NodePath("")"> [NodePath] to a [CollisionObject3D] this SoftBody3D should avoid clipping. @@ -103,13 +103,13 @@ <member name="ray_pickable" type="bool" setter="set_ray_pickable" getter="is_ray_pickable" default="true"> If [code]true[/code], the [SoftBody3D] will respond to [RayCast3D]s. </member> - <member name="simulation_precision" type="int" setter="set_simulation_precision" getter="get_simulation_precision" default="5"> + <member name="simulation_precision" type="int" setter="set_simulation_precision" getter="get_simulation_precision" default="0"> Increasing this value will improve the resulting simulation, but can affect performance. Use with care. </member> - <member name="total_mass" type="float" setter="set_total_mass" getter="get_total_mass" default="1.0"> + <member name="total_mass" type="float" setter="set_total_mass" getter="get_total_mass" default="0.0"> The SoftBody3D's mass. </member> - <member name="volume_stiffness" type="float" setter="set_volume_stiffness" getter="get_volume_stiffness" default="0.5"> + <member name="volume_stiffness" type="float" setter="set_volume_stiffness" getter="get_volume_stiffness" default="0.0"> </member> </members> <constants> diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml index e674ceb57e..a08d4f5b44 100644 --- a/doc/classes/SpinBox.xml +++ b/doc/classes/SpinBox.xml @@ -15,6 +15,7 @@ [/codeblock] The above code will create a [SpinBox], disable context menu on it and set the text alignment to right. See [Range] class for more options over the [SpinBox]. + [b]Note:[/b] [SpinBox] relies on an underlying [LineEdit] node. To theme a [SpinBox]'s background, add theme items for [LineEdit] and customize them. </description> <tutorials> </tutorials> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 44b08408c1..078520a095 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -102,7 +102,7 @@ This mode performs standard alpha blending. It can display translucent areas, but transparency sorting issues may be visible when multiple transparent materials are overlapping. </constant> <constant name="ALPHA_CUT_DISCARD" value="1" enum="AlphaCutMode"> - This mode only allows fully transparent or fully opaque pixels. Harsh edges will be visible unless some form of screen-space antialiasing is enabled (see [member ProjectSettings.rendering/quality/screen_filters/screen_space_aa]). On the bright side, this mode doesn't suffer from transparency sorting issues when multiple transparent materials are overlapping. This mode is also known as [i]alpha testing[/i] or [i]1-bit transparency[/i]. + This mode only allows fully transparent or fully opaque pixels. Harsh edges will be visible unless some form of screen-space antialiasing is enabled (see [member ProjectSettings.rendering/anti_aliasing/quality/screen_space_aa]). On the bright side, this mode doesn't suffer from transparency sorting issues when multiple transparent materials are overlapping. This mode is also known as [i]alpha testing[/i] or [i]1-bit transparency[/i]. </constant> <constant name="ALPHA_CUT_OPAQUE_PREPASS" value="2" enum="AlphaCutMode"> This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 79f21a0e70..c03f6357ab 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -63,9 +63,18 @@ <method name="bin_to_int"> <return type="int"> </return> - <argument index="0" name="with_prefix" type="bool" default="true"> - </argument> <description> + Converts a string containing a binary number into an integer. Binary strings can either be prefixed with [code]0b[/code] or not, and they can also start with a [code]-[/code] before the optional prefix. + [codeblocks] + [gdscript] + print("0x101".bin_to_int()) # Prints "5". + print("101".bin_to_int()) # Prints "5". + [/gdscript] + [csharp] + GD.Print("0x101".BinToInt()); // Prints "5". + GD.Print("101".BinToInt()); // Prints "5". + [/csharp] + [/codeblocks] </description> </method> <method name="c_escape"> @@ -221,34 +230,18 @@ <method name="hex_to_int"> <return type="int"> </return> - <argument index="0" name="with_prefix" type="bool" default="true"> - </argument> - <description> - Converts a string containing a hexadecimal number into a decimal integer. If [code]with_prefix[/code] is [code]true[/code], the hexadecimal string should start with the [code]0x[/code] prefix, otherwise [code]0[/code] is returned. - [codeblock] - print("0xff".hex_to_int()) # Print "255" - print("ab".hex_to_int(false)) # Print "171" - [/codeblock] - </description> - </method> - <method name="http_escape"> - <return type="String"> - </return> <description> - Escapes (encodes) a string to URL friendly format. Also referred to as 'URL encode'. - [codeblock] - print("https://example.org/?escaped=" + "Godot Engine:'docs'".http_escape()) - [/codeblock] - </description> - </method> - <method name="http_unescape"> - <return type="String"> - </return> - <description> - Unescapes (decodes) a string in URL encoded format. Also referred to as 'URL decode'. - [codeblock] - print("https://example.org/?escaped=" + "Godot%20Engine%3A%27docs%27".http_unescape()) - [/codeblock] + Converts a string containing a hexadecimal number into an integer. Hexadecimal strings can either be prefixed with [code]0x[/code] or not, and they can also start with a [code]-[/code] before the optional prefix. + [codeblocks] + [gdscript] + print("0xff".hex_to_int()) # Prints "255". + print("ab".hex_to_int()) # Prints "171". + [/gdscript] + [csharp] + GD.Print("0xff".HexToInt()); // Prints "255". + GD.Print("ab".HexToInt()); // Prints "171". + [/csharp] + [/codeblocks] </description> </method> <method name="insert"> @@ -406,7 +399,8 @@ <argument index="0" name="chars" type="String"> </argument> <description> - Returns a copy of the string with characters removed from the left. + Returns a copy of the string with characters removed from the left. The [code]chars[/code] argument is a string specifying the set of characters to be removed. + [b]Note:[/b] The [code]chars[/code] is not a prefix. See [method trim_prefix] method that will remove a single prefix string rather than a set of characters. </description> </method> <method name="match"> @@ -546,15 +540,6 @@ <description> </description> </method> - <method name="ord_at"> - <return type="int"> - </return> - <argument index="0" name="at" type="int"> - </argument> - <description> - Returns the character code at position [code]at[/code]. - </description> - </method> <method name="pad_decimals"> <return type="String"> </return> @@ -573,20 +558,6 @@ Formats a number to have an exact number of [code]digits[/code] before the decimal point. </description> </method> - <method name="percent_decode"> - <return type="String"> - </return> - <description> - Decode a percent-encoded string. See [method percent_encode]. - </description> - </method> - <method name="percent_encode"> - <return type="String"> - </return> - <description> - Percent-encodes a string. Encodes parameters in a URL when sending a HTTP GET request (and bodies of form-urlencoded POST requests). - </description> - </method> <method name="plus_file"> <return type="String"> </return> @@ -698,7 +669,8 @@ <argument index="0" name="chars" type="String"> </argument> <description> - Returns a copy of the string with characters removed from the right. + Returns a copy of the string with characters removed from the right. The [code]chars[/code] argument is a string specifying the set of characters to be removed. + [b]Note:[/b] The [code]chars[/code] is not a suffix. See [method trim_suffix] method that will remove a single suffix string rather than a set of characters. </description> </method> <method name="sha1_buffer"> @@ -876,6 +848,45 @@ Removes a given string from the end if it ends with it or leaves the string unchanged. </description> </method> + <method name="unicode_at"> + <return type="int"> + </return> + <argument index="0" name="at" type="int"> + </argument> + <description> + Returns the character code at position [code]at[/code]. + </description> + </method> + <method name="uri_decode"> + <return type="String"> + </return> + <description> + Decodes a string in URL encoded format. This is meant to decode parameters in a URL when receiving an HTTP request. + [codeblocks] + [gdscript] + print("https://example.org/?escaped=" + "Godot%20Engine%3A%27docs%27".uri_decode()) + [/gdscript] + [csharp] + GD.Print("https://example.org/?escaped=" + "Godot%20Engine%3a%27Docs%27".URIDecode()); + [/csharp] + [/codeblocks] + </description> + </method> + <method name="uri_encode"> + <return type="String"> + </return> + <description> + Encodes a string to URL friendly format. This is meant to encode parameters in a URL when sending an HTTP request. + [codeblocks] + [gdscript] + print("https://example.org/?escaped=" + "Godot Engine:'docs'".uri_encode()) + [/gdscript] + [csharp] + GD.Print("https://example.org/?escaped=" + "Godot Engine:'docs'".URIEncode()); + [/csharp] + [/codeblocks] + </description> + </method> <method name="xml_escape"> <return type="String"> </return> diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml index 13ea7df294..d66ae210ec 100644 --- a/doc/classes/StyleBoxFlat.xml +++ b/doc/classes/StyleBoxFlat.xml @@ -4,12 +4,12 @@ Customizable [StyleBox] with a given set of parameters (no texture required). </brief_description> <description> - This [StyleBox] can be used to achieve all kinds of looks without the need of a texture. Those properties are customizable: + This [StyleBox] can be used to achieve all kinds of looks without the need of a texture. The following properties are customizable: - Color - Border width (individual width for each border) - Rounded corners (individual radius for each corner) - Shadow (with blur and offset) - Setting corner radius to high values is allowed. As soon as corners would overlap, the stylebox will switch to a relative system. Example: + Setting corner radius to high values is allowed. As soon as corners overlap, the stylebox will switch to a relative system. Example: [codeblock] height = 30 corner_radius_top_left = 50 @@ -178,8 +178,8 @@ Border width for the top border. </member> <member name="corner_detail" type="int" setter="set_corner_detail" getter="get_corner_detail" default="8"> - This sets the amount of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value, you should take the corner radius ([method set_corner_radius_all]) into account. - For corner radii smaller than 10, [code]4[/code] or [code]5[/code] should be enough. For corner radii smaller than 30, values between [code]8[/code] and [code]12[/code] should be enough. + This sets the number of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value, you should take the corner radius ([method set_corner_radius_all]) into account. + For corner radii less than 10, [code]4[/code] or [code]5[/code] should be enough. For corner radii less than 30, values between [code]8[/code] and [code]12[/code] should be enough. A corner detail of [code]1[/code] will result in chamfered corners instead of rounded corners, which is useful for some artistic effects. </member> <member name="corner_radius_bottom_left" type="int" setter="set_corner_radius" getter="get_corner_radius" default="0"> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index e10b65e309..331de4284e 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -155,8 +155,8 @@ <argument index="0" name="flip" type="bool" default="false"> </argument> <description> - Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. - Requires the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]. + Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. [method generate_normals] should be called [i]after[/i] generating geometry and [i]before[/i] committing the mesh using [method commit] or [method commit_to_arrays]. + [b]Note:[/b] [method generate_normals] only works if the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]. </description> </method> <method name="generate_tangents"> diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml index 2d6e3de02a..642d75fa9b 100644 --- a/doc/classes/SyntaxHighlighter.xml +++ b/doc/classes/SyntaxHighlighter.xml @@ -1,50 +1,83 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="SyntaxHighlighter" inherits="Resource" version="4.0"> <brief_description> + Base Syntax highlighter resource for [TextEdit]. </brief_description> <description> + Base syntax highlighter resource all syntax highlighters extend from, provides syntax highlighting data to [TextEdit]. + The associated [TextEdit] node will call into the [SyntaxHighlighter] on a as needed basis. + [b]Note:[/b] Each Syntax highlighter instance should not be shared across multiple [TextEdit] nodes. </description> <tutorials> </tutorials> <methods> + <method name="_clear_highlighting_cache" qualifiers="virtual"> + <return type="void"> + </return> + <description> + Virtual method which can be overridden to clear any local caches. + </description> + </method> <method name="_get_line_syntax_highlighting" qualifiers="virtual"> <return type="Dictionary"> </return> - <argument index="0" name="p_line" type="int"> + <argument index="0" name="line" type="int"> </argument> <description> + Virtual method which can be overridden to return syntax highlighting data. + See [method get_line_syntax_highlighting] for more details. </description> </method> <method name="_update_cache" qualifiers="virtual"> <return type="void"> </return> <description> + Virtual method which can be overridden to update any local caches. </description> </method> <method name="clear_highlighting_cache"> <return type="void"> </return> <description> + Clears all cached syntax highlighting data. + Then calls overridable method [method _clear_highlighting_cache]. </description> </method> <method name="get_line_syntax_highlighting"> <return type="Dictionary"> </return> - <argument index="0" name="p_line" type="int"> + <argument index="0" name="line" type="int"> </argument> <description> + Returns syntax highlighting data for a single line. If the line is not cached, calls [method _get_line_syntax_highlighting] to calculate the data. + The return [Dictionary] is column number to [Dictionary]. The column number notes the start of a region, the region will end if another region is found, or at the end of the line. The nested [Dictionary] contains the data for that region, currently only the key "color" is supported. + [b]Example return:[/b] + [codeblock] + var color_map = { + 0: { + "color": Color(1, 0, 0) + }, + 5: { + "color": Color(0, 1, 0) + } + } + [/codeblock] + This will color columns 0-4 red, and columns 5-eol in green. </description> </method> <method name="get_text_edit"> <return type="TextEdit"> </return> <description> + Returns the associated [TextEdit] node. </description> </method> <method name="update_cache"> <return type="void"> </return> <description> + Clears then updates the [SyntaxHighlighter] caches. Override [method _update_cache] for a callback. + [b]Note:[/b] This is called automatically when the associated [TextEdit] node, updates its own cache. </description> </method> </methods> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 10cdd0eade..ddf6b465a4 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -198,18 +198,21 @@ <theme_item name="font" type="Font"> The font used to draw tab names. </theme_item> - <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> - Font color of inactive tabs. - </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> Font color of disabled tabs. </theme_item> - <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the tab name. + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> Font color of the currently selected tab. </theme_item> <theme_item name="font_size" type="int"> Font size of the tab names. </theme_item> + <theme_item name="font_unselected_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> + Font color of the other, unselected tabs. + </theme_item> <theme_item name="icon_separation" type="int" default="4"> Space between tab's name and its icon. </theme_item> @@ -225,20 +228,23 @@ <theme_item name="menu_highlight" type="Texture2D"> The icon for the menu button (see [method set_popup]) when it's being hovered with the cursor. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the tab text outline. + </theme_item> <theme_item name="panel" type="StyleBox"> The style for the background fill. </theme_item> <theme_item name="side_margin" type="int" default="8"> The space at the left and right edges of the tab bar. </theme_item> - <theme_item name="tab_bg" type="StyleBox"> - The style of inactive tabs. - </theme_item> <theme_item name="tab_disabled" type="StyleBox"> The style of disabled tabs. </theme_item> - <theme_item name="tab_fg" type="StyleBox"> + <theme_item name="tab_selected" type="StyleBox"> The style of the currently selected tab. </theme_item> + <theme_item name="tab_unselected" type="StyleBox"> + The style of the other, unselected tabs. + </theme_item> </theme_items> </class> diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index 47cf869fe9..df9680bf28 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -359,18 +359,21 @@ <theme_item name="font" type="Font"> The font used to draw tab names. </theme_item> - <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> - Font color of inactive tabs. - </theme_item> - <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> + <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> Font color of disabled tabs. </theme_item> - <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the tab name. + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> Font color of the currently selected tab. </theme_item> <theme_item name="font_size" type="int"> Font size of the tab names. </theme_item> + <theme_item name="font_unselected_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> + Font color of the other, unselected tabs. + </theme_item> <theme_item name="hseparation" type="int" default="4"> The horizontal separation between the tabs. </theme_item> @@ -380,16 +383,19 @@ <theme_item name="increment_highlight" type="Texture2D"> Icon for the right arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor. </theme_item> - <theme_item name="panel" type="StyleBox"> + <theme_item name="outline_size" type="int" default="0"> + The size of the tab text outline. </theme_item> - <theme_item name="tab_bg" type="StyleBox"> - The style of an inactive tab. + <theme_item name="panel" type="StyleBox"> </theme_item> <theme_item name="tab_disabled" type="StyleBox"> - The style of a disabled tab + The style of disabled tabs. </theme_item> - <theme_item name="tab_fg" type="StyleBox"> + <theme_item name="tab_selected" type="StyleBox"> The style of the currently selected tab. </theme_item> + <theme_item name="tab_unselected" type="StyleBox"> + The style of the other, unselected tabs. + </theme_item> </theme_items> </class> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index e8a54c6c20..1d50cd60e5 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -697,7 +697,7 @@ </member> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" /> <member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false"> - If [code]true[/code], custom [code]font_color_selected[/code] will be used for selected text. + If [code]true[/code], custom [code]font_selected_color[/code] will be used for selected text. </member> <member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false"> If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added. @@ -725,6 +725,7 @@ Set additional options for BiDi override. </member> <member name="syntax_highlighter" type="SyntaxHighlighter" setter="set_syntax_highlighter" getter="get_syntax_highlighter"> + Sets the [SyntaxHighlighter] to use. </member> <member name="text" type="String" setter="set_text" getter="get_text" default=""""> String value of the [TextEdit]. @@ -914,7 +915,7 @@ </constants> <theme_items> <theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 0 )"> - Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] has to be enabled. + Sets the background [Color] of this [TextEdit]. </theme_item> <theme_item name="brace_mismatch_color" type="Color" default="Color( 1, 0.2, 0.2, 1 )"> </theme_item> @@ -953,9 +954,12 @@ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Sets the font [Color]. </theme_item> - <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the [TextEdit]. </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> + <theme_item name="font_readonly_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )"> Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled. </theme_item> <theme_item name="font_size" type="int"> @@ -970,6 +974,9 @@ <theme_item name="normal" type="StyleBox"> Sets the [StyleBox] of this [TextEdit]. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="read_only" type="StyleBox"> Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled. </theme_item> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 791646000b..5635ec2be0 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -9,6 +9,19 @@ <tutorials> </tutorials> <methods> + <method name="create_font_bitmap"> + <return type="RID"> + </return> + <argument index="0" name="height" type="float"> + </argument> + <argument index="1" name="ascent" type="float"> + </argument> + <argument index="2" name="base_size" type="int"> + </argument> + <description> + Creates new, empty bitmap font. To free the resulting font, use [method free_rid] method. + </description> + </method> <method name="create_font_memory"> <return type="RID"> </return> @@ -78,6 +91,51 @@ Draws box displaying character hexadecimal code. Used for replacing missing characters. </description> </method> + <method name="font_bitmap_add_char"> + <return type="void"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <argument index="1" name="char" type="int"> + </argument> + <argument index="2" name="texture_idx" type="int"> + </argument> + <argument index="3" name="rect" type="Rect2"> + </argument> + <argument index="4" name="align" type="Vector2"> + </argument> + <argument index="5" name="advance" type="float"> + </argument> + <description> + Adds a character to the font, where [code]character[/code] is the Unicode value, [code]texture[/code] is the texture index, [code]rect[/code] is the region in the texture (in pixels!), [code]align[/code] is the (optional) alignment for the character and [code]advance[/code] is the (optional) advance. + </description> + </method> + <method name="font_bitmap_add_kerning_pair"> + <return type="void"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <argument index="1" name="A" type="int"> + </argument> + <argument index="2" name="B" type="int"> + </argument> + <argument index="3" name="kerning" type="int"> + </argument> + <description> + Adds a kerning pair to the bitmap font as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character. + </description> + </method> + <method name="font_bitmap_add_texture"> + <return type="void"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <argument index="1" name="texture" type="Texture"> + </argument> + <description> + Adds a texture to the bitmap font. + </description> + </method> <method name="font_draw_glyph" qualifiers="const"> <return type="Vector2"> </return> @@ -295,6 +353,24 @@ Returns list of script support overrides. </description> </method> + <method name="font_get_spacing_glyph" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <description> + Returns extra spacing for each glyphs in pixels. + </description> + </method> + <method name="font_get_spacing_space" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <description> + Sets extra spacing for each glyphs in pixels. + </description> + </method> <method name="font_get_supported_chars" qualifiers="const"> <return type="String"> </return> @@ -490,6 +566,28 @@ Adds override for [method font_is_script_supported]. </description> </method> + <method name="font_set_spacing_glyph"> + <return type="void"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <argument index="1" name="value" type="int"> + </argument> + <description> + Returns extra spacing for the space character in pixels. + </description> + </method> + <method name="font_set_spacing_space"> + <return type="void"> + </return> + <argument index="0" name="font" type="RID"> + </argument> + <argument index="1" name="value" type="int"> + </argument> + <description> + Sets extra spacing for the space character in pixels. + </description> + </method> <method name="font_set_variation"> <return type="void"> </return> @@ -655,7 +753,7 @@ <method name="shaped_text_clear"> <return type="void"> </return> - <argument index="0" name="arg0" type="RID"> + <argument index="0" name="rid" type="RID"> </argument> <description> Clears text buffer (removes text and inline objects). diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml index 3f7f22ebcd..9f976838e9 100644 --- a/doc/classes/Theme.xml +++ b/doc/classes/Theme.xml @@ -236,7 +236,8 @@ <argument index="1" name="node_type" type="StringName"> </argument> <description> - Returns the icon [StyleBox] at [code]name[/code] if the theme has [code]node_type[/code]. + Returns the [StyleBox] at [code]name[/code] if the theme has [code]node_type[/code]. + Valid [code]name[/code]s may be found using [method get_stylebox_list]. Valid [code]node_type[/code]s may be found using [method get_stylebox_type_list]. </description> </method> <method name="get_stylebox_list" qualifiers="const"> @@ -246,6 +247,7 @@ </argument> <description> Returns all the [StyleBox]s as a [PackedStringArray] filled with each [StyleBox]'s name, for use in [method get_stylebox], if the theme has [code]node_type[/code]. + Valid [code]node_type[/code]s may be found using [method get_stylebox_type_list]. </description> </method> <method name="get_stylebox_type_list" qualifiers="const"> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index c500052592..a12ef614e3 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -5,6 +5,7 @@ </brief_description> <description> Node for 2D tile-based maps. Tilemaps use a [TileSet] which contain a list of tiles (textures plus optional collision, navigation, and/or occluder shapes) which are used to create grid-based maps. + When doing physics queries against the tilemap, the cell coordinates are encoded as [code]metadata[/code] for each detected collision shape returned by methods such as [method PhysicsDirectSpaceState2D.intersect_shape], [method PhysicsDirectBodyState2D.get_contact_collider_shape_metadata] etc. </description> <tutorials> <link title="Using Tilemaps">https://docs.godotengine.org/en/latest/tutorials/2d/using_tilemaps.html</link> @@ -143,7 +144,7 @@ <argument index="1" name="ignore_half_ofs" type="bool" default="false"> </argument> <description> - Returns the global position corresponding to the given tilemap (grid-based) coordinates. + Returns the local position corresponding to the given tilemap (grid-based) coordinates. Optionally, the tilemap's half offset can be ignored. </description> </method> diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml index ab75e21ce8..5265e75429 100644 --- a/doc/classes/Timer.xml +++ b/doc/classes/Timer.xml @@ -47,8 +47,8 @@ <member name="paused" type="bool" setter="set_paused" getter="is_paused"> If [code]true[/code], the timer is paused and will not process until it is unpaused again, even if [method start] is called. </member> - <member name="process_mode" type="int" setter="set_timer_process_mode" getter="get_timer_process_mode" enum="Timer.TimerProcessMode" default="1"> - Processing mode. See [enum TimerProcessMode]. + <member name="process_callback" type="int" setter="set_timer_process_callback" getter="get_timer_process_callback" enum="Timer.TimerProcessCallback" default="1"> + Processing callback. See [enum TimerProcessCallback]. </member> <member name="time_left" type="float" setter="" getter="get_time_left"> The timer's remaining time in seconds. Returns 0 if the timer is inactive. @@ -66,10 +66,10 @@ </signal> </signals> <constants> - <constant name="TIMER_PROCESS_PHYSICS" value="0" enum="TimerProcessMode"> + <constant name="TIMER_PROCESS_PHYSICS" value="0" enum="TimerProcessCallback"> Update the timer during the physics step at each frame (fixed framerate processing). </constant> - <constant name="TIMER_PROCESS_IDLE" value="1" enum="TimerProcessMode"> + <constant name="TIMER_PROCESS_IDLE" value="1" enum="TimerProcessCallback"> Update the timer during the idle time at each frame. </constant> </constants> diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml index 355804f2a3..bb4c17c531 100644 --- a/doc/classes/TouchScreenButton.xml +++ b/doc/classes/TouchScreenButton.xml @@ -4,7 +4,7 @@ Button for touch screen devices for gameplay use. </brief_description> <description> - TouchScreenButton allows you to create on-screen buttons for touch devices. It's intended for gameplay use, such as a unit you have to touch to move. + TouchScreenButton allows you to create on-screen buttons for touch devices. It's intended for gameplay use, such as a unit you have to touch to move. Unlike [Button], TouchScreenButton supports multitouch out of the box. Several TouchScreenButtons can be pressed at the same time with touch input. This node inherits from [Node2D]. Unlike with [Control] nodes, you cannot set anchors on it. If you want to create menus or user interfaces, you may want to use [Button] nodes instead. To make button nodes react to touch events, you can enable the Emulate Mouse option in the Project Settings. You can configure TouchScreenButton to be visible only on touch devices, helping you develop your game both for desktop and mobile devices. </description> @@ -30,7 +30,8 @@ The button's texture for the normal state. </member> <member name="passby_press" type="bool" setter="set_passby_press" getter="is_passby_press_enabled" default="false"> - If [code]true[/code], pass-by presses are enabled. + If [code]true[/code], the [signal pressed] and [signal released] signals are emitted whenever a pressed finger goes in and out of the button, even if the pressure started outside the active area of the button. + [b]Note:[/b] this is a "pass-by" (not "bypass") press mode. </member> <member name="pressed" type="Texture2D" setter="set_texture_pressed" getter="get_texture_pressed"> The button's texture for the pressed state. @@ -42,7 +43,7 @@ If [code]true[/code], the button's shape is centered in the provided texture. If no texture is used, this property has no effect. </member> <member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible" default="true"> - If [code]true[/code], the button's shape is visible. + If [code]true[/code], the button's shape is visible in the editor. </member> <member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" enum="TouchScreenButton.VisibilityMode" default="0"> The button's visibility mode. See [enum VisibilityMode] for possible values. diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index cda69f6a64..d75b81eece 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -97,7 +97,7 @@ </return> <argument index="0" name="target" type="Vector3"> </argument> - <argument index="1" name="up" type="Vector3"> + <argument index="1" name="up" type="Vector3" default="Vector3( 0, 1, 0 )"> </argument> <description> Returns a copy of the transform rotated such that its -Z axis points towards the [code]target[/code] position. diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 01818e2993..8502707096 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -57,6 +57,13 @@ The new item will be the [code]idx[/code]th child of parent, or it will be the last child if there are not enough siblings. </description> </method> + <method name="edit_selected"> + <return type="bool"> + </return> + <description> + Edits the selected tree item as if it was clicked. The item must be set editable with [method TreeItem.set_editable]. Returns [code]true[/code] if the item could be edited. Fails if no item is selected. + </description> + </method> <method name="ensure_cursor_is_visible"> <return type="void"> </return> @@ -230,6 +237,14 @@ To tell whether a column of an item is selected, use [method TreeItem.is_selected]. </description> </method> + <method name="scroll_to_item"> + <return type="void"> + </return> + <argument index="0" name="item" type="Object"> + </argument> + <description> + </description> + </method> <method name="set_column_expand"> <return type="void"> </return> @@ -524,7 +539,10 @@ <theme_item name="font_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> Default text [Color] of the item. </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 1, 1, 1, 1 )"> + <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )"> + The tint of text outline of the item. + </theme_item> + <theme_item name="font_selected_color" type="Color" default="Color( 1, 1, 1, 1 )"> Text [Color] used when the item is selected. </theme_item> <theme_item name="font_size" type="int"> @@ -539,6 +557,9 @@ <theme_item name="item_margin" type="int" default="12"> The horizontal margin at the start of an item. This is used when folding is enabled for the item. </theme_item> + <theme_item name="outline_size" type="int" default="0"> + The size of the text outline. + </theme_item> <theme_item name="relationship_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> [Color] of the relationship lines. </theme_item> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index e97c1e580c..fd157e5eb9 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -208,6 +208,7 @@ <argument index="0" name="column" type="int"> </argument> <description> + Returns the metadata value that was set for the given column using [method set_metadata]. </description> </method> <method name="get_next"> @@ -268,6 +269,7 @@ <argument index="0" name="column" type="int"> </argument> <description> + Returns the value of a [constant CELL_MODE_RANGE] column. </description> </method> <method name="get_range_config"> @@ -276,6 +278,7 @@ <argument index="0" name="column" type="int"> </argument> <description> + Returns a dictionary containing the range parameters for a given column. The keys are "min", "max", "step", and "expr". </description> </method> <method name="get_structured_text_bidi_override" qualifiers="const"> @@ -300,6 +303,7 @@ <argument index="0" name="column" type="int"> </argument> <description> + Gets the suffix string shown after the column value. </description> </method> <method name="get_text" qualifiers="const"> @@ -606,6 +610,7 @@ <argument index="1" name="meta" type="Variant"> </argument> <description> + Sets the metadata value for the given column, which can be retrieved later using [method get_metadata]. This can be used, for example, to store a reference to the original data. </description> </method> <method name="set_opentype_feature"> @@ -629,6 +634,7 @@ <argument index="1" name="value" type="float"> </argument> <description> + Sets the value of a [constant CELL_MODE_RANGE] column. </description> </method> <method name="set_range_config"> @@ -645,6 +651,8 @@ <argument index="4" name="expr" type="bool" default="false"> </argument> <description> + Sets the range of accepted values for a column. The column must be in the [constant CELL_MODE_RANGE] mode. + If [code]expr[/code] is [code]true[/code], the edit mode slider will use an exponential scale as with [member Range.exp_edit]. </description> </method> <method name="set_selectable"> @@ -686,6 +694,7 @@ <argument index="1" name="text" type="String"> </argument> <description> + Sets a string to be shown after a column's value (for example, a unit abbreviation). </description> </method> <method name="set_text"> @@ -696,6 +705,7 @@ <argument index="1" name="text" type="String"> </argument> <description> + Sets the given column's text value. </description> </method> <method name="set_text_align"> @@ -748,7 +758,7 @@ Cell contains a string. </constant> <constant name="CELL_MODE_CHECK" value="1" enum="TreeCellMode"> - Cell can be checked. + Cell contains a checkbox. </constant> <constant name="CELL_MODE_RANGE" value="2" enum="TreeCellMode"> Cell contains a range. diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml index 2cc3e974e2..e8124d0e6a 100644 --- a/doc/classes/UndoRedo.xml +++ b/doc/classes/UndoRedo.xml @@ -110,8 +110,10 @@ <method name="commit_action"> <return type="void"> </return> + <argument index="0" name="execute" type="bool" default="true"> + </argument> <description> - Commit the action. All "do" methods/properties are called/set when this function is called. + Commit the action. If [code]execute[/code] is true (default), all "do" methods/properties are called/set when this function is called. </description> </method> <method name="create_action"> @@ -126,11 +128,34 @@ The way actions are merged is dictated by the [code]merge_mode[/code] argument. See [enum MergeMode] for details. </description> </method> + <method name="get_action_name"> + <return type="String"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + Gets the action name from its index. + </description> + </method> + <method name="get_current_action"> + <return type="int"> + </return> + <description> + Gets the index of the current action. + </description> + </method> <method name="get_current_action_name" qualifiers="const"> <return type="String"> </return> <description> - Gets the name of the current action. + Gets the name of the current action, equivalent to [code]get_action_name(get_current_action())[/code]. + </description> + </method> + <method name="get_history_count"> + <return type="int"> + </return> + <description> + Return how many element are in the history. </description> </method> <method name="get_version" qualifiers="const"> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 2d129a2c86..ea80b7c248 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -68,7 +68,7 @@ <argument index="0" name="to" type="Vector3"> </argument> <description> - Returns the minimum angle to the given vector, in radians. + Returns the unsigned minimum angle to the given vector, in radians. </description> </method> <method name="bounce"> @@ -465,6 +465,17 @@ Returns a vector with each component set to one or negative one, depending on the signs of this vector's components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. </description> </method> + <method name="signed_angle_to"> + <return type="float"> + </return> + <argument index="0" name="to" type="Vector3"> + </argument> + <argument index="1" name="axis" type="Vector3"> + </argument> + <description> + Returns the signed angle to the given vector, in radians. The sign of the angle is positive in a counter-clockwise direction and negative in a clockwise direction when viewed from the side specified by the [code]axis[/code]. + </description> + </method> <method name="slerp"> <return type="Vector3"> </return> diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml index 80f97c3419..b2ab356b0d 100644 --- a/doc/classes/VideoPlayer.xml +++ b/doc/classes/VideoPlayer.xml @@ -7,6 +7,7 @@ Control node for playing video streams using [VideoStream] resources. Supported video formats are [url=https://www.webmproject.org/]WebM[/url] ([code].webm[/code], [VideoStreamWebm]), [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]), and any format exposed via a GDNative plugin using [VideoStreamGDNative]. [b]Note:[/b] Due to a bug, VideoPlayer does not support localization remapping yet. + [b]Warning:[/b] On HTML5, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations, especially for VP8/VP9. </description> <tutorials> </tutorials> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index e66b8353a8..8120ae539e 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -240,6 +240,8 @@ </member> <member name="sdf_scale" type="int" setter="set_sdf_scale" getter="get_sdf_scale" enum="Viewport.SDFScale" default="1"> </member> + <member name="shadow_atlas_16_bits" type="bool" setter="set_shadow_atlas_16_bits" getter="get_shadow_atlas_16_bits" default="true"> + </member> <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2"> The subdivision amount of the first quadrant on the shadow atlas. </member> @@ -252,9 +254,9 @@ <member name="shadow_atlas_quad_3" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="4"> The subdivision amount of the fourth quadrant on the shadow atlas. </member> - <member name="shadow_atlas_size" type="int" setter="set_shadow_atlas_size" getter="get_shadow_atlas_size" default="0"> + <member name="shadow_atlas_size" type="int" setter="set_shadow_atlas_size" getter="get_shadow_atlas_size" default="2048"> The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2. - [b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-created viewports default to a value of 0, this value must be set above 0 manually. + [b]Note:[/b] If this is set to 0, shadows won't be visible. </member> <member name="snap_2d_transforms_to_pixel" type="bool" setter="set_snap_2d_transforms_to_pixel" getter="is_snap_2d_transforms_to_pixel_enabled" default="false"> </member> @@ -409,6 +411,14 @@ </constant> <constant name="DEBUG_DRAW_DISABLE_LOD" value="18" enum="DebugDraw"> </constant> + <constant name="DEBUG_DRAW_CLUSTER_OMNI_LIGHTS" value="19" enum="DebugDraw"> + </constant> + <constant name="DEBUG_DRAW_CLUSTER_SPOT_LIGHTS" value="20" enum="DebugDraw"> + </constant> + <constant name="DEBUG_DRAW_CLUSTER_DECALS" value="21" enum="DebugDraw"> + </constant> + <constant name="DEBUG_DRAW_CLUSTER_REFLECTION_PROBES" value="22" enum="DebugDraw"> + </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter"> The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> diff --git a/doc/classes/VisualShader.xml b/doc/classes/VisualShader.xml index f03550bd5e..c29c30289a 100644 --- a/doc/classes/VisualShader.xml +++ b/doc/classes/VisualShader.xml @@ -169,6 +169,19 @@ Removes the specified node from the shader. </description> </method> + <method name="replace_node"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="VisualShader.Type"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <argument index="2" name="new_class" type="StringName"> + </argument> + <description> + Replaces the specified node with a node of new class type. + </description> + </method> <method name="set_mode"> <return type="void"> </return> diff --git a/doc/classes/VisualShaderNodeBooleanConstant.xml b/doc/classes/VisualShaderNodeBooleanConstant.xml index cccb64e874..688679f2a3 100644 --- a/doc/classes/VisualShaderNodeBooleanConstant.xml +++ b/doc/classes/VisualShaderNodeBooleanConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeBooleanConstant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeBooleanConstant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> A boolean constant to be used within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeClamp.xml b/doc/classes/VisualShaderNodeClamp.xml new file mode 100644 index 0000000000..504171bb13 --- /dev/null +++ b/doc/classes/VisualShaderNodeClamp.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeClamp" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Clamps a value within the visual shader graph. + </brief_description> + <description> + Constrains a value to lie between [code]min[/code] and [code]max[/code] values. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeClamp.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_FLOAT" value="0" enum="OpType"> + A floating-point scalar. + </constant> + <constant name="OP_TYPE_INT" value="1" enum="OpType"> + An integer scalar. + </constant> + <constant name="OP_TYPE_VECTOR" value="2" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeColorConstant.xml b/doc/classes/VisualShaderNodeColorConstant.xml index 9b122ca8e1..8644013ef2 100644 --- a/doc/classes/VisualShaderNodeColorConstant.xml +++ b/doc/classes/VisualShaderNodeColorConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeColorConstant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeColorConstant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> A [Color] constant to be used within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeConstant.xml b/doc/classes/VisualShaderNodeConstant.xml new file mode 100644 index 0000000000..8c61529dd1 --- /dev/null +++ b/doc/classes/VisualShaderNodeConstant.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeConstant" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A base type for the constants within the visual shader graph. + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeFloatConstant.xml b/doc/classes/VisualShaderNodeFloatConstant.xml index 3ba9ff07d3..a71563af54 100644 --- a/doc/classes/VisualShaderNodeFloatConstant.xml +++ b/doc/classes/VisualShaderNodeFloatConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeFloatConstant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeFloatConstant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> A scalar floating-point constant to be used within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeIntConstant.xml b/doc/classes/VisualShaderNodeIntConstant.xml index 1c407b21ca..18d6e96ab5 100644 --- a/doc/classes/VisualShaderNodeIntConstant.xml +++ b/doc/classes/VisualShaderNodeIntConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeIntConstant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeIntConstant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> A scalar integer constant to be used within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeIntFunc.xml b/doc/classes/VisualShaderNodeIntFunc.xml index 5c68c0ec71..a9f4144a01 100644 --- a/doc/classes/VisualShaderNodeIntFunc.xml +++ b/doc/classes/VisualShaderNodeIntFunc.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="3"> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="2"> A function to be applied to the scalar. See [enum Function] for options. </member> </members> @@ -19,13 +19,10 @@ <constant name="FUNC_ABS" value="0" enum="Function"> Returns the absolute value of the parameter. Translates to [code]abs(x)[/code] in the Godot Shader Language. </constant> - <constant name="FUNC_CLAMP" value="1" enum="Function"> - Constrains a parameter between [code]min[/code] and [code]max[/code]. Translates to [code]clamp(x, min, max)[/code] in the Godot Shader Language. - </constant> - <constant name="FUNC_NEGATE" value="2" enum="Function"> + <constant name="FUNC_NEGATE" value="1" enum="Function"> Negates the [code]x[/code] using [code]-(x)[/code]. </constant> - <constant name="FUNC_SIGN" value="3" enum="Function"> + <constant name="FUNC_SIGN" value="2" enum="Function"> Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language. </constant> </constants> diff --git a/doc/classes/VisualShaderNodeMix.xml b/doc/classes/VisualShaderNodeMix.xml new file mode 100644 index 0000000000..c70ac7e599 --- /dev/null +++ b/doc/classes/VisualShaderNodeMix.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeMix" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Linearly interpolates between two values within the visual shader graph. + </brief_description> + <description> + Translates to [code]mix(a, b, weight)[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeMix.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A scalar type. + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType"> + A vector type. [code]weight[/code] port is using a scalar type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeSDFRaymarch.xml b/doc/classes/VisualShaderNodeSDFRaymarch.xml new file mode 100644 index 0000000000..775f2814c2 --- /dev/null +++ b/doc/classes/VisualShaderNodeSDFRaymarch.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeSDFRaymarch" inherits="VisualShaderNode" version="4.0"> + <brief_description> + SDF raymarching algorithm to be used within the visual shader graph. + </brief_description> + <description> + Casts a ray against the screen SDF (signed-distance field) and returns the distance travelled. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeSDFToScreenUV.xml b/doc/classes/VisualShaderNodeSDFToScreenUV.xml new file mode 100644 index 0000000000..ea04180095 --- /dev/null +++ b/doc/classes/VisualShaderNodeSDFToScreenUV.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeSDFToScreenUV" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A function to convert a SDF (signed-distance field) to screen UV, to be used within the visual shader graph. + </brief_description> + <description> + Translates to [code]sdf_to_screen_uv(sdf_pos)[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeScalarClamp.xml b/doc/classes/VisualShaderNodeScalarClamp.xml deleted file mode 100644 index 7432e8dfca..0000000000 --- a/doc/classes/VisualShaderNodeScalarClamp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarClamp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Clamps a scalar value within the visual shader graph. - </brief_description> - <description> - Constrains a value to lie between [code]min[/code] and [code]max[/code] values. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarInterp.xml b/doc/classes/VisualShaderNodeScalarInterp.xml deleted file mode 100644 index 393ea70e1a..0000000000 --- a/doc/classes/VisualShaderNodeScalarInterp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarInterp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Linearly interpolates between two scalars within the visual shader graph. - </brief_description> - <description> - Translates to [code]mix(a, b, weight)[/code] in the shader language. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarSmoothStep.xml b/doc/classes/VisualShaderNodeScalarSmoothStep.xml deleted file mode 100644 index e619cc8571..0000000000 --- a/doc/classes/VisualShaderNodeScalarSmoothStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarSmoothStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a scalar SmoothStep function within the visual shader graph. - </brief_description> - <description> - Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarSwitch.xml b/doc/classes/VisualShaderNodeScalarSwitch.xml deleted file mode 100644 index 2ad5202745..0000000000 --- a/doc/classes/VisualShaderNodeScalarSwitch.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarSwitch" inherits="VisualShaderNodeSwitch" version="4.0"> - <brief_description> - A boolean/scalar function for use within the visual shader graph. - </brief_description> - <description> - Returns an associated scalar if the provided boolean value is [code]true[/code] or [code]false[/code]. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScreenUVToSDF.xml b/doc/classes/VisualShaderNodeScreenUVToSDF.xml new file mode 100644 index 0000000000..438c8dc67b --- /dev/null +++ b/doc/classes/VisualShaderNodeScreenUVToSDF.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeScreenUVToSDF" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A function to convert screen UV to a SDF (signed-distance field), to be used within the visual shader graph. + </brief_description> + <description> + Translates to [code]screen_uv_to_sdf(uv)[/code] in the shader language. If the UV port isn't connected, [code]SCREEN_UV[/code] is used instead. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeSmoothStep.xml b/doc/classes/VisualShaderNodeSmoothStep.xml new file mode 100644 index 0000000000..fa22d16da8 --- /dev/null +++ b/doc/classes/VisualShaderNodeSmoothStep.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeSmoothStep" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Calculates a SmoothStep function within the visual shader graph. + </brief_description> + <description> + Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language. + Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeSmoothStep.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A scalar type. + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType"> + A vector type. [code]edge0[/code] and [code]edge1[/code] are using a scalar type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeStep.xml b/doc/classes/VisualShaderNodeStep.xml new file mode 100644 index 0000000000..694c144445 --- /dev/null +++ b/doc/classes/VisualShaderNodeStep.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeStep" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Calculates a Step function within the visual shader graph. + </brief_description> + <description> + Translates to [code]step(edge, x)[/code] in the shader language. + Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeStep.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A scalar type. + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType"> + A vector type. [code]edge[/code] port is using a scalar type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeSwitch.xml b/doc/classes/VisualShaderNodeSwitch.xml index 9f8a12c0fd..3961070a74 100644 --- a/doc/classes/VisualShaderNodeSwitch.xml +++ b/doc/classes/VisualShaderNodeSwitch.xml @@ -1,15 +1,38 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeSwitch" inherits="VisualShaderNode" version="4.0"> <brief_description> - A boolean/vector function for use within the visual shader graph. + A selector function for use within the visual shader graph. </brief_description> <description> - Returns an associated vector if the provided boolean value is [code]true[/code] or [code]false[/code]. + Returns an associated value of the [code]op_type[/code] type if the provided boolean value is [code]true[/code] or [code]false[/code]. </description> <tutorials> </tutorials> <methods> </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeSwitch.OpType" default="0"> + A type of operands and returned value. + </member> + </members> <constants> + <constant name="OP_TYPE_FLOAT" value="0" enum="OpType"> + A floating-point scalar. + </constant> + <constant name="OP_TYPE_INT" value="1" enum="OpType"> + An integer scalar. + </constant> + <constant name="OP_TYPE_VECTOR" value="2" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_BOOLEAN" value="3" enum="OpType"> + A boolean type. + </constant> + <constant name="OP_TYPE_TRANSFORM" value="4" enum="OpType"> + A transform type. + </constant> + <constant name="OP_TYPE_MAX" value="5" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> </constants> </class> diff --git a/doc/classes/VisualShaderNodeTextureSDF.xml b/doc/classes/VisualShaderNodeTextureSDF.xml new file mode 100644 index 0000000000..7d3d654bd0 --- /dev/null +++ b/doc/classes/VisualShaderNodeTextureSDF.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTextureSDF" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Performs a SDF (signed-distance field) texture lookup within the visual shader graph. + </brief_description> + <description> + Translates to [code]texture_sdf(sdf_pos)[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTextureSDFNormal.xml b/doc/classes/VisualShaderNodeTextureSDFNormal.xml new file mode 100644 index 0000000000..5dbf3e545a --- /dev/null +++ b/doc/classes/VisualShaderNodeTextureSDFNormal.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTextureSDFNormal" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Performs a SDF (signed-distance field) normal texture lookup within the visual shader graph. + </brief_description> + <description> + Translates to [code]texture_sdf_normal(sdf_pos)[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTransformConstant.xml b/doc/classes/VisualShaderNodeTransformConstant.xml index e5004e5bb6..b8f054e914 100644 --- a/doc/classes/VisualShaderNodeTransformConstant.xml +++ b/doc/classes/VisualShaderNodeTransformConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTransformConstant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeTransformConstant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> A [Transform] constant for use within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeVec3Constant.xml b/doc/classes/VisualShaderNodeVec3Constant.xml index 4dfc9dc081..b01bb514fe 100644 --- a/doc/classes/VisualShaderNodeVec3Constant.xml +++ b/doc/classes/VisualShaderNodeVec3Constant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVec3Constant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeVec3Constant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> A [Vector3] constant to be used within the visual shader graph. </brief_description> diff --git a/doc/classes/VisualShaderNodeVectorClamp.xml b/doc/classes/VisualShaderNodeVectorClamp.xml deleted file mode 100644 index 567fed8a41..0000000000 --- a/doc/classes/VisualShaderNodeVectorClamp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorClamp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Clamps a vector value within the visual shader graph. - </brief_description> - <description> - Constrains a value to lie between [code]min[/code] and [code]max[/code] values. The operation is performed on each component of the vector individually. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorInterp.xml b/doc/classes/VisualShaderNodeVectorInterp.xml deleted file mode 100644 index b63d34b742..0000000000 --- a/doc/classes/VisualShaderNodeVectorInterp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorInterp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Linearly interpolates between two vectors within the visual shader graph. - </brief_description> - <description> - Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]weight[/code] is a [Vector3] with weights for each component. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml deleted file mode 100644 index 791a9e6be1..0000000000 --- a/doc/classes/VisualShaderNodeVectorScalarMix.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Linearly interpolates between two vectors using a scalar. For use within the visual shader graph. - </brief_description> - <description> - Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]a[/code] and [code]b[/code] are vectors and [code]weight[/code] is a scalar. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml b/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml deleted file mode 100644 index 580abaf5fe..0000000000 --- a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorScalarSmoothStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a vector SmoothStep function using scalar within the visual shader graph. - </brief_description> - <description> - Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a scalar. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorScalarStep.xml b/doc/classes/VisualShaderNodeVectorScalarStep.xml deleted file mode 100644 index d61414f3a8..0000000000 --- a/doc/classes/VisualShaderNodeVectorScalarStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorScalarStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a vector Step function within the visual shader graph. - </brief_description> - <description> - Translates to [code]step(edge, x)[/code] in the shader language. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorSmoothStep.xml b/doc/classes/VisualShaderNodeVectorSmoothStep.xml deleted file mode 100644 index 1b77a3c535..0000000000 --- a/doc/classes/VisualShaderNodeVectorSmoothStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorSmoothStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a vector SmoothStep function within the visual shader graph. - </brief_description> - <description> - Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a vector. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 0f887c7705..b99a251a11 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -276,7 +276,7 @@ <method name="set_ime_active"> <return type="void"> </return> - <argument index="0" name="arg0" type="bool"> + <argument index="0" name="active" type="bool"> </argument> <description> </description> @@ -284,7 +284,7 @@ <method name="set_ime_position"> <return type="void"> </return> - <argument index="0" name="arg0" type="Vector2i"> + <argument index="0" name="position" type="Vector2i"> </argument> <description> </description> @@ -474,8 +474,17 @@ </theme_item> <theme_item name="title_font" type="Font"> </theme_item> + <theme_item name="title_font_size" type="int"> + The size of the title font. + </theme_item> <theme_item name="title_height" type="int" default="20"> </theme_item> + <theme_item name="title_outline_modulate" type="Color" default="Color( 1, 1, 1, 1 )"> + The color of the title outline. + </theme_item> + <theme_item name="title_outline_size" type="int" default="0"> + The size of the title outline. + </theme_item> <theme_item name="window_panel" type="StyleBox"> </theme_item> </theme_items> diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index 5335116c8a..ae3cc73098 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -110,6 +110,9 @@ class ClassDef: self.theme_items = None # type: Optional[OrderedDict[str, List[ThemeItemDef]]] self.tutorials = [] # type: List[str] + # Used to match the class with XML source for output filtering purposes. + self.filepath = "" # type: str + class State: def __init__(self): # type: () -> None @@ -118,11 +121,12 @@ class State: self.classes = OrderedDict() # type: OrderedDict[str, ClassDef] self.current_class = "" # type: str - def parse_class(self, class_root): # type: (ET.Element) -> None + def parse_class(self, class_root, filepath): # type: (ET.Element, str) -> None class_name = class_root.attrib["name"] class_def = ClassDef(class_name) self.classes[class_name] = class_def + class_def.filepath = filepath inherits = class_root.get("inherits") if inherits is not None: @@ -278,6 +282,7 @@ def parse_arguments(root): # type: (ET.Element) -> List[ParameterDef] def main(): # type: () -> None parser = argparse.ArgumentParser() parser.add_argument("path", nargs="+", help="A path to an XML file or a directory containing XML files to parse.") + parser.add_argument("--filter", default="", help="The filepath pattern for XML files to filter.") group = parser.add_mutually_exclusive_group() group.add_argument("--output", "-o", default=".", help="The directory to save output .rst files in.") group.add_argument( @@ -333,17 +338,21 @@ def main(): # type: () -> None print_error("Duplicate class '{}'".format(name), state) continue - classes[name] = doc + classes[name] = (doc, cur_file) for name, data in classes.items(): try: - state.parse_class(data) + state.parse_class(data[0], data[1]) except Exception as e: print_error("Exception while parsing class '{}': {}".format(name, e), state) state.sort_classes() + pattern = re.compile(args.filter) + for class_name, class_def in state.classes.items(): + if args.filter and not pattern.search(class_def.filepath): + continue state.current_class = class_name make_rst_class(class_def, state, args.dry_run, args.output) diff --git a/doc/translations/README.md b/doc/translations/README.md new file mode 100644 index 0000000000..a941eeaf49 --- /dev/null +++ b/doc/translations/README.md @@ -0,0 +1 @@ +These `.po` and `.pot` files come from Weblate. Do not modify them manually. diff --git a/drivers/alsa/SCsub b/drivers/alsa/SCsub index 91e1140b75..1d76bb18c4 100644 --- a/drivers/alsa/SCsub +++ b/drivers/alsa/SCsub @@ -2,4 +2,7 @@ Import("env") +if "alsa" in env and env["alsa"]: + env.add_source_files(env.drivers_sources, "asound-so_wrap.c") + env.add_source_files(env.drivers_sources, "*.cpp") diff --git a/drivers/alsa/asound-so_wrap.c b/drivers/alsa/asound-so_wrap.c new file mode 100644 index 0000000000..65624bcb70 --- /dev/null +++ b/drivers/alsa/asound-so_wrap.c @@ -0,0 +1,14092 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-22 19:22:12 +// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/alsa/asoundlib.h --sys-include <alsa/asoundlib.h> --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header asound-so_wrap.h --output-implementation asound-so_wrap.c +// +#include <stdint.h> + +#define snd_asoundlib_version snd_asoundlib_version_dylibloader_orig_asound +#define snd_dlpath snd_dlpath_dylibloader_orig_asound +#define snd_dlopen snd_dlopen_dylibloader_orig_asound +#define snd_dlsym snd_dlsym_dylibloader_orig_asound +#define snd_dlclose snd_dlclose_dylibloader_orig_asound +#define snd_async_add_handler snd_async_add_handler_dylibloader_orig_asound +#define snd_async_del_handler snd_async_del_handler_dylibloader_orig_asound +#define snd_async_handler_get_fd snd_async_handler_get_fd_dylibloader_orig_asound +#define snd_async_handler_get_signo snd_async_handler_get_signo_dylibloader_orig_asound +#define snd_async_handler_get_callback_private snd_async_handler_get_callback_private_dylibloader_orig_asound +#define snd_shm_area_create snd_shm_area_create_dylibloader_orig_asound +#define snd_shm_area_share snd_shm_area_share_dylibloader_orig_asound +#define snd_shm_area_destroy snd_shm_area_destroy_dylibloader_orig_asound +#define snd_user_file snd_user_file_dylibloader_orig_asound +#define snd_input_stdio_open snd_input_stdio_open_dylibloader_orig_asound +#define snd_input_stdio_attach snd_input_stdio_attach_dylibloader_orig_asound +#define snd_input_buffer_open snd_input_buffer_open_dylibloader_orig_asound +#define snd_input_close snd_input_close_dylibloader_orig_asound +#define snd_input_scanf snd_input_scanf_dylibloader_orig_asound +#define snd_input_gets snd_input_gets_dylibloader_orig_asound +#define snd_input_getc snd_input_getc_dylibloader_orig_asound +#define snd_input_ungetc snd_input_ungetc_dylibloader_orig_asound +#define snd_output_stdio_open snd_output_stdio_open_dylibloader_orig_asound +#define snd_output_stdio_attach snd_output_stdio_attach_dylibloader_orig_asound +#define snd_output_buffer_open snd_output_buffer_open_dylibloader_orig_asound +#define snd_output_buffer_string snd_output_buffer_string_dylibloader_orig_asound +#define snd_output_close snd_output_close_dylibloader_orig_asound +#define snd_output_printf snd_output_printf_dylibloader_orig_asound +#define snd_output_vprintf snd_output_vprintf_dylibloader_orig_asound +#define snd_output_puts snd_output_puts_dylibloader_orig_asound +#define snd_output_putc snd_output_putc_dylibloader_orig_asound +#define snd_output_flush snd_output_flush_dylibloader_orig_asound +#define snd_strerror snd_strerror_dylibloader_orig_asound +#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_orig_asound +#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_orig_asound +#define snd_config_topdir snd_config_topdir_dylibloader_orig_asound +#define snd_config_top snd_config_top_dylibloader_orig_asound +#define snd_config_load snd_config_load_dylibloader_orig_asound +#define snd_config_load_override snd_config_load_override_dylibloader_orig_asound +#define snd_config_save snd_config_save_dylibloader_orig_asound +#define snd_config_update snd_config_update_dylibloader_orig_asound +#define snd_config_update_r snd_config_update_r_dylibloader_orig_asound +#define snd_config_update_free snd_config_update_free_dylibloader_orig_asound +#define snd_config_update_free_global snd_config_update_free_global_dylibloader_orig_asound +#define snd_config_update_ref snd_config_update_ref_dylibloader_orig_asound +#define snd_config_ref snd_config_ref_dylibloader_orig_asound +#define snd_config_unref snd_config_unref_dylibloader_orig_asound +#define snd_config_search snd_config_search_dylibloader_orig_asound +#define snd_config_searchv snd_config_searchv_dylibloader_orig_asound +#define snd_config_search_definition snd_config_search_definition_dylibloader_orig_asound +#define snd_config_expand snd_config_expand_dylibloader_orig_asound +#define snd_config_evaluate snd_config_evaluate_dylibloader_orig_asound +#define snd_config_add snd_config_add_dylibloader_orig_asound +#define snd_config_add_before snd_config_add_before_dylibloader_orig_asound +#define snd_config_add_after snd_config_add_after_dylibloader_orig_asound +#define snd_config_remove snd_config_remove_dylibloader_orig_asound +#define snd_config_delete snd_config_delete_dylibloader_orig_asound +#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_orig_asound +#define snd_config_copy snd_config_copy_dylibloader_orig_asound +#define snd_config_make snd_config_make_dylibloader_orig_asound +#define snd_config_make_integer snd_config_make_integer_dylibloader_orig_asound +#define snd_config_make_integer64 snd_config_make_integer64_dylibloader_orig_asound +#define snd_config_make_real snd_config_make_real_dylibloader_orig_asound +#define snd_config_make_string snd_config_make_string_dylibloader_orig_asound +#define snd_config_make_pointer snd_config_make_pointer_dylibloader_orig_asound +#define snd_config_make_compound snd_config_make_compound_dylibloader_orig_asound +#define snd_config_imake_integer snd_config_imake_integer_dylibloader_orig_asound +#define snd_config_imake_integer64 snd_config_imake_integer64_dylibloader_orig_asound +#define snd_config_imake_real snd_config_imake_real_dylibloader_orig_asound +#define snd_config_imake_string snd_config_imake_string_dylibloader_orig_asound +#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_orig_asound +#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_orig_asound +#define snd_config_get_type snd_config_get_type_dylibloader_orig_asound +#define snd_config_is_array snd_config_is_array_dylibloader_orig_asound +#define snd_config_set_id snd_config_set_id_dylibloader_orig_asound +#define snd_config_set_integer snd_config_set_integer_dylibloader_orig_asound +#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_orig_asound +#define snd_config_set_real snd_config_set_real_dylibloader_orig_asound +#define snd_config_set_string snd_config_set_string_dylibloader_orig_asound +#define snd_config_set_ascii snd_config_set_ascii_dylibloader_orig_asound +#define snd_config_set_pointer snd_config_set_pointer_dylibloader_orig_asound +#define snd_config_get_id snd_config_get_id_dylibloader_orig_asound +#define snd_config_get_integer snd_config_get_integer_dylibloader_orig_asound +#define snd_config_get_integer64 snd_config_get_integer64_dylibloader_orig_asound +#define snd_config_get_real snd_config_get_real_dylibloader_orig_asound +#define snd_config_get_ireal snd_config_get_ireal_dylibloader_orig_asound +#define snd_config_get_string snd_config_get_string_dylibloader_orig_asound +#define snd_config_get_ascii snd_config_get_ascii_dylibloader_orig_asound +#define snd_config_get_pointer snd_config_get_pointer_dylibloader_orig_asound +#define snd_config_test_id snd_config_test_id_dylibloader_orig_asound +#define snd_config_iterator_first snd_config_iterator_first_dylibloader_orig_asound +#define snd_config_iterator_next snd_config_iterator_next_dylibloader_orig_asound +#define snd_config_iterator_end snd_config_iterator_end_dylibloader_orig_asound +#define snd_config_iterator_entry snd_config_iterator_entry_dylibloader_orig_asound +#define snd_config_get_bool_ascii snd_config_get_bool_ascii_dylibloader_orig_asound +#define snd_config_get_bool snd_config_get_bool_dylibloader_orig_asound +#define snd_config_get_ctl_iface_ascii snd_config_get_ctl_iface_ascii_dylibloader_orig_asound +#define snd_config_get_ctl_iface snd_config_get_ctl_iface_dylibloader_orig_asound +#define snd_names_list snd_names_list_dylibloader_orig_asound +#define snd_names_list_free snd_names_list_free_dylibloader_orig_asound +#define snd_pcm_open snd_pcm_open_dylibloader_orig_asound +#define snd_pcm_open_lconf snd_pcm_open_lconf_dylibloader_orig_asound +#define snd_pcm_open_fallback snd_pcm_open_fallback_dylibloader_orig_asound +#define snd_pcm_close snd_pcm_close_dylibloader_orig_asound +#define snd_pcm_name snd_pcm_name_dylibloader_orig_asound +#define snd_pcm_type snd_pcm_type_dylibloader_orig_asound +#define snd_pcm_stream snd_pcm_stream_dylibloader_orig_asound +#define snd_pcm_poll_descriptors_count snd_pcm_poll_descriptors_count_dylibloader_orig_asound +#define snd_pcm_poll_descriptors snd_pcm_poll_descriptors_dylibloader_orig_asound +#define snd_pcm_poll_descriptors_revents snd_pcm_poll_descriptors_revents_dylibloader_orig_asound +#define snd_pcm_nonblock snd_pcm_nonblock_dylibloader_orig_asound +#define snd_async_add_pcm_handler snd_async_add_pcm_handler_dylibloader_orig_asound +#define snd_async_handler_get_pcm snd_async_handler_get_pcm_dylibloader_orig_asound +#define snd_pcm_info snd_pcm_info_dylibloader_orig_asound +#define snd_pcm_hw_params_current snd_pcm_hw_params_current_dylibloader_orig_asound +#define snd_pcm_hw_params snd_pcm_hw_params_dylibloader_orig_asound +#define snd_pcm_hw_free snd_pcm_hw_free_dylibloader_orig_asound +#define snd_pcm_sw_params_current snd_pcm_sw_params_current_dylibloader_orig_asound +#define snd_pcm_sw_params snd_pcm_sw_params_dylibloader_orig_asound +#define snd_pcm_prepare snd_pcm_prepare_dylibloader_orig_asound +#define snd_pcm_reset snd_pcm_reset_dylibloader_orig_asound +#define snd_pcm_status snd_pcm_status_dylibloader_orig_asound +#define snd_pcm_start snd_pcm_start_dylibloader_orig_asound +#define snd_pcm_drop snd_pcm_drop_dylibloader_orig_asound +#define snd_pcm_drain snd_pcm_drain_dylibloader_orig_asound +#define snd_pcm_pause snd_pcm_pause_dylibloader_orig_asound +#define snd_pcm_state snd_pcm_state_dylibloader_orig_asound +#define snd_pcm_hwsync snd_pcm_hwsync_dylibloader_orig_asound +#define snd_pcm_delay snd_pcm_delay_dylibloader_orig_asound +#define snd_pcm_resume snd_pcm_resume_dylibloader_orig_asound +#define snd_pcm_htimestamp snd_pcm_htimestamp_dylibloader_orig_asound +#define snd_pcm_avail snd_pcm_avail_dylibloader_orig_asound +#define snd_pcm_avail_update snd_pcm_avail_update_dylibloader_orig_asound +#define snd_pcm_avail_delay snd_pcm_avail_delay_dylibloader_orig_asound +#define snd_pcm_rewindable snd_pcm_rewindable_dylibloader_orig_asound +#define snd_pcm_rewind snd_pcm_rewind_dylibloader_orig_asound +#define snd_pcm_forwardable snd_pcm_forwardable_dylibloader_orig_asound +#define snd_pcm_forward snd_pcm_forward_dylibloader_orig_asound +#define snd_pcm_writei snd_pcm_writei_dylibloader_orig_asound +#define snd_pcm_readi snd_pcm_readi_dylibloader_orig_asound +#define snd_pcm_writen snd_pcm_writen_dylibloader_orig_asound +#define snd_pcm_readn snd_pcm_readn_dylibloader_orig_asound +#define snd_pcm_wait snd_pcm_wait_dylibloader_orig_asound +#define snd_pcm_link snd_pcm_link_dylibloader_orig_asound +#define snd_pcm_unlink snd_pcm_unlink_dylibloader_orig_asound +#define snd_pcm_query_chmaps snd_pcm_query_chmaps_dylibloader_orig_asound +#define snd_pcm_query_chmaps_from_hw snd_pcm_query_chmaps_from_hw_dylibloader_orig_asound +#define snd_pcm_free_chmaps snd_pcm_free_chmaps_dylibloader_orig_asound +#define snd_pcm_get_chmap snd_pcm_get_chmap_dylibloader_orig_asound +#define snd_pcm_set_chmap snd_pcm_set_chmap_dylibloader_orig_asound +#define snd_pcm_chmap_type_name snd_pcm_chmap_type_name_dylibloader_orig_asound +#define snd_pcm_chmap_name snd_pcm_chmap_name_dylibloader_orig_asound +#define snd_pcm_chmap_long_name snd_pcm_chmap_long_name_dylibloader_orig_asound +#define snd_pcm_chmap_print snd_pcm_chmap_print_dylibloader_orig_asound +#define snd_pcm_chmap_from_string snd_pcm_chmap_from_string_dylibloader_orig_asound +#define snd_pcm_chmap_parse_string snd_pcm_chmap_parse_string_dylibloader_orig_asound +#define snd_pcm_recover snd_pcm_recover_dylibloader_orig_asound +#define snd_pcm_set_params snd_pcm_set_params_dylibloader_orig_asound +#define snd_pcm_get_params snd_pcm_get_params_dylibloader_orig_asound +#define snd_pcm_info_sizeof snd_pcm_info_sizeof_dylibloader_orig_asound +#define snd_pcm_info_malloc snd_pcm_info_malloc_dylibloader_orig_asound +#define snd_pcm_info_free snd_pcm_info_free_dylibloader_orig_asound +#define snd_pcm_info_copy snd_pcm_info_copy_dylibloader_orig_asound +#define snd_pcm_info_get_device snd_pcm_info_get_device_dylibloader_orig_asound +#define snd_pcm_info_get_subdevice snd_pcm_info_get_subdevice_dylibloader_orig_asound +#define snd_pcm_info_get_stream snd_pcm_info_get_stream_dylibloader_orig_asound +#define snd_pcm_info_get_card snd_pcm_info_get_card_dylibloader_orig_asound +#define snd_pcm_info_get_id snd_pcm_info_get_id_dylibloader_orig_asound +#define snd_pcm_info_get_name snd_pcm_info_get_name_dylibloader_orig_asound +#define snd_pcm_info_get_subdevice_name snd_pcm_info_get_subdevice_name_dylibloader_orig_asound +#define snd_pcm_info_get_class snd_pcm_info_get_class_dylibloader_orig_asound +#define snd_pcm_info_get_subclass snd_pcm_info_get_subclass_dylibloader_orig_asound +#define snd_pcm_info_get_subdevices_count snd_pcm_info_get_subdevices_count_dylibloader_orig_asound +#define snd_pcm_info_get_subdevices_avail snd_pcm_info_get_subdevices_avail_dylibloader_orig_asound +#define snd_pcm_info_get_sync snd_pcm_info_get_sync_dylibloader_orig_asound +#define snd_pcm_info_set_device snd_pcm_info_set_device_dylibloader_orig_asound +#define snd_pcm_info_set_subdevice snd_pcm_info_set_subdevice_dylibloader_orig_asound +#define snd_pcm_info_set_stream snd_pcm_info_set_stream_dylibloader_orig_asound +#define snd_pcm_hw_params_any snd_pcm_hw_params_any_dylibloader_orig_asound +#define snd_pcm_hw_params_can_mmap_sample_resolution snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_orig_asound +#define snd_pcm_hw_params_is_double snd_pcm_hw_params_is_double_dylibloader_orig_asound +#define snd_pcm_hw_params_is_batch snd_pcm_hw_params_is_batch_dylibloader_orig_asound +#define snd_pcm_hw_params_is_block_transfer snd_pcm_hw_params_is_block_transfer_dylibloader_orig_asound +#define snd_pcm_hw_params_is_monotonic snd_pcm_hw_params_is_monotonic_dylibloader_orig_asound +#define snd_pcm_hw_params_can_overrange snd_pcm_hw_params_can_overrange_dylibloader_orig_asound +#define snd_pcm_hw_params_can_pause snd_pcm_hw_params_can_pause_dylibloader_orig_asound +#define snd_pcm_hw_params_can_resume snd_pcm_hw_params_can_resume_dylibloader_orig_asound +#define snd_pcm_hw_params_is_half_duplex snd_pcm_hw_params_is_half_duplex_dylibloader_orig_asound +#define snd_pcm_hw_params_is_joint_duplex snd_pcm_hw_params_is_joint_duplex_dylibloader_orig_asound +#define snd_pcm_hw_params_can_sync_start snd_pcm_hw_params_can_sync_start_dylibloader_orig_asound +#define snd_pcm_hw_params_can_disable_period_wakeup snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_orig_asound +#define snd_pcm_hw_params_supports_audio_wallclock_ts snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_orig_asound +#define snd_pcm_hw_params_supports_audio_ts_type snd_pcm_hw_params_supports_audio_ts_type_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_numden snd_pcm_hw_params_get_rate_numden_dylibloader_orig_asound +#define snd_pcm_hw_params_get_sbits snd_pcm_hw_params_get_sbits_dylibloader_orig_asound +#define snd_pcm_hw_params_get_fifo_size snd_pcm_hw_params_get_fifo_size_dylibloader_orig_asound +#define snd_pcm_hw_params_sizeof snd_pcm_hw_params_sizeof_dylibloader_orig_asound +#define snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc_dylibloader_orig_asound +#define snd_pcm_hw_params_free snd_pcm_hw_params_free_dylibloader_orig_asound +#define snd_pcm_hw_params_copy snd_pcm_hw_params_copy_dylibloader_orig_asound +#define snd_pcm_hw_params_get_access snd_pcm_hw_params_get_access_dylibloader_orig_asound +#define snd_pcm_hw_params_test_access snd_pcm_hw_params_test_access_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access_first snd_pcm_hw_params_set_access_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access_last snd_pcm_hw_params_set_access_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access_mask snd_pcm_hw_params_set_access_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_access_mask snd_pcm_hw_params_get_access_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_format snd_pcm_hw_params_get_format_dylibloader_orig_asound +#define snd_pcm_hw_params_test_format snd_pcm_hw_params_test_format_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format_first snd_pcm_hw_params_set_format_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format_last snd_pcm_hw_params_set_format_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format_mask snd_pcm_hw_params_set_format_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_format_mask snd_pcm_hw_params_get_format_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_subformat snd_pcm_hw_params_get_subformat_dylibloader_orig_asound +#define snd_pcm_hw_params_test_subformat snd_pcm_hw_params_test_subformat_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat snd_pcm_hw_params_set_subformat_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat_first snd_pcm_hw_params_set_subformat_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat_last snd_pcm_hw_params_set_subformat_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat_mask snd_pcm_hw_params_set_subformat_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_subformat_mask snd_pcm_hw_params_get_subformat_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_channels snd_pcm_hw_params_get_channels_dylibloader_orig_asound +#define snd_pcm_hw_params_get_channels_min snd_pcm_hw_params_get_channels_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_channels_max snd_pcm_hw_params_get_channels_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_channels snd_pcm_hw_params_test_channels_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels snd_pcm_hw_params_set_channels_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_min snd_pcm_hw_params_set_channels_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_max snd_pcm_hw_params_set_channels_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_minmax snd_pcm_hw_params_set_channels_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_near snd_pcm_hw_params_set_channels_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_first snd_pcm_hw_params_set_channels_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_last snd_pcm_hw_params_set_channels_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate snd_pcm_hw_params_get_rate_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_min snd_pcm_hw_params_get_rate_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_max snd_pcm_hw_params_get_rate_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_rate snd_pcm_hw_params_test_rate_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate snd_pcm_hw_params_set_rate_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_min snd_pcm_hw_params_set_rate_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_max snd_pcm_hw_params_set_rate_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_minmax snd_pcm_hw_params_set_rate_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_near snd_pcm_hw_params_set_rate_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_first snd_pcm_hw_params_set_rate_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_last snd_pcm_hw_params_set_rate_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_resample snd_pcm_hw_params_set_rate_resample_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_resample snd_pcm_hw_params_get_rate_resample_dylibloader_orig_asound +#define snd_pcm_hw_params_set_export_buffer snd_pcm_hw_params_set_export_buffer_dylibloader_orig_asound +#define snd_pcm_hw_params_get_export_buffer snd_pcm_hw_params_get_export_buffer_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_wakeup snd_pcm_hw_params_set_period_wakeup_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_wakeup snd_pcm_hw_params_get_period_wakeup_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_time snd_pcm_hw_params_get_period_time_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_time_min snd_pcm_hw_params_get_period_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_time_max snd_pcm_hw_params_get_period_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_period_time snd_pcm_hw_params_test_period_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time snd_pcm_hw_params_set_period_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_min snd_pcm_hw_params_set_period_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_max snd_pcm_hw_params_set_period_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_minmax snd_pcm_hw_params_set_period_time_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_near snd_pcm_hw_params_set_period_time_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_first snd_pcm_hw_params_set_period_time_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_last snd_pcm_hw_params_set_period_time_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_size snd_pcm_hw_params_get_period_size_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_size_min snd_pcm_hw_params_get_period_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_size_max snd_pcm_hw_params_get_period_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_period_size snd_pcm_hw_params_test_period_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size snd_pcm_hw_params_set_period_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_min snd_pcm_hw_params_set_period_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_max snd_pcm_hw_params_set_period_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_minmax snd_pcm_hw_params_set_period_size_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_near snd_pcm_hw_params_set_period_size_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_first snd_pcm_hw_params_set_period_size_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_last snd_pcm_hw_params_set_period_size_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_integer snd_pcm_hw_params_set_period_size_integer_dylibloader_orig_asound +#define snd_pcm_hw_params_get_periods snd_pcm_hw_params_get_periods_dylibloader_orig_asound +#define snd_pcm_hw_params_get_periods_min snd_pcm_hw_params_get_periods_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_periods_max snd_pcm_hw_params_get_periods_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_periods snd_pcm_hw_params_test_periods_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods snd_pcm_hw_params_set_periods_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_min snd_pcm_hw_params_set_periods_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_max snd_pcm_hw_params_set_periods_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_minmax snd_pcm_hw_params_set_periods_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_near snd_pcm_hw_params_set_periods_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_first snd_pcm_hw_params_set_periods_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_last snd_pcm_hw_params_set_periods_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_integer snd_pcm_hw_params_set_periods_integer_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_time snd_pcm_hw_params_get_buffer_time_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_time_min snd_pcm_hw_params_get_buffer_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_time_max snd_pcm_hw_params_get_buffer_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_buffer_time snd_pcm_hw_params_test_buffer_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time snd_pcm_hw_params_set_buffer_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_min snd_pcm_hw_params_set_buffer_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_max snd_pcm_hw_params_set_buffer_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_minmax snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_near snd_pcm_hw_params_set_buffer_time_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_first snd_pcm_hw_params_set_buffer_time_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_last snd_pcm_hw_params_set_buffer_time_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_size snd_pcm_hw_params_get_buffer_size_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_size_min snd_pcm_hw_params_get_buffer_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_size_max snd_pcm_hw_params_get_buffer_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_buffer_size snd_pcm_hw_params_test_buffer_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size snd_pcm_hw_params_set_buffer_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_min snd_pcm_hw_params_set_buffer_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_max snd_pcm_hw_params_set_buffer_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_minmax snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_near snd_pcm_hw_params_set_buffer_size_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_first snd_pcm_hw_params_set_buffer_size_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_last snd_pcm_hw_params_set_buffer_size_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_min_align snd_pcm_hw_params_get_min_align_dylibloader_orig_asound +#define snd_pcm_sw_params_sizeof snd_pcm_sw_params_sizeof_dylibloader_orig_asound +#define snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc_dylibloader_orig_asound +#define snd_pcm_sw_params_free snd_pcm_sw_params_free_dylibloader_orig_asound +#define snd_pcm_sw_params_copy snd_pcm_sw_params_copy_dylibloader_orig_asound +#define snd_pcm_sw_params_get_boundary snd_pcm_sw_params_get_boundary_dylibloader_orig_asound +#define snd_pcm_sw_params_set_tstamp_mode snd_pcm_sw_params_set_tstamp_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_get_tstamp_mode snd_pcm_sw_params_get_tstamp_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_set_avail_min snd_pcm_sw_params_set_avail_min_dylibloader_orig_asound +#define snd_pcm_sw_params_get_avail_min snd_pcm_sw_params_get_avail_min_dylibloader_orig_asound +#define snd_pcm_sw_params_set_period_event snd_pcm_sw_params_set_period_event_dylibloader_orig_asound +#define snd_pcm_sw_params_get_period_event snd_pcm_sw_params_get_period_event_dylibloader_orig_asound +#define snd_pcm_sw_params_set_start_threshold snd_pcm_sw_params_set_start_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_get_start_threshold snd_pcm_sw_params_get_start_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_set_stop_threshold snd_pcm_sw_params_set_stop_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_get_stop_threshold snd_pcm_sw_params_get_stop_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_set_silence_threshold snd_pcm_sw_params_set_silence_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_get_silence_threshold snd_pcm_sw_params_get_silence_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_set_silence_size snd_pcm_sw_params_set_silence_size_dylibloader_orig_asound +#define snd_pcm_sw_params_get_silence_size snd_pcm_sw_params_get_silence_size_dylibloader_orig_asound +#define snd_pcm_access_mask_sizeof snd_pcm_access_mask_sizeof_dylibloader_orig_asound +#define snd_pcm_access_mask_malloc snd_pcm_access_mask_malloc_dylibloader_orig_asound +#define snd_pcm_access_mask_free snd_pcm_access_mask_free_dylibloader_orig_asound +#define snd_pcm_access_mask_copy snd_pcm_access_mask_copy_dylibloader_orig_asound +#define snd_pcm_access_mask_none snd_pcm_access_mask_none_dylibloader_orig_asound +#define snd_pcm_access_mask_any snd_pcm_access_mask_any_dylibloader_orig_asound +#define snd_pcm_access_mask_test snd_pcm_access_mask_test_dylibloader_orig_asound +#define snd_pcm_access_mask_empty snd_pcm_access_mask_empty_dylibloader_orig_asound +#define snd_pcm_access_mask_set snd_pcm_access_mask_set_dylibloader_orig_asound +#define snd_pcm_access_mask_reset snd_pcm_access_mask_reset_dylibloader_orig_asound +#define snd_pcm_format_mask_sizeof snd_pcm_format_mask_sizeof_dylibloader_orig_asound +#define snd_pcm_format_mask_malloc snd_pcm_format_mask_malloc_dylibloader_orig_asound +#define snd_pcm_format_mask_free snd_pcm_format_mask_free_dylibloader_orig_asound +#define snd_pcm_format_mask_copy snd_pcm_format_mask_copy_dylibloader_orig_asound +#define snd_pcm_format_mask_none snd_pcm_format_mask_none_dylibloader_orig_asound +#define snd_pcm_format_mask_any snd_pcm_format_mask_any_dylibloader_orig_asound +#define snd_pcm_format_mask_test snd_pcm_format_mask_test_dylibloader_orig_asound +#define snd_pcm_format_mask_empty snd_pcm_format_mask_empty_dylibloader_orig_asound +#define snd_pcm_format_mask_set snd_pcm_format_mask_set_dylibloader_orig_asound +#define snd_pcm_format_mask_reset snd_pcm_format_mask_reset_dylibloader_orig_asound +#define snd_pcm_subformat_mask_sizeof snd_pcm_subformat_mask_sizeof_dylibloader_orig_asound +#define snd_pcm_subformat_mask_malloc snd_pcm_subformat_mask_malloc_dylibloader_orig_asound +#define snd_pcm_subformat_mask_free snd_pcm_subformat_mask_free_dylibloader_orig_asound +#define snd_pcm_subformat_mask_copy snd_pcm_subformat_mask_copy_dylibloader_orig_asound +#define snd_pcm_subformat_mask_none snd_pcm_subformat_mask_none_dylibloader_orig_asound +#define snd_pcm_subformat_mask_any snd_pcm_subformat_mask_any_dylibloader_orig_asound +#define snd_pcm_subformat_mask_test snd_pcm_subformat_mask_test_dylibloader_orig_asound +#define snd_pcm_subformat_mask_empty snd_pcm_subformat_mask_empty_dylibloader_orig_asound +#define snd_pcm_subformat_mask_set snd_pcm_subformat_mask_set_dylibloader_orig_asound +#define snd_pcm_subformat_mask_reset snd_pcm_subformat_mask_reset_dylibloader_orig_asound +#define snd_pcm_status_sizeof snd_pcm_status_sizeof_dylibloader_orig_asound +#define snd_pcm_status_malloc snd_pcm_status_malloc_dylibloader_orig_asound +#define snd_pcm_status_free snd_pcm_status_free_dylibloader_orig_asound +#define snd_pcm_status_copy snd_pcm_status_copy_dylibloader_orig_asound +#define snd_pcm_status_get_state snd_pcm_status_get_state_dylibloader_orig_asound +#define snd_pcm_status_get_trigger_tstamp snd_pcm_status_get_trigger_tstamp_dylibloader_orig_asound +#define snd_pcm_status_get_trigger_htstamp snd_pcm_status_get_trigger_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_tstamp snd_pcm_status_get_tstamp_dylibloader_orig_asound +#define snd_pcm_status_get_htstamp snd_pcm_status_get_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_audio_htstamp snd_pcm_status_get_audio_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_driver_htstamp snd_pcm_status_get_driver_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_delay snd_pcm_status_get_delay_dylibloader_orig_asound +#define snd_pcm_status_get_avail snd_pcm_status_get_avail_dylibloader_orig_asound +#define snd_pcm_status_get_avail_max snd_pcm_status_get_avail_max_dylibloader_orig_asound +#define snd_pcm_status_get_overrange snd_pcm_status_get_overrange_dylibloader_orig_asound +#define snd_pcm_type_name snd_pcm_type_name_dylibloader_orig_asound +#define snd_pcm_stream_name snd_pcm_stream_name_dylibloader_orig_asound +#define snd_pcm_access_name snd_pcm_access_name_dylibloader_orig_asound +#define snd_pcm_format_name snd_pcm_format_name_dylibloader_orig_asound +#define snd_pcm_format_description snd_pcm_format_description_dylibloader_orig_asound +#define snd_pcm_subformat_name snd_pcm_subformat_name_dylibloader_orig_asound +#define snd_pcm_subformat_description snd_pcm_subformat_description_dylibloader_orig_asound +#define snd_pcm_format_value snd_pcm_format_value_dylibloader_orig_asound +#define snd_pcm_tstamp_mode_name snd_pcm_tstamp_mode_name_dylibloader_orig_asound +#define snd_pcm_state_name snd_pcm_state_name_dylibloader_orig_asound +#define snd_pcm_dump snd_pcm_dump_dylibloader_orig_asound +#define snd_pcm_dump_hw_setup snd_pcm_dump_hw_setup_dylibloader_orig_asound +#define snd_pcm_dump_sw_setup snd_pcm_dump_sw_setup_dylibloader_orig_asound +#define snd_pcm_dump_setup snd_pcm_dump_setup_dylibloader_orig_asound +#define snd_pcm_hw_params_dump snd_pcm_hw_params_dump_dylibloader_orig_asound +#define snd_pcm_sw_params_dump snd_pcm_sw_params_dump_dylibloader_orig_asound +#define snd_pcm_status_dump snd_pcm_status_dump_dylibloader_orig_asound +#define snd_pcm_mmap_begin snd_pcm_mmap_begin_dylibloader_orig_asound +#define snd_pcm_mmap_commit snd_pcm_mmap_commit_dylibloader_orig_asound +#define snd_pcm_mmap_writei snd_pcm_mmap_writei_dylibloader_orig_asound +#define snd_pcm_mmap_readi snd_pcm_mmap_readi_dylibloader_orig_asound +#define snd_pcm_mmap_writen snd_pcm_mmap_writen_dylibloader_orig_asound +#define snd_pcm_mmap_readn snd_pcm_mmap_readn_dylibloader_orig_asound +#define snd_pcm_format_signed snd_pcm_format_signed_dylibloader_orig_asound +#define snd_pcm_format_unsigned snd_pcm_format_unsigned_dylibloader_orig_asound +#define snd_pcm_format_linear snd_pcm_format_linear_dylibloader_orig_asound +#define snd_pcm_format_float snd_pcm_format_float_dylibloader_orig_asound +#define snd_pcm_format_little_endian snd_pcm_format_little_endian_dylibloader_orig_asound +#define snd_pcm_format_big_endian snd_pcm_format_big_endian_dylibloader_orig_asound +#define snd_pcm_format_cpu_endian snd_pcm_format_cpu_endian_dylibloader_orig_asound +#define snd_pcm_format_width snd_pcm_format_width_dylibloader_orig_asound +#define snd_pcm_format_physical_width snd_pcm_format_physical_width_dylibloader_orig_asound +#define snd_pcm_build_linear_format snd_pcm_build_linear_format_dylibloader_orig_asound +#define snd_pcm_format_size snd_pcm_format_size_dylibloader_orig_asound +#define snd_pcm_format_silence snd_pcm_format_silence_dylibloader_orig_asound +#define snd_pcm_format_silence_16 snd_pcm_format_silence_16_dylibloader_orig_asound +#define snd_pcm_format_silence_32 snd_pcm_format_silence_32_dylibloader_orig_asound +#define snd_pcm_format_silence_64 snd_pcm_format_silence_64_dylibloader_orig_asound +#define snd_pcm_format_set_silence snd_pcm_format_set_silence_dylibloader_orig_asound +#define snd_pcm_bytes_to_frames snd_pcm_bytes_to_frames_dylibloader_orig_asound +#define snd_pcm_frames_to_bytes snd_pcm_frames_to_bytes_dylibloader_orig_asound +#define snd_pcm_bytes_to_samples snd_pcm_bytes_to_samples_dylibloader_orig_asound +#define snd_pcm_samples_to_bytes snd_pcm_samples_to_bytes_dylibloader_orig_asound +#define snd_pcm_area_silence snd_pcm_area_silence_dylibloader_orig_asound +#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_orig_asound +#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_orig_asound +#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_orig_asound +#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_orig_asound +#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_orig_asound +#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_orig_asound +#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_orig_asound +#define snd_pcm_hook_add snd_pcm_hook_add_dylibloader_orig_asound +#define snd_pcm_hook_remove snd_pcm_hook_remove_dylibloader_orig_asound +#define snd_pcm_meter_get_bufsize snd_pcm_meter_get_bufsize_dylibloader_orig_asound +#define snd_pcm_meter_get_channels snd_pcm_meter_get_channels_dylibloader_orig_asound +#define snd_pcm_meter_get_rate snd_pcm_meter_get_rate_dylibloader_orig_asound +#define snd_pcm_meter_get_now snd_pcm_meter_get_now_dylibloader_orig_asound +#define snd_pcm_meter_get_boundary snd_pcm_meter_get_boundary_dylibloader_orig_asound +#define snd_pcm_meter_add_scope snd_pcm_meter_add_scope_dylibloader_orig_asound +#define snd_pcm_meter_search_scope snd_pcm_meter_search_scope_dylibloader_orig_asound +#define snd_pcm_scope_malloc snd_pcm_scope_malloc_dylibloader_orig_asound +#define snd_pcm_scope_set_ops snd_pcm_scope_set_ops_dylibloader_orig_asound +#define snd_pcm_scope_set_name snd_pcm_scope_set_name_dylibloader_orig_asound +#define snd_pcm_scope_get_name snd_pcm_scope_get_name_dylibloader_orig_asound +#define snd_pcm_scope_get_callback_private snd_pcm_scope_get_callback_private_dylibloader_orig_asound +#define snd_pcm_scope_set_callback_private snd_pcm_scope_set_callback_private_dylibloader_orig_asound +#define snd_pcm_scope_s16_open snd_pcm_scope_s16_open_dylibloader_orig_asound +#define snd_pcm_scope_s16_get_channel_buffer snd_pcm_scope_s16_get_channel_buffer_dylibloader_orig_asound +#define snd_spcm_init snd_spcm_init_dylibloader_orig_asound +#define snd_spcm_init_duplex snd_spcm_init_duplex_dylibloader_orig_asound +#define snd_spcm_init_get_params snd_spcm_init_get_params_dylibloader_orig_asound +#define snd_pcm_start_mode_name snd_pcm_start_mode_name_dylibloader_orig_asound +#define snd_pcm_xrun_mode_name snd_pcm_xrun_mode_name_dylibloader_orig_asound +#define snd_pcm_sw_params_set_start_mode snd_pcm_sw_params_set_start_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_get_start_mode snd_pcm_sw_params_get_start_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_set_xrun_mode snd_pcm_sw_params_set_xrun_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_get_xrun_mode snd_pcm_sw_params_get_xrun_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_set_xfer_align snd_pcm_sw_params_set_xfer_align_dylibloader_orig_asound +#define snd_pcm_sw_params_get_xfer_align snd_pcm_sw_params_get_xfer_align_dylibloader_orig_asound +#define snd_pcm_sw_params_set_sleep_min snd_pcm_sw_params_set_sleep_min_dylibloader_orig_asound +#define snd_pcm_sw_params_get_sleep_min snd_pcm_sw_params_get_sleep_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_tick_time snd_pcm_hw_params_get_tick_time_dylibloader_orig_asound +#define snd_pcm_hw_params_get_tick_time_min snd_pcm_hw_params_get_tick_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_tick_time_max snd_pcm_hw_params_get_tick_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_tick_time snd_pcm_hw_params_test_tick_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time snd_pcm_hw_params_set_tick_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_min snd_pcm_hw_params_set_tick_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_max snd_pcm_hw_params_set_tick_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_minmax snd_pcm_hw_params_set_tick_time_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_near snd_pcm_hw_params_set_tick_time_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_first snd_pcm_hw_params_set_tick_time_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_last snd_pcm_hw_params_set_tick_time_last_dylibloader_orig_asound +#define snd_rawmidi_open snd_rawmidi_open_dylibloader_orig_asound +#define snd_rawmidi_open_lconf snd_rawmidi_open_lconf_dylibloader_orig_asound +#define snd_rawmidi_close snd_rawmidi_close_dylibloader_orig_asound +#define snd_rawmidi_poll_descriptors_count snd_rawmidi_poll_descriptors_count_dylibloader_orig_asound +#define snd_rawmidi_poll_descriptors snd_rawmidi_poll_descriptors_dylibloader_orig_asound +#define snd_rawmidi_poll_descriptors_revents snd_rawmidi_poll_descriptors_revents_dylibloader_orig_asound +#define snd_rawmidi_nonblock snd_rawmidi_nonblock_dylibloader_orig_asound +#define snd_rawmidi_info_sizeof snd_rawmidi_info_sizeof_dylibloader_orig_asound +#define snd_rawmidi_info_malloc snd_rawmidi_info_malloc_dylibloader_orig_asound +#define snd_rawmidi_info_free snd_rawmidi_info_free_dylibloader_orig_asound +#define snd_rawmidi_info_copy snd_rawmidi_info_copy_dylibloader_orig_asound +#define snd_rawmidi_info_get_device snd_rawmidi_info_get_device_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevice snd_rawmidi_info_get_subdevice_dylibloader_orig_asound +#define snd_rawmidi_info_get_stream snd_rawmidi_info_get_stream_dylibloader_orig_asound +#define snd_rawmidi_info_get_card snd_rawmidi_info_get_card_dylibloader_orig_asound +#define snd_rawmidi_info_get_flags snd_rawmidi_info_get_flags_dylibloader_orig_asound +#define snd_rawmidi_info_get_id snd_rawmidi_info_get_id_dylibloader_orig_asound +#define snd_rawmidi_info_get_name snd_rawmidi_info_get_name_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevice_name snd_rawmidi_info_get_subdevice_name_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevices_count snd_rawmidi_info_get_subdevices_count_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevices_avail snd_rawmidi_info_get_subdevices_avail_dylibloader_orig_asound +#define snd_rawmidi_info_set_device snd_rawmidi_info_set_device_dylibloader_orig_asound +#define snd_rawmidi_info_set_subdevice snd_rawmidi_info_set_subdevice_dylibloader_orig_asound +#define snd_rawmidi_info_set_stream snd_rawmidi_info_set_stream_dylibloader_orig_asound +#define snd_rawmidi_info snd_rawmidi_info_dylibloader_orig_asound +#define snd_rawmidi_params_sizeof snd_rawmidi_params_sizeof_dylibloader_orig_asound +#define snd_rawmidi_params_malloc snd_rawmidi_params_malloc_dylibloader_orig_asound +#define snd_rawmidi_params_free snd_rawmidi_params_free_dylibloader_orig_asound +#define snd_rawmidi_params_copy snd_rawmidi_params_copy_dylibloader_orig_asound +#define snd_rawmidi_params_set_buffer_size snd_rawmidi_params_set_buffer_size_dylibloader_orig_asound +#define snd_rawmidi_params_get_buffer_size snd_rawmidi_params_get_buffer_size_dylibloader_orig_asound +#define snd_rawmidi_params_set_avail_min snd_rawmidi_params_set_avail_min_dylibloader_orig_asound +#define snd_rawmidi_params_get_avail_min snd_rawmidi_params_get_avail_min_dylibloader_orig_asound +#define snd_rawmidi_params_set_no_active_sensing snd_rawmidi_params_set_no_active_sensing_dylibloader_orig_asound +#define snd_rawmidi_params_get_no_active_sensing snd_rawmidi_params_get_no_active_sensing_dylibloader_orig_asound +#define snd_rawmidi_params snd_rawmidi_params_dylibloader_orig_asound +#define snd_rawmidi_params_current snd_rawmidi_params_current_dylibloader_orig_asound +#define snd_rawmidi_status_sizeof snd_rawmidi_status_sizeof_dylibloader_orig_asound +#define snd_rawmidi_status_malloc snd_rawmidi_status_malloc_dylibloader_orig_asound +#define snd_rawmidi_status_free snd_rawmidi_status_free_dylibloader_orig_asound +#define snd_rawmidi_status_copy snd_rawmidi_status_copy_dylibloader_orig_asound +#define snd_rawmidi_status_get_tstamp snd_rawmidi_status_get_tstamp_dylibloader_orig_asound +#define snd_rawmidi_status_get_avail snd_rawmidi_status_get_avail_dylibloader_orig_asound +#define snd_rawmidi_status_get_xruns snd_rawmidi_status_get_xruns_dylibloader_orig_asound +#define snd_rawmidi_status snd_rawmidi_status_dylibloader_orig_asound +#define snd_rawmidi_drain snd_rawmidi_drain_dylibloader_orig_asound +#define snd_rawmidi_drop snd_rawmidi_drop_dylibloader_orig_asound +#define snd_rawmidi_write snd_rawmidi_write_dylibloader_orig_asound +#define snd_rawmidi_read snd_rawmidi_read_dylibloader_orig_asound +#define snd_rawmidi_name snd_rawmidi_name_dylibloader_orig_asound +#define snd_rawmidi_type snd_rawmidi_type_dylibloader_orig_asound +#define snd_rawmidi_stream snd_rawmidi_stream_dylibloader_orig_asound +#define snd_timer_query_open snd_timer_query_open_dylibloader_orig_asound +#define snd_timer_query_open_lconf snd_timer_query_open_lconf_dylibloader_orig_asound +#define snd_timer_query_close snd_timer_query_close_dylibloader_orig_asound +#define snd_timer_query_next_device snd_timer_query_next_device_dylibloader_orig_asound +#define snd_timer_query_info snd_timer_query_info_dylibloader_orig_asound +#define snd_timer_query_params snd_timer_query_params_dylibloader_orig_asound +#define snd_timer_query_status snd_timer_query_status_dylibloader_orig_asound +#define snd_timer_open snd_timer_open_dylibloader_orig_asound +#define snd_timer_open_lconf snd_timer_open_lconf_dylibloader_orig_asound +#define snd_timer_close snd_timer_close_dylibloader_orig_asound +#define snd_async_add_timer_handler snd_async_add_timer_handler_dylibloader_orig_asound +#define snd_async_handler_get_timer snd_async_handler_get_timer_dylibloader_orig_asound +#define snd_timer_poll_descriptors_count snd_timer_poll_descriptors_count_dylibloader_orig_asound +#define snd_timer_poll_descriptors snd_timer_poll_descriptors_dylibloader_orig_asound +#define snd_timer_poll_descriptors_revents snd_timer_poll_descriptors_revents_dylibloader_orig_asound +#define snd_timer_info snd_timer_info_dylibloader_orig_asound +#define snd_timer_params snd_timer_params_dylibloader_orig_asound +#define snd_timer_status snd_timer_status_dylibloader_orig_asound +#define snd_timer_start snd_timer_start_dylibloader_orig_asound +#define snd_timer_stop snd_timer_stop_dylibloader_orig_asound +#define snd_timer_continue snd_timer_continue_dylibloader_orig_asound +#define snd_timer_read snd_timer_read_dylibloader_orig_asound +#define snd_timer_id_sizeof snd_timer_id_sizeof_dylibloader_orig_asound +#define snd_timer_id_malloc snd_timer_id_malloc_dylibloader_orig_asound +#define snd_timer_id_free snd_timer_id_free_dylibloader_orig_asound +#define snd_timer_id_copy snd_timer_id_copy_dylibloader_orig_asound +#define snd_timer_id_set_class snd_timer_id_set_class_dylibloader_orig_asound +#define snd_timer_id_get_class snd_timer_id_get_class_dylibloader_orig_asound +#define snd_timer_id_set_sclass snd_timer_id_set_sclass_dylibloader_orig_asound +#define snd_timer_id_get_sclass snd_timer_id_get_sclass_dylibloader_orig_asound +#define snd_timer_id_set_card snd_timer_id_set_card_dylibloader_orig_asound +#define snd_timer_id_get_card snd_timer_id_get_card_dylibloader_orig_asound +#define snd_timer_id_set_device snd_timer_id_set_device_dylibloader_orig_asound +#define snd_timer_id_get_device snd_timer_id_get_device_dylibloader_orig_asound +#define snd_timer_id_set_subdevice snd_timer_id_set_subdevice_dylibloader_orig_asound +#define snd_timer_id_get_subdevice snd_timer_id_get_subdevice_dylibloader_orig_asound +#define snd_timer_ginfo_sizeof snd_timer_ginfo_sizeof_dylibloader_orig_asound +#define snd_timer_ginfo_malloc snd_timer_ginfo_malloc_dylibloader_orig_asound +#define snd_timer_ginfo_free snd_timer_ginfo_free_dylibloader_orig_asound +#define snd_timer_ginfo_copy snd_timer_ginfo_copy_dylibloader_orig_asound +#define snd_timer_ginfo_set_tid snd_timer_ginfo_set_tid_dylibloader_orig_asound +#define snd_timer_ginfo_get_tid snd_timer_ginfo_get_tid_dylibloader_orig_asound +#define snd_timer_ginfo_get_flags snd_timer_ginfo_get_flags_dylibloader_orig_asound +#define snd_timer_ginfo_get_card snd_timer_ginfo_get_card_dylibloader_orig_asound +#define snd_timer_ginfo_get_id snd_timer_ginfo_get_id_dylibloader_orig_asound +#define snd_timer_ginfo_get_name snd_timer_ginfo_get_name_dylibloader_orig_asound +#define snd_timer_ginfo_get_resolution snd_timer_ginfo_get_resolution_dylibloader_orig_asound +#define snd_timer_ginfo_get_resolution_min snd_timer_ginfo_get_resolution_min_dylibloader_orig_asound +#define snd_timer_ginfo_get_resolution_max snd_timer_ginfo_get_resolution_max_dylibloader_orig_asound +#define snd_timer_ginfo_get_clients snd_timer_ginfo_get_clients_dylibloader_orig_asound +#define snd_timer_info_sizeof snd_timer_info_sizeof_dylibloader_orig_asound +#define snd_timer_info_malloc snd_timer_info_malloc_dylibloader_orig_asound +#define snd_timer_info_free snd_timer_info_free_dylibloader_orig_asound +#define snd_timer_info_copy snd_timer_info_copy_dylibloader_orig_asound +#define snd_timer_info_is_slave snd_timer_info_is_slave_dylibloader_orig_asound +#define snd_timer_info_get_card snd_timer_info_get_card_dylibloader_orig_asound +#define snd_timer_info_get_id snd_timer_info_get_id_dylibloader_orig_asound +#define snd_timer_info_get_name snd_timer_info_get_name_dylibloader_orig_asound +#define snd_timer_info_get_resolution snd_timer_info_get_resolution_dylibloader_orig_asound +#define snd_timer_params_sizeof snd_timer_params_sizeof_dylibloader_orig_asound +#define snd_timer_params_malloc snd_timer_params_malloc_dylibloader_orig_asound +#define snd_timer_params_free snd_timer_params_free_dylibloader_orig_asound +#define snd_timer_params_copy snd_timer_params_copy_dylibloader_orig_asound +#define snd_timer_params_set_auto_start snd_timer_params_set_auto_start_dylibloader_orig_asound +#define snd_timer_params_get_auto_start snd_timer_params_get_auto_start_dylibloader_orig_asound +#define snd_timer_params_set_exclusive snd_timer_params_set_exclusive_dylibloader_orig_asound +#define snd_timer_params_get_exclusive snd_timer_params_get_exclusive_dylibloader_orig_asound +#define snd_timer_params_set_early_event snd_timer_params_set_early_event_dylibloader_orig_asound +#define snd_timer_params_get_early_event snd_timer_params_get_early_event_dylibloader_orig_asound +#define snd_timer_params_set_ticks snd_timer_params_set_ticks_dylibloader_orig_asound +#define snd_timer_params_get_ticks snd_timer_params_get_ticks_dylibloader_orig_asound +#define snd_timer_params_set_queue_size snd_timer_params_set_queue_size_dylibloader_orig_asound +#define snd_timer_params_get_queue_size snd_timer_params_get_queue_size_dylibloader_orig_asound +#define snd_timer_params_set_filter snd_timer_params_set_filter_dylibloader_orig_asound +#define snd_timer_params_get_filter snd_timer_params_get_filter_dylibloader_orig_asound +#define snd_timer_status_sizeof snd_timer_status_sizeof_dylibloader_orig_asound +#define snd_timer_status_malloc snd_timer_status_malloc_dylibloader_orig_asound +#define snd_timer_status_free snd_timer_status_free_dylibloader_orig_asound +#define snd_timer_status_copy snd_timer_status_copy_dylibloader_orig_asound +#define snd_timer_status_get_timestamp snd_timer_status_get_timestamp_dylibloader_orig_asound +#define snd_timer_status_get_resolution snd_timer_status_get_resolution_dylibloader_orig_asound +#define snd_timer_status_get_lost snd_timer_status_get_lost_dylibloader_orig_asound +#define snd_timer_status_get_overrun snd_timer_status_get_overrun_dylibloader_orig_asound +#define snd_timer_status_get_queue snd_timer_status_get_queue_dylibloader_orig_asound +#define snd_timer_info_get_ticks snd_timer_info_get_ticks_dylibloader_orig_asound +#define snd_hwdep_open snd_hwdep_open_dylibloader_orig_asound +#define snd_hwdep_close snd_hwdep_close_dylibloader_orig_asound +#define snd_hwdep_poll_descriptors snd_hwdep_poll_descriptors_dylibloader_orig_asound +#define snd_hwdep_poll_descriptors_count snd_hwdep_poll_descriptors_count_dylibloader_orig_asound +#define snd_hwdep_poll_descriptors_revents snd_hwdep_poll_descriptors_revents_dylibloader_orig_asound +#define snd_hwdep_nonblock snd_hwdep_nonblock_dylibloader_orig_asound +#define snd_hwdep_info snd_hwdep_info_dylibloader_orig_asound +#define snd_hwdep_dsp_status snd_hwdep_dsp_status_dylibloader_orig_asound +#define snd_hwdep_dsp_load snd_hwdep_dsp_load_dylibloader_orig_asound +#define snd_hwdep_ioctl snd_hwdep_ioctl_dylibloader_orig_asound +#define snd_hwdep_write snd_hwdep_write_dylibloader_orig_asound +#define snd_hwdep_read snd_hwdep_read_dylibloader_orig_asound +#define snd_hwdep_info_sizeof snd_hwdep_info_sizeof_dylibloader_orig_asound +#define snd_hwdep_info_malloc snd_hwdep_info_malloc_dylibloader_orig_asound +#define snd_hwdep_info_free snd_hwdep_info_free_dylibloader_orig_asound +#define snd_hwdep_info_copy snd_hwdep_info_copy_dylibloader_orig_asound +#define snd_hwdep_info_get_device snd_hwdep_info_get_device_dylibloader_orig_asound +#define snd_hwdep_info_get_card snd_hwdep_info_get_card_dylibloader_orig_asound +#define snd_hwdep_info_get_id snd_hwdep_info_get_id_dylibloader_orig_asound +#define snd_hwdep_info_get_name snd_hwdep_info_get_name_dylibloader_orig_asound +#define snd_hwdep_info_get_iface snd_hwdep_info_get_iface_dylibloader_orig_asound +#define snd_hwdep_info_set_device snd_hwdep_info_set_device_dylibloader_orig_asound +#define snd_hwdep_dsp_status_sizeof snd_hwdep_dsp_status_sizeof_dylibloader_orig_asound +#define snd_hwdep_dsp_status_malloc snd_hwdep_dsp_status_malloc_dylibloader_orig_asound +#define snd_hwdep_dsp_status_free snd_hwdep_dsp_status_free_dylibloader_orig_asound +#define snd_hwdep_dsp_status_copy snd_hwdep_dsp_status_copy_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_version snd_hwdep_dsp_status_get_version_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_id snd_hwdep_dsp_status_get_id_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_num_dsps snd_hwdep_dsp_status_get_num_dsps_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_dsp_loaded snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_chip_ready snd_hwdep_dsp_status_get_chip_ready_dylibloader_orig_asound +#define snd_hwdep_dsp_image_sizeof snd_hwdep_dsp_image_sizeof_dylibloader_orig_asound +#define snd_hwdep_dsp_image_malloc snd_hwdep_dsp_image_malloc_dylibloader_orig_asound +#define snd_hwdep_dsp_image_free snd_hwdep_dsp_image_free_dylibloader_orig_asound +#define snd_hwdep_dsp_image_copy snd_hwdep_dsp_image_copy_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_index snd_hwdep_dsp_image_get_index_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_name snd_hwdep_dsp_image_get_name_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_image snd_hwdep_dsp_image_get_image_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_length snd_hwdep_dsp_image_get_length_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_index snd_hwdep_dsp_image_set_index_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_name snd_hwdep_dsp_image_set_name_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_image snd_hwdep_dsp_image_set_image_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_length snd_hwdep_dsp_image_set_length_dylibloader_orig_asound +#define snd_card_load snd_card_load_dylibloader_orig_asound +#define snd_card_next snd_card_next_dylibloader_orig_asound +#define snd_card_get_index snd_card_get_index_dylibloader_orig_asound +#define snd_card_get_name snd_card_get_name_dylibloader_orig_asound +#define snd_card_get_longname snd_card_get_longname_dylibloader_orig_asound +#define snd_device_name_hint snd_device_name_hint_dylibloader_orig_asound +#define snd_device_name_free_hint snd_device_name_free_hint_dylibloader_orig_asound +#define snd_device_name_get_hint snd_device_name_get_hint_dylibloader_orig_asound +#define snd_ctl_open snd_ctl_open_dylibloader_orig_asound +#define snd_ctl_open_lconf snd_ctl_open_lconf_dylibloader_orig_asound +#define snd_ctl_open_fallback snd_ctl_open_fallback_dylibloader_orig_asound +#define snd_ctl_close snd_ctl_close_dylibloader_orig_asound +#define snd_ctl_nonblock snd_ctl_nonblock_dylibloader_orig_asound +#define snd_async_add_ctl_handler snd_async_add_ctl_handler_dylibloader_orig_asound +#define snd_async_handler_get_ctl snd_async_handler_get_ctl_dylibloader_orig_asound +#define snd_ctl_poll_descriptors_count snd_ctl_poll_descriptors_count_dylibloader_orig_asound +#define snd_ctl_poll_descriptors snd_ctl_poll_descriptors_dylibloader_orig_asound +#define snd_ctl_poll_descriptors_revents snd_ctl_poll_descriptors_revents_dylibloader_orig_asound +#define snd_ctl_subscribe_events snd_ctl_subscribe_events_dylibloader_orig_asound +#define snd_ctl_card_info snd_ctl_card_info_dylibloader_orig_asound +#define snd_ctl_elem_list snd_ctl_elem_list_dylibloader_orig_asound +#define snd_ctl_elem_info snd_ctl_elem_info_dylibloader_orig_asound +#define snd_ctl_elem_read snd_ctl_elem_read_dylibloader_orig_asound +#define snd_ctl_elem_write snd_ctl_elem_write_dylibloader_orig_asound +#define snd_ctl_elem_lock snd_ctl_elem_lock_dylibloader_orig_asound +#define snd_ctl_elem_unlock snd_ctl_elem_unlock_dylibloader_orig_asound +#define snd_ctl_elem_tlv_read snd_ctl_elem_tlv_read_dylibloader_orig_asound +#define snd_ctl_elem_tlv_write snd_ctl_elem_tlv_write_dylibloader_orig_asound +#define snd_ctl_elem_tlv_command snd_ctl_elem_tlv_command_dylibloader_orig_asound +#define snd_ctl_hwdep_next_device snd_ctl_hwdep_next_device_dylibloader_orig_asound +#define snd_ctl_hwdep_info snd_ctl_hwdep_info_dylibloader_orig_asound +#define snd_ctl_pcm_next_device snd_ctl_pcm_next_device_dylibloader_orig_asound +#define snd_ctl_pcm_info snd_ctl_pcm_info_dylibloader_orig_asound +#define snd_ctl_pcm_prefer_subdevice snd_ctl_pcm_prefer_subdevice_dylibloader_orig_asound +#define snd_ctl_rawmidi_next_device snd_ctl_rawmidi_next_device_dylibloader_orig_asound +#define snd_ctl_rawmidi_info snd_ctl_rawmidi_info_dylibloader_orig_asound +#define snd_ctl_rawmidi_prefer_subdevice snd_ctl_rawmidi_prefer_subdevice_dylibloader_orig_asound +#define snd_ctl_set_power_state snd_ctl_set_power_state_dylibloader_orig_asound +#define snd_ctl_get_power_state snd_ctl_get_power_state_dylibloader_orig_asound +#define snd_ctl_read snd_ctl_read_dylibloader_orig_asound +#define snd_ctl_wait snd_ctl_wait_dylibloader_orig_asound +#define snd_ctl_name snd_ctl_name_dylibloader_orig_asound +#define snd_ctl_type snd_ctl_type_dylibloader_orig_asound +#define snd_ctl_elem_type_name snd_ctl_elem_type_name_dylibloader_orig_asound +#define snd_ctl_elem_iface_name snd_ctl_elem_iface_name_dylibloader_orig_asound +#define snd_ctl_event_type_name snd_ctl_event_type_name_dylibloader_orig_asound +#define snd_ctl_event_elem_get_mask snd_ctl_event_elem_get_mask_dylibloader_orig_asound +#define snd_ctl_event_elem_get_numid snd_ctl_event_elem_get_numid_dylibloader_orig_asound +#define snd_ctl_event_elem_get_id snd_ctl_event_elem_get_id_dylibloader_orig_asound +#define snd_ctl_event_elem_get_interface snd_ctl_event_elem_get_interface_dylibloader_orig_asound +#define snd_ctl_event_elem_get_device snd_ctl_event_elem_get_device_dylibloader_orig_asound +#define snd_ctl_event_elem_get_subdevice snd_ctl_event_elem_get_subdevice_dylibloader_orig_asound +#define snd_ctl_event_elem_get_name snd_ctl_event_elem_get_name_dylibloader_orig_asound +#define snd_ctl_event_elem_get_index snd_ctl_event_elem_get_index_dylibloader_orig_asound +#define snd_ctl_elem_list_alloc_space snd_ctl_elem_list_alloc_space_dylibloader_orig_asound +#define snd_ctl_elem_list_free_space snd_ctl_elem_list_free_space_dylibloader_orig_asound +#define snd_ctl_ascii_elem_id_get snd_ctl_ascii_elem_id_get_dylibloader_orig_asound +#define snd_ctl_ascii_elem_id_parse snd_ctl_ascii_elem_id_parse_dylibloader_orig_asound +#define snd_ctl_ascii_value_parse snd_ctl_ascii_value_parse_dylibloader_orig_asound +#define snd_ctl_elem_id_sizeof snd_ctl_elem_id_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_id_malloc snd_ctl_elem_id_malloc_dylibloader_orig_asound +#define snd_ctl_elem_id_free snd_ctl_elem_id_free_dylibloader_orig_asound +#define snd_ctl_elem_id_clear snd_ctl_elem_id_clear_dylibloader_orig_asound +#define snd_ctl_elem_id_copy snd_ctl_elem_id_copy_dylibloader_orig_asound +#define snd_ctl_elem_id_get_numid snd_ctl_elem_id_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_id_get_interface snd_ctl_elem_id_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_id_get_device snd_ctl_elem_id_get_device_dylibloader_orig_asound +#define snd_ctl_elem_id_get_subdevice snd_ctl_elem_id_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_id_get_name snd_ctl_elem_id_get_name_dylibloader_orig_asound +#define snd_ctl_elem_id_get_index snd_ctl_elem_id_get_index_dylibloader_orig_asound +#define snd_ctl_elem_id_set_numid snd_ctl_elem_id_set_numid_dylibloader_orig_asound +#define snd_ctl_elem_id_set_interface snd_ctl_elem_id_set_interface_dylibloader_orig_asound +#define snd_ctl_elem_id_set_device snd_ctl_elem_id_set_device_dylibloader_orig_asound +#define snd_ctl_elem_id_set_subdevice snd_ctl_elem_id_set_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_id_set_name snd_ctl_elem_id_set_name_dylibloader_orig_asound +#define snd_ctl_elem_id_set_index snd_ctl_elem_id_set_index_dylibloader_orig_asound +#define snd_ctl_card_info_sizeof snd_ctl_card_info_sizeof_dylibloader_orig_asound +#define snd_ctl_card_info_malloc snd_ctl_card_info_malloc_dylibloader_orig_asound +#define snd_ctl_card_info_free snd_ctl_card_info_free_dylibloader_orig_asound +#define snd_ctl_card_info_clear snd_ctl_card_info_clear_dylibloader_orig_asound +#define snd_ctl_card_info_copy snd_ctl_card_info_copy_dylibloader_orig_asound +#define snd_ctl_card_info_get_card snd_ctl_card_info_get_card_dylibloader_orig_asound +#define snd_ctl_card_info_get_id snd_ctl_card_info_get_id_dylibloader_orig_asound +#define snd_ctl_card_info_get_driver snd_ctl_card_info_get_driver_dylibloader_orig_asound +#define snd_ctl_card_info_get_name snd_ctl_card_info_get_name_dylibloader_orig_asound +#define snd_ctl_card_info_get_longname snd_ctl_card_info_get_longname_dylibloader_orig_asound +#define snd_ctl_card_info_get_mixername snd_ctl_card_info_get_mixername_dylibloader_orig_asound +#define snd_ctl_card_info_get_components snd_ctl_card_info_get_components_dylibloader_orig_asound +#define snd_ctl_event_sizeof snd_ctl_event_sizeof_dylibloader_orig_asound +#define snd_ctl_event_malloc snd_ctl_event_malloc_dylibloader_orig_asound +#define snd_ctl_event_free snd_ctl_event_free_dylibloader_orig_asound +#define snd_ctl_event_clear snd_ctl_event_clear_dylibloader_orig_asound +#define snd_ctl_event_copy snd_ctl_event_copy_dylibloader_orig_asound +#define snd_ctl_event_get_type snd_ctl_event_get_type_dylibloader_orig_asound +#define snd_ctl_elem_list_sizeof snd_ctl_elem_list_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_list_malloc snd_ctl_elem_list_malloc_dylibloader_orig_asound +#define snd_ctl_elem_list_free snd_ctl_elem_list_free_dylibloader_orig_asound +#define snd_ctl_elem_list_clear snd_ctl_elem_list_clear_dylibloader_orig_asound +#define snd_ctl_elem_list_copy snd_ctl_elem_list_copy_dylibloader_orig_asound +#define snd_ctl_elem_list_set_offset snd_ctl_elem_list_set_offset_dylibloader_orig_asound +#define snd_ctl_elem_list_get_used snd_ctl_elem_list_get_used_dylibloader_orig_asound +#define snd_ctl_elem_list_get_count snd_ctl_elem_list_get_count_dylibloader_orig_asound +#define snd_ctl_elem_list_get_id snd_ctl_elem_list_get_id_dylibloader_orig_asound +#define snd_ctl_elem_list_get_numid snd_ctl_elem_list_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_list_get_interface snd_ctl_elem_list_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_list_get_device snd_ctl_elem_list_get_device_dylibloader_orig_asound +#define snd_ctl_elem_list_get_subdevice snd_ctl_elem_list_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_list_get_name snd_ctl_elem_list_get_name_dylibloader_orig_asound +#define snd_ctl_elem_list_get_index snd_ctl_elem_list_get_index_dylibloader_orig_asound +#define snd_ctl_elem_info_sizeof snd_ctl_elem_info_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_info_malloc snd_ctl_elem_info_malloc_dylibloader_orig_asound +#define snd_ctl_elem_info_free snd_ctl_elem_info_free_dylibloader_orig_asound +#define snd_ctl_elem_info_clear snd_ctl_elem_info_clear_dylibloader_orig_asound +#define snd_ctl_elem_info_copy snd_ctl_elem_info_copy_dylibloader_orig_asound +#define snd_ctl_elem_info_get_type snd_ctl_elem_info_get_type_dylibloader_orig_asound +#define snd_ctl_elem_info_is_readable snd_ctl_elem_info_is_readable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_writable snd_ctl_elem_info_is_writable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_volatile snd_ctl_elem_info_is_volatile_dylibloader_orig_asound +#define snd_ctl_elem_info_is_inactive snd_ctl_elem_info_is_inactive_dylibloader_orig_asound +#define snd_ctl_elem_info_is_locked snd_ctl_elem_info_is_locked_dylibloader_orig_asound +#define snd_ctl_elem_info_is_tlv_readable snd_ctl_elem_info_is_tlv_readable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_tlv_writable snd_ctl_elem_info_is_tlv_writable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_tlv_commandable snd_ctl_elem_info_is_tlv_commandable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_owner snd_ctl_elem_info_is_owner_dylibloader_orig_asound +#define snd_ctl_elem_info_is_user snd_ctl_elem_info_is_user_dylibloader_orig_asound +#define snd_ctl_elem_info_get_owner snd_ctl_elem_info_get_owner_dylibloader_orig_asound +#define snd_ctl_elem_info_get_count snd_ctl_elem_info_get_count_dylibloader_orig_asound +#define snd_ctl_elem_info_get_min snd_ctl_elem_info_get_min_dylibloader_orig_asound +#define snd_ctl_elem_info_get_max snd_ctl_elem_info_get_max_dylibloader_orig_asound +#define snd_ctl_elem_info_get_step snd_ctl_elem_info_get_step_dylibloader_orig_asound +#define snd_ctl_elem_info_get_min64 snd_ctl_elem_info_get_min64_dylibloader_orig_asound +#define snd_ctl_elem_info_get_max64 snd_ctl_elem_info_get_max64_dylibloader_orig_asound +#define snd_ctl_elem_info_get_step64 snd_ctl_elem_info_get_step64_dylibloader_orig_asound +#define snd_ctl_elem_info_get_items snd_ctl_elem_info_get_items_dylibloader_orig_asound +#define snd_ctl_elem_info_set_item snd_ctl_elem_info_set_item_dylibloader_orig_asound +#define snd_ctl_elem_info_get_item_name snd_ctl_elem_info_get_item_name_dylibloader_orig_asound +#define snd_ctl_elem_info_get_dimensions snd_ctl_elem_info_get_dimensions_dylibloader_orig_asound +#define snd_ctl_elem_info_get_dimension snd_ctl_elem_info_get_dimension_dylibloader_orig_asound +#define snd_ctl_elem_info_set_dimension snd_ctl_elem_info_set_dimension_dylibloader_orig_asound +#define snd_ctl_elem_info_get_id snd_ctl_elem_info_get_id_dylibloader_orig_asound +#define snd_ctl_elem_info_get_numid snd_ctl_elem_info_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_info_get_interface snd_ctl_elem_info_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_info_get_device snd_ctl_elem_info_get_device_dylibloader_orig_asound +#define snd_ctl_elem_info_get_subdevice snd_ctl_elem_info_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_info_get_name snd_ctl_elem_info_get_name_dylibloader_orig_asound +#define snd_ctl_elem_info_get_index snd_ctl_elem_info_get_index_dylibloader_orig_asound +#define snd_ctl_elem_info_set_id snd_ctl_elem_info_set_id_dylibloader_orig_asound +#define snd_ctl_elem_info_set_numid snd_ctl_elem_info_set_numid_dylibloader_orig_asound +#define snd_ctl_elem_info_set_interface snd_ctl_elem_info_set_interface_dylibloader_orig_asound +#define snd_ctl_elem_info_set_device snd_ctl_elem_info_set_device_dylibloader_orig_asound +#define snd_ctl_elem_info_set_subdevice snd_ctl_elem_info_set_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_info_set_name snd_ctl_elem_info_set_name_dylibloader_orig_asound +#define snd_ctl_elem_info_set_index snd_ctl_elem_info_set_index_dylibloader_orig_asound +#define snd_ctl_add_integer_elem_set snd_ctl_add_integer_elem_set_dylibloader_orig_asound +#define snd_ctl_add_integer64_elem_set snd_ctl_add_integer64_elem_set_dylibloader_orig_asound +#define snd_ctl_add_boolean_elem_set snd_ctl_add_boolean_elem_set_dylibloader_orig_asound +#define snd_ctl_add_enumerated_elem_set snd_ctl_add_enumerated_elem_set_dylibloader_orig_asound +#define snd_ctl_add_bytes_elem_set snd_ctl_add_bytes_elem_set_dylibloader_orig_asound +#define snd_ctl_elem_add_integer snd_ctl_elem_add_integer_dylibloader_orig_asound +#define snd_ctl_elem_add_integer64 snd_ctl_elem_add_integer64_dylibloader_orig_asound +#define snd_ctl_elem_add_boolean snd_ctl_elem_add_boolean_dylibloader_orig_asound +#define snd_ctl_elem_add_enumerated snd_ctl_elem_add_enumerated_dylibloader_orig_asound +#define snd_ctl_elem_add_iec958 snd_ctl_elem_add_iec958_dylibloader_orig_asound +#define snd_ctl_elem_remove snd_ctl_elem_remove_dylibloader_orig_asound +#define snd_ctl_elem_value_sizeof snd_ctl_elem_value_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_value_malloc snd_ctl_elem_value_malloc_dylibloader_orig_asound +#define snd_ctl_elem_value_free snd_ctl_elem_value_free_dylibloader_orig_asound +#define snd_ctl_elem_value_clear snd_ctl_elem_value_clear_dylibloader_orig_asound +#define snd_ctl_elem_value_copy snd_ctl_elem_value_copy_dylibloader_orig_asound +#define snd_ctl_elem_value_compare snd_ctl_elem_value_compare_dylibloader_orig_asound +#define snd_ctl_elem_value_get_id snd_ctl_elem_value_get_id_dylibloader_orig_asound +#define snd_ctl_elem_value_get_numid snd_ctl_elem_value_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_value_get_interface snd_ctl_elem_value_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_value_get_device snd_ctl_elem_value_get_device_dylibloader_orig_asound +#define snd_ctl_elem_value_get_subdevice snd_ctl_elem_value_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_value_get_name snd_ctl_elem_value_get_name_dylibloader_orig_asound +#define snd_ctl_elem_value_get_index snd_ctl_elem_value_get_index_dylibloader_orig_asound +#define snd_ctl_elem_value_set_id snd_ctl_elem_value_set_id_dylibloader_orig_asound +#define snd_ctl_elem_value_set_numid snd_ctl_elem_value_set_numid_dylibloader_orig_asound +#define snd_ctl_elem_value_set_interface snd_ctl_elem_value_set_interface_dylibloader_orig_asound +#define snd_ctl_elem_value_set_device snd_ctl_elem_value_set_device_dylibloader_orig_asound +#define snd_ctl_elem_value_set_subdevice snd_ctl_elem_value_set_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_value_set_name snd_ctl_elem_value_set_name_dylibloader_orig_asound +#define snd_ctl_elem_value_set_index snd_ctl_elem_value_set_index_dylibloader_orig_asound +#define snd_ctl_elem_value_get_boolean snd_ctl_elem_value_get_boolean_dylibloader_orig_asound +#define snd_ctl_elem_value_get_integer snd_ctl_elem_value_get_integer_dylibloader_orig_asound +#define snd_ctl_elem_value_get_integer64 snd_ctl_elem_value_get_integer64_dylibloader_orig_asound +#define snd_ctl_elem_value_get_enumerated snd_ctl_elem_value_get_enumerated_dylibloader_orig_asound +#define snd_ctl_elem_value_get_byte snd_ctl_elem_value_get_byte_dylibloader_orig_asound +#define snd_ctl_elem_value_set_boolean snd_ctl_elem_value_set_boolean_dylibloader_orig_asound +#define snd_ctl_elem_value_set_integer snd_ctl_elem_value_set_integer_dylibloader_orig_asound +#define snd_ctl_elem_value_set_integer64 snd_ctl_elem_value_set_integer64_dylibloader_orig_asound +#define snd_ctl_elem_value_set_enumerated snd_ctl_elem_value_set_enumerated_dylibloader_orig_asound +#define snd_ctl_elem_value_set_byte snd_ctl_elem_value_set_byte_dylibloader_orig_asound +#define snd_ctl_elem_set_bytes snd_ctl_elem_set_bytes_dylibloader_orig_asound +#define snd_ctl_elem_value_get_bytes snd_ctl_elem_value_get_bytes_dylibloader_orig_asound +#define snd_ctl_elem_value_get_iec958 snd_ctl_elem_value_get_iec958_dylibloader_orig_asound +#define snd_ctl_elem_value_set_iec958 snd_ctl_elem_value_set_iec958_dylibloader_orig_asound +#define snd_tlv_parse_dB_info snd_tlv_parse_dB_info_dylibloader_orig_asound +#define snd_tlv_get_dB_range snd_tlv_get_dB_range_dylibloader_orig_asound +#define snd_tlv_convert_to_dB snd_tlv_convert_to_dB_dylibloader_orig_asound +#define snd_tlv_convert_from_dB snd_tlv_convert_from_dB_dylibloader_orig_asound +#define snd_ctl_get_dB_range snd_ctl_get_dB_range_dylibloader_orig_asound +#define snd_ctl_convert_to_dB snd_ctl_convert_to_dB_dylibloader_orig_asound +#define snd_ctl_convert_from_dB snd_ctl_convert_from_dB_dylibloader_orig_asound +#define snd_hctl_compare_fast snd_hctl_compare_fast_dylibloader_orig_asound +#define snd_hctl_open snd_hctl_open_dylibloader_orig_asound +#define snd_hctl_open_ctl snd_hctl_open_ctl_dylibloader_orig_asound +#define snd_hctl_close snd_hctl_close_dylibloader_orig_asound +#define snd_hctl_nonblock snd_hctl_nonblock_dylibloader_orig_asound +#define snd_hctl_poll_descriptors_count snd_hctl_poll_descriptors_count_dylibloader_orig_asound +#define snd_hctl_poll_descriptors snd_hctl_poll_descriptors_dylibloader_orig_asound +#define snd_hctl_poll_descriptors_revents snd_hctl_poll_descriptors_revents_dylibloader_orig_asound +#define snd_hctl_get_count snd_hctl_get_count_dylibloader_orig_asound +#define snd_hctl_set_compare snd_hctl_set_compare_dylibloader_orig_asound +#define snd_hctl_first_elem snd_hctl_first_elem_dylibloader_orig_asound +#define snd_hctl_last_elem snd_hctl_last_elem_dylibloader_orig_asound +#define snd_hctl_find_elem snd_hctl_find_elem_dylibloader_orig_asound +#define snd_hctl_set_callback snd_hctl_set_callback_dylibloader_orig_asound +#define snd_hctl_set_callback_private snd_hctl_set_callback_private_dylibloader_orig_asound +#define snd_hctl_get_callback_private snd_hctl_get_callback_private_dylibloader_orig_asound +#define snd_hctl_load snd_hctl_load_dylibloader_orig_asound +#define snd_hctl_free snd_hctl_free_dylibloader_orig_asound +#define snd_hctl_handle_events snd_hctl_handle_events_dylibloader_orig_asound +#define snd_hctl_name snd_hctl_name_dylibloader_orig_asound +#define snd_hctl_wait snd_hctl_wait_dylibloader_orig_asound +#define snd_hctl_ctl snd_hctl_ctl_dylibloader_orig_asound +#define snd_hctl_elem_next snd_hctl_elem_next_dylibloader_orig_asound +#define snd_hctl_elem_prev snd_hctl_elem_prev_dylibloader_orig_asound +#define snd_hctl_elem_info snd_hctl_elem_info_dylibloader_orig_asound +#define snd_hctl_elem_read snd_hctl_elem_read_dylibloader_orig_asound +#define snd_hctl_elem_write snd_hctl_elem_write_dylibloader_orig_asound +#define snd_hctl_elem_tlv_read snd_hctl_elem_tlv_read_dylibloader_orig_asound +#define snd_hctl_elem_tlv_write snd_hctl_elem_tlv_write_dylibloader_orig_asound +#define snd_hctl_elem_tlv_command snd_hctl_elem_tlv_command_dylibloader_orig_asound +#define snd_hctl_elem_get_hctl snd_hctl_elem_get_hctl_dylibloader_orig_asound +#define snd_hctl_elem_get_id snd_hctl_elem_get_id_dylibloader_orig_asound +#define snd_hctl_elem_get_numid snd_hctl_elem_get_numid_dylibloader_orig_asound +#define snd_hctl_elem_get_interface snd_hctl_elem_get_interface_dylibloader_orig_asound +#define snd_hctl_elem_get_device snd_hctl_elem_get_device_dylibloader_orig_asound +#define snd_hctl_elem_get_subdevice snd_hctl_elem_get_subdevice_dylibloader_orig_asound +#define snd_hctl_elem_get_name snd_hctl_elem_get_name_dylibloader_orig_asound +#define snd_hctl_elem_get_index snd_hctl_elem_get_index_dylibloader_orig_asound +#define snd_hctl_elem_set_callback snd_hctl_elem_set_callback_dylibloader_orig_asound +#define snd_hctl_elem_get_callback_private snd_hctl_elem_get_callback_private_dylibloader_orig_asound +#define snd_hctl_elem_set_callback_private snd_hctl_elem_set_callback_private_dylibloader_orig_asound +#define snd_sctl_build snd_sctl_build_dylibloader_orig_asound +#define snd_sctl_free snd_sctl_free_dylibloader_orig_asound +#define snd_sctl_install snd_sctl_install_dylibloader_orig_asound +#define snd_sctl_remove snd_sctl_remove_dylibloader_orig_asound +#define snd_mixer_open snd_mixer_open_dylibloader_orig_asound +#define snd_mixer_close snd_mixer_close_dylibloader_orig_asound +#define snd_mixer_first_elem snd_mixer_first_elem_dylibloader_orig_asound +#define snd_mixer_last_elem snd_mixer_last_elem_dylibloader_orig_asound +#define snd_mixer_handle_events snd_mixer_handle_events_dylibloader_orig_asound +#define snd_mixer_attach snd_mixer_attach_dylibloader_orig_asound +#define snd_mixer_attach_hctl snd_mixer_attach_hctl_dylibloader_orig_asound +#define snd_mixer_detach snd_mixer_detach_dylibloader_orig_asound +#define snd_mixer_detach_hctl snd_mixer_detach_hctl_dylibloader_orig_asound +#define snd_mixer_get_hctl snd_mixer_get_hctl_dylibloader_orig_asound +#define snd_mixer_poll_descriptors_count snd_mixer_poll_descriptors_count_dylibloader_orig_asound +#define snd_mixer_poll_descriptors snd_mixer_poll_descriptors_dylibloader_orig_asound +#define snd_mixer_poll_descriptors_revents snd_mixer_poll_descriptors_revents_dylibloader_orig_asound +#define snd_mixer_load snd_mixer_load_dylibloader_orig_asound +#define snd_mixer_free snd_mixer_free_dylibloader_orig_asound +#define snd_mixer_wait snd_mixer_wait_dylibloader_orig_asound +#define snd_mixer_set_compare snd_mixer_set_compare_dylibloader_orig_asound +#define snd_mixer_set_callback snd_mixer_set_callback_dylibloader_orig_asound +#define snd_mixer_get_callback_private snd_mixer_get_callback_private_dylibloader_orig_asound +#define snd_mixer_set_callback_private snd_mixer_set_callback_private_dylibloader_orig_asound +#define snd_mixer_get_count snd_mixer_get_count_dylibloader_orig_asound +#define snd_mixer_class_unregister snd_mixer_class_unregister_dylibloader_orig_asound +#define snd_mixer_elem_next snd_mixer_elem_next_dylibloader_orig_asound +#define snd_mixer_elem_prev snd_mixer_elem_prev_dylibloader_orig_asound +#define snd_mixer_elem_set_callback snd_mixer_elem_set_callback_dylibloader_orig_asound +#define snd_mixer_elem_get_callback_private snd_mixer_elem_get_callback_private_dylibloader_orig_asound +#define snd_mixer_elem_set_callback_private snd_mixer_elem_set_callback_private_dylibloader_orig_asound +#define snd_mixer_elem_get_type snd_mixer_elem_get_type_dylibloader_orig_asound +#define snd_mixer_class_register snd_mixer_class_register_dylibloader_orig_asound +#define snd_mixer_elem_new snd_mixer_elem_new_dylibloader_orig_asound +#define snd_mixer_elem_add snd_mixer_elem_add_dylibloader_orig_asound +#define snd_mixer_elem_remove snd_mixer_elem_remove_dylibloader_orig_asound +#define snd_mixer_elem_free snd_mixer_elem_free_dylibloader_orig_asound +#define snd_mixer_elem_info snd_mixer_elem_info_dylibloader_orig_asound +#define snd_mixer_elem_value snd_mixer_elem_value_dylibloader_orig_asound +#define snd_mixer_elem_attach snd_mixer_elem_attach_dylibloader_orig_asound +#define snd_mixer_elem_detach snd_mixer_elem_detach_dylibloader_orig_asound +#define snd_mixer_elem_empty snd_mixer_elem_empty_dylibloader_orig_asound +#define snd_mixer_elem_get_private snd_mixer_elem_get_private_dylibloader_orig_asound +#define snd_mixer_class_sizeof snd_mixer_class_sizeof_dylibloader_orig_asound +#define snd_mixer_class_malloc snd_mixer_class_malloc_dylibloader_orig_asound +#define snd_mixer_class_free snd_mixer_class_free_dylibloader_orig_asound +#define snd_mixer_class_copy snd_mixer_class_copy_dylibloader_orig_asound +#define snd_mixer_class_get_mixer snd_mixer_class_get_mixer_dylibloader_orig_asound +#define snd_mixer_class_get_event snd_mixer_class_get_event_dylibloader_orig_asound +#define snd_mixer_class_get_private snd_mixer_class_get_private_dylibloader_orig_asound +#define snd_mixer_class_get_compare snd_mixer_class_get_compare_dylibloader_orig_asound +#define snd_mixer_class_set_event snd_mixer_class_set_event_dylibloader_orig_asound +#define snd_mixer_class_set_private snd_mixer_class_set_private_dylibloader_orig_asound +#define snd_mixer_class_set_private_free snd_mixer_class_set_private_free_dylibloader_orig_asound +#define snd_mixer_class_set_compare snd_mixer_class_set_compare_dylibloader_orig_asound +#define snd_mixer_selem_channel_name snd_mixer_selem_channel_name_dylibloader_orig_asound +#define snd_mixer_selem_register snd_mixer_selem_register_dylibloader_orig_asound +#define snd_mixer_selem_get_id snd_mixer_selem_get_id_dylibloader_orig_asound +#define snd_mixer_selem_get_name snd_mixer_selem_get_name_dylibloader_orig_asound +#define snd_mixer_selem_get_index snd_mixer_selem_get_index_dylibloader_orig_asound +#define snd_mixer_find_selem snd_mixer_find_selem_dylibloader_orig_asound +#define snd_mixer_selem_is_active snd_mixer_selem_is_active_dylibloader_orig_asound +#define snd_mixer_selem_is_playback_mono snd_mixer_selem_is_playback_mono_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_channel snd_mixer_selem_has_playback_channel_dylibloader_orig_asound +#define snd_mixer_selem_is_capture_mono snd_mixer_selem_is_capture_mono_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_channel snd_mixer_selem_has_capture_channel_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_group snd_mixer_selem_get_capture_group_dylibloader_orig_asound +#define snd_mixer_selem_has_common_volume snd_mixer_selem_has_common_volume_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_volume snd_mixer_selem_has_playback_volume_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_volume_joined snd_mixer_selem_has_playback_volume_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_volume snd_mixer_selem_has_capture_volume_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_volume_joined snd_mixer_selem_has_capture_volume_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_common_switch snd_mixer_selem_has_common_switch_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_switch snd_mixer_selem_has_playback_switch_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_switch_joined snd_mixer_selem_has_playback_switch_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_switch snd_mixer_selem_has_capture_switch_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_switch_joined snd_mixer_selem_has_capture_switch_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_switch_exclusive snd_mixer_selem_has_capture_switch_exclusive_dylibloader_orig_asound +#define snd_mixer_selem_ask_playback_vol_dB snd_mixer_selem_ask_playback_vol_dB_dylibloader_orig_asound +#define snd_mixer_selem_ask_capture_vol_dB snd_mixer_selem_ask_capture_vol_dB_dylibloader_orig_asound +#define snd_mixer_selem_ask_playback_dB_vol snd_mixer_selem_ask_playback_dB_vol_dylibloader_orig_asound +#define snd_mixer_selem_ask_capture_dB_vol snd_mixer_selem_ask_capture_dB_vol_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_volume snd_mixer_selem_get_playback_volume_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_volume snd_mixer_selem_get_capture_volume_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_dB snd_mixer_selem_get_playback_dB_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_dB snd_mixer_selem_get_capture_dB_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_switch snd_mixer_selem_get_playback_switch_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_switch snd_mixer_selem_get_capture_switch_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_volume snd_mixer_selem_set_playback_volume_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_volume snd_mixer_selem_set_capture_volume_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_dB snd_mixer_selem_set_playback_dB_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_dB snd_mixer_selem_set_capture_dB_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_volume_all snd_mixer_selem_set_playback_volume_all_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_volume_all snd_mixer_selem_set_capture_volume_all_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_dB_all snd_mixer_selem_set_playback_dB_all_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_dB_all snd_mixer_selem_set_capture_dB_all_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_switch snd_mixer_selem_set_playback_switch_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_switch snd_mixer_selem_set_capture_switch_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_switch_all snd_mixer_selem_set_playback_switch_all_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_switch_all snd_mixer_selem_set_capture_switch_all_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_volume_range snd_mixer_selem_get_playback_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_dB_range snd_mixer_selem_get_playback_dB_range_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_volume_range snd_mixer_selem_set_playback_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_volume_range snd_mixer_selem_get_capture_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_dB_range snd_mixer_selem_get_capture_dB_range_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_volume_range snd_mixer_selem_set_capture_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_is_enumerated snd_mixer_selem_is_enumerated_dylibloader_orig_asound +#define snd_mixer_selem_is_enum_playback snd_mixer_selem_is_enum_playback_dylibloader_orig_asound +#define snd_mixer_selem_is_enum_capture snd_mixer_selem_is_enum_capture_dylibloader_orig_asound +#define snd_mixer_selem_get_enum_items snd_mixer_selem_get_enum_items_dylibloader_orig_asound +#define snd_mixer_selem_get_enum_item_name snd_mixer_selem_get_enum_item_name_dylibloader_orig_asound +#define snd_mixer_selem_get_enum_item snd_mixer_selem_get_enum_item_dylibloader_orig_asound +#define snd_mixer_selem_set_enum_item snd_mixer_selem_set_enum_item_dylibloader_orig_asound +#define snd_mixer_selem_id_sizeof snd_mixer_selem_id_sizeof_dylibloader_orig_asound +#define snd_mixer_selem_id_malloc snd_mixer_selem_id_malloc_dylibloader_orig_asound +#define snd_mixer_selem_id_free snd_mixer_selem_id_free_dylibloader_orig_asound +#define snd_mixer_selem_id_copy snd_mixer_selem_id_copy_dylibloader_orig_asound +#define snd_mixer_selem_id_get_name snd_mixer_selem_id_get_name_dylibloader_orig_asound +#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_orig_asound +#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_orig_asound +#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_orig_asound +#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_orig_asound +#define snd_seq_open snd_seq_open_dylibloader_orig_asound +#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_orig_asound +#define snd_seq_name snd_seq_name_dylibloader_orig_asound +#define snd_seq_type snd_seq_type_dylibloader_orig_asound +#define snd_seq_close snd_seq_close_dylibloader_orig_asound +#define snd_seq_poll_descriptors_count snd_seq_poll_descriptors_count_dylibloader_orig_asound +#define snd_seq_poll_descriptors snd_seq_poll_descriptors_dylibloader_orig_asound +#define snd_seq_poll_descriptors_revents snd_seq_poll_descriptors_revents_dylibloader_orig_asound +#define snd_seq_nonblock snd_seq_nonblock_dylibloader_orig_asound +#define snd_seq_client_id snd_seq_client_id_dylibloader_orig_asound +#define snd_seq_get_output_buffer_size snd_seq_get_output_buffer_size_dylibloader_orig_asound +#define snd_seq_get_input_buffer_size snd_seq_get_input_buffer_size_dylibloader_orig_asound +#define snd_seq_set_output_buffer_size snd_seq_set_output_buffer_size_dylibloader_orig_asound +#define snd_seq_set_input_buffer_size snd_seq_set_input_buffer_size_dylibloader_orig_asound +#define snd_seq_system_info_sizeof snd_seq_system_info_sizeof_dylibloader_orig_asound +#define snd_seq_system_info_malloc snd_seq_system_info_malloc_dylibloader_orig_asound +#define snd_seq_system_info_free snd_seq_system_info_free_dylibloader_orig_asound +#define snd_seq_system_info_copy snd_seq_system_info_copy_dylibloader_orig_asound +#define snd_seq_system_info_get_queues snd_seq_system_info_get_queues_dylibloader_orig_asound +#define snd_seq_system_info_get_clients snd_seq_system_info_get_clients_dylibloader_orig_asound +#define snd_seq_system_info_get_ports snd_seq_system_info_get_ports_dylibloader_orig_asound +#define snd_seq_system_info_get_channels snd_seq_system_info_get_channels_dylibloader_orig_asound +#define snd_seq_system_info_get_cur_clients snd_seq_system_info_get_cur_clients_dylibloader_orig_asound +#define snd_seq_system_info_get_cur_queues snd_seq_system_info_get_cur_queues_dylibloader_orig_asound +#define snd_seq_system_info snd_seq_system_info_dylibloader_orig_asound +#define snd_seq_client_info_sizeof snd_seq_client_info_sizeof_dylibloader_orig_asound +#define snd_seq_client_info_malloc snd_seq_client_info_malloc_dylibloader_orig_asound +#define snd_seq_client_info_free snd_seq_client_info_free_dylibloader_orig_asound +#define snd_seq_client_info_copy snd_seq_client_info_copy_dylibloader_orig_asound +#define snd_seq_client_info_get_client snd_seq_client_info_get_client_dylibloader_orig_asound +#define snd_seq_client_info_get_type snd_seq_client_info_get_type_dylibloader_orig_asound +#define snd_seq_client_info_get_name snd_seq_client_info_get_name_dylibloader_orig_asound +#define snd_seq_client_info_get_broadcast_filter snd_seq_client_info_get_broadcast_filter_dylibloader_orig_asound +#define snd_seq_client_info_get_error_bounce snd_seq_client_info_get_error_bounce_dylibloader_orig_asound +#define snd_seq_client_info_get_card snd_seq_client_info_get_card_dylibloader_orig_asound +#define snd_seq_client_info_get_pid snd_seq_client_info_get_pid_dylibloader_orig_asound +#define snd_seq_client_info_get_event_filter snd_seq_client_info_get_event_filter_dylibloader_orig_asound +#define snd_seq_client_info_get_num_ports snd_seq_client_info_get_num_ports_dylibloader_orig_asound +#define snd_seq_client_info_get_event_lost snd_seq_client_info_get_event_lost_dylibloader_orig_asound +#define snd_seq_client_info_set_client snd_seq_client_info_set_client_dylibloader_orig_asound +#define snd_seq_client_info_set_name snd_seq_client_info_set_name_dylibloader_orig_asound +#define snd_seq_client_info_set_broadcast_filter snd_seq_client_info_set_broadcast_filter_dylibloader_orig_asound +#define snd_seq_client_info_set_error_bounce snd_seq_client_info_set_error_bounce_dylibloader_orig_asound +#define snd_seq_client_info_set_event_filter snd_seq_client_info_set_event_filter_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_clear snd_seq_client_info_event_filter_clear_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_add snd_seq_client_info_event_filter_add_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_del snd_seq_client_info_event_filter_del_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_check snd_seq_client_info_event_filter_check_dylibloader_orig_asound +#define snd_seq_get_client_info snd_seq_get_client_info_dylibloader_orig_asound +#define snd_seq_get_any_client_info snd_seq_get_any_client_info_dylibloader_orig_asound +#define snd_seq_set_client_info snd_seq_set_client_info_dylibloader_orig_asound +#define snd_seq_query_next_client snd_seq_query_next_client_dylibloader_orig_asound +#define snd_seq_client_pool_sizeof snd_seq_client_pool_sizeof_dylibloader_orig_asound +#define snd_seq_client_pool_malloc snd_seq_client_pool_malloc_dylibloader_orig_asound +#define snd_seq_client_pool_free snd_seq_client_pool_free_dylibloader_orig_asound +#define snd_seq_client_pool_copy snd_seq_client_pool_copy_dylibloader_orig_asound +#define snd_seq_client_pool_get_client snd_seq_client_pool_get_client_dylibloader_orig_asound +#define snd_seq_client_pool_get_output_pool snd_seq_client_pool_get_output_pool_dylibloader_orig_asound +#define snd_seq_client_pool_get_input_pool snd_seq_client_pool_get_input_pool_dylibloader_orig_asound +#define snd_seq_client_pool_get_output_room snd_seq_client_pool_get_output_room_dylibloader_orig_asound +#define snd_seq_client_pool_get_output_free snd_seq_client_pool_get_output_free_dylibloader_orig_asound +#define snd_seq_client_pool_get_input_free snd_seq_client_pool_get_input_free_dylibloader_orig_asound +#define snd_seq_client_pool_set_output_pool snd_seq_client_pool_set_output_pool_dylibloader_orig_asound +#define snd_seq_client_pool_set_input_pool snd_seq_client_pool_set_input_pool_dylibloader_orig_asound +#define snd_seq_client_pool_set_output_room snd_seq_client_pool_set_output_room_dylibloader_orig_asound +#define snd_seq_get_client_pool snd_seq_get_client_pool_dylibloader_orig_asound +#define snd_seq_set_client_pool snd_seq_set_client_pool_dylibloader_orig_asound +#define snd_seq_port_info_sizeof snd_seq_port_info_sizeof_dylibloader_orig_asound +#define snd_seq_port_info_malloc snd_seq_port_info_malloc_dylibloader_orig_asound +#define snd_seq_port_info_free snd_seq_port_info_free_dylibloader_orig_asound +#define snd_seq_port_info_copy snd_seq_port_info_copy_dylibloader_orig_asound +#define snd_seq_port_info_get_client snd_seq_port_info_get_client_dylibloader_orig_asound +#define snd_seq_port_info_get_port snd_seq_port_info_get_port_dylibloader_orig_asound +#define snd_seq_port_info_get_addr snd_seq_port_info_get_addr_dylibloader_orig_asound +#define snd_seq_port_info_get_name snd_seq_port_info_get_name_dylibloader_orig_asound +#define snd_seq_port_info_get_capability snd_seq_port_info_get_capability_dylibloader_orig_asound +#define snd_seq_port_info_get_type snd_seq_port_info_get_type_dylibloader_orig_asound +#define snd_seq_port_info_get_midi_channels snd_seq_port_info_get_midi_channels_dylibloader_orig_asound +#define snd_seq_port_info_get_midi_voices snd_seq_port_info_get_midi_voices_dylibloader_orig_asound +#define snd_seq_port_info_get_synth_voices snd_seq_port_info_get_synth_voices_dylibloader_orig_asound +#define snd_seq_port_info_get_read_use snd_seq_port_info_get_read_use_dylibloader_orig_asound +#define snd_seq_port_info_get_write_use snd_seq_port_info_get_write_use_dylibloader_orig_asound +#define snd_seq_port_info_get_port_specified snd_seq_port_info_get_port_specified_dylibloader_orig_asound +#define snd_seq_port_info_get_timestamping snd_seq_port_info_get_timestamping_dylibloader_orig_asound +#define snd_seq_port_info_get_timestamp_real snd_seq_port_info_get_timestamp_real_dylibloader_orig_asound +#define snd_seq_port_info_get_timestamp_queue snd_seq_port_info_get_timestamp_queue_dylibloader_orig_asound +#define snd_seq_port_info_set_client snd_seq_port_info_set_client_dylibloader_orig_asound +#define snd_seq_port_info_set_port snd_seq_port_info_set_port_dylibloader_orig_asound +#define snd_seq_port_info_set_addr snd_seq_port_info_set_addr_dylibloader_orig_asound +#define snd_seq_port_info_set_name snd_seq_port_info_set_name_dylibloader_orig_asound +#define snd_seq_port_info_set_capability snd_seq_port_info_set_capability_dylibloader_orig_asound +#define snd_seq_port_info_set_type snd_seq_port_info_set_type_dylibloader_orig_asound +#define snd_seq_port_info_set_midi_channels snd_seq_port_info_set_midi_channels_dylibloader_orig_asound +#define snd_seq_port_info_set_midi_voices snd_seq_port_info_set_midi_voices_dylibloader_orig_asound +#define snd_seq_port_info_set_synth_voices snd_seq_port_info_set_synth_voices_dylibloader_orig_asound +#define snd_seq_port_info_set_port_specified snd_seq_port_info_set_port_specified_dylibloader_orig_asound +#define snd_seq_port_info_set_timestamping snd_seq_port_info_set_timestamping_dylibloader_orig_asound +#define snd_seq_port_info_set_timestamp_real snd_seq_port_info_set_timestamp_real_dylibloader_orig_asound +#define snd_seq_port_info_set_timestamp_queue snd_seq_port_info_set_timestamp_queue_dylibloader_orig_asound +#define snd_seq_create_port snd_seq_create_port_dylibloader_orig_asound +#define snd_seq_delete_port snd_seq_delete_port_dylibloader_orig_asound +#define snd_seq_get_port_info snd_seq_get_port_info_dylibloader_orig_asound +#define snd_seq_get_any_port_info snd_seq_get_any_port_info_dylibloader_orig_asound +#define snd_seq_set_port_info snd_seq_set_port_info_dylibloader_orig_asound +#define snd_seq_query_next_port snd_seq_query_next_port_dylibloader_orig_asound +#define snd_seq_port_subscribe_sizeof snd_seq_port_subscribe_sizeof_dylibloader_orig_asound +#define snd_seq_port_subscribe_malloc snd_seq_port_subscribe_malloc_dylibloader_orig_asound +#define snd_seq_port_subscribe_free snd_seq_port_subscribe_free_dylibloader_orig_asound +#define snd_seq_port_subscribe_copy snd_seq_port_subscribe_copy_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_sender snd_seq_port_subscribe_get_sender_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_dest snd_seq_port_subscribe_get_dest_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_queue snd_seq_port_subscribe_get_queue_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_exclusive snd_seq_port_subscribe_get_exclusive_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_time_update snd_seq_port_subscribe_get_time_update_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_time_real snd_seq_port_subscribe_get_time_real_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_sender snd_seq_port_subscribe_set_sender_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_dest snd_seq_port_subscribe_set_dest_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_queue snd_seq_port_subscribe_set_queue_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_exclusive snd_seq_port_subscribe_set_exclusive_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_time_update snd_seq_port_subscribe_set_time_update_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_time_real snd_seq_port_subscribe_set_time_real_dylibloader_orig_asound +#define snd_seq_get_port_subscription snd_seq_get_port_subscription_dylibloader_orig_asound +#define snd_seq_subscribe_port snd_seq_subscribe_port_dylibloader_orig_asound +#define snd_seq_unsubscribe_port snd_seq_unsubscribe_port_dylibloader_orig_asound +#define snd_seq_query_subscribe_sizeof snd_seq_query_subscribe_sizeof_dylibloader_orig_asound +#define snd_seq_query_subscribe_malloc snd_seq_query_subscribe_malloc_dylibloader_orig_asound +#define snd_seq_query_subscribe_free snd_seq_query_subscribe_free_dylibloader_orig_asound +#define snd_seq_query_subscribe_copy snd_seq_query_subscribe_copy_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_client snd_seq_query_subscribe_get_client_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_port snd_seq_query_subscribe_get_port_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_root snd_seq_query_subscribe_get_root_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_type snd_seq_query_subscribe_get_type_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_index snd_seq_query_subscribe_get_index_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_num_subs snd_seq_query_subscribe_get_num_subs_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_addr snd_seq_query_subscribe_get_addr_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_queue snd_seq_query_subscribe_get_queue_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_exclusive snd_seq_query_subscribe_get_exclusive_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_time_update snd_seq_query_subscribe_get_time_update_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_time_real snd_seq_query_subscribe_get_time_real_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_client snd_seq_query_subscribe_set_client_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_port snd_seq_query_subscribe_set_port_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_root snd_seq_query_subscribe_set_root_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_type snd_seq_query_subscribe_set_type_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_index snd_seq_query_subscribe_set_index_dylibloader_orig_asound +#define snd_seq_query_port_subscribers snd_seq_query_port_subscribers_dylibloader_orig_asound +#define snd_seq_queue_info_sizeof snd_seq_queue_info_sizeof_dylibloader_orig_asound +#define snd_seq_queue_info_malloc snd_seq_queue_info_malloc_dylibloader_orig_asound +#define snd_seq_queue_info_free snd_seq_queue_info_free_dylibloader_orig_asound +#define snd_seq_queue_info_copy snd_seq_queue_info_copy_dylibloader_orig_asound +#define snd_seq_queue_info_get_queue snd_seq_queue_info_get_queue_dylibloader_orig_asound +#define snd_seq_queue_info_get_name snd_seq_queue_info_get_name_dylibloader_orig_asound +#define snd_seq_queue_info_get_owner snd_seq_queue_info_get_owner_dylibloader_orig_asound +#define snd_seq_queue_info_get_locked snd_seq_queue_info_get_locked_dylibloader_orig_asound +#define snd_seq_queue_info_get_flags snd_seq_queue_info_get_flags_dylibloader_orig_asound +#define snd_seq_queue_info_set_name snd_seq_queue_info_set_name_dylibloader_orig_asound +#define snd_seq_queue_info_set_owner snd_seq_queue_info_set_owner_dylibloader_orig_asound +#define snd_seq_queue_info_set_locked snd_seq_queue_info_set_locked_dylibloader_orig_asound +#define snd_seq_queue_info_set_flags snd_seq_queue_info_set_flags_dylibloader_orig_asound +#define snd_seq_create_queue snd_seq_create_queue_dylibloader_orig_asound +#define snd_seq_alloc_named_queue snd_seq_alloc_named_queue_dylibloader_orig_asound +#define snd_seq_alloc_queue snd_seq_alloc_queue_dylibloader_orig_asound +#define snd_seq_free_queue snd_seq_free_queue_dylibloader_orig_asound +#define snd_seq_get_queue_info snd_seq_get_queue_info_dylibloader_orig_asound +#define snd_seq_set_queue_info snd_seq_set_queue_info_dylibloader_orig_asound +#define snd_seq_query_named_queue snd_seq_query_named_queue_dylibloader_orig_asound +#define snd_seq_get_queue_usage snd_seq_get_queue_usage_dylibloader_orig_asound +#define snd_seq_set_queue_usage snd_seq_set_queue_usage_dylibloader_orig_asound +#define snd_seq_queue_status_sizeof snd_seq_queue_status_sizeof_dylibloader_orig_asound +#define snd_seq_queue_status_malloc snd_seq_queue_status_malloc_dylibloader_orig_asound +#define snd_seq_queue_status_free snd_seq_queue_status_free_dylibloader_orig_asound +#define snd_seq_queue_status_copy snd_seq_queue_status_copy_dylibloader_orig_asound +#define snd_seq_queue_status_get_queue snd_seq_queue_status_get_queue_dylibloader_orig_asound +#define snd_seq_queue_status_get_events snd_seq_queue_status_get_events_dylibloader_orig_asound +#define snd_seq_queue_status_get_tick_time snd_seq_queue_status_get_tick_time_dylibloader_orig_asound +#define snd_seq_queue_status_get_real_time snd_seq_queue_status_get_real_time_dylibloader_orig_asound +#define snd_seq_queue_status_get_status snd_seq_queue_status_get_status_dylibloader_orig_asound +#define snd_seq_get_queue_status snd_seq_get_queue_status_dylibloader_orig_asound +#define snd_seq_queue_tempo_sizeof snd_seq_queue_tempo_sizeof_dylibloader_orig_asound +#define snd_seq_queue_tempo_malloc snd_seq_queue_tempo_malloc_dylibloader_orig_asound +#define snd_seq_queue_tempo_free snd_seq_queue_tempo_free_dylibloader_orig_asound +#define snd_seq_queue_tempo_copy snd_seq_queue_tempo_copy_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_queue snd_seq_queue_tempo_get_queue_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_tempo snd_seq_queue_tempo_get_tempo_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_ppq snd_seq_queue_tempo_get_ppq_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_skew snd_seq_queue_tempo_get_skew_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_skew_base snd_seq_queue_tempo_get_skew_base_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_tempo snd_seq_queue_tempo_set_tempo_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_ppq snd_seq_queue_tempo_set_ppq_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_skew snd_seq_queue_tempo_set_skew_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_skew_base snd_seq_queue_tempo_set_skew_base_dylibloader_orig_asound +#define snd_seq_get_queue_tempo snd_seq_get_queue_tempo_dylibloader_orig_asound +#define snd_seq_set_queue_tempo snd_seq_set_queue_tempo_dylibloader_orig_asound +#define snd_seq_queue_timer_sizeof snd_seq_queue_timer_sizeof_dylibloader_orig_asound +#define snd_seq_queue_timer_malloc snd_seq_queue_timer_malloc_dylibloader_orig_asound +#define snd_seq_queue_timer_free snd_seq_queue_timer_free_dylibloader_orig_asound +#define snd_seq_queue_timer_copy snd_seq_queue_timer_copy_dylibloader_orig_asound +#define snd_seq_queue_timer_get_queue snd_seq_queue_timer_get_queue_dylibloader_orig_asound +#define snd_seq_queue_timer_get_type snd_seq_queue_timer_get_type_dylibloader_orig_asound +#define snd_seq_queue_timer_get_id snd_seq_queue_timer_get_id_dylibloader_orig_asound +#define snd_seq_queue_timer_get_resolution snd_seq_queue_timer_get_resolution_dylibloader_orig_asound +#define snd_seq_queue_timer_set_type snd_seq_queue_timer_set_type_dylibloader_orig_asound +#define snd_seq_queue_timer_set_id snd_seq_queue_timer_set_id_dylibloader_orig_asound +#define snd_seq_queue_timer_set_resolution snd_seq_queue_timer_set_resolution_dylibloader_orig_asound +#define snd_seq_get_queue_timer snd_seq_get_queue_timer_dylibloader_orig_asound +#define snd_seq_set_queue_timer snd_seq_set_queue_timer_dylibloader_orig_asound +#define snd_seq_free_event snd_seq_free_event_dylibloader_orig_asound +#define snd_seq_event_length snd_seq_event_length_dylibloader_orig_asound +#define snd_seq_event_output snd_seq_event_output_dylibloader_orig_asound +#define snd_seq_event_output_buffer snd_seq_event_output_buffer_dylibloader_orig_asound +#define snd_seq_event_output_direct snd_seq_event_output_direct_dylibloader_orig_asound +#define snd_seq_event_input snd_seq_event_input_dylibloader_orig_asound +#define snd_seq_event_input_pending snd_seq_event_input_pending_dylibloader_orig_asound +#define snd_seq_drain_output snd_seq_drain_output_dylibloader_orig_asound +#define snd_seq_event_output_pending snd_seq_event_output_pending_dylibloader_orig_asound +#define snd_seq_extract_output snd_seq_extract_output_dylibloader_orig_asound +#define snd_seq_drop_output snd_seq_drop_output_dylibloader_orig_asound +#define snd_seq_drop_output_buffer snd_seq_drop_output_buffer_dylibloader_orig_asound +#define snd_seq_drop_input snd_seq_drop_input_dylibloader_orig_asound +#define snd_seq_drop_input_buffer snd_seq_drop_input_buffer_dylibloader_orig_asound +#define snd_seq_remove_events_sizeof snd_seq_remove_events_sizeof_dylibloader_orig_asound +#define snd_seq_remove_events_malloc snd_seq_remove_events_malloc_dylibloader_orig_asound +#define snd_seq_remove_events_free snd_seq_remove_events_free_dylibloader_orig_asound +#define snd_seq_remove_events_copy snd_seq_remove_events_copy_dylibloader_orig_asound +#define snd_seq_remove_events_get_condition snd_seq_remove_events_get_condition_dylibloader_orig_asound +#define snd_seq_remove_events_get_queue snd_seq_remove_events_get_queue_dylibloader_orig_asound +#define snd_seq_remove_events_get_time snd_seq_remove_events_get_time_dylibloader_orig_asound +#define snd_seq_remove_events_get_dest snd_seq_remove_events_get_dest_dylibloader_orig_asound +#define snd_seq_remove_events_get_channel snd_seq_remove_events_get_channel_dylibloader_orig_asound +#define snd_seq_remove_events_get_event_type snd_seq_remove_events_get_event_type_dylibloader_orig_asound +#define snd_seq_remove_events_get_tag snd_seq_remove_events_get_tag_dylibloader_orig_asound +#define snd_seq_remove_events_set_condition snd_seq_remove_events_set_condition_dylibloader_orig_asound +#define snd_seq_remove_events_set_queue snd_seq_remove_events_set_queue_dylibloader_orig_asound +#define snd_seq_remove_events_set_time snd_seq_remove_events_set_time_dylibloader_orig_asound +#define snd_seq_remove_events_set_dest snd_seq_remove_events_set_dest_dylibloader_orig_asound +#define snd_seq_remove_events_set_channel snd_seq_remove_events_set_channel_dylibloader_orig_asound +#define snd_seq_remove_events_set_event_type snd_seq_remove_events_set_event_type_dylibloader_orig_asound +#define snd_seq_remove_events_set_tag snd_seq_remove_events_set_tag_dylibloader_orig_asound +#define snd_seq_remove_events snd_seq_remove_events_dylibloader_orig_asound +#define snd_seq_set_bit snd_seq_set_bit_dylibloader_orig_asound +#define snd_seq_unset_bit snd_seq_unset_bit_dylibloader_orig_asound +#define snd_seq_change_bit snd_seq_change_bit_dylibloader_orig_asound +#define snd_seq_get_bit snd_seq_get_bit_dylibloader_orig_asound +#define snd_seq_control_queue snd_seq_control_queue_dylibloader_orig_asound +#define snd_seq_create_simple_port snd_seq_create_simple_port_dylibloader_orig_asound +#define snd_seq_delete_simple_port snd_seq_delete_simple_port_dylibloader_orig_asound +#define snd_seq_connect_from snd_seq_connect_from_dylibloader_orig_asound +#define snd_seq_connect_to snd_seq_connect_to_dylibloader_orig_asound +#define snd_seq_disconnect_from snd_seq_disconnect_from_dylibloader_orig_asound +#define snd_seq_disconnect_to snd_seq_disconnect_to_dylibloader_orig_asound +#define snd_seq_set_client_name snd_seq_set_client_name_dylibloader_orig_asound +#define snd_seq_set_client_event_filter snd_seq_set_client_event_filter_dylibloader_orig_asound +#define snd_seq_set_client_pool_output snd_seq_set_client_pool_output_dylibloader_orig_asound +#define snd_seq_set_client_pool_output_room snd_seq_set_client_pool_output_room_dylibloader_orig_asound +#define snd_seq_set_client_pool_input snd_seq_set_client_pool_input_dylibloader_orig_asound +#define snd_seq_sync_output_queue snd_seq_sync_output_queue_dylibloader_orig_asound +#define snd_seq_parse_address snd_seq_parse_address_dylibloader_orig_asound +#define snd_seq_reset_pool_output snd_seq_reset_pool_output_dylibloader_orig_asound +#define snd_seq_reset_pool_input snd_seq_reset_pool_input_dylibloader_orig_asound +#define snd_midi_event_new snd_midi_event_new_dylibloader_orig_asound +#define snd_midi_event_resize_buffer snd_midi_event_resize_buffer_dylibloader_orig_asound +#define snd_midi_event_free snd_midi_event_free_dylibloader_orig_asound +#define snd_midi_event_init snd_midi_event_init_dylibloader_orig_asound +#define snd_midi_event_reset_encode snd_midi_event_reset_encode_dylibloader_orig_asound +#define snd_midi_event_reset_decode snd_midi_event_reset_decode_dylibloader_orig_asound +#define snd_midi_event_no_status snd_midi_event_no_status_dylibloader_orig_asound +#define snd_midi_event_encode snd_midi_event_encode_dylibloader_orig_asound +#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_orig_asound +#define snd_midi_event_decode snd_midi_event_decode_dylibloader_orig_asound +#include <alsa/asoundlib.h> +#undef snd_asoundlib_version +#undef snd_dlpath +#undef snd_dlopen +#undef snd_dlsym +#undef snd_dlclose +#undef snd_async_add_handler +#undef snd_async_del_handler +#undef snd_async_handler_get_fd +#undef snd_async_handler_get_signo +#undef snd_async_handler_get_callback_private +#undef snd_shm_area_create +#undef snd_shm_area_share +#undef snd_shm_area_destroy +#undef snd_user_file +#undef snd_input_stdio_open +#undef snd_input_stdio_attach +#undef snd_input_buffer_open +#undef snd_input_close +#undef snd_input_scanf +#undef snd_input_gets +#undef snd_input_getc +#undef snd_input_ungetc +#undef snd_output_stdio_open +#undef snd_output_stdio_attach +#undef snd_output_buffer_open +#undef snd_output_buffer_string +#undef snd_output_close +#undef snd_output_printf +#undef snd_output_vprintf +#undef snd_output_puts +#undef snd_output_putc +#undef snd_output_flush +#undef snd_strerror +#undef snd_lib_error_set_handler +#undef snd_lib_error_set_local +#undef snd_config_topdir +#undef snd_config_top +#undef snd_config_load +#undef snd_config_load_override +#undef snd_config_save +#undef snd_config_update +#undef snd_config_update_r +#undef snd_config_update_free +#undef snd_config_update_free_global +#undef snd_config_update_ref +#undef snd_config_ref +#undef snd_config_unref +#undef snd_config_search +#undef snd_config_searchv +#undef snd_config_search_definition +#undef snd_config_expand +#undef snd_config_evaluate +#undef snd_config_add +#undef snd_config_add_before +#undef snd_config_add_after +#undef snd_config_remove +#undef snd_config_delete +#undef snd_config_delete_compound_members +#undef snd_config_copy +#undef snd_config_make +#undef snd_config_make_integer +#undef snd_config_make_integer64 +#undef snd_config_make_real +#undef snd_config_make_string +#undef snd_config_make_pointer +#undef snd_config_make_compound +#undef snd_config_imake_integer +#undef snd_config_imake_integer64 +#undef snd_config_imake_real +#undef snd_config_imake_string +#undef snd_config_imake_safe_string +#undef snd_config_imake_pointer +#undef snd_config_get_type +#undef snd_config_is_array +#undef snd_config_set_id +#undef snd_config_set_integer +#undef snd_config_set_integer64 +#undef snd_config_set_real +#undef snd_config_set_string +#undef snd_config_set_ascii +#undef snd_config_set_pointer +#undef snd_config_get_id +#undef snd_config_get_integer +#undef snd_config_get_integer64 +#undef snd_config_get_real +#undef snd_config_get_ireal +#undef snd_config_get_string +#undef snd_config_get_ascii +#undef snd_config_get_pointer +#undef snd_config_test_id +#undef snd_config_iterator_first +#undef snd_config_iterator_next +#undef snd_config_iterator_end +#undef snd_config_iterator_entry +#undef snd_config_get_bool_ascii +#undef snd_config_get_bool +#undef snd_config_get_ctl_iface_ascii +#undef snd_config_get_ctl_iface +#undef snd_names_list +#undef snd_names_list_free +#undef snd_pcm_open +#undef snd_pcm_open_lconf +#undef snd_pcm_open_fallback +#undef snd_pcm_close +#undef snd_pcm_name +#undef snd_pcm_type +#undef snd_pcm_stream +#undef snd_pcm_poll_descriptors_count +#undef snd_pcm_poll_descriptors +#undef snd_pcm_poll_descriptors_revents +#undef snd_pcm_nonblock +#undef snd_async_add_pcm_handler +#undef snd_async_handler_get_pcm +#undef snd_pcm_info +#undef snd_pcm_hw_params_current +#undef snd_pcm_hw_params +#undef snd_pcm_hw_free +#undef snd_pcm_sw_params_current +#undef snd_pcm_sw_params +#undef snd_pcm_prepare +#undef snd_pcm_reset +#undef snd_pcm_status +#undef snd_pcm_start +#undef snd_pcm_drop +#undef snd_pcm_drain +#undef snd_pcm_pause +#undef snd_pcm_state +#undef snd_pcm_hwsync +#undef snd_pcm_delay +#undef snd_pcm_resume +#undef snd_pcm_htimestamp +#undef snd_pcm_avail +#undef snd_pcm_avail_update +#undef snd_pcm_avail_delay +#undef snd_pcm_rewindable +#undef snd_pcm_rewind +#undef snd_pcm_forwardable +#undef snd_pcm_forward +#undef snd_pcm_writei +#undef snd_pcm_readi +#undef snd_pcm_writen +#undef snd_pcm_readn +#undef snd_pcm_wait +#undef snd_pcm_link +#undef snd_pcm_unlink +#undef snd_pcm_query_chmaps +#undef snd_pcm_query_chmaps_from_hw +#undef snd_pcm_free_chmaps +#undef snd_pcm_get_chmap +#undef snd_pcm_set_chmap +#undef snd_pcm_chmap_type_name +#undef snd_pcm_chmap_name +#undef snd_pcm_chmap_long_name +#undef snd_pcm_chmap_print +#undef snd_pcm_chmap_from_string +#undef snd_pcm_chmap_parse_string +#undef snd_pcm_recover +#undef snd_pcm_set_params +#undef snd_pcm_get_params +#undef snd_pcm_info_sizeof +#undef snd_pcm_info_malloc +#undef snd_pcm_info_free +#undef snd_pcm_info_copy +#undef snd_pcm_info_get_device +#undef snd_pcm_info_get_subdevice +#undef snd_pcm_info_get_stream +#undef snd_pcm_info_get_card +#undef snd_pcm_info_get_id +#undef snd_pcm_info_get_name +#undef snd_pcm_info_get_subdevice_name +#undef snd_pcm_info_get_class +#undef snd_pcm_info_get_subclass +#undef snd_pcm_info_get_subdevices_count +#undef snd_pcm_info_get_subdevices_avail +#undef snd_pcm_info_get_sync +#undef snd_pcm_info_set_device +#undef snd_pcm_info_set_subdevice +#undef snd_pcm_info_set_stream +#undef snd_pcm_hw_params_any +#undef snd_pcm_hw_params_can_mmap_sample_resolution +#undef snd_pcm_hw_params_is_double +#undef snd_pcm_hw_params_is_batch +#undef snd_pcm_hw_params_is_block_transfer +#undef snd_pcm_hw_params_is_monotonic +#undef snd_pcm_hw_params_can_overrange +#undef snd_pcm_hw_params_can_pause +#undef snd_pcm_hw_params_can_resume +#undef snd_pcm_hw_params_is_half_duplex +#undef snd_pcm_hw_params_is_joint_duplex +#undef snd_pcm_hw_params_can_sync_start +#undef snd_pcm_hw_params_can_disable_period_wakeup +#undef snd_pcm_hw_params_supports_audio_wallclock_ts +#undef snd_pcm_hw_params_supports_audio_ts_type +#undef snd_pcm_hw_params_get_rate_numden +#undef snd_pcm_hw_params_get_sbits +#undef snd_pcm_hw_params_get_fifo_size +#undef snd_pcm_hw_params_sizeof +#undef snd_pcm_hw_params_malloc +#undef snd_pcm_hw_params_free +#undef snd_pcm_hw_params_copy +#undef snd_pcm_hw_params_get_access +#undef snd_pcm_hw_params_test_access +#undef snd_pcm_hw_params_set_access +#undef snd_pcm_hw_params_set_access_first +#undef snd_pcm_hw_params_set_access_last +#undef snd_pcm_hw_params_set_access_mask +#undef snd_pcm_hw_params_get_access_mask +#undef snd_pcm_hw_params_get_format +#undef snd_pcm_hw_params_test_format +#undef snd_pcm_hw_params_set_format +#undef snd_pcm_hw_params_set_format_first +#undef snd_pcm_hw_params_set_format_last +#undef snd_pcm_hw_params_set_format_mask +#undef snd_pcm_hw_params_get_format_mask +#undef snd_pcm_hw_params_get_subformat +#undef snd_pcm_hw_params_test_subformat +#undef snd_pcm_hw_params_set_subformat +#undef snd_pcm_hw_params_set_subformat_first +#undef snd_pcm_hw_params_set_subformat_last +#undef snd_pcm_hw_params_set_subformat_mask +#undef snd_pcm_hw_params_get_subformat_mask +#undef snd_pcm_hw_params_get_channels +#undef snd_pcm_hw_params_get_channels_min +#undef snd_pcm_hw_params_get_channels_max +#undef snd_pcm_hw_params_test_channels +#undef snd_pcm_hw_params_set_channels +#undef snd_pcm_hw_params_set_channels_min +#undef snd_pcm_hw_params_set_channels_max +#undef snd_pcm_hw_params_set_channels_minmax +#undef snd_pcm_hw_params_set_channels_near +#undef snd_pcm_hw_params_set_channels_first +#undef snd_pcm_hw_params_set_channels_last +#undef snd_pcm_hw_params_get_rate +#undef snd_pcm_hw_params_get_rate_min +#undef snd_pcm_hw_params_get_rate_max +#undef snd_pcm_hw_params_test_rate +#undef snd_pcm_hw_params_set_rate +#undef snd_pcm_hw_params_set_rate_min +#undef snd_pcm_hw_params_set_rate_max +#undef snd_pcm_hw_params_set_rate_minmax +#undef snd_pcm_hw_params_set_rate_near +#undef snd_pcm_hw_params_set_rate_first +#undef snd_pcm_hw_params_set_rate_last +#undef snd_pcm_hw_params_set_rate_resample +#undef snd_pcm_hw_params_get_rate_resample +#undef snd_pcm_hw_params_set_export_buffer +#undef snd_pcm_hw_params_get_export_buffer +#undef snd_pcm_hw_params_set_period_wakeup +#undef snd_pcm_hw_params_get_period_wakeup +#undef snd_pcm_hw_params_get_period_time +#undef snd_pcm_hw_params_get_period_time_min +#undef snd_pcm_hw_params_get_period_time_max +#undef snd_pcm_hw_params_test_period_time +#undef snd_pcm_hw_params_set_period_time +#undef snd_pcm_hw_params_set_period_time_min +#undef snd_pcm_hw_params_set_period_time_max +#undef snd_pcm_hw_params_set_period_time_minmax +#undef snd_pcm_hw_params_set_period_time_near +#undef snd_pcm_hw_params_set_period_time_first +#undef snd_pcm_hw_params_set_period_time_last +#undef snd_pcm_hw_params_get_period_size +#undef snd_pcm_hw_params_get_period_size_min +#undef snd_pcm_hw_params_get_period_size_max +#undef snd_pcm_hw_params_test_period_size +#undef snd_pcm_hw_params_set_period_size +#undef snd_pcm_hw_params_set_period_size_min +#undef snd_pcm_hw_params_set_period_size_max +#undef snd_pcm_hw_params_set_period_size_minmax +#undef snd_pcm_hw_params_set_period_size_near +#undef snd_pcm_hw_params_set_period_size_first +#undef snd_pcm_hw_params_set_period_size_last +#undef snd_pcm_hw_params_set_period_size_integer +#undef snd_pcm_hw_params_get_periods +#undef snd_pcm_hw_params_get_periods_min +#undef snd_pcm_hw_params_get_periods_max +#undef snd_pcm_hw_params_test_periods +#undef snd_pcm_hw_params_set_periods +#undef snd_pcm_hw_params_set_periods_min +#undef snd_pcm_hw_params_set_periods_max +#undef snd_pcm_hw_params_set_periods_minmax +#undef snd_pcm_hw_params_set_periods_near +#undef snd_pcm_hw_params_set_periods_first +#undef snd_pcm_hw_params_set_periods_last +#undef snd_pcm_hw_params_set_periods_integer +#undef snd_pcm_hw_params_get_buffer_time +#undef snd_pcm_hw_params_get_buffer_time_min +#undef snd_pcm_hw_params_get_buffer_time_max +#undef snd_pcm_hw_params_test_buffer_time +#undef snd_pcm_hw_params_set_buffer_time +#undef snd_pcm_hw_params_set_buffer_time_min +#undef snd_pcm_hw_params_set_buffer_time_max +#undef snd_pcm_hw_params_set_buffer_time_minmax +#undef snd_pcm_hw_params_set_buffer_time_near +#undef snd_pcm_hw_params_set_buffer_time_first +#undef snd_pcm_hw_params_set_buffer_time_last +#undef snd_pcm_hw_params_get_buffer_size +#undef snd_pcm_hw_params_get_buffer_size_min +#undef snd_pcm_hw_params_get_buffer_size_max +#undef snd_pcm_hw_params_test_buffer_size +#undef snd_pcm_hw_params_set_buffer_size +#undef snd_pcm_hw_params_set_buffer_size_min +#undef snd_pcm_hw_params_set_buffer_size_max +#undef snd_pcm_hw_params_set_buffer_size_minmax +#undef snd_pcm_hw_params_set_buffer_size_near +#undef snd_pcm_hw_params_set_buffer_size_first +#undef snd_pcm_hw_params_set_buffer_size_last +#undef snd_pcm_hw_params_get_min_align +#undef snd_pcm_sw_params_sizeof +#undef snd_pcm_sw_params_malloc +#undef snd_pcm_sw_params_free +#undef snd_pcm_sw_params_copy +#undef snd_pcm_sw_params_get_boundary +#undef snd_pcm_sw_params_set_tstamp_mode +#undef snd_pcm_sw_params_get_tstamp_mode +#undef snd_pcm_sw_params_set_avail_min +#undef snd_pcm_sw_params_get_avail_min +#undef snd_pcm_sw_params_set_period_event +#undef snd_pcm_sw_params_get_period_event +#undef snd_pcm_sw_params_set_start_threshold +#undef snd_pcm_sw_params_get_start_threshold +#undef snd_pcm_sw_params_set_stop_threshold +#undef snd_pcm_sw_params_get_stop_threshold +#undef snd_pcm_sw_params_set_silence_threshold +#undef snd_pcm_sw_params_get_silence_threshold +#undef snd_pcm_sw_params_set_silence_size +#undef snd_pcm_sw_params_get_silence_size +#undef snd_pcm_access_mask_sizeof +#undef snd_pcm_access_mask_malloc +#undef snd_pcm_access_mask_free +#undef snd_pcm_access_mask_copy +#undef snd_pcm_access_mask_none +#undef snd_pcm_access_mask_any +#undef snd_pcm_access_mask_test +#undef snd_pcm_access_mask_empty +#undef snd_pcm_access_mask_set +#undef snd_pcm_access_mask_reset +#undef snd_pcm_format_mask_sizeof +#undef snd_pcm_format_mask_malloc +#undef snd_pcm_format_mask_free +#undef snd_pcm_format_mask_copy +#undef snd_pcm_format_mask_none +#undef snd_pcm_format_mask_any +#undef snd_pcm_format_mask_test +#undef snd_pcm_format_mask_empty +#undef snd_pcm_format_mask_set +#undef snd_pcm_format_mask_reset +#undef snd_pcm_subformat_mask_sizeof +#undef snd_pcm_subformat_mask_malloc +#undef snd_pcm_subformat_mask_free +#undef snd_pcm_subformat_mask_copy +#undef snd_pcm_subformat_mask_none +#undef snd_pcm_subformat_mask_any +#undef snd_pcm_subformat_mask_test +#undef snd_pcm_subformat_mask_empty +#undef snd_pcm_subformat_mask_set +#undef snd_pcm_subformat_mask_reset +#undef snd_pcm_status_sizeof +#undef snd_pcm_status_malloc +#undef snd_pcm_status_free +#undef snd_pcm_status_copy +#undef snd_pcm_status_get_state +#undef snd_pcm_status_get_trigger_tstamp +#undef snd_pcm_status_get_trigger_htstamp +#undef snd_pcm_status_get_tstamp +#undef snd_pcm_status_get_htstamp +#undef snd_pcm_status_get_audio_htstamp +#undef snd_pcm_status_get_driver_htstamp +#undef snd_pcm_status_get_delay +#undef snd_pcm_status_get_avail +#undef snd_pcm_status_get_avail_max +#undef snd_pcm_status_get_overrange +#undef snd_pcm_type_name +#undef snd_pcm_stream_name +#undef snd_pcm_access_name +#undef snd_pcm_format_name +#undef snd_pcm_format_description +#undef snd_pcm_subformat_name +#undef snd_pcm_subformat_description +#undef snd_pcm_format_value +#undef snd_pcm_tstamp_mode_name +#undef snd_pcm_state_name +#undef snd_pcm_dump +#undef snd_pcm_dump_hw_setup +#undef snd_pcm_dump_sw_setup +#undef snd_pcm_dump_setup +#undef snd_pcm_hw_params_dump +#undef snd_pcm_sw_params_dump +#undef snd_pcm_status_dump +#undef snd_pcm_mmap_begin +#undef snd_pcm_mmap_commit +#undef snd_pcm_mmap_writei +#undef snd_pcm_mmap_readi +#undef snd_pcm_mmap_writen +#undef snd_pcm_mmap_readn +#undef snd_pcm_format_signed +#undef snd_pcm_format_unsigned +#undef snd_pcm_format_linear +#undef snd_pcm_format_float +#undef snd_pcm_format_little_endian +#undef snd_pcm_format_big_endian +#undef snd_pcm_format_cpu_endian +#undef snd_pcm_format_width +#undef snd_pcm_format_physical_width +#undef snd_pcm_build_linear_format +#undef snd_pcm_format_size +#undef snd_pcm_format_silence +#undef snd_pcm_format_silence_16 +#undef snd_pcm_format_silence_32 +#undef snd_pcm_format_silence_64 +#undef snd_pcm_format_set_silence +#undef snd_pcm_bytes_to_frames +#undef snd_pcm_frames_to_bytes +#undef snd_pcm_bytes_to_samples +#undef snd_pcm_samples_to_bytes +#undef snd_pcm_area_silence +#undef snd_pcm_areas_silence +#undef snd_pcm_area_copy +#undef snd_pcm_areas_copy +#undef snd_pcm_areas_copy_wrap +#undef snd_pcm_hook_get_pcm +#undef snd_pcm_hook_get_private +#undef snd_pcm_hook_set_private +#undef snd_pcm_hook_add +#undef snd_pcm_hook_remove +#undef snd_pcm_meter_get_bufsize +#undef snd_pcm_meter_get_channels +#undef snd_pcm_meter_get_rate +#undef snd_pcm_meter_get_now +#undef snd_pcm_meter_get_boundary +#undef snd_pcm_meter_add_scope +#undef snd_pcm_meter_search_scope +#undef snd_pcm_scope_malloc +#undef snd_pcm_scope_set_ops +#undef snd_pcm_scope_set_name +#undef snd_pcm_scope_get_name +#undef snd_pcm_scope_get_callback_private +#undef snd_pcm_scope_set_callback_private +#undef snd_pcm_scope_s16_open +#undef snd_pcm_scope_s16_get_channel_buffer +#undef snd_spcm_init +#undef snd_spcm_init_duplex +#undef snd_spcm_init_get_params +#undef snd_pcm_start_mode_name +#undef snd_pcm_xrun_mode_name +#undef snd_pcm_sw_params_set_start_mode +#undef snd_pcm_sw_params_get_start_mode +#undef snd_pcm_sw_params_set_xrun_mode +#undef snd_pcm_sw_params_get_xrun_mode +#undef snd_pcm_sw_params_set_xfer_align +#undef snd_pcm_sw_params_get_xfer_align +#undef snd_pcm_sw_params_set_sleep_min +#undef snd_pcm_sw_params_get_sleep_min +#undef snd_pcm_hw_params_get_tick_time +#undef snd_pcm_hw_params_get_tick_time_min +#undef snd_pcm_hw_params_get_tick_time_max +#undef snd_pcm_hw_params_test_tick_time +#undef snd_pcm_hw_params_set_tick_time +#undef snd_pcm_hw_params_set_tick_time_min +#undef snd_pcm_hw_params_set_tick_time_max +#undef snd_pcm_hw_params_set_tick_time_minmax +#undef snd_pcm_hw_params_set_tick_time_near +#undef snd_pcm_hw_params_set_tick_time_first +#undef snd_pcm_hw_params_set_tick_time_last +#undef snd_rawmidi_open +#undef snd_rawmidi_open_lconf +#undef snd_rawmidi_close +#undef snd_rawmidi_poll_descriptors_count +#undef snd_rawmidi_poll_descriptors +#undef snd_rawmidi_poll_descriptors_revents +#undef snd_rawmidi_nonblock +#undef snd_rawmidi_info_sizeof +#undef snd_rawmidi_info_malloc +#undef snd_rawmidi_info_free +#undef snd_rawmidi_info_copy +#undef snd_rawmidi_info_get_device +#undef snd_rawmidi_info_get_subdevice +#undef snd_rawmidi_info_get_stream +#undef snd_rawmidi_info_get_card +#undef snd_rawmidi_info_get_flags +#undef snd_rawmidi_info_get_id +#undef snd_rawmidi_info_get_name +#undef snd_rawmidi_info_get_subdevice_name +#undef snd_rawmidi_info_get_subdevices_count +#undef snd_rawmidi_info_get_subdevices_avail +#undef snd_rawmidi_info_set_device +#undef snd_rawmidi_info_set_subdevice +#undef snd_rawmidi_info_set_stream +#undef snd_rawmidi_info +#undef snd_rawmidi_params_sizeof +#undef snd_rawmidi_params_malloc +#undef snd_rawmidi_params_free +#undef snd_rawmidi_params_copy +#undef snd_rawmidi_params_set_buffer_size +#undef snd_rawmidi_params_get_buffer_size +#undef snd_rawmidi_params_set_avail_min +#undef snd_rawmidi_params_get_avail_min +#undef snd_rawmidi_params_set_no_active_sensing +#undef snd_rawmidi_params_get_no_active_sensing +#undef snd_rawmidi_params +#undef snd_rawmidi_params_current +#undef snd_rawmidi_status_sizeof +#undef snd_rawmidi_status_malloc +#undef snd_rawmidi_status_free +#undef snd_rawmidi_status_copy +#undef snd_rawmidi_status_get_tstamp +#undef snd_rawmidi_status_get_avail +#undef snd_rawmidi_status_get_xruns +#undef snd_rawmidi_status +#undef snd_rawmidi_drain +#undef snd_rawmidi_drop +#undef snd_rawmidi_write +#undef snd_rawmidi_read +#undef snd_rawmidi_name +#undef snd_rawmidi_type +#undef snd_rawmidi_stream +#undef snd_timer_query_open +#undef snd_timer_query_open_lconf +#undef snd_timer_query_close +#undef snd_timer_query_next_device +#undef snd_timer_query_info +#undef snd_timer_query_params +#undef snd_timer_query_status +#undef snd_timer_open +#undef snd_timer_open_lconf +#undef snd_timer_close +#undef snd_async_add_timer_handler +#undef snd_async_handler_get_timer +#undef snd_timer_poll_descriptors_count +#undef snd_timer_poll_descriptors +#undef snd_timer_poll_descriptors_revents +#undef snd_timer_info +#undef snd_timer_params +#undef snd_timer_status +#undef snd_timer_start +#undef snd_timer_stop +#undef snd_timer_continue +#undef snd_timer_read +#undef snd_timer_id_sizeof +#undef snd_timer_id_malloc +#undef snd_timer_id_free +#undef snd_timer_id_copy +#undef snd_timer_id_set_class +#undef snd_timer_id_get_class +#undef snd_timer_id_set_sclass +#undef snd_timer_id_get_sclass +#undef snd_timer_id_set_card +#undef snd_timer_id_get_card +#undef snd_timer_id_set_device +#undef snd_timer_id_get_device +#undef snd_timer_id_set_subdevice +#undef snd_timer_id_get_subdevice +#undef snd_timer_ginfo_sizeof +#undef snd_timer_ginfo_malloc +#undef snd_timer_ginfo_free +#undef snd_timer_ginfo_copy +#undef snd_timer_ginfo_set_tid +#undef snd_timer_ginfo_get_tid +#undef snd_timer_ginfo_get_flags +#undef snd_timer_ginfo_get_card +#undef snd_timer_ginfo_get_id +#undef snd_timer_ginfo_get_name +#undef snd_timer_ginfo_get_resolution +#undef snd_timer_ginfo_get_resolution_min +#undef snd_timer_ginfo_get_resolution_max +#undef snd_timer_ginfo_get_clients +#undef snd_timer_info_sizeof +#undef snd_timer_info_malloc +#undef snd_timer_info_free +#undef snd_timer_info_copy +#undef snd_timer_info_is_slave +#undef snd_timer_info_get_card +#undef snd_timer_info_get_id +#undef snd_timer_info_get_name +#undef snd_timer_info_get_resolution +#undef snd_timer_params_sizeof +#undef snd_timer_params_malloc +#undef snd_timer_params_free +#undef snd_timer_params_copy +#undef snd_timer_params_set_auto_start +#undef snd_timer_params_get_auto_start +#undef snd_timer_params_set_exclusive +#undef snd_timer_params_get_exclusive +#undef snd_timer_params_set_early_event +#undef snd_timer_params_get_early_event +#undef snd_timer_params_set_ticks +#undef snd_timer_params_get_ticks +#undef snd_timer_params_set_queue_size +#undef snd_timer_params_get_queue_size +#undef snd_timer_params_set_filter +#undef snd_timer_params_get_filter +#undef snd_timer_status_sizeof +#undef snd_timer_status_malloc +#undef snd_timer_status_free +#undef snd_timer_status_copy +#undef snd_timer_status_get_timestamp +#undef snd_timer_status_get_resolution +#undef snd_timer_status_get_lost +#undef snd_timer_status_get_overrun +#undef snd_timer_status_get_queue +#undef snd_timer_info_get_ticks +#undef snd_hwdep_open +#undef snd_hwdep_close +#undef snd_hwdep_poll_descriptors +#undef snd_hwdep_poll_descriptors_count +#undef snd_hwdep_poll_descriptors_revents +#undef snd_hwdep_nonblock +#undef snd_hwdep_info +#undef snd_hwdep_dsp_status +#undef snd_hwdep_dsp_load +#undef snd_hwdep_ioctl +#undef snd_hwdep_write +#undef snd_hwdep_read +#undef snd_hwdep_info_sizeof +#undef snd_hwdep_info_malloc +#undef snd_hwdep_info_free +#undef snd_hwdep_info_copy +#undef snd_hwdep_info_get_device +#undef snd_hwdep_info_get_card +#undef snd_hwdep_info_get_id +#undef snd_hwdep_info_get_name +#undef snd_hwdep_info_get_iface +#undef snd_hwdep_info_set_device +#undef snd_hwdep_dsp_status_sizeof +#undef snd_hwdep_dsp_status_malloc +#undef snd_hwdep_dsp_status_free +#undef snd_hwdep_dsp_status_copy +#undef snd_hwdep_dsp_status_get_version +#undef snd_hwdep_dsp_status_get_id +#undef snd_hwdep_dsp_status_get_num_dsps +#undef snd_hwdep_dsp_status_get_dsp_loaded +#undef snd_hwdep_dsp_status_get_chip_ready +#undef snd_hwdep_dsp_image_sizeof +#undef snd_hwdep_dsp_image_malloc +#undef snd_hwdep_dsp_image_free +#undef snd_hwdep_dsp_image_copy +#undef snd_hwdep_dsp_image_get_index +#undef snd_hwdep_dsp_image_get_name +#undef snd_hwdep_dsp_image_get_image +#undef snd_hwdep_dsp_image_get_length +#undef snd_hwdep_dsp_image_set_index +#undef snd_hwdep_dsp_image_set_name +#undef snd_hwdep_dsp_image_set_image +#undef snd_hwdep_dsp_image_set_length +#undef snd_card_load +#undef snd_card_next +#undef snd_card_get_index +#undef snd_card_get_name +#undef snd_card_get_longname +#undef snd_device_name_hint +#undef snd_device_name_free_hint +#undef snd_device_name_get_hint +#undef snd_ctl_open +#undef snd_ctl_open_lconf +#undef snd_ctl_open_fallback +#undef snd_ctl_close +#undef snd_ctl_nonblock +#undef snd_async_add_ctl_handler +#undef snd_async_handler_get_ctl +#undef snd_ctl_poll_descriptors_count +#undef snd_ctl_poll_descriptors +#undef snd_ctl_poll_descriptors_revents +#undef snd_ctl_subscribe_events +#undef snd_ctl_card_info +#undef snd_ctl_elem_list +#undef snd_ctl_elem_info +#undef snd_ctl_elem_read +#undef snd_ctl_elem_write +#undef snd_ctl_elem_lock +#undef snd_ctl_elem_unlock +#undef snd_ctl_elem_tlv_read +#undef snd_ctl_elem_tlv_write +#undef snd_ctl_elem_tlv_command +#undef snd_ctl_hwdep_next_device +#undef snd_ctl_hwdep_info +#undef snd_ctl_pcm_next_device +#undef snd_ctl_pcm_info +#undef snd_ctl_pcm_prefer_subdevice +#undef snd_ctl_rawmidi_next_device +#undef snd_ctl_rawmidi_info +#undef snd_ctl_rawmidi_prefer_subdevice +#undef snd_ctl_set_power_state +#undef snd_ctl_get_power_state +#undef snd_ctl_read +#undef snd_ctl_wait +#undef snd_ctl_name +#undef snd_ctl_type +#undef snd_ctl_elem_type_name +#undef snd_ctl_elem_iface_name +#undef snd_ctl_event_type_name +#undef snd_ctl_event_elem_get_mask +#undef snd_ctl_event_elem_get_numid +#undef snd_ctl_event_elem_get_id +#undef snd_ctl_event_elem_get_interface +#undef snd_ctl_event_elem_get_device +#undef snd_ctl_event_elem_get_subdevice +#undef snd_ctl_event_elem_get_name +#undef snd_ctl_event_elem_get_index +#undef snd_ctl_elem_list_alloc_space +#undef snd_ctl_elem_list_free_space +#undef snd_ctl_ascii_elem_id_get +#undef snd_ctl_ascii_elem_id_parse +#undef snd_ctl_ascii_value_parse +#undef snd_ctl_elem_id_sizeof +#undef snd_ctl_elem_id_malloc +#undef snd_ctl_elem_id_free +#undef snd_ctl_elem_id_clear +#undef snd_ctl_elem_id_copy +#undef snd_ctl_elem_id_get_numid +#undef snd_ctl_elem_id_get_interface +#undef snd_ctl_elem_id_get_device +#undef snd_ctl_elem_id_get_subdevice +#undef snd_ctl_elem_id_get_name +#undef snd_ctl_elem_id_get_index +#undef snd_ctl_elem_id_set_numid +#undef snd_ctl_elem_id_set_interface +#undef snd_ctl_elem_id_set_device +#undef snd_ctl_elem_id_set_subdevice +#undef snd_ctl_elem_id_set_name +#undef snd_ctl_elem_id_set_index +#undef snd_ctl_card_info_sizeof +#undef snd_ctl_card_info_malloc +#undef snd_ctl_card_info_free +#undef snd_ctl_card_info_clear +#undef snd_ctl_card_info_copy +#undef snd_ctl_card_info_get_card +#undef snd_ctl_card_info_get_id +#undef snd_ctl_card_info_get_driver +#undef snd_ctl_card_info_get_name +#undef snd_ctl_card_info_get_longname +#undef snd_ctl_card_info_get_mixername +#undef snd_ctl_card_info_get_components +#undef snd_ctl_event_sizeof +#undef snd_ctl_event_malloc +#undef snd_ctl_event_free +#undef snd_ctl_event_clear +#undef snd_ctl_event_copy +#undef snd_ctl_event_get_type +#undef snd_ctl_elem_list_sizeof +#undef snd_ctl_elem_list_malloc +#undef snd_ctl_elem_list_free +#undef snd_ctl_elem_list_clear +#undef snd_ctl_elem_list_copy +#undef snd_ctl_elem_list_set_offset +#undef snd_ctl_elem_list_get_used +#undef snd_ctl_elem_list_get_count +#undef snd_ctl_elem_list_get_id +#undef snd_ctl_elem_list_get_numid +#undef snd_ctl_elem_list_get_interface +#undef snd_ctl_elem_list_get_device +#undef snd_ctl_elem_list_get_subdevice +#undef snd_ctl_elem_list_get_name +#undef snd_ctl_elem_list_get_index +#undef snd_ctl_elem_info_sizeof +#undef snd_ctl_elem_info_malloc +#undef snd_ctl_elem_info_free +#undef snd_ctl_elem_info_clear +#undef snd_ctl_elem_info_copy +#undef snd_ctl_elem_info_get_type +#undef snd_ctl_elem_info_is_readable +#undef snd_ctl_elem_info_is_writable +#undef snd_ctl_elem_info_is_volatile +#undef snd_ctl_elem_info_is_inactive +#undef snd_ctl_elem_info_is_locked +#undef snd_ctl_elem_info_is_tlv_readable +#undef snd_ctl_elem_info_is_tlv_writable +#undef snd_ctl_elem_info_is_tlv_commandable +#undef snd_ctl_elem_info_is_owner +#undef snd_ctl_elem_info_is_user +#undef snd_ctl_elem_info_get_owner +#undef snd_ctl_elem_info_get_count +#undef snd_ctl_elem_info_get_min +#undef snd_ctl_elem_info_get_max +#undef snd_ctl_elem_info_get_step +#undef snd_ctl_elem_info_get_min64 +#undef snd_ctl_elem_info_get_max64 +#undef snd_ctl_elem_info_get_step64 +#undef snd_ctl_elem_info_get_items +#undef snd_ctl_elem_info_set_item +#undef snd_ctl_elem_info_get_item_name +#undef snd_ctl_elem_info_get_dimensions +#undef snd_ctl_elem_info_get_dimension +#undef snd_ctl_elem_info_set_dimension +#undef snd_ctl_elem_info_get_id +#undef snd_ctl_elem_info_get_numid +#undef snd_ctl_elem_info_get_interface +#undef snd_ctl_elem_info_get_device +#undef snd_ctl_elem_info_get_subdevice +#undef snd_ctl_elem_info_get_name +#undef snd_ctl_elem_info_get_index +#undef snd_ctl_elem_info_set_id +#undef snd_ctl_elem_info_set_numid +#undef snd_ctl_elem_info_set_interface +#undef snd_ctl_elem_info_set_device +#undef snd_ctl_elem_info_set_subdevice +#undef snd_ctl_elem_info_set_name +#undef snd_ctl_elem_info_set_index +#undef snd_ctl_add_integer_elem_set +#undef snd_ctl_add_integer64_elem_set +#undef snd_ctl_add_boolean_elem_set +#undef snd_ctl_add_enumerated_elem_set +#undef snd_ctl_add_bytes_elem_set +#undef snd_ctl_elem_add_integer +#undef snd_ctl_elem_add_integer64 +#undef snd_ctl_elem_add_boolean +#undef snd_ctl_elem_add_enumerated +#undef snd_ctl_elem_add_iec958 +#undef snd_ctl_elem_remove +#undef snd_ctl_elem_value_sizeof +#undef snd_ctl_elem_value_malloc +#undef snd_ctl_elem_value_free +#undef snd_ctl_elem_value_clear +#undef snd_ctl_elem_value_copy +#undef snd_ctl_elem_value_compare +#undef snd_ctl_elem_value_get_id +#undef snd_ctl_elem_value_get_numid +#undef snd_ctl_elem_value_get_interface +#undef snd_ctl_elem_value_get_device +#undef snd_ctl_elem_value_get_subdevice +#undef snd_ctl_elem_value_get_name +#undef snd_ctl_elem_value_get_index +#undef snd_ctl_elem_value_set_id +#undef snd_ctl_elem_value_set_numid +#undef snd_ctl_elem_value_set_interface +#undef snd_ctl_elem_value_set_device +#undef snd_ctl_elem_value_set_subdevice +#undef snd_ctl_elem_value_set_name +#undef snd_ctl_elem_value_set_index +#undef snd_ctl_elem_value_get_boolean +#undef snd_ctl_elem_value_get_integer +#undef snd_ctl_elem_value_get_integer64 +#undef snd_ctl_elem_value_get_enumerated +#undef snd_ctl_elem_value_get_byte +#undef snd_ctl_elem_value_set_boolean +#undef snd_ctl_elem_value_set_integer +#undef snd_ctl_elem_value_set_integer64 +#undef snd_ctl_elem_value_set_enumerated +#undef snd_ctl_elem_value_set_byte +#undef snd_ctl_elem_set_bytes +#undef snd_ctl_elem_value_get_bytes +#undef snd_ctl_elem_value_get_iec958 +#undef snd_ctl_elem_value_set_iec958 +#undef snd_tlv_parse_dB_info +#undef snd_tlv_get_dB_range +#undef snd_tlv_convert_to_dB +#undef snd_tlv_convert_from_dB +#undef snd_ctl_get_dB_range +#undef snd_ctl_convert_to_dB +#undef snd_ctl_convert_from_dB +#undef snd_hctl_compare_fast +#undef snd_hctl_open +#undef snd_hctl_open_ctl +#undef snd_hctl_close +#undef snd_hctl_nonblock +#undef snd_hctl_poll_descriptors_count +#undef snd_hctl_poll_descriptors +#undef snd_hctl_poll_descriptors_revents +#undef snd_hctl_get_count +#undef snd_hctl_set_compare +#undef snd_hctl_first_elem +#undef snd_hctl_last_elem +#undef snd_hctl_find_elem +#undef snd_hctl_set_callback +#undef snd_hctl_set_callback_private +#undef snd_hctl_get_callback_private +#undef snd_hctl_load +#undef snd_hctl_free +#undef snd_hctl_handle_events +#undef snd_hctl_name +#undef snd_hctl_wait +#undef snd_hctl_ctl +#undef snd_hctl_elem_next +#undef snd_hctl_elem_prev +#undef snd_hctl_elem_info +#undef snd_hctl_elem_read +#undef snd_hctl_elem_write +#undef snd_hctl_elem_tlv_read +#undef snd_hctl_elem_tlv_write +#undef snd_hctl_elem_tlv_command +#undef snd_hctl_elem_get_hctl +#undef snd_hctl_elem_get_id +#undef snd_hctl_elem_get_numid +#undef snd_hctl_elem_get_interface +#undef snd_hctl_elem_get_device +#undef snd_hctl_elem_get_subdevice +#undef snd_hctl_elem_get_name +#undef snd_hctl_elem_get_index +#undef snd_hctl_elem_set_callback +#undef snd_hctl_elem_get_callback_private +#undef snd_hctl_elem_set_callback_private +#undef snd_sctl_build +#undef snd_sctl_free +#undef snd_sctl_install +#undef snd_sctl_remove +#undef snd_mixer_open +#undef snd_mixer_close +#undef snd_mixer_first_elem +#undef snd_mixer_last_elem +#undef snd_mixer_handle_events +#undef snd_mixer_attach +#undef snd_mixer_attach_hctl +#undef snd_mixer_detach +#undef snd_mixer_detach_hctl +#undef snd_mixer_get_hctl +#undef snd_mixer_poll_descriptors_count +#undef snd_mixer_poll_descriptors +#undef snd_mixer_poll_descriptors_revents +#undef snd_mixer_load +#undef snd_mixer_free +#undef snd_mixer_wait +#undef snd_mixer_set_compare +#undef snd_mixer_set_callback +#undef snd_mixer_get_callback_private +#undef snd_mixer_set_callback_private +#undef snd_mixer_get_count +#undef snd_mixer_class_unregister +#undef snd_mixer_elem_next +#undef snd_mixer_elem_prev +#undef snd_mixer_elem_set_callback +#undef snd_mixer_elem_get_callback_private +#undef snd_mixer_elem_set_callback_private +#undef snd_mixer_elem_get_type +#undef snd_mixer_class_register +#undef snd_mixer_elem_new +#undef snd_mixer_elem_add +#undef snd_mixer_elem_remove +#undef snd_mixer_elem_free +#undef snd_mixer_elem_info +#undef snd_mixer_elem_value +#undef snd_mixer_elem_attach +#undef snd_mixer_elem_detach +#undef snd_mixer_elem_empty +#undef snd_mixer_elem_get_private +#undef snd_mixer_class_sizeof +#undef snd_mixer_class_malloc +#undef snd_mixer_class_free +#undef snd_mixer_class_copy +#undef snd_mixer_class_get_mixer +#undef snd_mixer_class_get_event +#undef snd_mixer_class_get_private +#undef snd_mixer_class_get_compare +#undef snd_mixer_class_set_event +#undef snd_mixer_class_set_private +#undef snd_mixer_class_set_private_free +#undef snd_mixer_class_set_compare +#undef snd_mixer_selem_channel_name +#undef snd_mixer_selem_register +#undef snd_mixer_selem_get_id +#undef snd_mixer_selem_get_name +#undef snd_mixer_selem_get_index +#undef snd_mixer_find_selem +#undef snd_mixer_selem_is_active +#undef snd_mixer_selem_is_playback_mono +#undef snd_mixer_selem_has_playback_channel +#undef snd_mixer_selem_is_capture_mono +#undef snd_mixer_selem_has_capture_channel +#undef snd_mixer_selem_get_capture_group +#undef snd_mixer_selem_has_common_volume +#undef snd_mixer_selem_has_playback_volume +#undef snd_mixer_selem_has_playback_volume_joined +#undef snd_mixer_selem_has_capture_volume +#undef snd_mixer_selem_has_capture_volume_joined +#undef snd_mixer_selem_has_common_switch +#undef snd_mixer_selem_has_playback_switch +#undef snd_mixer_selem_has_playback_switch_joined +#undef snd_mixer_selem_has_capture_switch +#undef snd_mixer_selem_has_capture_switch_joined +#undef snd_mixer_selem_has_capture_switch_exclusive +#undef snd_mixer_selem_ask_playback_vol_dB +#undef snd_mixer_selem_ask_capture_vol_dB +#undef snd_mixer_selem_ask_playback_dB_vol +#undef snd_mixer_selem_ask_capture_dB_vol +#undef snd_mixer_selem_get_playback_volume +#undef snd_mixer_selem_get_capture_volume +#undef snd_mixer_selem_get_playback_dB +#undef snd_mixer_selem_get_capture_dB +#undef snd_mixer_selem_get_playback_switch +#undef snd_mixer_selem_get_capture_switch +#undef snd_mixer_selem_set_playback_volume +#undef snd_mixer_selem_set_capture_volume +#undef snd_mixer_selem_set_playback_dB +#undef snd_mixer_selem_set_capture_dB +#undef snd_mixer_selem_set_playback_volume_all +#undef snd_mixer_selem_set_capture_volume_all +#undef snd_mixer_selem_set_playback_dB_all +#undef snd_mixer_selem_set_capture_dB_all +#undef snd_mixer_selem_set_playback_switch +#undef snd_mixer_selem_set_capture_switch +#undef snd_mixer_selem_set_playback_switch_all +#undef snd_mixer_selem_set_capture_switch_all +#undef snd_mixer_selem_get_playback_volume_range +#undef snd_mixer_selem_get_playback_dB_range +#undef snd_mixer_selem_set_playback_volume_range +#undef snd_mixer_selem_get_capture_volume_range +#undef snd_mixer_selem_get_capture_dB_range +#undef snd_mixer_selem_set_capture_volume_range +#undef snd_mixer_selem_is_enumerated +#undef snd_mixer_selem_is_enum_playback +#undef snd_mixer_selem_is_enum_capture +#undef snd_mixer_selem_get_enum_items +#undef snd_mixer_selem_get_enum_item_name +#undef snd_mixer_selem_get_enum_item +#undef snd_mixer_selem_set_enum_item +#undef snd_mixer_selem_id_sizeof +#undef snd_mixer_selem_id_malloc +#undef snd_mixer_selem_id_free +#undef snd_mixer_selem_id_copy +#undef snd_mixer_selem_id_get_name +#undef snd_mixer_selem_id_get_index +#undef snd_mixer_selem_id_set_name +#undef snd_mixer_selem_id_set_index +#undef snd_mixer_selem_id_parse +#undef snd_seq_open +#undef snd_seq_open_lconf +#undef snd_seq_name +#undef snd_seq_type +#undef snd_seq_close +#undef snd_seq_poll_descriptors_count +#undef snd_seq_poll_descriptors +#undef snd_seq_poll_descriptors_revents +#undef snd_seq_nonblock +#undef snd_seq_client_id +#undef snd_seq_get_output_buffer_size +#undef snd_seq_get_input_buffer_size +#undef snd_seq_set_output_buffer_size +#undef snd_seq_set_input_buffer_size +#undef snd_seq_system_info_sizeof +#undef snd_seq_system_info_malloc +#undef snd_seq_system_info_free +#undef snd_seq_system_info_copy +#undef snd_seq_system_info_get_queues +#undef snd_seq_system_info_get_clients +#undef snd_seq_system_info_get_ports +#undef snd_seq_system_info_get_channels +#undef snd_seq_system_info_get_cur_clients +#undef snd_seq_system_info_get_cur_queues +#undef snd_seq_system_info +#undef snd_seq_client_info_sizeof +#undef snd_seq_client_info_malloc +#undef snd_seq_client_info_free +#undef snd_seq_client_info_copy +#undef snd_seq_client_info_get_client +#undef snd_seq_client_info_get_type +#undef snd_seq_client_info_get_name +#undef snd_seq_client_info_get_broadcast_filter +#undef snd_seq_client_info_get_error_bounce +#undef snd_seq_client_info_get_card +#undef snd_seq_client_info_get_pid +#undef snd_seq_client_info_get_event_filter +#undef snd_seq_client_info_get_num_ports +#undef snd_seq_client_info_get_event_lost +#undef snd_seq_client_info_set_client +#undef snd_seq_client_info_set_name +#undef snd_seq_client_info_set_broadcast_filter +#undef snd_seq_client_info_set_error_bounce +#undef snd_seq_client_info_set_event_filter +#undef snd_seq_client_info_event_filter_clear +#undef snd_seq_client_info_event_filter_add +#undef snd_seq_client_info_event_filter_del +#undef snd_seq_client_info_event_filter_check +#undef snd_seq_get_client_info +#undef snd_seq_get_any_client_info +#undef snd_seq_set_client_info +#undef snd_seq_query_next_client +#undef snd_seq_client_pool_sizeof +#undef snd_seq_client_pool_malloc +#undef snd_seq_client_pool_free +#undef snd_seq_client_pool_copy +#undef snd_seq_client_pool_get_client +#undef snd_seq_client_pool_get_output_pool +#undef snd_seq_client_pool_get_input_pool +#undef snd_seq_client_pool_get_output_room +#undef snd_seq_client_pool_get_output_free +#undef snd_seq_client_pool_get_input_free +#undef snd_seq_client_pool_set_output_pool +#undef snd_seq_client_pool_set_input_pool +#undef snd_seq_client_pool_set_output_room +#undef snd_seq_get_client_pool +#undef snd_seq_set_client_pool +#undef snd_seq_port_info_sizeof +#undef snd_seq_port_info_malloc +#undef snd_seq_port_info_free +#undef snd_seq_port_info_copy +#undef snd_seq_port_info_get_client +#undef snd_seq_port_info_get_port +#undef snd_seq_port_info_get_addr +#undef snd_seq_port_info_get_name +#undef snd_seq_port_info_get_capability +#undef snd_seq_port_info_get_type +#undef snd_seq_port_info_get_midi_channels +#undef snd_seq_port_info_get_midi_voices +#undef snd_seq_port_info_get_synth_voices +#undef snd_seq_port_info_get_read_use +#undef snd_seq_port_info_get_write_use +#undef snd_seq_port_info_get_port_specified +#undef snd_seq_port_info_get_timestamping +#undef snd_seq_port_info_get_timestamp_real +#undef snd_seq_port_info_get_timestamp_queue +#undef snd_seq_port_info_set_client +#undef snd_seq_port_info_set_port +#undef snd_seq_port_info_set_addr +#undef snd_seq_port_info_set_name +#undef snd_seq_port_info_set_capability +#undef snd_seq_port_info_set_type +#undef snd_seq_port_info_set_midi_channels +#undef snd_seq_port_info_set_midi_voices +#undef snd_seq_port_info_set_synth_voices +#undef snd_seq_port_info_set_port_specified +#undef snd_seq_port_info_set_timestamping +#undef snd_seq_port_info_set_timestamp_real +#undef snd_seq_port_info_set_timestamp_queue +#undef snd_seq_create_port +#undef snd_seq_delete_port +#undef snd_seq_get_port_info +#undef snd_seq_get_any_port_info +#undef snd_seq_set_port_info +#undef snd_seq_query_next_port +#undef snd_seq_port_subscribe_sizeof +#undef snd_seq_port_subscribe_malloc +#undef snd_seq_port_subscribe_free +#undef snd_seq_port_subscribe_copy +#undef snd_seq_port_subscribe_get_sender +#undef snd_seq_port_subscribe_get_dest +#undef snd_seq_port_subscribe_get_queue +#undef snd_seq_port_subscribe_get_exclusive +#undef snd_seq_port_subscribe_get_time_update +#undef snd_seq_port_subscribe_get_time_real +#undef snd_seq_port_subscribe_set_sender +#undef snd_seq_port_subscribe_set_dest +#undef snd_seq_port_subscribe_set_queue +#undef snd_seq_port_subscribe_set_exclusive +#undef snd_seq_port_subscribe_set_time_update +#undef snd_seq_port_subscribe_set_time_real +#undef snd_seq_get_port_subscription +#undef snd_seq_subscribe_port +#undef snd_seq_unsubscribe_port +#undef snd_seq_query_subscribe_sizeof +#undef snd_seq_query_subscribe_malloc +#undef snd_seq_query_subscribe_free +#undef snd_seq_query_subscribe_copy +#undef snd_seq_query_subscribe_get_client +#undef snd_seq_query_subscribe_get_port +#undef snd_seq_query_subscribe_get_root +#undef snd_seq_query_subscribe_get_type +#undef snd_seq_query_subscribe_get_index +#undef snd_seq_query_subscribe_get_num_subs +#undef snd_seq_query_subscribe_get_addr +#undef snd_seq_query_subscribe_get_queue +#undef snd_seq_query_subscribe_get_exclusive +#undef snd_seq_query_subscribe_get_time_update +#undef snd_seq_query_subscribe_get_time_real +#undef snd_seq_query_subscribe_set_client +#undef snd_seq_query_subscribe_set_port +#undef snd_seq_query_subscribe_set_root +#undef snd_seq_query_subscribe_set_type +#undef snd_seq_query_subscribe_set_index +#undef snd_seq_query_port_subscribers +#undef snd_seq_queue_info_sizeof +#undef snd_seq_queue_info_malloc +#undef snd_seq_queue_info_free +#undef snd_seq_queue_info_copy +#undef snd_seq_queue_info_get_queue +#undef snd_seq_queue_info_get_name +#undef snd_seq_queue_info_get_owner +#undef snd_seq_queue_info_get_locked +#undef snd_seq_queue_info_get_flags +#undef snd_seq_queue_info_set_name +#undef snd_seq_queue_info_set_owner +#undef snd_seq_queue_info_set_locked +#undef snd_seq_queue_info_set_flags +#undef snd_seq_create_queue +#undef snd_seq_alloc_named_queue +#undef snd_seq_alloc_queue +#undef snd_seq_free_queue +#undef snd_seq_get_queue_info +#undef snd_seq_set_queue_info +#undef snd_seq_query_named_queue +#undef snd_seq_get_queue_usage +#undef snd_seq_set_queue_usage +#undef snd_seq_queue_status_sizeof +#undef snd_seq_queue_status_malloc +#undef snd_seq_queue_status_free +#undef snd_seq_queue_status_copy +#undef snd_seq_queue_status_get_queue +#undef snd_seq_queue_status_get_events +#undef snd_seq_queue_status_get_tick_time +#undef snd_seq_queue_status_get_real_time +#undef snd_seq_queue_status_get_status +#undef snd_seq_get_queue_status +#undef snd_seq_queue_tempo_sizeof +#undef snd_seq_queue_tempo_malloc +#undef snd_seq_queue_tempo_free +#undef snd_seq_queue_tempo_copy +#undef snd_seq_queue_tempo_get_queue +#undef snd_seq_queue_tempo_get_tempo +#undef snd_seq_queue_tempo_get_ppq +#undef snd_seq_queue_tempo_get_skew +#undef snd_seq_queue_tempo_get_skew_base +#undef snd_seq_queue_tempo_set_tempo +#undef snd_seq_queue_tempo_set_ppq +#undef snd_seq_queue_tempo_set_skew +#undef snd_seq_queue_tempo_set_skew_base +#undef snd_seq_get_queue_tempo +#undef snd_seq_set_queue_tempo +#undef snd_seq_queue_timer_sizeof +#undef snd_seq_queue_timer_malloc +#undef snd_seq_queue_timer_free +#undef snd_seq_queue_timer_copy +#undef snd_seq_queue_timer_get_queue +#undef snd_seq_queue_timer_get_type +#undef snd_seq_queue_timer_get_id +#undef snd_seq_queue_timer_get_resolution +#undef snd_seq_queue_timer_set_type +#undef snd_seq_queue_timer_set_id +#undef snd_seq_queue_timer_set_resolution +#undef snd_seq_get_queue_timer +#undef snd_seq_set_queue_timer +#undef snd_seq_free_event +#undef snd_seq_event_length +#undef snd_seq_event_output +#undef snd_seq_event_output_buffer +#undef snd_seq_event_output_direct +#undef snd_seq_event_input +#undef snd_seq_event_input_pending +#undef snd_seq_drain_output +#undef snd_seq_event_output_pending +#undef snd_seq_extract_output +#undef snd_seq_drop_output +#undef snd_seq_drop_output_buffer +#undef snd_seq_drop_input +#undef snd_seq_drop_input_buffer +#undef snd_seq_remove_events_sizeof +#undef snd_seq_remove_events_malloc +#undef snd_seq_remove_events_free +#undef snd_seq_remove_events_copy +#undef snd_seq_remove_events_get_condition +#undef snd_seq_remove_events_get_queue +#undef snd_seq_remove_events_get_time +#undef snd_seq_remove_events_get_dest +#undef snd_seq_remove_events_get_channel +#undef snd_seq_remove_events_get_event_type +#undef snd_seq_remove_events_get_tag +#undef snd_seq_remove_events_set_condition +#undef snd_seq_remove_events_set_queue +#undef snd_seq_remove_events_set_time +#undef snd_seq_remove_events_set_dest +#undef snd_seq_remove_events_set_channel +#undef snd_seq_remove_events_set_event_type +#undef snd_seq_remove_events_set_tag +#undef snd_seq_remove_events +#undef snd_seq_set_bit +#undef snd_seq_unset_bit +#undef snd_seq_change_bit +#undef snd_seq_get_bit +#undef snd_seq_control_queue +#undef snd_seq_create_simple_port +#undef snd_seq_delete_simple_port +#undef snd_seq_connect_from +#undef snd_seq_connect_to +#undef snd_seq_disconnect_from +#undef snd_seq_disconnect_to +#undef snd_seq_set_client_name +#undef snd_seq_set_client_event_filter +#undef snd_seq_set_client_pool_output +#undef snd_seq_set_client_pool_output_room +#undef snd_seq_set_client_pool_input +#undef snd_seq_sync_output_queue +#undef snd_seq_parse_address +#undef snd_seq_reset_pool_output +#undef snd_seq_reset_pool_input +#undef snd_midi_event_new +#undef snd_midi_event_resize_buffer +#undef snd_midi_event_free +#undef snd_midi_event_init +#undef snd_midi_event_reset_encode +#undef snd_midi_event_reset_decode +#undef snd_midi_event_no_status +#undef snd_midi_event_encode +#undef snd_midi_event_encode_byte +#undef snd_midi_event_decode +#include <dlfcn.h> +#include <stdio.h> +const char* (*snd_asoundlib_version_dylibloader_wrapper_asound)( void); +int (*snd_dlpath_dylibloader_wrapper_asound)( char*, size_t,const char*); +void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int, char*, size_t); +void* (*snd_dlsym_dylibloader_wrapper_asound)( void*,const char*,const char*); +int (*snd_dlclose_dylibloader_wrapper_asound)( void*); +int (*snd_async_add_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, int, snd_async_callback_t, void*); +int (*snd_async_del_handler_dylibloader_wrapper_asound)( snd_async_handler_t*); +int (*snd_async_handler_get_fd_dylibloader_wrapper_asound)( snd_async_handler_t*); +int (*snd_async_handler_get_signo_dylibloader_wrapper_asound)( snd_async_handler_t*); +void* (*snd_async_handler_get_callback_private_dylibloader_wrapper_asound)( snd_async_handler_t*); +struct snd_shm_area* (*snd_shm_area_create_dylibloader_wrapper_asound)( int, void*); +struct snd_shm_area* (*snd_shm_area_share_dylibloader_wrapper_asound)(struct snd_shm_area*); +int (*snd_shm_area_destroy_dylibloader_wrapper_asound)(struct snd_shm_area*); +int (*snd_user_file_dylibloader_wrapper_asound)(const char*, char**); +int (*snd_input_stdio_open_dylibloader_wrapper_asound)( snd_input_t**,const char*,const char*); +int (*snd_input_stdio_attach_dylibloader_wrapper_asound)( snd_input_t**, FILE*, int); +int (*snd_input_buffer_open_dylibloader_wrapper_asound)( snd_input_t**,const char*, ssize_t); +int (*snd_input_close_dylibloader_wrapper_asound)( snd_input_t*); +int (*snd_input_scanf_dylibloader_wrapper_asound)( snd_input_t*,const char*,...); +char* (*snd_input_gets_dylibloader_wrapper_asound)( snd_input_t*, char*, size_t); +int (*snd_input_getc_dylibloader_wrapper_asound)( snd_input_t*); +int (*snd_input_ungetc_dylibloader_wrapper_asound)( snd_input_t*, int); +int (*snd_output_stdio_open_dylibloader_wrapper_asound)( snd_output_t**,const char*,const char*); +int (*snd_output_stdio_attach_dylibloader_wrapper_asound)( snd_output_t**, FILE*, int); +int (*snd_output_buffer_open_dylibloader_wrapper_asound)( snd_output_t**); +size_t (*snd_output_buffer_string_dylibloader_wrapper_asound)( snd_output_t*, char**); +int (*snd_output_close_dylibloader_wrapper_asound)( snd_output_t*); +int (*snd_output_printf_dylibloader_wrapper_asound)( snd_output_t*,const char*,...); +int (*snd_output_vprintf_dylibloader_wrapper_asound)( snd_output_t*,const char*, va_list); +int (*snd_output_puts_dylibloader_wrapper_asound)( snd_output_t*,const char*); +int (*snd_output_putc_dylibloader_wrapper_asound)( snd_output_t*, int); +int (*snd_output_flush_dylibloader_wrapper_asound)( snd_output_t*); +const char* (*snd_strerror_dylibloader_wrapper_asound)( int); +int (*snd_lib_error_set_handler_dylibloader_wrapper_asound)( snd_lib_error_handler_t); +snd_local_error_handler_t (*snd_lib_error_set_local_dylibloader_wrapper_asound)( snd_local_error_handler_t); +const char* (*snd_config_topdir_dylibloader_wrapper_asound)( void); +int (*snd_config_top_dylibloader_wrapper_asound)( snd_config_t**); +int (*snd_config_load_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*); +int (*snd_config_load_override_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*); +int (*snd_config_save_dylibloader_wrapper_asound)( snd_config_t*, snd_output_t*); +int (*snd_config_update_dylibloader_wrapper_asound)( void); +int (*snd_config_update_r_dylibloader_wrapper_asound)( snd_config_t**, snd_config_update_t**,const char*); +int (*snd_config_update_free_dylibloader_wrapper_asound)( snd_config_update_t*); +int (*snd_config_update_free_global_dylibloader_wrapper_asound)( void); +int (*snd_config_update_ref_dylibloader_wrapper_asound)( snd_config_t**); +void (*snd_config_ref_dylibloader_wrapper_asound)( snd_config_t*); +void (*snd_config_unref_dylibloader_wrapper_asound)( snd_config_t*); +int (*snd_config_search_dylibloader_wrapper_asound)( snd_config_t*,const char*, snd_config_t**); +int (*snd_config_searchv_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t**,...); +int (*snd_config_search_definition_dylibloader_wrapper_asound)( snd_config_t*,const char*,const char*, snd_config_t**); +int (*snd_config_expand_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*,const char*, snd_config_t*, snd_config_t**); +int (*snd_config_evaluate_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*, snd_config_t*, snd_config_t**); +int (*snd_config_add_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*); +int (*snd_config_add_before_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*); +int (*snd_config_add_after_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*); +int (*snd_config_remove_dylibloader_wrapper_asound)( snd_config_t*); +int (*snd_config_delete_dylibloader_wrapper_asound)( snd_config_t*); +int (*snd_config_delete_compound_members_dylibloader_wrapper_asound)(const snd_config_t*); +int (*snd_config_copy_dylibloader_wrapper_asound)( snd_config_t**, snd_config_t*); +int (*snd_config_make_dylibloader_wrapper_asound)( snd_config_t**,const char*, snd_config_type_t); +int (*snd_config_make_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*); +int (*snd_config_make_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*); +int (*snd_config_make_real_dylibloader_wrapper_asound)( snd_config_t**,const char*); +int (*snd_config_make_string_dylibloader_wrapper_asound)( snd_config_t**,const char*); +int (*snd_config_make_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*); +int (*snd_config_make_compound_dylibloader_wrapper_asound)( snd_config_t**,const char*, int); +int (*snd_config_imake_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long); +int (*snd_config_imake_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long long); +int (*snd_config_imake_real_dylibloader_wrapper_asound)( snd_config_t**,const char*,const double); +int (*snd_config_imake_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*); +int (*snd_config_imake_safe_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*); +int (*snd_config_imake_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const void*); +snd_config_type_t (*snd_config_get_type_dylibloader_wrapper_asound)(const snd_config_t*); +int (*snd_config_is_array_dylibloader_wrapper_asound)(const snd_config_t*); +int (*snd_config_set_id_dylibloader_wrapper_asound)( snd_config_t*,const char*); +int (*snd_config_set_integer_dylibloader_wrapper_asound)( snd_config_t*, long); +int (*snd_config_set_integer64_dylibloader_wrapper_asound)( snd_config_t*, long long); +int (*snd_config_set_real_dylibloader_wrapper_asound)( snd_config_t*, double); +int (*snd_config_set_string_dylibloader_wrapper_asound)( snd_config_t*,const char*); +int (*snd_config_set_ascii_dylibloader_wrapper_asound)( snd_config_t*,const char*); +int (*snd_config_set_pointer_dylibloader_wrapper_asound)( snd_config_t*,const void*); +int (*snd_config_get_id_dylibloader_wrapper_asound)(const snd_config_t*,const char**); +int (*snd_config_get_integer_dylibloader_wrapper_asound)(const snd_config_t*, long*); +int (*snd_config_get_integer64_dylibloader_wrapper_asound)(const snd_config_t*, long long*); +int (*snd_config_get_real_dylibloader_wrapper_asound)(const snd_config_t*, double*); +int (*snd_config_get_ireal_dylibloader_wrapper_asound)(const snd_config_t*, double*); +int (*snd_config_get_string_dylibloader_wrapper_asound)(const snd_config_t*,const char**); +int (*snd_config_get_ascii_dylibloader_wrapper_asound)(const snd_config_t*, char**); +int (*snd_config_get_pointer_dylibloader_wrapper_asound)(const snd_config_t*,const void**); +int (*snd_config_test_id_dylibloader_wrapper_asound)(const snd_config_t*,const char*); +snd_config_iterator_t (*snd_config_iterator_first_dylibloader_wrapper_asound)(const snd_config_t*); +snd_config_iterator_t (*snd_config_iterator_next_dylibloader_wrapper_asound)(const snd_config_iterator_t); +snd_config_iterator_t (*snd_config_iterator_end_dylibloader_wrapper_asound)(const snd_config_t*); +snd_config_t* (*snd_config_iterator_entry_dylibloader_wrapper_asound)(const snd_config_iterator_t); +int (*snd_config_get_bool_ascii_dylibloader_wrapper_asound)(const char*); +int (*snd_config_get_bool_dylibloader_wrapper_asound)(const snd_config_t*); +int (*snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound)(const char*); +int (*snd_config_get_ctl_iface_dylibloader_wrapper_asound)(const snd_config_t*); +int (*snd_names_list_dylibloader_wrapper_asound)(const char*, snd_devname_t**); +void (*snd_names_list_free_dylibloader_wrapper_asound)( snd_devname_t*); +int (*snd_pcm_open_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int); +int (*snd_pcm_open_lconf_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int, snd_config_t*); +int (*snd_pcm_open_fallback_dylibloader_wrapper_asound)( snd_pcm_t**, snd_config_t*,const char*,const char*, snd_pcm_stream_t, int); +int (*snd_pcm_close_dylibloader_wrapper_asound)( snd_pcm_t*); +const char* (*snd_pcm_name_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_type_t (*snd_pcm_type_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_stream_t (*snd_pcm_stream_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_poll_descriptors_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int); +int (*snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_pcm_nonblock_dylibloader_wrapper_asound)( snd_pcm_t*, int); +int (*snd_async_add_pcm_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_pcm_t*, snd_async_callback_t, void*); +snd_pcm_t* (*snd_async_handler_get_pcm_dylibloader_wrapper_asound)( snd_async_handler_t*); +int (*snd_pcm_info_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_info_t*); +int (*snd_pcm_hw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +int (*snd_pcm_hw_free_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_sw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*); +int (*snd_pcm_sw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*); +int (*snd_pcm_prepare_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_reset_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_status_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_status_t*); +int (*snd_pcm_start_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_drop_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_drain_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_pause_dylibloader_wrapper_asound)( snd_pcm_t*, int); +snd_pcm_state_t (*snd_pcm_state_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_hwsync_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*); +int (*snd_pcm_resume_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_htimestamp_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_htimestamp_t*); +snd_pcm_sframes_t (*snd_pcm_avail_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_sframes_t (*snd_pcm_avail_update_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_avail_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*, snd_pcm_sframes_t*); +snd_pcm_sframes_t (*snd_pcm_rewindable_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_sframes_t (*snd_pcm_rewind_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_forwardable_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_sframes_t (*snd_pcm_forward_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +int (*snd_pcm_wait_dylibloader_wrapper_asound)( snd_pcm_t*, int); +int (*snd_pcm_link_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*); +int (*snd_pcm_unlink_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound)( int, int, int, snd_pcm_stream_t); +void (*snd_pcm_free_chmaps_dylibloader_wrapper_asound)( snd_pcm_chmap_query_t**); +snd_pcm_chmap_t* (*snd_pcm_get_chmap_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_set_chmap_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_chmap_t*); +const char* (*snd_pcm_chmap_type_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_type); +const char* (*snd_pcm_chmap_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position); +const char* (*snd_pcm_chmap_long_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position); +int (*snd_pcm_chmap_print_dylibloader_wrapper_asound)(const snd_pcm_chmap_t*, size_t, char*); +unsigned int (*snd_pcm_chmap_from_string_dylibloader_wrapper_asound)(const char*); +snd_pcm_chmap_t* (*snd_pcm_chmap_parse_string_dylibloader_wrapper_asound)(const char*); +int (*snd_pcm_recover_dylibloader_wrapper_asound)( snd_pcm_t*, int, int); +int (*snd_pcm_set_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int); +int (*snd_pcm_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +size_t (*snd_pcm_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_info_malloc_dylibloader_wrapper_asound)( snd_pcm_info_t**); +void (*snd_pcm_info_free_dylibloader_wrapper_asound)( snd_pcm_info_t*); +void (*snd_pcm_info_copy_dylibloader_wrapper_asound)( snd_pcm_info_t*,const snd_pcm_info_t*); +unsigned int (*snd_pcm_info_get_device_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +unsigned int (*snd_pcm_info_get_subdevice_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +snd_pcm_stream_t (*snd_pcm_info_get_stream_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +int (*snd_pcm_info_get_card_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +const char* (*snd_pcm_info_get_id_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +const char* (*snd_pcm_info_get_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +const char* (*snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +snd_pcm_class_t (*snd_pcm_info_get_class_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +snd_pcm_subclass_t (*snd_pcm_info_get_subclass_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +unsigned int (*snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +unsigned int (*snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +snd_pcm_sync_id_t (*snd_pcm_info_get_sync_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +void (*snd_pcm_info_set_device_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int); +void (*snd_pcm_info_set_subdevice_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int); +void (*snd_pcm_info_set_stream_dylibloader_wrapper_asound)( snd_pcm_info_t*, snd_pcm_stream_t); +int (*snd_pcm_hw_params_any_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_is_double_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, int); +int (*snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, unsigned int*); +int (*snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +size_t (*snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_hw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_hw_params_t**); +void (*snd_pcm_hw_params_free_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*); +void (*snd_pcm_hw_params_copy_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*,const snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_get_access_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_access_t*); +int (*snd_pcm_hw_params_test_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t); +int (*snd_pcm_hw_params_set_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t); +int (*snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*); +int (*snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*); +int (*snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_mask_t*); +int (*snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_access_mask_t*); +int (*snd_pcm_hw_params_get_format_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_format_t*); +int (*snd_pcm_hw_params_test_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t); +int (*snd_pcm_hw_params_set_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t); +int (*snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*); +int (*snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*); +int (*snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_mask_t*); +void (*snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_format_mask_t*); +int (*snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_subformat_t*); +int (*snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t); +int (*snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t); +int (*snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*); +int (*snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*); +int (*snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*); +void (*snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*); +int (*snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +int (*snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +int (*snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, unsigned int*); +int (*snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +int (*snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +int (*snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +int (*snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int); +int (*snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int); +int (*snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +int (*snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +int (*snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +size_t (*snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_sw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_sw_params_t**); +void (*snd_pcm_sw_params_free_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*); +void (*snd_pcm_sw_params_copy_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*,const snd_pcm_sw_params_t*); +int (*snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_tstamp_t); +int (*snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_tstamp_t*); +int (*snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, int); +int (*snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, int*); +int (*snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +size_t (*snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_access_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_access_mask_t**); +void (*snd_pcm_access_mask_free_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*); +void (*snd_pcm_access_mask_copy_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*,const snd_pcm_access_mask_t*); +void (*snd_pcm_access_mask_none_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*); +void (*snd_pcm_access_mask_any_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*); +int (*snd_pcm_access_mask_test_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*, snd_pcm_access_t); +int (*snd_pcm_access_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*); +void (*snd_pcm_access_mask_set_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t); +void (*snd_pcm_access_mask_reset_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t); +size_t (*snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_format_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_format_mask_t**); +void (*snd_pcm_format_mask_free_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*); +void (*snd_pcm_format_mask_copy_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*,const snd_pcm_format_mask_t*); +void (*snd_pcm_format_mask_none_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*); +void (*snd_pcm_format_mask_any_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*); +int (*snd_pcm_format_mask_test_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*, snd_pcm_format_t); +int (*snd_pcm_format_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*); +void (*snd_pcm_format_mask_set_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t); +void (*snd_pcm_format_mask_reset_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t); +size_t (*snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t**); +void (*snd_pcm_subformat_mask_free_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*); +void (*snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*,const snd_pcm_subformat_mask_t*); +void (*snd_pcm_subformat_mask_none_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*); +void (*snd_pcm_subformat_mask_any_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*); +int (*snd_pcm_subformat_mask_test_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*, snd_pcm_subformat_t); +int (*snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*); +void (*snd_pcm_subformat_mask_set_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t); +void (*snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t); +size_t (*snd_pcm_status_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_pcm_status_malloc_dylibloader_wrapper_asound)( snd_pcm_status_t**); +void (*snd_pcm_status_free_dylibloader_wrapper_asound)( snd_pcm_status_t*); +void (*snd_pcm_status_copy_dylibloader_wrapper_asound)( snd_pcm_status_t*,const snd_pcm_status_t*); +snd_pcm_state_t (*snd_pcm_status_get_state_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +void (*snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*); +void (*snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +void (*snd_pcm_status_get_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*); +void (*snd_pcm_status_get_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +void (*snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +void (*snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +snd_pcm_sframes_t (*snd_pcm_status_get_delay_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +snd_pcm_uframes_t (*snd_pcm_status_get_avail_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +snd_pcm_uframes_t (*snd_pcm_status_get_avail_max_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +snd_pcm_uframes_t (*snd_pcm_status_get_overrange_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +const char* (*snd_pcm_type_name_dylibloader_wrapper_asound)( snd_pcm_type_t); +const char* (*snd_pcm_stream_name_dylibloader_wrapper_asound)(const snd_pcm_stream_t); +const char* (*snd_pcm_access_name_dylibloader_wrapper_asound)(const snd_pcm_access_t); +const char* (*snd_pcm_format_name_dylibloader_wrapper_asound)(const snd_pcm_format_t); +const char* (*snd_pcm_format_description_dylibloader_wrapper_asound)(const snd_pcm_format_t); +const char* (*snd_pcm_subformat_name_dylibloader_wrapper_asound)(const snd_pcm_subformat_t); +const char* (*snd_pcm_subformat_description_dylibloader_wrapper_asound)(const snd_pcm_subformat_t); +snd_pcm_format_t (*snd_pcm_format_value_dylibloader_wrapper_asound)(const char*); +const char* (*snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound)(const snd_pcm_tstamp_t); +const char* (*snd_pcm_state_name_dylibloader_wrapper_asound)(const snd_pcm_state_t); +int (*snd_pcm_dump_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +int (*snd_pcm_dump_hw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +int (*snd_pcm_dump_sw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +int (*snd_pcm_dump_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +int (*snd_pcm_hw_params_dump_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_output_t*); +int (*snd_pcm_sw_params_dump_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*, snd_output_t*); +int (*snd_pcm_status_dump_dylibloader_wrapper_asound)( snd_pcm_status_t*, snd_output_t*); +int (*snd_pcm_mmap_begin_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_channel_area_t**, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +snd_pcm_sframes_t (*snd_pcm_mmap_commit_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_mmap_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_mmap_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_mmap_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +snd_pcm_sframes_t (*snd_pcm_mmap_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +int (*snd_pcm_format_signed_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_unsigned_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_linear_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_float_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_little_endian_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_big_endian_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_cpu_endian_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_width_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_physical_width_dylibloader_wrapper_asound)( snd_pcm_format_t); +snd_pcm_format_t (*snd_pcm_build_linear_format_dylibloader_wrapper_asound)( int, int, int, int); +ssize_t (*snd_pcm_format_size_dylibloader_wrapper_asound)( snd_pcm_format_t, size_t); +uint8_t (*snd_pcm_format_silence_dylibloader_wrapper_asound)( snd_pcm_format_t); +uint16_t (*snd_pcm_format_silence_16_dylibloader_wrapper_asound)( snd_pcm_format_t); +uint32_t (*snd_pcm_format_silence_32_dylibloader_wrapper_asound)( snd_pcm_format_t); +uint64_t (*snd_pcm_format_silence_64_dylibloader_wrapper_asound)( snd_pcm_format_t); +int (*snd_pcm_format_set_silence_dylibloader_wrapper_asound)( snd_pcm_format_t, void*, unsigned int); +snd_pcm_sframes_t (*snd_pcm_bytes_to_frames_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t); +ssize_t (*snd_pcm_frames_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t); +long (*snd_pcm_bytes_to_samples_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t); +ssize_t (*snd_pcm_samples_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, long); +int (*snd_pcm_area_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t); +int (*snd_pcm_areas_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t); +int (*snd_pcm_area_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t); +int (*snd_pcm_areas_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t); +int (*snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const unsigned int, snd_pcm_uframes_t,const snd_pcm_format_t); +snd_pcm_t* (*snd_pcm_hook_get_pcm_dylibloader_wrapper_asound)( snd_pcm_hook_t*); +void* (*snd_pcm_hook_get_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*); +void (*snd_pcm_hook_set_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*, void*); +int (*snd_pcm_hook_add_dylibloader_wrapper_asound)( snd_pcm_hook_t**, snd_pcm_t*, snd_pcm_hook_type_t, snd_pcm_hook_func_t, void*); +int (*snd_pcm_hook_remove_dylibloader_wrapper_asound)( snd_pcm_hook_t*); +snd_pcm_uframes_t (*snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound)( snd_pcm_t*); +unsigned int (*snd_pcm_meter_get_channels_dylibloader_wrapper_asound)( snd_pcm_t*); +unsigned int (*snd_pcm_meter_get_rate_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_uframes_t (*snd_pcm_meter_get_now_dylibloader_wrapper_asound)( snd_pcm_t*); +snd_pcm_uframes_t (*snd_pcm_meter_get_boundary_dylibloader_wrapper_asound)( snd_pcm_t*); +int (*snd_pcm_meter_add_scope_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_scope_t*); +snd_pcm_scope_t* (*snd_pcm_meter_search_scope_dylibloader_wrapper_asound)( snd_pcm_t*,const char*); +int (*snd_pcm_scope_malloc_dylibloader_wrapper_asound)( snd_pcm_scope_t**); +void (*snd_pcm_scope_set_ops_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const snd_pcm_scope_ops_t*); +void (*snd_pcm_scope_set_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const char*); +const char* (*snd_pcm_scope_get_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*); +void* (*snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*); +void (*snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*, void*); +int (*snd_pcm_scope_s16_open_dylibloader_wrapper_asound)( snd_pcm_t*,const char*, snd_pcm_scope_t**); +int16_t* (*snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound)( snd_pcm_scope_t*, unsigned int); +int (*snd_spcm_init_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t); +int (*snd_spcm_init_duplex_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t, snd_spcm_duplex_type_t); +int (*snd_spcm_init_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int*, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +const char* (*snd_pcm_start_mode_name_dylibloader_wrapper_asound)( snd_pcm_start_t); +const char* (*snd_pcm_xrun_mode_name_dylibloader_wrapper_asound)( snd_pcm_xrun_t); +int (*snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_start_t); +snd_pcm_start_t (*snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*); +int (*snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_xrun_t); +snd_pcm_xrun_t (*snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*); +int (*snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +int (*snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +int (*snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, unsigned int); +int (*snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, unsigned int*); +int (*snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +int (*snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +int (*snd_rawmidi_open_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int); +int (*snd_rawmidi_open_lconf_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int, snd_config_t*); +int (*snd_rawmidi_close_dylibloader_wrapper_asound)( snd_rawmidi_t*); +int (*snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound)( snd_rawmidi_t*); +int (*snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int); +int (*snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_rawmidi_nonblock_dylibloader_wrapper_asound)( snd_rawmidi_t*, int); +size_t (*snd_rawmidi_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_rawmidi_info_malloc_dylibloader_wrapper_asound)( snd_rawmidi_info_t**); +void (*snd_rawmidi_info_free_dylibloader_wrapper_asound)( snd_rawmidi_info_t*); +void (*snd_rawmidi_info_copy_dylibloader_wrapper_asound)( snd_rawmidi_info_t*,const snd_rawmidi_info_t*); +unsigned int (*snd_rawmidi_info_get_device_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +unsigned int (*snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +snd_rawmidi_stream_t (*snd_rawmidi_info_get_stream_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +int (*snd_rawmidi_info_get_card_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +unsigned int (*snd_rawmidi_info_get_flags_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +const char* (*snd_rawmidi_info_get_id_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +const char* (*snd_rawmidi_info_get_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +const char* (*snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +unsigned int (*snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +unsigned int (*snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +void (*snd_rawmidi_info_set_device_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int); +void (*snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int); +void (*snd_rawmidi_info_set_stream_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, snd_rawmidi_stream_t); +int (*snd_rawmidi_info_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_info_t*); +size_t (*snd_rawmidi_params_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_rawmidi_params_malloc_dylibloader_wrapper_asound)( snd_rawmidi_params_t**); +void (*snd_rawmidi_params_free_dylibloader_wrapper_asound)( snd_rawmidi_params_t*); +void (*snd_rawmidi_params_copy_dylibloader_wrapper_asound)( snd_rawmidi_params_t*,const snd_rawmidi_params_t*); +int (*snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t); +size_t (*snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*); +int (*snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t); +size_t (*snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*); +int (*snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, int); +int (*snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*); +int (*snd_rawmidi_params_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*); +int (*snd_rawmidi_params_current_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*); +size_t (*snd_rawmidi_status_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_rawmidi_status_malloc_dylibloader_wrapper_asound)( snd_rawmidi_status_t**); +void (*snd_rawmidi_status_free_dylibloader_wrapper_asound)( snd_rawmidi_status_t*); +void (*snd_rawmidi_status_copy_dylibloader_wrapper_asound)( snd_rawmidi_status_t*,const snd_rawmidi_status_t*); +void (*snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*, snd_htimestamp_t*); +size_t (*snd_rawmidi_status_get_avail_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*); +size_t (*snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*); +int (*snd_rawmidi_status_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_status_t*); +int (*snd_rawmidi_drain_dylibloader_wrapper_asound)( snd_rawmidi_t*); +int (*snd_rawmidi_drop_dylibloader_wrapper_asound)( snd_rawmidi_t*); +ssize_t (*snd_rawmidi_write_dylibloader_wrapper_asound)( snd_rawmidi_t*,const void*, size_t); +ssize_t (*snd_rawmidi_read_dylibloader_wrapper_asound)( snd_rawmidi_t*, void*, size_t); +const char* (*snd_rawmidi_name_dylibloader_wrapper_asound)( snd_rawmidi_t*); +snd_rawmidi_type_t (*snd_rawmidi_type_dylibloader_wrapper_asound)( snd_rawmidi_t*); +snd_rawmidi_stream_t (*snd_rawmidi_stream_dylibloader_wrapper_asound)( snd_rawmidi_t*); +int (*snd_timer_query_open_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int); +int (*snd_timer_query_open_lconf_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int, snd_config_t*); +int (*snd_timer_query_close_dylibloader_wrapper_asound)( snd_timer_query_t*); +int (*snd_timer_query_next_device_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_id_t*); +int (*snd_timer_query_info_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_ginfo_t*); +int (*snd_timer_query_params_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gparams_t*); +int (*snd_timer_query_status_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gstatus_t*); +int (*snd_timer_open_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int); +int (*snd_timer_open_lconf_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int, snd_config_t*); +int (*snd_timer_close_dylibloader_wrapper_asound)( snd_timer_t*); +int (*snd_async_add_timer_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_timer_t*, snd_async_callback_t, void*); +snd_timer_t* (*snd_async_handler_get_timer_dylibloader_wrapper_asound)( snd_async_handler_t*); +int (*snd_timer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_timer_t*); +int (*snd_timer_poll_descriptors_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int); +int (*snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_timer_info_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_info_t*); +int (*snd_timer_params_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_params_t*); +int (*snd_timer_status_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_status_t*); +int (*snd_timer_start_dylibloader_wrapper_asound)( snd_timer_t*); +int (*snd_timer_stop_dylibloader_wrapper_asound)( snd_timer_t*); +int (*snd_timer_continue_dylibloader_wrapper_asound)( snd_timer_t*); +ssize_t (*snd_timer_read_dylibloader_wrapper_asound)( snd_timer_t*, void*, size_t); +size_t (*snd_timer_id_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_timer_id_malloc_dylibloader_wrapper_asound)( snd_timer_id_t**); +void (*snd_timer_id_free_dylibloader_wrapper_asound)( snd_timer_id_t*); +void (*snd_timer_id_copy_dylibloader_wrapper_asound)( snd_timer_id_t*,const snd_timer_id_t*); +void (*snd_timer_id_set_class_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +int (*snd_timer_id_get_class_dylibloader_wrapper_asound)( snd_timer_id_t*); +void (*snd_timer_id_set_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +int (*snd_timer_id_get_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*); +void (*snd_timer_id_set_card_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +int (*snd_timer_id_get_card_dylibloader_wrapper_asound)( snd_timer_id_t*); +void (*snd_timer_id_set_device_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +int (*snd_timer_id_get_device_dylibloader_wrapper_asound)( snd_timer_id_t*); +void (*snd_timer_id_set_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +int (*snd_timer_id_get_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*); +size_t (*snd_timer_ginfo_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_timer_ginfo_malloc_dylibloader_wrapper_asound)( snd_timer_ginfo_t**); +void (*snd_timer_ginfo_free_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +void (*snd_timer_ginfo_copy_dylibloader_wrapper_asound)( snd_timer_ginfo_t*,const snd_timer_ginfo_t*); +int (*snd_timer_ginfo_set_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*, snd_timer_id_t*); +snd_timer_id_t* (*snd_timer_ginfo_get_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +unsigned int (*snd_timer_ginfo_get_flags_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +int (*snd_timer_ginfo_get_card_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +char* (*snd_timer_ginfo_get_id_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +char* (*snd_timer_ginfo_get_name_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +unsigned long (*snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +unsigned long (*snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +unsigned long (*snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +unsigned int (*snd_timer_ginfo_get_clients_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +size_t (*snd_timer_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_timer_info_malloc_dylibloader_wrapper_asound)( snd_timer_info_t**); +void (*snd_timer_info_free_dylibloader_wrapper_asound)( snd_timer_info_t*); +void (*snd_timer_info_copy_dylibloader_wrapper_asound)( snd_timer_info_t*,const snd_timer_info_t*); +int (*snd_timer_info_is_slave_dylibloader_wrapper_asound)( snd_timer_info_t*); +int (*snd_timer_info_get_card_dylibloader_wrapper_asound)( snd_timer_info_t*); +const char* (*snd_timer_info_get_id_dylibloader_wrapper_asound)( snd_timer_info_t*); +const char* (*snd_timer_info_get_name_dylibloader_wrapper_asound)( snd_timer_info_t*); +long (*snd_timer_info_get_resolution_dylibloader_wrapper_asound)( snd_timer_info_t*); +size_t (*snd_timer_params_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_timer_params_malloc_dylibloader_wrapper_asound)( snd_timer_params_t**); +void (*snd_timer_params_free_dylibloader_wrapper_asound)( snd_timer_params_t*); +void (*snd_timer_params_copy_dylibloader_wrapper_asound)( snd_timer_params_t*,const snd_timer_params_t*); +int (*snd_timer_params_set_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*, int); +int (*snd_timer_params_get_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*); +int (*snd_timer_params_set_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*, int); +int (*snd_timer_params_get_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*); +int (*snd_timer_params_set_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*, int); +int (*snd_timer_params_get_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*); +void (*snd_timer_params_set_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*, long); +long (*snd_timer_params_get_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*); +void (*snd_timer_params_set_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*, long); +long (*snd_timer_params_get_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*); +void (*snd_timer_params_set_filter_dylibloader_wrapper_asound)( snd_timer_params_t*, unsigned int); +unsigned int (*snd_timer_params_get_filter_dylibloader_wrapper_asound)( snd_timer_params_t*); +size_t (*snd_timer_status_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_timer_status_malloc_dylibloader_wrapper_asound)( snd_timer_status_t**); +void (*snd_timer_status_free_dylibloader_wrapper_asound)( snd_timer_status_t*); +void (*snd_timer_status_copy_dylibloader_wrapper_asound)( snd_timer_status_t*,const snd_timer_status_t*); +snd_htimestamp_t (*snd_timer_status_get_timestamp_dylibloader_wrapper_asound)( snd_timer_status_t*); +long (*snd_timer_status_get_resolution_dylibloader_wrapper_asound)( snd_timer_status_t*); +long (*snd_timer_status_get_lost_dylibloader_wrapper_asound)( snd_timer_status_t*); +long (*snd_timer_status_get_overrun_dylibloader_wrapper_asound)( snd_timer_status_t*); +long (*snd_timer_status_get_queue_dylibloader_wrapper_asound)( snd_timer_status_t*); +long (*snd_timer_info_get_ticks_dylibloader_wrapper_asound)( snd_timer_info_t*); +int (*snd_hwdep_open_dylibloader_wrapper_asound)( snd_hwdep_t**,const char*, int); +int (*snd_hwdep_close_dylibloader_wrapper_asound)( snd_hwdep_t*); +int (*snd_hwdep_poll_descriptors_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int); +int (*snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hwdep_t*); +int (*snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_hwdep_nonblock_dylibloader_wrapper_asound)( snd_hwdep_t*, int); +int (*snd_hwdep_info_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_info_t*); +int (*snd_hwdep_dsp_status_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_status_t*); +int (*snd_hwdep_dsp_load_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_image_t*); +int (*snd_hwdep_ioctl_dylibloader_wrapper_asound)( snd_hwdep_t*, unsigned int, void*); +ssize_t (*snd_hwdep_write_dylibloader_wrapper_asound)( snd_hwdep_t*,const void*, size_t); +ssize_t (*snd_hwdep_read_dylibloader_wrapper_asound)( snd_hwdep_t*, void*, size_t); +size_t (*snd_hwdep_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_hwdep_info_malloc_dylibloader_wrapper_asound)( snd_hwdep_info_t**); +void (*snd_hwdep_info_free_dylibloader_wrapper_asound)( snd_hwdep_info_t*); +void (*snd_hwdep_info_copy_dylibloader_wrapper_asound)( snd_hwdep_info_t*,const snd_hwdep_info_t*); +unsigned int (*snd_hwdep_info_get_device_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +int (*snd_hwdep_info_get_card_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +const char* (*snd_hwdep_info_get_id_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +const char* (*snd_hwdep_info_get_name_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +snd_hwdep_iface_t (*snd_hwdep_info_get_iface_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +void (*snd_hwdep_info_set_device_dylibloader_wrapper_asound)( snd_hwdep_info_t*, unsigned int); +size_t (*snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t**); +void (*snd_hwdep_dsp_status_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*); +void (*snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*,const snd_hwdep_dsp_status_t*); +unsigned int (*snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +const char* (*snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +unsigned int (*snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +unsigned int (*snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +unsigned int (*snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +size_t (*snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t**); +void (*snd_hwdep_dsp_image_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*); +void (*snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const snd_hwdep_dsp_image_t*); +unsigned int (*snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +const char* (*snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +const void* (*snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +size_t (*snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +void (*snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, unsigned int); +void (*snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const char*); +void (*snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, void*); +void (*snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, size_t); +int (*snd_card_load_dylibloader_wrapper_asound)( int); +int (*snd_card_next_dylibloader_wrapper_asound)( int*); +int (*snd_card_get_index_dylibloader_wrapper_asound)(const char*); +int (*snd_card_get_name_dylibloader_wrapper_asound)( int, char**); +int (*snd_card_get_longname_dylibloader_wrapper_asound)( int, char**); +int (*snd_device_name_hint_dylibloader_wrapper_asound)( int,const char*, void***); +int (*snd_device_name_free_hint_dylibloader_wrapper_asound)( void**); +char* (*snd_device_name_get_hint_dylibloader_wrapper_asound)(const void*,const char*); +int (*snd_ctl_open_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int); +int (*snd_ctl_open_lconf_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int, snd_config_t*); +int (*snd_ctl_open_fallback_dylibloader_wrapper_asound)( snd_ctl_t**, snd_config_t*,const char*,const char*, int); +int (*snd_ctl_close_dylibloader_wrapper_asound)( snd_ctl_t*); +int (*snd_ctl_nonblock_dylibloader_wrapper_asound)( snd_ctl_t*, int); +int (*snd_async_add_ctl_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_ctl_t*, snd_async_callback_t, void*); +snd_ctl_t* (*snd_async_handler_get_ctl_dylibloader_wrapper_asound)( snd_async_handler_t*); +int (*snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_ctl_t*); +int (*snd_ctl_poll_descriptors_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int); +int (*snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_ctl_subscribe_events_dylibloader_wrapper_asound)( snd_ctl_t*, int); +int (*snd_ctl_card_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_card_info_t*); +int (*snd_ctl_elem_list_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_list_t*); +int (*snd_ctl_elem_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*); +int (*snd_ctl_elem_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*); +int (*snd_ctl_elem_write_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*); +int (*snd_ctl_elem_lock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*); +int (*snd_ctl_elem_unlock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*); +int (*snd_ctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int*, unsigned int); +int (*snd_ctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*); +int (*snd_ctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*); +int (*snd_ctl_hwdep_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*); +int (*snd_ctl_hwdep_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_hwdep_info_t*); +int (*snd_ctl_pcm_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*); +int (*snd_ctl_pcm_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_pcm_info_t*); +int (*snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int); +int (*snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*); +int (*snd_ctl_rawmidi_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_rawmidi_info_t*); +int (*snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int); +int (*snd_ctl_set_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int); +int (*snd_ctl_get_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int*); +int (*snd_ctl_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_event_t*); +int (*snd_ctl_wait_dylibloader_wrapper_asound)( snd_ctl_t*, int); +const char* (*snd_ctl_name_dylibloader_wrapper_asound)( snd_ctl_t*); +snd_ctl_type_t (*snd_ctl_type_dylibloader_wrapper_asound)( snd_ctl_t*); +const char* (*snd_ctl_elem_type_name_dylibloader_wrapper_asound)( snd_ctl_elem_type_t); +const char* (*snd_ctl_elem_iface_name_dylibloader_wrapper_asound)( snd_ctl_elem_iface_t); +const char* (*snd_ctl_event_type_name_dylibloader_wrapper_asound)( snd_ctl_event_type_t); +unsigned int (*snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +unsigned int (*snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +void (*snd_ctl_event_elem_get_id_dylibloader_wrapper_asound)(const snd_ctl_event_t*, snd_ctl_elem_id_t*); +snd_ctl_elem_iface_t (*snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +unsigned int (*snd_ctl_event_elem_get_device_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +unsigned int (*snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +const char* (*snd_ctl_event_elem_get_name_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +unsigned int (*snd_ctl_event_elem_get_index_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +int (*snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int); +void (*snd_ctl_elem_list_free_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*); +char* (*snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*); +int (*snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*); +int (*snd_ctl_ascii_value_parse_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*, snd_ctl_elem_info_t*,const char*); +size_t (*snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_ctl_elem_id_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_id_t**); +void (*snd_ctl_elem_id_free_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*); +void (*snd_ctl_elem_id_clear_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*); +void (*snd_ctl_elem_id_copy_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +snd_ctl_elem_iface_t (*snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_id_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +const char* (*snd_ctl_elem_id_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_id_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +void (*snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +void (*snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, snd_ctl_elem_iface_t); +void (*snd_ctl_elem_id_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +void (*snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +void (*snd_ctl_elem_id_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*); +void (*snd_ctl_elem_id_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +size_t (*snd_ctl_card_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_ctl_card_info_malloc_dylibloader_wrapper_asound)( snd_ctl_card_info_t**); +void (*snd_ctl_card_info_free_dylibloader_wrapper_asound)( snd_ctl_card_info_t*); +void (*snd_ctl_card_info_clear_dylibloader_wrapper_asound)( snd_ctl_card_info_t*); +void (*snd_ctl_card_info_copy_dylibloader_wrapper_asound)( snd_ctl_card_info_t*,const snd_ctl_card_info_t*); +int (*snd_ctl_card_info_get_card_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +const char* (*snd_ctl_card_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +const char* (*snd_ctl_card_info_get_driver_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +const char* (*snd_ctl_card_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +const char* (*snd_ctl_card_info_get_longname_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +const char* (*snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +const char* (*snd_ctl_card_info_get_components_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +size_t (*snd_ctl_event_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_ctl_event_malloc_dylibloader_wrapper_asound)( snd_ctl_event_t**); +void (*snd_ctl_event_free_dylibloader_wrapper_asound)( snd_ctl_event_t*); +void (*snd_ctl_event_clear_dylibloader_wrapper_asound)( snd_ctl_event_t*); +void (*snd_ctl_event_copy_dylibloader_wrapper_asound)( snd_ctl_event_t*,const snd_ctl_event_t*); +snd_ctl_event_type_t (*snd_ctl_event_get_type_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +size_t (*snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_ctl_elem_list_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_list_t**); +void (*snd_ctl_elem_list_free_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*); +void (*snd_ctl_elem_list_clear_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*); +void (*snd_ctl_elem_list_copy_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*,const snd_ctl_elem_list_t*); +void (*snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int); +unsigned int (*snd_ctl_elem_list_get_used_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*); +unsigned int (*snd_ctl_elem_list_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*); +void (*snd_ctl_elem_list_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int, snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +snd_ctl_elem_iface_t (*snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +unsigned int (*snd_ctl_elem_list_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +unsigned int (*snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +const char* (*snd_ctl_elem_list_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +unsigned int (*snd_ctl_elem_list_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +size_t (*snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_ctl_elem_info_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_info_t**); +void (*snd_ctl_elem_info_free_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*); +void (*snd_ctl_elem_info_clear_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*); +void (*snd_ctl_elem_info_copy_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_info_t*); +snd_ctl_elem_type_t (*snd_ctl_elem_info_get_type_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_is_user_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +pid_t (*snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +unsigned int (*snd_ctl_elem_info_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +long (*snd_ctl_elem_info_get_min_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +long (*snd_ctl_elem_info_get_max_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +long (*snd_ctl_elem_info_get_step_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +long long (*snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +long long (*snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +long long (*snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +unsigned int (*snd_ctl_elem_info_get_items_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +void (*snd_ctl_elem_info_set_item_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +const char* (*snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +int (*snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, unsigned int); +int (*snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const int [4]); +void (*snd_ctl_elem_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +snd_ctl_elem_iface_t (*snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +unsigned int (*snd_ctl_elem_info_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +unsigned int (*snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +const char* (*snd_ctl_elem_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +unsigned int (*snd_ctl_elem_info_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +void (*snd_ctl_elem_info_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_id_t*); +void (*snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +void (*snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, snd_ctl_elem_iface_t); +void (*snd_ctl_elem_info_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +void (*snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +void (*snd_ctl_elem_info_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const char*); +void (*snd_ctl_elem_info_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +int (*snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long, long, long); +int (*snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long long, long long, long long); +int (*snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int); +int (*snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, unsigned int,const char* []); +int (*snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int); +int (*snd_ctl_elem_add_integer_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long, long, long); +int (*snd_ctl_elem_add_integer64_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long long, long long, long long); +int (*snd_ctl_elem_add_boolean_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int); +int (*snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, unsigned int,const char* []); +int (*snd_ctl_elem_add_iec958_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*); +int (*snd_ctl_elem_remove_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*); +size_t (*snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_ctl_elem_value_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_value_t**); +void (*snd_ctl_elem_value_free_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*); +void (*snd_ctl_elem_value_clear_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*); +void (*snd_ctl_elem_value_copy_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*); +int (*snd_ctl_elem_value_compare_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*); +void (*snd_ctl_elem_value_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_ctl_elem_id_t*); +unsigned int (*snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +snd_ctl_elem_iface_t (*snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +unsigned int (*snd_ctl_elem_value_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +unsigned int (*snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +const char* (*snd_ctl_elem_value_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +unsigned int (*snd_ctl_elem_value_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +void (*snd_ctl_elem_value_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_id_t*); +void (*snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +void (*snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, snd_ctl_elem_iface_t); +void (*snd_ctl_elem_value_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +void (*snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +void (*snd_ctl_elem_value_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const char*); +void (*snd_ctl_elem_value_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +int (*snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +long (*snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +long long (*snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +unsigned int (*snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +unsigned char (*snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +void (*snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long); +void (*snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long); +void (*snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long long); +void (*snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned int); +void (*snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned char); +void (*snd_ctl_elem_set_bytes_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, void*, size_t); +const void* (*snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +void (*snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_aes_iec958_t*); +void (*snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_aes_iec958_t*); +int (*snd_tlv_parse_dB_info_dylibloader_wrapper_asound)( unsigned int*, unsigned int, unsigned int**); +int (*snd_tlv_get_dB_range_dylibloader_wrapper_asound)( unsigned int*, long, long, long*, long*); +int (*snd_tlv_convert_to_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*); +int (*snd_tlv_convert_from_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*, int); +int (*snd_ctl_get_dB_range_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long*, long*); +int (*snd_ctl_convert_to_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*); +int (*snd_ctl_convert_from_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*, int); +int (*snd_hctl_compare_fast_dylibloader_wrapper_asound)(const snd_hctl_elem_t*,const snd_hctl_elem_t*); +int (*snd_hctl_open_dylibloader_wrapper_asound)( snd_hctl_t**,const char*, int); +int (*snd_hctl_open_ctl_dylibloader_wrapper_asound)( snd_hctl_t**, snd_ctl_t*); +int (*snd_hctl_close_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_nonblock_dylibloader_wrapper_asound)( snd_hctl_t*, int); +int (*snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_poll_descriptors_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int); +int (*snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int, unsigned short*); +unsigned int (*snd_hctl_get_count_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_set_compare_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_compare_t); +snd_hctl_elem_t* (*snd_hctl_first_elem_dylibloader_wrapper_asound)( snd_hctl_t*); +snd_hctl_elem_t* (*snd_hctl_last_elem_dylibloader_wrapper_asound)( snd_hctl_t*); +snd_hctl_elem_t* (*snd_hctl_find_elem_dylibloader_wrapper_asound)( snd_hctl_t*,const snd_ctl_elem_id_t*); +void (*snd_hctl_set_callback_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_callback_t); +void (*snd_hctl_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*, void*); +void* (*snd_hctl_get_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_load_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_free_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_handle_events_dylibloader_wrapper_asound)( snd_hctl_t*); +const char* (*snd_hctl_name_dylibloader_wrapper_asound)( snd_hctl_t*); +int (*snd_hctl_wait_dylibloader_wrapper_asound)( snd_hctl_t*, int); +snd_ctl_t* (*snd_hctl_ctl_dylibloader_wrapper_asound)( snd_hctl_t*); +snd_hctl_elem_t* (*snd_hctl_elem_next_dylibloader_wrapper_asound)( snd_hctl_elem_t*); +snd_hctl_elem_t* (*snd_hctl_elem_prev_dylibloader_wrapper_asound)( snd_hctl_elem_t*); +int (*snd_hctl_elem_info_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_info_t*); +int (*snd_hctl_elem_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*); +int (*snd_hctl_elem_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*); +int (*snd_hctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, unsigned int*, unsigned int); +int (*snd_hctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*); +int (*snd_hctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*); +snd_hctl_t* (*snd_hctl_elem_get_hctl_dylibloader_wrapper_asound)( snd_hctl_elem_t*); +void (*snd_hctl_elem_get_id_dylibloader_wrapper_asound)(const snd_hctl_elem_t*, snd_ctl_elem_id_t*); +unsigned int (*snd_hctl_elem_get_numid_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +snd_ctl_elem_iface_t (*snd_hctl_elem_get_interface_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +unsigned int (*snd_hctl_elem_get_device_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +unsigned int (*snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +const char* (*snd_hctl_elem_get_name_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +unsigned int (*snd_hctl_elem_get_index_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +void (*snd_hctl_elem_set_callback_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_hctl_elem_callback_t); +void* (*snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +void (*snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_elem_t*, void*); +int (*snd_sctl_build_dylibloader_wrapper_asound)( snd_sctl_t**, snd_ctl_t*, snd_config_t*, snd_config_t*, int); +int (*snd_sctl_free_dylibloader_wrapper_asound)( snd_sctl_t*); +int (*snd_sctl_install_dylibloader_wrapper_asound)( snd_sctl_t*); +int (*snd_sctl_remove_dylibloader_wrapper_asound)( snd_sctl_t*); +int (*snd_mixer_open_dylibloader_wrapper_asound)( snd_mixer_t**, int); +int (*snd_mixer_close_dylibloader_wrapper_asound)( snd_mixer_t*); +snd_mixer_elem_t* (*snd_mixer_first_elem_dylibloader_wrapper_asound)( snd_mixer_t*); +snd_mixer_elem_t* (*snd_mixer_last_elem_dylibloader_wrapper_asound)( snd_mixer_t*); +int (*snd_mixer_handle_events_dylibloader_wrapper_asound)( snd_mixer_t*); +int (*snd_mixer_attach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*); +int (*snd_mixer_attach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*); +int (*snd_mixer_detach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*); +int (*snd_mixer_detach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*); +int (*snd_mixer_get_hctl_dylibloader_wrapper_asound)( snd_mixer_t*,const char*, snd_hctl_t**); +int (*snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_mixer_t*); +int (*snd_mixer_poll_descriptors_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int); +int (*snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_mixer_load_dylibloader_wrapper_asound)( snd_mixer_t*); +void (*snd_mixer_free_dylibloader_wrapper_asound)( snd_mixer_t*); +int (*snd_mixer_wait_dylibloader_wrapper_asound)( snd_mixer_t*, int); +int (*snd_mixer_set_compare_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_compare_t); +void (*snd_mixer_set_callback_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_callback_t); +void* (*snd_mixer_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_t*); +void (*snd_mixer_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_t*, void*); +unsigned int (*snd_mixer_get_count_dylibloader_wrapper_asound)(const snd_mixer_t*); +int (*snd_mixer_class_unregister_dylibloader_wrapper_asound)( snd_mixer_class_t*); +snd_mixer_elem_t* (*snd_mixer_elem_next_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +snd_mixer_elem_t* (*snd_mixer_elem_prev_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +void (*snd_mixer_elem_set_callback_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_elem_callback_t); +void* (*snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*); +void (*snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_elem_t*, void*); +snd_mixer_elem_type_t (*snd_mixer_elem_get_type_dylibloader_wrapper_asound)(const snd_mixer_elem_t*); +int (*snd_mixer_class_register_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_t*); +int (*snd_mixer_elem_new_dylibloader_wrapper_asound)( snd_mixer_elem_t**, snd_mixer_elem_type_t, int, void*, void*); +int (*snd_mixer_elem_add_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_class_t*); +int (*snd_mixer_elem_remove_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +void (*snd_mixer_elem_free_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_elem_info_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_elem_value_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_elem_attach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*); +int (*snd_mixer_elem_detach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*); +int (*snd_mixer_elem_empty_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +void* (*snd_mixer_elem_get_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*); +size_t (*snd_mixer_class_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_mixer_class_malloc_dylibloader_wrapper_asound)( snd_mixer_class_t**); +void (*snd_mixer_class_free_dylibloader_wrapper_asound)( snd_mixer_class_t*); +void (*snd_mixer_class_copy_dylibloader_wrapper_asound)( snd_mixer_class_t*,const snd_mixer_class_t*); +snd_mixer_t* (*snd_mixer_class_get_mixer_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +snd_mixer_event_t (*snd_mixer_class_get_event_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +void* (*snd_mixer_class_get_private_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +snd_mixer_compare_t (*snd_mixer_class_get_compare_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +int (*snd_mixer_class_set_event_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_event_t); +int (*snd_mixer_class_set_private_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*); +int (*snd_mixer_class_set_private_free_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*); +int (*snd_mixer_class_set_compare_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_compare_t); +const char* (*snd_mixer_selem_channel_name_dylibloader_wrapper_asound)( snd_mixer_selem_channel_id_t); +int (*snd_mixer_selem_register_dylibloader_wrapper_asound)( snd_mixer_t*,struct snd_mixer_selem_regopt*, snd_mixer_class_t**); +void (*snd_mixer_selem_get_id_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_id_t*); +const char* (*snd_mixer_selem_get_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +unsigned int (*snd_mixer_selem_get_index_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +snd_mixer_elem_t* (*snd_mixer_find_selem_dylibloader_wrapper_asound)( snd_mixer_t*,const snd_mixer_selem_id_t*); +int (*snd_mixer_selem_is_active_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t); +int (*snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t); +int (*snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*); +int (*snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*); +int (*snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*); +int (*snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*); +int (*snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +int (*snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +int (*snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +int (*snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +int (*snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*); +int (*snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*); +int (*snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long); +int (*snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long); +int (*snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int); +int (*snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int); +int (*snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long); +int (*snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long); +int (*snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int); +int (*snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int); +int (*snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int); +int (*snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int); +int (*snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int); +int (*snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int); +int (*snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +int (*snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +int (*snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long); +int (*snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +int (*snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +int (*snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long); +int (*snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +int (*snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*, unsigned int, size_t, char*); +int (*snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int*); +int (*snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int); +size_t (*snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_mixer_selem_id_malloc_dylibloader_wrapper_asound)( snd_mixer_selem_id_t**); +void (*snd_mixer_selem_id_free_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*); +void (*snd_mixer_selem_id_copy_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const snd_mixer_selem_id_t*); +const char* (*snd_mixer_selem_id_get_name_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*); +unsigned int (*snd_mixer_selem_id_get_index_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*); +void (*snd_mixer_selem_id_set_name_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*); +void (*snd_mixer_selem_id_set_index_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*, unsigned int); +int (*snd_mixer_selem_id_parse_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*); +int (*snd_seq_open_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int); +int (*snd_seq_open_lconf_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int, snd_config_t*); +const char* (*snd_seq_name_dylibloader_wrapper_asound)( snd_seq_t*); +snd_seq_type_t (*snd_seq_type_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_close_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_poll_descriptors_count_dylibloader_wrapper_asound)( snd_seq_t*, short); +int (*snd_seq_poll_descriptors_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, short); +int (*snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, unsigned short*); +int (*snd_seq_nonblock_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_client_id_dylibloader_wrapper_asound)( snd_seq_t*); +size_t (*snd_seq_get_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*); +size_t (*snd_seq_get_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_set_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +int (*snd_seq_set_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +size_t (*snd_seq_system_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_system_info_malloc_dylibloader_wrapper_asound)( snd_seq_system_info_t**); +void (*snd_seq_system_info_free_dylibloader_wrapper_asound)( snd_seq_system_info_t*); +void (*snd_seq_system_info_copy_dylibloader_wrapper_asound)( snd_seq_system_info_t*,const snd_seq_system_info_t*); +int (*snd_seq_system_info_get_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +int (*snd_seq_system_info_get_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +int (*snd_seq_system_info_get_ports_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +int (*snd_seq_system_info_get_channels_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +int (*snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +int (*snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +int (*snd_seq_system_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_system_info_t*); +size_t (*snd_seq_client_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_client_info_malloc_dylibloader_wrapper_asound)( snd_seq_client_info_t**); +void (*snd_seq_client_info_free_dylibloader_wrapper_asound)( snd_seq_client_info_t*); +void (*snd_seq_client_info_copy_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const snd_seq_client_info_t*); +int (*snd_seq_client_info_get_client_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +snd_seq_client_type_t (*snd_seq_client_info_get_type_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +const char* (*snd_seq_client_info_get_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*); +int (*snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +int (*snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +int (*snd_seq_client_info_get_card_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +int (*snd_seq_client_info_get_pid_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +const unsigned char* (*snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +int (*snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +int (*snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +void (*snd_seq_client_info_set_client_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +void (*snd_seq_client_info_set_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const char*); +void (*snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +void (*snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +void (*snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, unsigned char*); +void (*snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound)( snd_seq_client_info_t*); +void (*snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +void (*snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +int (*snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +int (*snd_seq_get_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*); +int (*snd_seq_get_any_client_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_client_info_t*); +int (*snd_seq_set_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*); +int (*snd_seq_query_next_client_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*); +size_t (*snd_seq_client_pool_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_client_pool_malloc_dylibloader_wrapper_asound)( snd_seq_client_pool_t**); +void (*snd_seq_client_pool_free_dylibloader_wrapper_asound)( snd_seq_client_pool_t*); +void (*snd_seq_client_pool_copy_dylibloader_wrapper_asound)( snd_seq_client_pool_t*,const snd_seq_client_pool_t*); +int (*snd_seq_client_pool_get_client_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +size_t (*snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +size_t (*snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +size_t (*snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +size_t (*snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +size_t (*snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +void (*snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t); +void (*snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t); +void (*snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t); +int (*snd_seq_get_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*); +int (*snd_seq_set_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*); +size_t (*snd_seq_port_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_port_info_malloc_dylibloader_wrapper_asound)( snd_seq_port_info_t**); +void (*snd_seq_port_info_free_dylibloader_wrapper_asound)( snd_seq_port_info_t*); +void (*snd_seq_port_info_copy_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_client_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_port_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +const snd_seq_addr_t* (*snd_seq_port_info_get_addr_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +const char* (*snd_seq_port_info_get_name_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +unsigned int (*snd_seq_port_info_get_capability_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +unsigned int (*snd_seq_port_info_get_type_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_read_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_write_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +int (*snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +void (*snd_seq_port_info_set_client_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_port_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_addr_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_addr_t*); +void (*snd_seq_port_info_set_name_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const char*); +void (*snd_seq_port_info_set_capability_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int); +void (*snd_seq_port_info_set_type_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int); +void (*snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +void (*snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +int (*snd_seq_create_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*); +int (*snd_seq_delete_port_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_get_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*); +int (*snd_seq_get_any_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, int, snd_seq_port_info_t*); +int (*snd_seq_set_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*); +int (*snd_seq_query_next_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*); +size_t (*snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t**); +void (*snd_seq_port_subscribe_free_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*); +void (*snd_seq_port_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_port_subscribe_t*); +const snd_seq_addr_t* (*snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +const snd_seq_addr_t* (*snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +int (*snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +int (*snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +int (*snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +int (*snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +void (*snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*); +void (*snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*); +void (*snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +void (*snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +void (*snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +void (*snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +int (*snd_seq_get_port_subscription_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*); +int (*snd_seq_subscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*); +int (*snd_seq_unsubscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*); +size_t (*snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t**); +void (*snd_seq_query_subscribe_free_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*); +void (*snd_seq_query_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +const snd_seq_addr_t* (*snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +snd_seq_query_subs_type_t (*snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +const snd_seq_addr_t* (*snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +int (*snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +void (*snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int); +void (*snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int); +void (*snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_addr_t*); +void (*snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, snd_seq_query_subs_type_t); +void (*snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int); +int (*snd_seq_query_port_subscribers_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_query_subscribe_t*); +size_t (*snd_seq_queue_info_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_queue_info_malloc_dylibloader_wrapper_asound)( snd_seq_queue_info_t**); +void (*snd_seq_queue_info_free_dylibloader_wrapper_asound)( snd_seq_queue_info_t*); +void (*snd_seq_queue_info_copy_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const snd_seq_queue_info_t*); +int (*snd_seq_queue_info_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +const char* (*snd_seq_queue_info_get_name_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +int (*snd_seq_queue_info_get_owner_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +int (*snd_seq_queue_info_get_locked_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +unsigned int (*snd_seq_queue_info_get_flags_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +void (*snd_seq_queue_info_set_name_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const char*); +void (*snd_seq_queue_info_set_owner_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int); +void (*snd_seq_queue_info_set_locked_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int); +void (*snd_seq_queue_info_set_flags_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, unsigned int); +int (*snd_seq_create_queue_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_queue_info_t*); +int (*snd_seq_alloc_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*); +int (*snd_seq_alloc_queue_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_free_queue_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_get_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*); +int (*snd_seq_set_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*); +int (*snd_seq_query_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*); +int (*snd_seq_get_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_set_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int, int); +size_t (*snd_seq_queue_status_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_queue_status_malloc_dylibloader_wrapper_asound)( snd_seq_queue_status_t**); +void (*snd_seq_queue_status_free_dylibloader_wrapper_asound)( snd_seq_queue_status_t*); +void (*snd_seq_queue_status_copy_dylibloader_wrapper_asound)( snd_seq_queue_status_t*,const snd_seq_queue_status_t*); +int (*snd_seq_queue_status_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +int (*snd_seq_queue_status_get_events_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +snd_seq_tick_time_t (*snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +const snd_seq_real_time_t* (*snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +unsigned int (*snd_seq_queue_status_get_status_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +int (*snd_seq_get_queue_status_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_status_t*); +size_t (*snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t**); +void (*snd_seq_queue_tempo_free_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*); +void (*snd_seq_queue_tempo_copy_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*,const snd_seq_queue_tempo_t*); +int (*snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +unsigned int (*snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +int (*snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +unsigned int (*snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +unsigned int (*snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +void (*snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int); +void (*snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, int); +void (*snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int); +void (*snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int); +int (*snd_seq_get_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*); +int (*snd_seq_set_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*); +size_t (*snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_queue_timer_malloc_dylibloader_wrapper_asound)( snd_seq_queue_timer_t**); +void (*snd_seq_queue_timer_free_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*); +void (*snd_seq_queue_timer_copy_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_seq_queue_timer_t*); +int (*snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +snd_seq_queue_timer_type_t (*snd_seq_queue_timer_get_type_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +const snd_timer_id_t* (*snd_seq_queue_timer_get_id_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +unsigned int (*snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +void (*snd_seq_queue_timer_set_type_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, snd_seq_queue_timer_type_t); +void (*snd_seq_queue_timer_set_id_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_timer_id_t*); +void (*snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, unsigned int); +int (*snd_seq_get_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*); +int (*snd_seq_set_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*); +int (*snd_seq_free_event_dylibloader_wrapper_asound)( snd_seq_event_t*); +ssize_t (*snd_seq_event_length_dylibloader_wrapper_asound)( snd_seq_event_t*); +int (*snd_seq_event_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*); +int (*snd_seq_event_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*); +int (*snd_seq_event_output_direct_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*); +int (*snd_seq_event_input_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**); +int (*snd_seq_event_input_pending_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_drain_output_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_event_output_pending_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_extract_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**); +int (*snd_seq_drop_output_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_drop_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_drop_input_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_drop_input_buffer_dylibloader_wrapper_asound)( snd_seq_t*); +size_t (*snd_seq_remove_events_sizeof_dylibloader_wrapper_asound)( void); +int (*snd_seq_remove_events_malloc_dylibloader_wrapper_asound)( snd_seq_remove_events_t**); +void (*snd_seq_remove_events_free_dylibloader_wrapper_asound)( snd_seq_remove_events_t*); +void (*snd_seq_remove_events_copy_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_remove_events_t*); +unsigned int (*snd_seq_remove_events_get_condition_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +int (*snd_seq_remove_events_get_queue_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +const snd_seq_timestamp_t* (*snd_seq_remove_events_get_time_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +const snd_seq_addr_t* (*snd_seq_remove_events_get_dest_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +int (*snd_seq_remove_events_get_channel_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +int (*snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +int (*snd_seq_remove_events_get_tag_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +void (*snd_seq_remove_events_set_condition_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, unsigned int); +void (*snd_seq_remove_events_set_queue_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +void (*snd_seq_remove_events_set_time_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_timestamp_t*); +void (*snd_seq_remove_events_set_dest_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_addr_t*); +void (*snd_seq_remove_events_set_channel_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +void (*snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +void (*snd_seq_remove_events_set_tag_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +int (*snd_seq_remove_events_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_remove_events_t*); +void (*snd_seq_set_bit_dylibloader_wrapper_asound)( int, void*); +void (*snd_seq_unset_bit_dylibloader_wrapper_asound)( int, void*); +int (*snd_seq_change_bit_dylibloader_wrapper_asound)( int, void*); +int (*snd_seq_get_bit_dylibloader_wrapper_asound)( int, void*); +int (*snd_seq_control_queue_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int, snd_seq_event_t*); +int (*snd_seq_create_simple_port_dylibloader_wrapper_asound)( snd_seq_t*,const char*, unsigned int, unsigned int); +int (*snd_seq_delete_simple_port_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_connect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +int (*snd_seq_connect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +int (*snd_seq_disconnect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +int (*snd_seq_disconnect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +int (*snd_seq_set_client_name_dylibloader_wrapper_asound)( snd_seq_t*,const char*); +int (*snd_seq_set_client_event_filter_dylibloader_wrapper_asound)( snd_seq_t*, int); +int (*snd_seq_set_client_pool_output_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +int (*snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +int (*snd_seq_set_client_pool_input_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +int (*snd_seq_sync_output_queue_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_parse_address_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_addr_t*,const char*); +int (*snd_seq_reset_pool_output_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_seq_reset_pool_input_dylibloader_wrapper_asound)( snd_seq_t*); +int (*snd_midi_event_new_dylibloader_wrapper_asound)( size_t, snd_midi_event_t**); +int (*snd_midi_event_resize_buffer_dylibloader_wrapper_asound)( snd_midi_event_t*, size_t); +void (*snd_midi_event_free_dylibloader_wrapper_asound)( snd_midi_event_t*); +void (*snd_midi_event_init_dylibloader_wrapper_asound)( snd_midi_event_t*); +void (*snd_midi_event_reset_encode_dylibloader_wrapper_asound)( snd_midi_event_t*); +void (*snd_midi_event_reset_decode_dylibloader_wrapper_asound)( snd_midi_event_t*); +void (*snd_midi_event_no_status_dylibloader_wrapper_asound)( snd_midi_event_t*, int); +long (*snd_midi_event_encode_dylibloader_wrapper_asound)( snd_midi_event_t*,const unsigned char*, long, snd_seq_event_t*); +int (*snd_midi_event_encode_byte_dylibloader_wrapper_asound)( snd_midi_event_t*, int, snd_seq_event_t*); +long (*snd_midi_event_decode_dylibloader_wrapper_asound)( snd_midi_event_t*, unsigned char*, long,const snd_seq_event_t*); +int initialize_asound(int verbose) { + void *handle; + char *error; + handle = dlopen("libasound.so.2", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// snd_asoundlib_version + *(void **) (&snd_asoundlib_version_dylibloader_wrapper_asound) = dlsym(handle, "snd_asoundlib_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_dlpath + *(void **) (&snd_dlpath_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlpath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_dlopen + *(void **) (&snd_dlopen_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlopen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_dlsym + *(void **) (&snd_dlsym_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlsym"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_dlclose + *(void **) (&snd_dlclose_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlclose"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_add_handler + *(void **) (&snd_async_add_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_handler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_del_handler + *(void **) (&snd_async_del_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_del_handler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_handler_get_fd + *(void **) (&snd_async_handler_get_fd_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_handler_get_signo + *(void **) (&snd_async_handler_get_signo_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_signo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_handler_get_callback_private + *(void **) (&snd_async_handler_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_shm_area_create + *(void **) (&snd_shm_area_create_dylibloader_wrapper_asound) = dlsym(handle, "snd_shm_area_create"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_shm_area_share + *(void **) (&snd_shm_area_share_dylibloader_wrapper_asound) = dlsym(handle, "snd_shm_area_share"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_shm_area_destroy + *(void **) (&snd_shm_area_destroy_dylibloader_wrapper_asound) = dlsym(handle, "snd_shm_area_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_user_file + *(void **) (&snd_user_file_dylibloader_wrapper_asound) = dlsym(handle, "snd_user_file"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_stdio_open + *(void **) (&snd_input_stdio_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_stdio_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_stdio_attach + *(void **) (&snd_input_stdio_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_stdio_attach"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_buffer_open + *(void **) (&snd_input_buffer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_buffer_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_close + *(void **) (&snd_input_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_scanf + *(void **) (&snd_input_scanf_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_scanf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_gets + *(void **) (&snd_input_gets_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_gets"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_getc + *(void **) (&snd_input_getc_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_getc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_input_ungetc + *(void **) (&snd_input_ungetc_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_ungetc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_stdio_open + *(void **) (&snd_output_stdio_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_stdio_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_stdio_attach + *(void **) (&snd_output_stdio_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_stdio_attach"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_buffer_open + *(void **) (&snd_output_buffer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_buffer_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_buffer_string + *(void **) (&snd_output_buffer_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_buffer_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_close + *(void **) (&snd_output_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_printf + *(void **) (&snd_output_printf_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_printf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_vprintf + *(void **) (&snd_output_vprintf_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_vprintf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_puts + *(void **) (&snd_output_puts_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_puts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_putc + *(void **) (&snd_output_putc_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_putc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_output_flush + *(void **) (&snd_output_flush_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_flush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_strerror + *(void **) (&snd_strerror_dylibloader_wrapper_asound) = dlsym(handle, "snd_strerror"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_lib_error_set_handler + *(void **) (&snd_lib_error_set_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_lib_error_set_handler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_lib_error_set_local + *(void **) (&snd_lib_error_set_local_dylibloader_wrapper_asound) = dlsym(handle, "snd_lib_error_set_local"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_topdir + *(void **) (&snd_config_topdir_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_topdir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_top + *(void **) (&snd_config_top_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_top"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_load + *(void **) (&snd_config_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_load"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_load_override + *(void **) (&snd_config_load_override_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_load_override"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_save + *(void **) (&snd_config_save_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_save"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_update + *(void **) (&snd_config_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_update_r + *(void **) (&snd_config_update_r_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_r"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_update_free + *(void **) (&snd_config_update_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_update_free_global + *(void **) (&snd_config_update_free_global_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_free_global"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_update_ref + *(void **) (&snd_config_update_ref_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_ref + *(void **) (&snd_config_ref_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_unref + *(void **) (&snd_config_unref_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_search + *(void **) (&snd_config_search_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_search"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_searchv + *(void **) (&snd_config_searchv_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_searchv"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_search_definition + *(void **) (&snd_config_search_definition_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_search_definition"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_expand + *(void **) (&snd_config_expand_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_expand"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_evaluate + *(void **) (&snd_config_evaluate_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_evaluate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_add + *(void **) (&snd_config_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_add_before + *(void **) (&snd_config_add_before_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add_before"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_add_after + *(void **) (&snd_config_add_after_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add_after"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_remove + *(void **) (&snd_config_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_delete + *(void **) (&snd_config_delete_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_delete"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_delete_compound_members + *(void **) (&snd_config_delete_compound_members_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_delete_compound_members"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_copy + *(void **) (&snd_config_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make + *(void **) (&snd_config_make_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make_integer + *(void **) (&snd_config_make_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make_integer64 + *(void **) (&snd_config_make_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make_real + *(void **) (&snd_config_make_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make_string + *(void **) (&snd_config_make_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make_pointer + *(void **) (&snd_config_make_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_pointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_make_compound + *(void **) (&snd_config_make_compound_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_compound"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_imake_integer + *(void **) (&snd_config_imake_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_imake_integer64 + *(void **) (&snd_config_imake_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_imake_real + *(void **) (&snd_config_imake_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_imake_string + *(void **) (&snd_config_imake_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_imake_safe_string + *(void **) (&snd_config_imake_safe_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_safe_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_imake_pointer + *(void **) (&snd_config_imake_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_pointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_type + *(void **) (&snd_config_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_is_array + *(void **) (&snd_config_is_array_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_is_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_id + *(void **) (&snd_config_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_integer + *(void **) (&snd_config_set_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_integer64 + *(void **) (&snd_config_set_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_real + *(void **) (&snd_config_set_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_string + *(void **) (&snd_config_set_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_ascii + *(void **) (&snd_config_set_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_ascii"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_set_pointer + *(void **) (&snd_config_set_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_pointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_id + *(void **) (&snd_config_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_integer + *(void **) (&snd_config_get_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_integer64 + *(void **) (&snd_config_get_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_real + *(void **) (&snd_config_get_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_ireal + *(void **) (&snd_config_get_ireal_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ireal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_string + *(void **) (&snd_config_get_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_ascii + *(void **) (&snd_config_get_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ascii"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_pointer + *(void **) (&snd_config_get_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_pointer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_test_id + *(void **) (&snd_config_test_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_test_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_iterator_first + *(void **) (&snd_config_iterator_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_iterator_next + *(void **) (&snd_config_iterator_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_iterator_end + *(void **) (&snd_config_iterator_end_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_end"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_iterator_entry + *(void **) (&snd_config_iterator_entry_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_bool_ascii + *(void **) (&snd_config_get_bool_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_bool_ascii"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_bool + *(void **) (&snd_config_get_bool_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_bool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_ctl_iface_ascii + *(void **) (&snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ctl_iface_ascii"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_config_get_ctl_iface + *(void **) (&snd_config_get_ctl_iface_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ctl_iface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_names_list + *(void **) (&snd_names_list_dylibloader_wrapper_asound) = dlsym(handle, "snd_names_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_names_list_free + *(void **) (&snd_names_list_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_names_list_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_open + *(void **) (&snd_pcm_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_open_lconf + *(void **) (&snd_pcm_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_open_lconf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_open_fallback + *(void **) (&snd_pcm_open_fallback_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_open_fallback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_close + *(void **) (&snd_pcm_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_name + *(void **) (&snd_pcm_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_type + *(void **) (&snd_pcm_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_stream + *(void **) (&snd_pcm_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_poll_descriptors_count + *(void **) (&snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_poll_descriptors + *(void **) (&snd_pcm_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_poll_descriptors_revents + *(void **) (&snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_nonblock + *(void **) (&snd_pcm_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_nonblock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_add_pcm_handler + *(void **) (&snd_async_add_pcm_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_pcm_handler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_handler_get_pcm + *(void **) (&snd_async_handler_get_pcm_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_pcm"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info + *(void **) (&snd_pcm_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_current + *(void **) (&snd_pcm_hw_params_current_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_current"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params + *(void **) (&snd_pcm_hw_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_free + *(void **) (&snd_pcm_hw_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_current + *(void **) (&snd_pcm_sw_params_current_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_current"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params + *(void **) (&snd_pcm_sw_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_prepare + *(void **) (&snd_pcm_prepare_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_prepare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_reset + *(void **) (&snd_pcm_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_reset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status + *(void **) (&snd_pcm_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_start + *(void **) (&snd_pcm_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_drop + *(void **) (&snd_pcm_drop_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_drop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_drain + *(void **) (&snd_pcm_drain_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_drain"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_pause + *(void **) (&snd_pcm_pause_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_pause"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_state + *(void **) (&snd_pcm_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hwsync + *(void **) (&snd_pcm_hwsync_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hwsync"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_delay + *(void **) (&snd_pcm_delay_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_delay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_resume + *(void **) (&snd_pcm_resume_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_resume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_htimestamp + *(void **) (&snd_pcm_htimestamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_htimestamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_avail + *(void **) (&snd_pcm_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_avail"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_avail_update + *(void **) (&snd_pcm_avail_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_avail_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_avail_delay + *(void **) (&snd_pcm_avail_delay_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_avail_delay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_rewindable + *(void **) (&snd_pcm_rewindable_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_rewindable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_rewind + *(void **) (&snd_pcm_rewind_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_rewind"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_forwardable + *(void **) (&snd_pcm_forwardable_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_forwardable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_forward + *(void **) (&snd_pcm_forward_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_forward"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_writei + *(void **) (&snd_pcm_writei_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_writei"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_readi + *(void **) (&snd_pcm_readi_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_readi"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_writen + *(void **) (&snd_pcm_writen_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_writen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_readn + *(void **) (&snd_pcm_readn_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_readn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_wait + *(void **) (&snd_pcm_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_link + *(void **) (&snd_pcm_link_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_link"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_unlink + *(void **) (&snd_pcm_unlink_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_unlink"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_query_chmaps + *(void **) (&snd_pcm_query_chmaps_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_query_chmaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_query_chmaps_from_hw + *(void **) (&snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_query_chmaps_from_hw"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_free_chmaps + *(void **) (&snd_pcm_free_chmaps_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_free_chmaps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_get_chmap + *(void **) (&snd_pcm_get_chmap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_get_chmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_set_chmap + *(void **) (&snd_pcm_set_chmap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_set_chmap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_chmap_type_name + *(void **) (&snd_pcm_chmap_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_type_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_chmap_name + *(void **) (&snd_pcm_chmap_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_chmap_long_name + *(void **) (&snd_pcm_chmap_long_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_long_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_chmap_print + *(void **) (&snd_pcm_chmap_print_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_print"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_chmap_from_string + *(void **) (&snd_pcm_chmap_from_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_chmap_parse_string + *(void **) (&snd_pcm_chmap_parse_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_parse_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_recover + *(void **) (&snd_pcm_recover_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_recover"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_set_params + *(void **) (&snd_pcm_set_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_set_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_get_params + *(void **) (&snd_pcm_get_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_get_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_sizeof + *(void **) (&snd_pcm_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_malloc + *(void **) (&snd_pcm_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_free + *(void **) (&snd_pcm_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_copy + *(void **) (&snd_pcm_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_device + *(void **) (&snd_pcm_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_subdevice + *(void **) (&snd_pcm_info_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_stream + *(void **) (&snd_pcm_info_get_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_card + *(void **) (&snd_pcm_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_id + *(void **) (&snd_pcm_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_name + *(void **) (&snd_pcm_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_subdevice_name + *(void **) (&snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevice_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_class + *(void **) (&snd_pcm_info_get_class_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_class"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_subclass + *(void **) (&snd_pcm_info_get_subclass_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subclass"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_subdevices_count + *(void **) (&snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevices_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_subdevices_avail + *(void **) (&snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevices_avail"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_get_sync + *(void **) (&snd_pcm_info_get_sync_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_sync"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_set_device + *(void **) (&snd_pcm_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_set_subdevice + *(void **) (&snd_pcm_info_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_set_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_info_set_stream + *(void **) (&snd_pcm_info_set_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_set_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_any + *(void **) (&snd_pcm_hw_params_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_any"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_can_mmap_sample_resolution + *(void **) (&snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_mmap_sample_resolution"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_is_double + *(void **) (&snd_pcm_hw_params_is_double_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_double"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_is_batch + *(void **) (&snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_batch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_is_block_transfer + *(void **) (&snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_block_transfer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_is_monotonic + *(void **) (&snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_monotonic"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_can_overrange + *(void **) (&snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_overrange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_can_pause + *(void **) (&snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_pause"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_can_resume + *(void **) (&snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_resume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_is_half_duplex + *(void **) (&snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_half_duplex"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_is_joint_duplex + *(void **) (&snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_joint_duplex"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_can_sync_start + *(void **) (&snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_sync_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_can_disable_period_wakeup + *(void **) (&snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_disable_period_wakeup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_supports_audio_wallclock_ts + *(void **) (&snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_supports_audio_wallclock_ts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_supports_audio_ts_type + *(void **) (&snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_supports_audio_ts_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_rate_numden + *(void **) (&snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_numden"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_sbits + *(void **) (&snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_sbits"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_fifo_size + *(void **) (&snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_fifo_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_sizeof + *(void **) (&snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_malloc + *(void **) (&snd_pcm_hw_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_free + *(void **) (&snd_pcm_hw_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_copy + *(void **) (&snd_pcm_hw_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_access + *(void **) (&snd_pcm_hw_params_get_access_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_access"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_access + *(void **) (&snd_pcm_hw_params_test_access_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_access"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_access + *(void **) (&snd_pcm_hw_params_set_access_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_access_first + *(void **) (&snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_access_last + *(void **) (&snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_access_mask + *(void **) (&snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_access_mask + *(void **) (&snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_access_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_format + *(void **) (&snd_pcm_hw_params_get_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_format + *(void **) (&snd_pcm_hw_params_test_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_format + *(void **) (&snd_pcm_hw_params_set_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_format_first + *(void **) (&snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_format_last + *(void **) (&snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_format_mask + *(void **) (&snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_format_mask + *(void **) (&snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_format_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_subformat + *(void **) (&snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_subformat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_subformat + *(void **) (&snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_subformat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_subformat + *(void **) (&snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_subformat_first + *(void **) (&snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_subformat_last + *(void **) (&snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_subformat_mask + *(void **) (&snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_subformat_mask + *(void **) (&snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_subformat_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_channels + *(void **) (&snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_channels_min + *(void **) (&snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_channels_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_channels_max + *(void **) (&snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_channels_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_channels + *(void **) (&snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels + *(void **) (&snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels_min + *(void **) (&snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels_max + *(void **) (&snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels_minmax + *(void **) (&snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels_near + *(void **) (&snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels_first + *(void **) (&snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_channels_last + *(void **) (&snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_rate + *(void **) (&snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_rate_min + *(void **) (&snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_rate_max + *(void **) (&snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_rate + *(void **) (&snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate + *(void **) (&snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_min + *(void **) (&snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_max + *(void **) (&snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_minmax + *(void **) (&snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_near + *(void **) (&snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_first + *(void **) (&snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_last + *(void **) (&snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_rate_resample + *(void **) (&snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_resample"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_rate_resample + *(void **) (&snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_resample"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_export_buffer + *(void **) (&snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_export_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_export_buffer + *(void **) (&snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_export_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_wakeup + *(void **) (&snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_wakeup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_wakeup + *(void **) (&snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_wakeup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_time + *(void **) (&snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_time_min + *(void **) (&snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_time_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_time_max + *(void **) (&snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_time_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_period_time + *(void **) (&snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_period_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time + *(void **) (&snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time_min + *(void **) (&snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time_max + *(void **) (&snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time_minmax + *(void **) (&snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time_near + *(void **) (&snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time_first + *(void **) (&snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_time_last + *(void **) (&snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_size + *(void **) (&snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_size_min + *(void **) (&snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_size_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_period_size_max + *(void **) (&snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_size_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_period_size + *(void **) (&snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_period_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size + *(void **) (&snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_min + *(void **) (&snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_max + *(void **) (&snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_minmax + *(void **) (&snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_near + *(void **) (&snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_first + *(void **) (&snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_last + *(void **) (&snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_period_size_integer + *(void **) (&snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_periods + *(void **) (&snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_periods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_periods_min + *(void **) (&snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_periods_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_periods_max + *(void **) (&snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_periods_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_periods + *(void **) (&snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_periods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods + *(void **) (&snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_min + *(void **) (&snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_max + *(void **) (&snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_minmax + *(void **) (&snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_near + *(void **) (&snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_first + *(void **) (&snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_last + *(void **) (&snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_periods_integer + *(void **) (&snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_buffer_time + *(void **) (&snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_buffer_time_min + *(void **) (&snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_time_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_buffer_time_max + *(void **) (&snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_time_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_buffer_time + *(void **) (&snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_buffer_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time + *(void **) (&snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time_min + *(void **) (&snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time_max + *(void **) (&snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time_minmax + *(void **) (&snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time_near + *(void **) (&snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time_first + *(void **) (&snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_time_last + *(void **) (&snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_buffer_size + *(void **) (&snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_buffer_size_min + *(void **) (&snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_size_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_buffer_size_max + *(void **) (&snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_size_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_buffer_size + *(void **) (&snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size + *(void **) (&snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size_min + *(void **) (&snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size_max + *(void **) (&snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size_minmax + *(void **) (&snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size_near + *(void **) (&snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size_first + *(void **) (&snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_buffer_size_last + *(void **) (&snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_min_align + *(void **) (&snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_min_align"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_sizeof + *(void **) (&snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_malloc + *(void **) (&snd_pcm_sw_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_free + *(void **) (&snd_pcm_sw_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_copy + *(void **) (&snd_pcm_sw_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_boundary + *(void **) (&snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_boundary"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_tstamp_mode + *(void **) (&snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_tstamp_mode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_tstamp_mode + *(void **) (&snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_tstamp_mode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_avail_min + *(void **) (&snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_avail_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_avail_min + *(void **) (&snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_avail_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_period_event + *(void **) (&snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_period_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_period_event + *(void **) (&snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_period_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_start_threshold + *(void **) (&snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_start_threshold"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_start_threshold + *(void **) (&snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_start_threshold"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_stop_threshold + *(void **) (&snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_stop_threshold"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_stop_threshold + *(void **) (&snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_stop_threshold"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_silence_threshold + *(void **) (&snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_silence_threshold"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_silence_threshold + *(void **) (&snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_silence_threshold"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_silence_size + *(void **) (&snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_silence_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_silence_size + *(void **) (&snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_silence_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_sizeof + *(void **) (&snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_malloc + *(void **) (&snd_pcm_access_mask_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_free + *(void **) (&snd_pcm_access_mask_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_copy + *(void **) (&snd_pcm_access_mask_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_none + *(void **) (&snd_pcm_access_mask_none_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_none"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_any + *(void **) (&snd_pcm_access_mask_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_any"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_test + *(void **) (&snd_pcm_access_mask_test_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_test"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_empty + *(void **) (&snd_pcm_access_mask_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_empty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_set + *(void **) (&snd_pcm_access_mask_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_mask_reset + *(void **) (&snd_pcm_access_mask_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_reset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_sizeof + *(void **) (&snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_malloc + *(void **) (&snd_pcm_format_mask_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_free + *(void **) (&snd_pcm_format_mask_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_copy + *(void **) (&snd_pcm_format_mask_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_none + *(void **) (&snd_pcm_format_mask_none_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_none"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_any + *(void **) (&snd_pcm_format_mask_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_any"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_test + *(void **) (&snd_pcm_format_mask_test_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_test"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_empty + *(void **) (&snd_pcm_format_mask_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_empty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_set + *(void **) (&snd_pcm_format_mask_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_mask_reset + *(void **) (&snd_pcm_format_mask_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_reset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_sizeof + *(void **) (&snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_malloc + *(void **) (&snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_free + *(void **) (&snd_pcm_subformat_mask_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_copy + *(void **) (&snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_none + *(void **) (&snd_pcm_subformat_mask_none_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_none"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_any + *(void **) (&snd_pcm_subformat_mask_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_any"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_test + *(void **) (&snd_pcm_subformat_mask_test_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_test"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_empty + *(void **) (&snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_empty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_set + *(void **) (&snd_pcm_subformat_mask_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_mask_reset + *(void **) (&snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_reset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_sizeof + *(void **) (&snd_pcm_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_malloc + *(void **) (&snd_pcm_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_free + *(void **) (&snd_pcm_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_copy + *(void **) (&snd_pcm_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_state + *(void **) (&snd_pcm_status_get_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_trigger_tstamp + *(void **) (&snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_trigger_tstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_trigger_htstamp + *(void **) (&snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_trigger_htstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_tstamp + *(void **) (&snd_pcm_status_get_tstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_tstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_htstamp + *(void **) (&snd_pcm_status_get_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_htstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_audio_htstamp + *(void **) (&snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_audio_htstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_driver_htstamp + *(void **) (&snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_driver_htstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_delay + *(void **) (&snd_pcm_status_get_delay_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_delay"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_avail + *(void **) (&snd_pcm_status_get_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_avail"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_avail_max + *(void **) (&snd_pcm_status_get_avail_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_avail_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_get_overrange + *(void **) (&snd_pcm_status_get_overrange_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_overrange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_type_name + *(void **) (&snd_pcm_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_type_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_stream_name + *(void **) (&snd_pcm_stream_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_stream_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_access_name + *(void **) (&snd_pcm_access_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_name + *(void **) (&snd_pcm_format_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_description + *(void **) (&snd_pcm_format_description_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_description"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_name + *(void **) (&snd_pcm_subformat_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_subformat_description + *(void **) (&snd_pcm_subformat_description_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_description"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_value + *(void **) (&snd_pcm_format_value_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_tstamp_mode_name + *(void **) (&snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_tstamp_mode_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_state_name + *(void **) (&snd_pcm_state_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_state_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_dump + *(void **) (&snd_pcm_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_dump_hw_setup + *(void **) (&snd_pcm_dump_hw_setup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump_hw_setup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_dump_sw_setup + *(void **) (&snd_pcm_dump_sw_setup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump_sw_setup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_dump_setup + *(void **) (&snd_pcm_dump_setup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump_setup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_dump + *(void **) (&snd_pcm_hw_params_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_dump"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_dump + *(void **) (&snd_pcm_sw_params_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_dump"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_status_dump + *(void **) (&snd_pcm_status_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_dump"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_mmap_begin + *(void **) (&snd_pcm_mmap_begin_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_begin"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_mmap_commit + *(void **) (&snd_pcm_mmap_commit_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_commit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_mmap_writei + *(void **) (&snd_pcm_mmap_writei_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_writei"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_mmap_readi + *(void **) (&snd_pcm_mmap_readi_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_readi"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_mmap_writen + *(void **) (&snd_pcm_mmap_writen_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_writen"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_mmap_readn + *(void **) (&snd_pcm_mmap_readn_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_readn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_signed + *(void **) (&snd_pcm_format_signed_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_signed"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_unsigned + *(void **) (&snd_pcm_format_unsigned_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_unsigned"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_linear + *(void **) (&snd_pcm_format_linear_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_linear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_float + *(void **) (&snd_pcm_format_float_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_float"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_little_endian + *(void **) (&snd_pcm_format_little_endian_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_little_endian"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_big_endian + *(void **) (&snd_pcm_format_big_endian_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_big_endian"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_cpu_endian + *(void **) (&snd_pcm_format_cpu_endian_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_cpu_endian"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_width + *(void **) (&snd_pcm_format_width_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_width"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_physical_width + *(void **) (&snd_pcm_format_physical_width_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_physical_width"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_build_linear_format + *(void **) (&snd_pcm_build_linear_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_build_linear_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_size + *(void **) (&snd_pcm_format_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_silence + *(void **) (&snd_pcm_format_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_silence_16 + *(void **) (&snd_pcm_format_silence_16_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence_16"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_silence_32 + *(void **) (&snd_pcm_format_silence_32_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence_32"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_silence_64 + *(void **) (&snd_pcm_format_silence_64_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence_64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_format_set_silence + *(void **) (&snd_pcm_format_set_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_set_silence"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_bytes_to_frames + *(void **) (&snd_pcm_bytes_to_frames_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_bytes_to_frames"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_frames_to_bytes + *(void **) (&snd_pcm_frames_to_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_frames_to_bytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_bytes_to_samples + *(void **) (&snd_pcm_bytes_to_samples_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_bytes_to_samples"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_samples_to_bytes + *(void **) (&snd_pcm_samples_to_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_samples_to_bytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_area_silence + *(void **) (&snd_pcm_area_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_area_silence"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_areas_silence + *(void **) (&snd_pcm_areas_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_silence"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_area_copy + *(void **) (&snd_pcm_area_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_area_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_areas_copy + *(void **) (&snd_pcm_areas_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_areas_copy_wrap + *(void **) (&snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_copy_wrap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hook_get_pcm + *(void **) (&snd_pcm_hook_get_pcm_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_get_pcm"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hook_get_private + *(void **) (&snd_pcm_hook_get_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_get_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hook_set_private + *(void **) (&snd_pcm_hook_set_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_set_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hook_add + *(void **) (&snd_pcm_hook_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_add"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hook_remove + *(void **) (&snd_pcm_hook_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_get_bufsize + *(void **) (&snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_bufsize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_get_channels + *(void **) (&snd_pcm_meter_get_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_get_rate + *(void **) (&snd_pcm_meter_get_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_get_now + *(void **) (&snd_pcm_meter_get_now_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_now"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_get_boundary + *(void **) (&snd_pcm_meter_get_boundary_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_boundary"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_add_scope + *(void **) (&snd_pcm_meter_add_scope_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_add_scope"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_meter_search_scope + *(void **) (&snd_pcm_meter_search_scope_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_search_scope"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_malloc + *(void **) (&snd_pcm_scope_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_set_ops + *(void **) (&snd_pcm_scope_set_ops_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_set_ops"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_set_name + *(void **) (&snd_pcm_scope_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_get_name + *(void **) (&snd_pcm_scope_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_get_callback_private + *(void **) (&snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_get_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_set_callback_private + *(void **) (&snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_set_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_s16_open + *(void **) (&snd_pcm_scope_s16_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_s16_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_scope_s16_get_channel_buffer + *(void **) (&snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_s16_get_channel_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_spcm_init + *(void **) (&snd_spcm_init_dylibloader_wrapper_asound) = dlsym(handle, "snd_spcm_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_spcm_init_duplex + *(void **) (&snd_spcm_init_duplex_dylibloader_wrapper_asound) = dlsym(handle, "snd_spcm_init_duplex"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_spcm_init_get_params + *(void **) (&snd_spcm_init_get_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_spcm_init_get_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_start_mode_name + *(void **) (&snd_pcm_start_mode_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_start_mode_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_xrun_mode_name + *(void **) (&snd_pcm_xrun_mode_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_xrun_mode_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_start_mode + *(void **) (&snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_start_mode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_start_mode + *(void **) (&snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_start_mode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_xrun_mode + *(void **) (&snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_xrun_mode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_xrun_mode + *(void **) (&snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_xrun_mode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_xfer_align + *(void **) (&snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_xfer_align"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_xfer_align + *(void **) (&snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_xfer_align"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_set_sleep_min + *(void **) (&snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_sleep_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_sw_params_get_sleep_min + *(void **) (&snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_sleep_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_tick_time + *(void **) (&snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_tick_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_tick_time_min + *(void **) (&snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_tick_time_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_get_tick_time_max + *(void **) (&snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_tick_time_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_test_tick_time + *(void **) (&snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_tick_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time + *(void **) (&snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time_min + *(void **) (&snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time_max + *(void **) (&snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time_minmax + *(void **) (&snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_minmax"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time_near + *(void **) (&snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_near"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time_first + *(void **) (&snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_first"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_pcm_hw_params_set_tick_time_last + *(void **) (&snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_last"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_open + *(void **) (&snd_rawmidi_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_open_lconf + *(void **) (&snd_rawmidi_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_open_lconf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_close + *(void **) (&snd_rawmidi_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_poll_descriptors_count + *(void **) (&snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_poll_descriptors + *(void **) (&snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_poll_descriptors_revents + *(void **) (&snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_nonblock + *(void **) (&snd_rawmidi_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_nonblock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_sizeof + *(void **) (&snd_rawmidi_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_malloc + *(void **) (&snd_rawmidi_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_free + *(void **) (&snd_rawmidi_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_copy + *(void **) (&snd_rawmidi_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_device + *(void **) (&snd_rawmidi_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_subdevice + *(void **) (&snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_stream + *(void **) (&snd_rawmidi_info_get_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_card + *(void **) (&snd_rawmidi_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_flags + *(void **) (&snd_rawmidi_info_get_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_flags"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_id + *(void **) (&snd_rawmidi_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_name + *(void **) (&snd_rawmidi_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_subdevice_name + *(void **) (&snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevice_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_subdevices_count + *(void **) (&snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevices_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_get_subdevices_avail + *(void **) (&snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevices_avail"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_set_device + *(void **) (&snd_rawmidi_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_set_subdevice + *(void **) (&snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_set_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info_set_stream + *(void **) (&snd_rawmidi_info_set_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_set_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_info + *(void **) (&snd_rawmidi_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_sizeof + *(void **) (&snd_rawmidi_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_malloc + *(void **) (&snd_rawmidi_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_free + *(void **) (&snd_rawmidi_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_copy + *(void **) (&snd_rawmidi_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_set_buffer_size + *(void **) (&snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_set_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_get_buffer_size + *(void **) (&snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_get_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_set_avail_min + *(void **) (&snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_set_avail_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_get_avail_min + *(void **) (&snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_get_avail_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_set_no_active_sensing + *(void **) (&snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_set_no_active_sensing"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_get_no_active_sensing + *(void **) (&snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_get_no_active_sensing"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params + *(void **) (&snd_rawmidi_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_params_current + *(void **) (&snd_rawmidi_params_current_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_current"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_sizeof + *(void **) (&snd_rawmidi_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_malloc + *(void **) (&snd_rawmidi_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_free + *(void **) (&snd_rawmidi_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_copy + *(void **) (&snd_rawmidi_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_get_tstamp + *(void **) (&snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_get_tstamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_get_avail + *(void **) (&snd_rawmidi_status_get_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_get_avail"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status_get_xruns + *(void **) (&snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_get_xruns"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_status + *(void **) (&snd_rawmidi_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_drain + *(void **) (&snd_rawmidi_drain_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_drain"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_drop + *(void **) (&snd_rawmidi_drop_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_drop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_write + *(void **) (&snd_rawmidi_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_read + *(void **) (&snd_rawmidi_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_name + *(void **) (&snd_rawmidi_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_type + *(void **) (&snd_rawmidi_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_rawmidi_stream + *(void **) (&snd_rawmidi_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_open + *(void **) (&snd_timer_query_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_open_lconf + *(void **) (&snd_timer_query_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_open_lconf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_close + *(void **) (&snd_timer_query_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_next_device + *(void **) (&snd_timer_query_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_next_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_info + *(void **) (&snd_timer_query_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_params + *(void **) (&snd_timer_query_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_query_status + *(void **) (&snd_timer_query_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_open + *(void **) (&snd_timer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_open_lconf + *(void **) (&snd_timer_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_open_lconf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_close + *(void **) (&snd_timer_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_add_timer_handler + *(void **) (&snd_async_add_timer_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_timer_handler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_handler_get_timer + *(void **) (&snd_async_handler_get_timer_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_timer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_poll_descriptors_count + *(void **) (&snd_timer_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_poll_descriptors + *(void **) (&snd_timer_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_poll_descriptors_revents + *(void **) (&snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info + *(void **) (&snd_timer_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params + *(void **) (&snd_timer_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status + *(void **) (&snd_timer_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_start + *(void **) (&snd_timer_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_stop + *(void **) (&snd_timer_stop_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_stop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_continue + *(void **) (&snd_timer_continue_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_continue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_read + *(void **) (&snd_timer_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_sizeof + *(void **) (&snd_timer_id_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_malloc + *(void **) (&snd_timer_id_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_free + *(void **) (&snd_timer_id_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_copy + *(void **) (&snd_timer_id_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_set_class + *(void **) (&snd_timer_id_set_class_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_class"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_get_class + *(void **) (&snd_timer_id_get_class_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_class"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_set_sclass + *(void **) (&snd_timer_id_set_sclass_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_sclass"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_get_sclass + *(void **) (&snd_timer_id_get_sclass_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_sclass"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_set_card + *(void **) (&snd_timer_id_set_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_get_card + *(void **) (&snd_timer_id_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_set_device + *(void **) (&snd_timer_id_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_get_device + *(void **) (&snd_timer_id_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_set_subdevice + *(void **) (&snd_timer_id_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_id_get_subdevice + *(void **) (&snd_timer_id_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_sizeof + *(void **) (&snd_timer_ginfo_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_malloc + *(void **) (&snd_timer_ginfo_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_free + *(void **) (&snd_timer_ginfo_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_copy + *(void **) (&snd_timer_ginfo_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_set_tid + *(void **) (&snd_timer_ginfo_set_tid_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_set_tid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_tid + *(void **) (&snd_timer_ginfo_get_tid_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_tid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_flags + *(void **) (&snd_timer_ginfo_get_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_flags"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_card + *(void **) (&snd_timer_ginfo_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_id + *(void **) (&snd_timer_ginfo_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_name + *(void **) (&snd_timer_ginfo_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_resolution + *(void **) (&snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_resolution"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_resolution_min + *(void **) (&snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_resolution_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_resolution_max + *(void **) (&snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_resolution_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_ginfo_get_clients + *(void **) (&snd_timer_ginfo_get_clients_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_clients"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_sizeof + *(void **) (&snd_timer_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_malloc + *(void **) (&snd_timer_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_free + *(void **) (&snd_timer_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_copy + *(void **) (&snd_timer_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_is_slave + *(void **) (&snd_timer_info_is_slave_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_is_slave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_get_card + *(void **) (&snd_timer_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_get_id + *(void **) (&snd_timer_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_get_name + *(void **) (&snd_timer_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_get_resolution + *(void **) (&snd_timer_info_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_resolution"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_sizeof + *(void **) (&snd_timer_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_malloc + *(void **) (&snd_timer_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_free + *(void **) (&snd_timer_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_copy + *(void **) (&snd_timer_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_set_auto_start + *(void **) (&snd_timer_params_set_auto_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_auto_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_get_auto_start + *(void **) (&snd_timer_params_get_auto_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_auto_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_set_exclusive + *(void **) (&snd_timer_params_set_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_exclusive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_get_exclusive + *(void **) (&snd_timer_params_get_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_exclusive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_set_early_event + *(void **) (&snd_timer_params_set_early_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_early_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_get_early_event + *(void **) (&snd_timer_params_get_early_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_early_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_set_ticks + *(void **) (&snd_timer_params_set_ticks_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_ticks"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_get_ticks + *(void **) (&snd_timer_params_get_ticks_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_ticks"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_set_queue_size + *(void **) (&snd_timer_params_set_queue_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_queue_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_get_queue_size + *(void **) (&snd_timer_params_get_queue_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_queue_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_set_filter + *(void **) (&snd_timer_params_set_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_params_get_filter + *(void **) (&snd_timer_params_get_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_sizeof + *(void **) (&snd_timer_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_malloc + *(void **) (&snd_timer_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_free + *(void **) (&snd_timer_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_copy + *(void **) (&snd_timer_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_get_timestamp + *(void **) (&snd_timer_status_get_timestamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_timestamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_get_resolution + *(void **) (&snd_timer_status_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_resolution"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_get_lost + *(void **) (&snd_timer_status_get_lost_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_lost"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_get_overrun + *(void **) (&snd_timer_status_get_overrun_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_overrun"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_status_get_queue + *(void **) (&snd_timer_status_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_timer_info_get_ticks + *(void **) (&snd_timer_info_get_ticks_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_ticks"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_open + *(void **) (&snd_hwdep_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_close + *(void **) (&snd_hwdep_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_poll_descriptors + *(void **) (&snd_hwdep_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_poll_descriptors_count + *(void **) (&snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_poll_descriptors_revents + *(void **) (&snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_nonblock + *(void **) (&snd_hwdep_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_nonblock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info + *(void **) (&snd_hwdep_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status + *(void **) (&snd_hwdep_dsp_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_load + *(void **) (&snd_hwdep_dsp_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_load"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_ioctl + *(void **) (&snd_hwdep_ioctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_ioctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_write + *(void **) (&snd_hwdep_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_read + *(void **) (&snd_hwdep_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_sizeof + *(void **) (&snd_hwdep_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_malloc + *(void **) (&snd_hwdep_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_free + *(void **) (&snd_hwdep_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_copy + *(void **) (&snd_hwdep_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_get_device + *(void **) (&snd_hwdep_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_get_card + *(void **) (&snd_hwdep_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_get_id + *(void **) (&snd_hwdep_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_get_name + *(void **) (&snd_hwdep_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_get_iface + *(void **) (&snd_hwdep_info_get_iface_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_iface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_info_set_device + *(void **) (&snd_hwdep_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_sizeof + *(void **) (&snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_malloc + *(void **) (&snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_free + *(void **) (&snd_hwdep_dsp_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_copy + *(void **) (&snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_get_version + *(void **) (&snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_get_id + *(void **) (&snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_get_num_dsps + *(void **) (&snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_num_dsps"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_get_dsp_loaded + *(void **) (&snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_dsp_loaded"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_status_get_chip_ready + *(void **) (&snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_chip_ready"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_sizeof + *(void **) (&snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_malloc + *(void **) (&snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_free + *(void **) (&snd_hwdep_dsp_image_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_copy + *(void **) (&snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_get_index + *(void **) (&snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_get_name + *(void **) (&snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_get_image + *(void **) (&snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_image"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_get_length + *(void **) (&snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_length"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_set_index + *(void **) (&snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_set_name + *(void **) (&snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_set_image + *(void **) (&snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_image"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hwdep_dsp_image_set_length + *(void **) (&snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_length"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_card_load + *(void **) (&snd_card_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_load"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_card_next + *(void **) (&snd_card_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_card_get_index + *(void **) (&snd_card_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_card_get_name + *(void **) (&snd_card_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_card_get_longname + *(void **) (&snd_card_get_longname_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_get_longname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_device_name_hint + *(void **) (&snd_device_name_hint_dylibloader_wrapper_asound) = dlsym(handle, "snd_device_name_hint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_device_name_free_hint + *(void **) (&snd_device_name_free_hint_dylibloader_wrapper_asound) = dlsym(handle, "snd_device_name_free_hint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_device_name_get_hint + *(void **) (&snd_device_name_get_hint_dylibloader_wrapper_asound) = dlsym(handle, "snd_device_name_get_hint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_open + *(void **) (&snd_ctl_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_open_lconf + *(void **) (&snd_ctl_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_open_lconf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_open_fallback + *(void **) (&snd_ctl_open_fallback_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_open_fallback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_close + *(void **) (&snd_ctl_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_nonblock + *(void **) (&snd_ctl_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_nonblock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_add_ctl_handler + *(void **) (&snd_async_add_ctl_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_ctl_handler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_async_handler_get_ctl + *(void **) (&snd_async_handler_get_ctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_ctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_poll_descriptors_count + *(void **) (&snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_poll_descriptors + *(void **) (&snd_ctl_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_poll_descriptors_revents + *(void **) (&snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_subscribe_events + *(void **) (&snd_ctl_subscribe_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_subscribe_events"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info + *(void **) (&snd_ctl_card_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list + *(void **) (&snd_ctl_elem_list_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info + *(void **) (&snd_ctl_elem_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_read + *(void **) (&snd_ctl_elem_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_write + *(void **) (&snd_ctl_elem_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_lock + *(void **) (&snd_ctl_elem_lock_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_lock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_unlock + *(void **) (&snd_ctl_elem_unlock_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_unlock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_tlv_read + *(void **) (&snd_ctl_elem_tlv_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_tlv_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_tlv_write + *(void **) (&snd_ctl_elem_tlv_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_tlv_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_tlv_command + *(void **) (&snd_ctl_elem_tlv_command_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_tlv_command"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_hwdep_next_device + *(void **) (&snd_ctl_hwdep_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_hwdep_next_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_hwdep_info + *(void **) (&snd_ctl_hwdep_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_hwdep_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_pcm_next_device + *(void **) (&snd_ctl_pcm_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_pcm_next_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_pcm_info + *(void **) (&snd_ctl_pcm_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_pcm_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_pcm_prefer_subdevice + *(void **) (&snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_pcm_prefer_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_rawmidi_next_device + *(void **) (&snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_rawmidi_next_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_rawmidi_info + *(void **) (&snd_ctl_rawmidi_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_rawmidi_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_rawmidi_prefer_subdevice + *(void **) (&snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_rawmidi_prefer_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_set_power_state + *(void **) (&snd_ctl_set_power_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_set_power_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_get_power_state + *(void **) (&snd_ctl_get_power_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_get_power_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_read + *(void **) (&snd_ctl_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_wait + *(void **) (&snd_ctl_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_name + *(void **) (&snd_ctl_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_type + *(void **) (&snd_ctl_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_type_name + *(void **) (&snd_ctl_elem_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_type_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_iface_name + *(void **) (&snd_ctl_elem_iface_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_iface_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_type_name + *(void **) (&snd_ctl_event_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_type_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_mask + *(void **) (&snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_numid + *(void **) (&snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_id + *(void **) (&snd_ctl_event_elem_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_interface + *(void **) (&snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_device + *(void **) (&snd_ctl_event_elem_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_subdevice + *(void **) (&snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_name + *(void **) (&snd_ctl_event_elem_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_elem_get_index + *(void **) (&snd_ctl_event_elem_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_alloc_space + *(void **) (&snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_alloc_space"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_free_space + *(void **) (&snd_ctl_elem_list_free_space_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_free_space"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_ascii_elem_id_get + *(void **) (&snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_ascii_elem_id_get"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_ascii_elem_id_parse + *(void **) (&snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_ascii_elem_id_parse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_ascii_value_parse + *(void **) (&snd_ctl_ascii_value_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_ascii_value_parse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_sizeof + *(void **) (&snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_malloc + *(void **) (&snd_ctl_elem_id_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_free + *(void **) (&snd_ctl_elem_id_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_clear + *(void **) (&snd_ctl_elem_id_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_copy + *(void **) (&snd_ctl_elem_id_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_get_numid + *(void **) (&snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_get_interface + *(void **) (&snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_get_device + *(void **) (&snd_ctl_elem_id_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_get_subdevice + *(void **) (&snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_get_name + *(void **) (&snd_ctl_elem_id_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_get_index + *(void **) (&snd_ctl_elem_id_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_set_numid + *(void **) (&snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_set_interface + *(void **) (&snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_set_device + *(void **) (&snd_ctl_elem_id_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_set_subdevice + *(void **) (&snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_set_name + *(void **) (&snd_ctl_elem_id_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_id_set_index + *(void **) (&snd_ctl_elem_id_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_sizeof + *(void **) (&snd_ctl_card_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_malloc + *(void **) (&snd_ctl_card_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_free + *(void **) (&snd_ctl_card_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_clear + *(void **) (&snd_ctl_card_info_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_copy + *(void **) (&snd_ctl_card_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_card + *(void **) (&snd_ctl_card_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_id + *(void **) (&snd_ctl_card_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_driver + *(void **) (&snd_ctl_card_info_get_driver_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_driver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_name + *(void **) (&snd_ctl_card_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_longname + *(void **) (&snd_ctl_card_info_get_longname_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_longname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_mixername + *(void **) (&snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_mixername"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_card_info_get_components + *(void **) (&snd_ctl_card_info_get_components_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_components"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_sizeof + *(void **) (&snd_ctl_event_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_malloc + *(void **) (&snd_ctl_event_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_free + *(void **) (&snd_ctl_event_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_clear + *(void **) (&snd_ctl_event_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_copy + *(void **) (&snd_ctl_event_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_event_get_type + *(void **) (&snd_ctl_event_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_sizeof + *(void **) (&snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_malloc + *(void **) (&snd_ctl_elem_list_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_free + *(void **) (&snd_ctl_elem_list_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_clear + *(void **) (&snd_ctl_elem_list_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_copy + *(void **) (&snd_ctl_elem_list_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_set_offset + *(void **) (&snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_set_offset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_used + *(void **) (&snd_ctl_elem_list_get_used_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_used"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_count + *(void **) (&snd_ctl_elem_list_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_id + *(void **) (&snd_ctl_elem_list_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_numid + *(void **) (&snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_interface + *(void **) (&snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_device + *(void **) (&snd_ctl_elem_list_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_subdevice + *(void **) (&snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_name + *(void **) (&snd_ctl_elem_list_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_list_get_index + *(void **) (&snd_ctl_elem_list_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_sizeof + *(void **) (&snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_malloc + *(void **) (&snd_ctl_elem_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_free + *(void **) (&snd_ctl_elem_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_clear + *(void **) (&snd_ctl_elem_info_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_copy + *(void **) (&snd_ctl_elem_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_type + *(void **) (&snd_ctl_elem_info_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_readable + *(void **) (&snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_readable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_writable + *(void **) (&snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_writable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_volatile + *(void **) (&snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_volatile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_inactive + *(void **) (&snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_inactive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_locked + *(void **) (&snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_locked"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_tlv_readable + *(void **) (&snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_tlv_readable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_tlv_writable + *(void **) (&snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_tlv_writable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_tlv_commandable + *(void **) (&snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_tlv_commandable"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_owner + *(void **) (&snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_owner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_is_user + *(void **) (&snd_ctl_elem_info_is_user_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_user"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_owner + *(void **) (&snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_owner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_count + *(void **) (&snd_ctl_elem_info_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_min + *(void **) (&snd_ctl_elem_info_get_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_max + *(void **) (&snd_ctl_elem_info_get_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_step + *(void **) (&snd_ctl_elem_info_get_step_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_step"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_min64 + *(void **) (&snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_min64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_max64 + *(void **) (&snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_max64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_step64 + *(void **) (&snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_step64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_items + *(void **) (&snd_ctl_elem_info_get_items_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_items"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_item + *(void **) (&snd_ctl_elem_info_set_item_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_item"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_item_name + *(void **) (&snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_item_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_dimensions + *(void **) (&snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_dimensions"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_dimension + *(void **) (&snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_dimension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_dimension + *(void **) (&snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_dimension"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_id + *(void **) (&snd_ctl_elem_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_numid + *(void **) (&snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_interface + *(void **) (&snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_device + *(void **) (&snd_ctl_elem_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_subdevice + *(void **) (&snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_name + *(void **) (&snd_ctl_elem_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_get_index + *(void **) (&snd_ctl_elem_info_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_id + *(void **) (&snd_ctl_elem_info_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_numid + *(void **) (&snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_interface + *(void **) (&snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_device + *(void **) (&snd_ctl_elem_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_subdevice + *(void **) (&snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_name + *(void **) (&snd_ctl_elem_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_info_set_index + *(void **) (&snd_ctl_elem_info_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_add_integer_elem_set + *(void **) (&snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_integer_elem_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_add_integer64_elem_set + *(void **) (&snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_integer64_elem_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_add_boolean_elem_set + *(void **) (&snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_boolean_elem_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_add_enumerated_elem_set + *(void **) (&snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_enumerated_elem_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_add_bytes_elem_set + *(void **) (&snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_bytes_elem_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_add_integer + *(void **) (&snd_ctl_elem_add_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_add_integer64 + *(void **) (&snd_ctl_elem_add_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_add_boolean + *(void **) (&snd_ctl_elem_add_boolean_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_boolean"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_add_enumerated + *(void **) (&snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_enumerated"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_add_iec958 + *(void **) (&snd_ctl_elem_add_iec958_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_iec958"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_remove + *(void **) (&snd_ctl_elem_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_sizeof + *(void **) (&snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_malloc + *(void **) (&snd_ctl_elem_value_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_free + *(void **) (&snd_ctl_elem_value_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_clear + *(void **) (&snd_ctl_elem_value_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_copy + *(void **) (&snd_ctl_elem_value_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_compare + *(void **) (&snd_ctl_elem_value_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_compare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_id + *(void **) (&snd_ctl_elem_value_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_numid + *(void **) (&snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_interface + *(void **) (&snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_device + *(void **) (&snd_ctl_elem_value_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_subdevice + *(void **) (&snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_name + *(void **) (&snd_ctl_elem_value_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_index + *(void **) (&snd_ctl_elem_value_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_id + *(void **) (&snd_ctl_elem_value_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_numid + *(void **) (&snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_interface + *(void **) (&snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_device + *(void **) (&snd_ctl_elem_value_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_subdevice + *(void **) (&snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_name + *(void **) (&snd_ctl_elem_value_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_index + *(void **) (&snd_ctl_elem_value_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_boolean + *(void **) (&snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_boolean"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_integer + *(void **) (&snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_integer64 + *(void **) (&snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_enumerated + *(void **) (&snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_enumerated"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_byte + *(void **) (&snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_byte"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_boolean + *(void **) (&snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_boolean"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_integer + *(void **) (&snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_integer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_integer64 + *(void **) (&snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_integer64"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_enumerated + *(void **) (&snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_enumerated"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_byte + *(void **) (&snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_byte"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_set_bytes + *(void **) (&snd_ctl_elem_set_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_set_bytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_bytes + *(void **) (&snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_bytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_get_iec958 + *(void **) (&snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_iec958"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_elem_value_set_iec958 + *(void **) (&snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_iec958"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_tlv_parse_dB_info + *(void **) (&snd_tlv_parse_dB_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_parse_dB_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_tlv_get_dB_range + *(void **) (&snd_tlv_get_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_get_dB_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_tlv_convert_to_dB + *(void **) (&snd_tlv_convert_to_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_convert_to_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_tlv_convert_from_dB + *(void **) (&snd_tlv_convert_from_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_convert_from_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_get_dB_range + *(void **) (&snd_ctl_get_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_get_dB_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_convert_to_dB + *(void **) (&snd_ctl_convert_to_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_convert_to_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_ctl_convert_from_dB + *(void **) (&snd_ctl_convert_from_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_convert_from_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_compare_fast + *(void **) (&snd_hctl_compare_fast_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_compare_fast"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_open + *(void **) (&snd_hctl_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_open_ctl + *(void **) (&snd_hctl_open_ctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_open_ctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_close + *(void **) (&snd_hctl_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_nonblock + *(void **) (&snd_hctl_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_nonblock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_poll_descriptors_count + *(void **) (&snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_poll_descriptors + *(void **) (&snd_hctl_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_poll_descriptors_revents + *(void **) (&snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_get_count + *(void **) (&snd_hctl_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_get_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_set_compare + *(void **) (&snd_hctl_set_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_set_compare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_first_elem + *(void **) (&snd_hctl_first_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_first_elem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_last_elem + *(void **) (&snd_hctl_last_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_last_elem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_find_elem + *(void **) (&snd_hctl_find_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_find_elem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_set_callback + *(void **) (&snd_hctl_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_set_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_set_callback_private + *(void **) (&snd_hctl_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_set_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_get_callback_private + *(void **) (&snd_hctl_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_get_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_load + *(void **) (&snd_hctl_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_load"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_free + *(void **) (&snd_hctl_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_handle_events + *(void **) (&snd_hctl_handle_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_handle_events"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_name + *(void **) (&snd_hctl_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_wait + *(void **) (&snd_hctl_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_ctl + *(void **) (&snd_hctl_ctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_ctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_next + *(void **) (&snd_hctl_elem_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_prev + *(void **) (&snd_hctl_elem_prev_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_prev"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_info + *(void **) (&snd_hctl_elem_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_read + *(void **) (&snd_hctl_elem_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_write + *(void **) (&snd_hctl_elem_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_tlv_read + *(void **) (&snd_hctl_elem_tlv_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_tlv_read"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_tlv_write + *(void **) (&snd_hctl_elem_tlv_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_tlv_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_tlv_command + *(void **) (&snd_hctl_elem_tlv_command_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_tlv_command"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_hctl + *(void **) (&snd_hctl_elem_get_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_hctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_id + *(void **) (&snd_hctl_elem_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_numid + *(void **) (&snd_hctl_elem_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_numid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_interface + *(void **) (&snd_hctl_elem_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_interface"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_device + *(void **) (&snd_hctl_elem_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_subdevice + *(void **) (&snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_subdevice"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_name + *(void **) (&snd_hctl_elem_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_index + *(void **) (&snd_hctl_elem_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_set_callback + *(void **) (&snd_hctl_elem_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_set_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_get_callback_private + *(void **) (&snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_hctl_elem_set_callback_private + *(void **) (&snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_set_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_sctl_build + *(void **) (&snd_sctl_build_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_build"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_sctl_free + *(void **) (&snd_sctl_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_sctl_install + *(void **) (&snd_sctl_install_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_install"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_sctl_remove + *(void **) (&snd_sctl_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_open + *(void **) (&snd_mixer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_close + *(void **) (&snd_mixer_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_first_elem + *(void **) (&snd_mixer_first_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_first_elem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_last_elem + *(void **) (&snd_mixer_last_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_last_elem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_handle_events + *(void **) (&snd_mixer_handle_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_handle_events"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_attach + *(void **) (&snd_mixer_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_attach"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_attach_hctl + *(void **) (&snd_mixer_attach_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_attach_hctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_detach + *(void **) (&snd_mixer_detach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_detach"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_detach_hctl + *(void **) (&snd_mixer_detach_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_detach_hctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_get_hctl + *(void **) (&snd_mixer_get_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_get_hctl"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_poll_descriptors_count + *(void **) (&snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_poll_descriptors + *(void **) (&snd_mixer_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_poll_descriptors_revents + *(void **) (&snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_load + *(void **) (&snd_mixer_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_load"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_free + *(void **) (&snd_mixer_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_wait + *(void **) (&snd_mixer_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_set_compare + *(void **) (&snd_mixer_set_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_set_compare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_set_callback + *(void **) (&snd_mixer_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_set_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_get_callback_private + *(void **) (&snd_mixer_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_get_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_set_callback_private + *(void **) (&snd_mixer_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_set_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_get_count + *(void **) (&snd_mixer_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_get_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_unregister + *(void **) (&snd_mixer_class_unregister_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_unregister"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_next + *(void **) (&snd_mixer_elem_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_prev + *(void **) (&snd_mixer_elem_prev_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_prev"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_set_callback + *(void **) (&snd_mixer_elem_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_set_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_get_callback_private + *(void **) (&snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_get_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_set_callback_private + *(void **) (&snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_set_callback_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_get_type + *(void **) (&snd_mixer_elem_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_register + *(void **) (&snd_mixer_class_register_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_register"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_new + *(void **) (&snd_mixer_elem_new_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_add + *(void **) (&snd_mixer_elem_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_add"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_remove + *(void **) (&snd_mixer_elem_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_free + *(void **) (&snd_mixer_elem_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_info + *(void **) (&snd_mixer_elem_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_value + *(void **) (&snd_mixer_elem_value_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_attach + *(void **) (&snd_mixer_elem_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_attach"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_detach + *(void **) (&snd_mixer_elem_detach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_detach"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_empty + *(void **) (&snd_mixer_elem_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_empty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_elem_get_private + *(void **) (&snd_mixer_elem_get_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_get_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_sizeof + *(void **) (&snd_mixer_class_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_malloc + *(void **) (&snd_mixer_class_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_free + *(void **) (&snd_mixer_class_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_copy + *(void **) (&snd_mixer_class_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_get_mixer + *(void **) (&snd_mixer_class_get_mixer_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_mixer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_get_event + *(void **) (&snd_mixer_class_get_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_get_private + *(void **) (&snd_mixer_class_get_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_get_compare + *(void **) (&snd_mixer_class_get_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_compare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_set_event + *(void **) (&snd_mixer_class_set_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_set_private + *(void **) (&snd_mixer_class_set_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_private"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_set_private_free + *(void **) (&snd_mixer_class_set_private_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_private_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_class_set_compare + *(void **) (&snd_mixer_class_set_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_compare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_channel_name + *(void **) (&snd_mixer_selem_channel_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_channel_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_register + *(void **) (&snd_mixer_selem_register_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_register"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_id + *(void **) (&snd_mixer_selem_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_name + *(void **) (&snd_mixer_selem_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_index + *(void **) (&snd_mixer_selem_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_find_selem + *(void **) (&snd_mixer_find_selem_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_find_selem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_is_active + *(void **) (&snd_mixer_selem_is_active_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_is_playback_mono + *(void **) (&snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_playback_mono"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_playback_channel + *(void **) (&snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_channel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_is_capture_mono + *(void **) (&snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_capture_mono"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_capture_channel + *(void **) (&snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_channel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_capture_group + *(void **) (&snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_group"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_common_volume + *(void **) (&snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_common_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_playback_volume + *(void **) (&snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_playback_volume_joined + *(void **) (&snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_volume_joined"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_capture_volume + *(void **) (&snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_capture_volume_joined + *(void **) (&snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_volume_joined"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_common_switch + *(void **) (&snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_common_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_playback_switch + *(void **) (&snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_playback_switch_joined + *(void **) (&snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_switch_joined"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_capture_switch + *(void **) (&snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_capture_switch_joined + *(void **) (&snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_switch_joined"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_has_capture_switch_exclusive + *(void **) (&snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_switch_exclusive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_ask_playback_vol_dB + *(void **) (&snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_playback_vol_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_ask_capture_vol_dB + *(void **) (&snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_capture_vol_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_ask_playback_dB_vol + *(void **) (&snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_playback_dB_vol"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_ask_capture_dB_vol + *(void **) (&snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_capture_dB_vol"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_playback_volume + *(void **) (&snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_capture_volume + *(void **) (&snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_playback_dB + *(void **) (&snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_capture_dB + *(void **) (&snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_playback_switch + *(void **) (&snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_capture_switch + *(void **) (&snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_volume + *(void **) (&snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_volume + *(void **) (&snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_dB + *(void **) (&snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_dB + *(void **) (&snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_volume_all + *(void **) (&snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_volume_all"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_volume_all + *(void **) (&snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_volume_all"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_dB_all + *(void **) (&snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_dB_all"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_dB_all + *(void **) (&snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_dB_all"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_switch + *(void **) (&snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_switch + *(void **) (&snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_switch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_switch_all + *(void **) (&snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_switch_all"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_switch_all + *(void **) (&snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_switch_all"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_playback_volume_range + *(void **) (&snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_volume_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_playback_dB_range + *(void **) (&snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_dB_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_playback_volume_range + *(void **) (&snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_volume_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_capture_volume_range + *(void **) (&snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_volume_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_capture_dB_range + *(void **) (&snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_dB_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_capture_volume_range + *(void **) (&snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_volume_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_is_enumerated + *(void **) (&snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_enumerated"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_is_enum_playback + *(void **) (&snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_enum_playback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_is_enum_capture + *(void **) (&snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_enum_capture"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_enum_items + *(void **) (&snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_enum_items"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_enum_item_name + *(void **) (&snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_enum_item_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_get_enum_item + *(void **) (&snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_enum_item"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_set_enum_item + *(void **) (&snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_enum_item"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_sizeof + *(void **) (&snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_malloc + *(void **) (&snd_mixer_selem_id_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_free + *(void **) (&snd_mixer_selem_id_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_copy + *(void **) (&snd_mixer_selem_id_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_get_name + *(void **) (&snd_mixer_selem_id_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_get_index + *(void **) (&snd_mixer_selem_id_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_set_name + *(void **) (&snd_mixer_selem_id_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_set_index + *(void **) (&snd_mixer_selem_id_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_set_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_mixer_selem_id_parse + *(void **) (&snd_mixer_selem_id_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_parse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_open + *(void **) (&snd_seq_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_open"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_open_lconf + *(void **) (&snd_seq_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_open_lconf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_name + *(void **) (&snd_seq_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_type + *(void **) (&snd_seq_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_close + *(void **) (&snd_seq_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_close"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_poll_descriptors_count + *(void **) (&snd_seq_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_poll_descriptors_count"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_poll_descriptors + *(void **) (&snd_seq_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_poll_descriptors"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_poll_descriptors_revents + *(void **) (&snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_poll_descriptors_revents"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_nonblock + *(void **) (&snd_seq_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_nonblock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_id + *(void **) (&snd_seq_client_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_output_buffer_size + *(void **) (&snd_seq_get_output_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_output_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_input_buffer_size + *(void **) (&snd_seq_get_input_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_input_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_output_buffer_size + *(void **) (&snd_seq_set_output_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_output_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_input_buffer_size + *(void **) (&snd_seq_set_input_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_input_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_sizeof + *(void **) (&snd_seq_system_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_malloc + *(void **) (&snd_seq_system_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_free + *(void **) (&snd_seq_system_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_copy + *(void **) (&snd_seq_system_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_get_queues + *(void **) (&snd_seq_system_info_get_queues_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_queues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_get_clients + *(void **) (&snd_seq_system_info_get_clients_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_clients"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_get_ports + *(void **) (&snd_seq_system_info_get_ports_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_ports"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_get_channels + *(void **) (&snd_seq_system_info_get_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_get_cur_clients + *(void **) (&snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_cur_clients"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info_get_cur_queues + *(void **) (&snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_cur_queues"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_system_info + *(void **) (&snd_seq_system_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_sizeof + *(void **) (&snd_seq_client_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_malloc + *(void **) (&snd_seq_client_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_free + *(void **) (&snd_seq_client_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_copy + *(void **) (&snd_seq_client_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_client + *(void **) (&snd_seq_client_info_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_type + *(void **) (&snd_seq_client_info_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_name + *(void **) (&snd_seq_client_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_broadcast_filter + *(void **) (&snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_broadcast_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_error_bounce + *(void **) (&snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_error_bounce"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_card + *(void **) (&snd_seq_client_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_card"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_pid + *(void **) (&snd_seq_client_info_get_pid_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_pid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_event_filter + *(void **) (&snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_event_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_num_ports + *(void **) (&snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_num_ports"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_get_event_lost + *(void **) (&snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_event_lost"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_set_client + *(void **) (&snd_seq_client_info_set_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_set_name + *(void **) (&snd_seq_client_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_set_broadcast_filter + *(void **) (&snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_broadcast_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_set_error_bounce + *(void **) (&snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_error_bounce"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_set_event_filter + *(void **) (&snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_event_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_event_filter_clear + *(void **) (&snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_event_filter_add + *(void **) (&snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_add"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_event_filter_del + *(void **) (&snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_del"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_info_event_filter_check + *(void **) (&snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_check"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_client_info + *(void **) (&snd_seq_get_client_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_client_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_any_client_info + *(void **) (&snd_seq_get_any_client_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_any_client_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_info + *(void **) (&snd_seq_set_client_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_next_client + *(void **) (&snd_seq_query_next_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_next_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_sizeof + *(void **) (&snd_seq_client_pool_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_malloc + *(void **) (&snd_seq_client_pool_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_free + *(void **) (&snd_seq_client_pool_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_copy + *(void **) (&snd_seq_client_pool_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_get_client + *(void **) (&snd_seq_client_pool_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_get_output_pool + *(void **) (&snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_output_pool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_get_input_pool + *(void **) (&snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_input_pool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_get_output_room + *(void **) (&snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_output_room"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_get_output_free + *(void **) (&snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_output_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_get_input_free + *(void **) (&snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_input_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_set_output_pool + *(void **) (&snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_set_output_pool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_set_input_pool + *(void **) (&snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_set_input_pool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_client_pool_set_output_room + *(void **) (&snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_set_output_room"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_client_pool + *(void **) (&snd_seq_get_client_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_client_pool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_pool + *(void **) (&snd_seq_set_client_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_sizeof + *(void **) (&snd_seq_port_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_malloc + *(void **) (&snd_seq_port_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_free + *(void **) (&snd_seq_port_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_copy + *(void **) (&snd_seq_port_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_client + *(void **) (&snd_seq_port_info_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_port + *(void **) (&snd_seq_port_info_get_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_addr + *(void **) (&snd_seq_port_info_get_addr_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_addr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_name + *(void **) (&snd_seq_port_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_capability + *(void **) (&snd_seq_port_info_get_capability_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_capability"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_type + *(void **) (&snd_seq_port_info_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_midi_channels + *(void **) (&snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_midi_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_midi_voices + *(void **) (&snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_midi_voices"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_synth_voices + *(void **) (&snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_synth_voices"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_read_use + *(void **) (&snd_seq_port_info_get_read_use_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_read_use"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_write_use + *(void **) (&snd_seq_port_info_get_write_use_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_write_use"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_port_specified + *(void **) (&snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_port_specified"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_timestamping + *(void **) (&snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_timestamping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_timestamp_real + *(void **) (&snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_timestamp_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_get_timestamp_queue + *(void **) (&snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_timestamp_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_client + *(void **) (&snd_seq_port_info_set_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_port + *(void **) (&snd_seq_port_info_set_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_addr + *(void **) (&snd_seq_port_info_set_addr_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_addr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_name + *(void **) (&snd_seq_port_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_capability + *(void **) (&snd_seq_port_info_set_capability_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_capability"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_type + *(void **) (&snd_seq_port_info_set_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_midi_channels + *(void **) (&snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_midi_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_midi_voices + *(void **) (&snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_midi_voices"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_synth_voices + *(void **) (&snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_synth_voices"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_port_specified + *(void **) (&snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_port_specified"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_timestamping + *(void **) (&snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_timestamping"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_timestamp_real + *(void **) (&snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_timestamp_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_info_set_timestamp_queue + *(void **) (&snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_timestamp_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_create_port + *(void **) (&snd_seq_create_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_create_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_delete_port + *(void **) (&snd_seq_delete_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_delete_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_port_info + *(void **) (&snd_seq_get_port_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_port_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_any_port_info + *(void **) (&snd_seq_get_any_port_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_any_port_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_port_info + *(void **) (&snd_seq_set_port_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_port_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_next_port + *(void **) (&snd_seq_query_next_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_next_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_sizeof + *(void **) (&snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_malloc + *(void **) (&snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_free + *(void **) (&snd_seq_port_subscribe_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_copy + *(void **) (&snd_seq_port_subscribe_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_get_sender + *(void **) (&snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_sender"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_get_dest + *(void **) (&snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_dest"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_get_queue + *(void **) (&snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_get_exclusive + *(void **) (&snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_exclusive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_get_time_update + *(void **) (&snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_time_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_get_time_real + *(void **) (&snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_time_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_set_sender + *(void **) (&snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_sender"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_set_dest + *(void **) (&snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_dest"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_set_queue + *(void **) (&snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_set_exclusive + *(void **) (&snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_exclusive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_set_time_update + *(void **) (&snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_time_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_port_subscribe_set_time_real + *(void **) (&snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_time_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_port_subscription + *(void **) (&snd_seq_get_port_subscription_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_port_subscription"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_subscribe_port + *(void **) (&snd_seq_subscribe_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_subscribe_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_unsubscribe_port + *(void **) (&snd_seq_unsubscribe_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_unsubscribe_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_sizeof + *(void **) (&snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_malloc + *(void **) (&snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_free + *(void **) (&snd_seq_query_subscribe_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_copy + *(void **) (&snd_seq_query_subscribe_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_client + *(void **) (&snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_port + *(void **) (&snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_root + *(void **) (&snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_root"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_type + *(void **) (&snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_index + *(void **) (&snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_num_subs + *(void **) (&snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_num_subs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_addr + *(void **) (&snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_addr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_queue + *(void **) (&snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_exclusive + *(void **) (&snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_exclusive"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_time_update + *(void **) (&snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_time_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_get_time_real + *(void **) (&snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_time_real"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_set_client + *(void **) (&snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_set_port + *(void **) (&snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_set_root + *(void **) (&snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_root"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_set_type + *(void **) (&snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_subscribe_set_index + *(void **) (&snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_port_subscribers + *(void **) (&snd_seq_query_port_subscribers_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_port_subscribers"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_sizeof + *(void **) (&snd_seq_queue_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_malloc + *(void **) (&snd_seq_queue_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_free + *(void **) (&snd_seq_queue_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_copy + *(void **) (&snd_seq_queue_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_get_queue + *(void **) (&snd_seq_queue_info_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_get_name + *(void **) (&snd_seq_queue_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_get_owner + *(void **) (&snd_seq_queue_info_get_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_owner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_get_locked + *(void **) (&snd_seq_queue_info_get_locked_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_locked"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_get_flags + *(void **) (&snd_seq_queue_info_get_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_flags"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_set_name + *(void **) (&snd_seq_queue_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_set_owner + *(void **) (&snd_seq_queue_info_set_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_owner"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_set_locked + *(void **) (&snd_seq_queue_info_set_locked_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_locked"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_info_set_flags + *(void **) (&snd_seq_queue_info_set_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_flags"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_create_queue + *(void **) (&snd_seq_create_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_create_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_alloc_named_queue + *(void **) (&snd_seq_alloc_named_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_alloc_named_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_alloc_queue + *(void **) (&snd_seq_alloc_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_alloc_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_free_queue + *(void **) (&snd_seq_free_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_free_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_queue_info + *(void **) (&snd_seq_get_queue_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_queue_info + *(void **) (&snd_seq_set_queue_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_query_named_queue + *(void **) (&snd_seq_query_named_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_named_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_queue_usage + *(void **) (&snd_seq_get_queue_usage_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_usage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_queue_usage + *(void **) (&snd_seq_set_queue_usage_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_usage"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_sizeof + *(void **) (&snd_seq_queue_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_malloc + *(void **) (&snd_seq_queue_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_free + *(void **) (&snd_seq_queue_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_copy + *(void **) (&snd_seq_queue_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_get_queue + *(void **) (&snd_seq_queue_status_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_get_events + *(void **) (&snd_seq_queue_status_get_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_events"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_get_tick_time + *(void **) (&snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_tick_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_get_real_time + *(void **) (&snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_real_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_status_get_status + *(void **) (&snd_seq_queue_status_get_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_queue_status + *(void **) (&snd_seq_get_queue_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_sizeof + *(void **) (&snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_malloc + *(void **) (&snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_free + *(void **) (&snd_seq_queue_tempo_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_copy + *(void **) (&snd_seq_queue_tempo_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_get_queue + *(void **) (&snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_get_tempo + *(void **) (&snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_tempo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_get_ppq + *(void **) (&snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_ppq"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_get_skew + *(void **) (&snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_skew"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_get_skew_base + *(void **) (&snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_skew_base"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_set_tempo + *(void **) (&snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_tempo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_set_ppq + *(void **) (&snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_ppq"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_set_skew + *(void **) (&snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_skew"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_tempo_set_skew_base + *(void **) (&snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_skew_base"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_queue_tempo + *(void **) (&snd_seq_get_queue_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_tempo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_queue_tempo + *(void **) (&snd_seq_set_queue_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_tempo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_sizeof + *(void **) (&snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_malloc + *(void **) (&snd_seq_queue_timer_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_free + *(void **) (&snd_seq_queue_timer_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_copy + *(void **) (&snd_seq_queue_timer_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_get_queue + *(void **) (&snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_get_type + *(void **) (&snd_seq_queue_timer_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_get_id + *(void **) (&snd_seq_queue_timer_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_get_resolution + *(void **) (&snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_resolution"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_set_type + *(void **) (&snd_seq_queue_timer_set_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_set_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_set_id + *(void **) (&snd_seq_queue_timer_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_set_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_queue_timer_set_resolution + *(void **) (&snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_set_resolution"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_queue_timer + *(void **) (&snd_seq_get_queue_timer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_timer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_queue_timer + *(void **) (&snd_seq_set_queue_timer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_timer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_free_event + *(void **) (&snd_seq_free_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_free_event"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_length + *(void **) (&snd_seq_event_length_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_length"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_output + *(void **) (&snd_seq_event_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_output_buffer + *(void **) (&snd_seq_event_output_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_output_direct + *(void **) (&snd_seq_event_output_direct_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output_direct"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_input + *(void **) (&snd_seq_event_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_input"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_input_pending + *(void **) (&snd_seq_event_input_pending_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_input_pending"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_drain_output + *(void **) (&snd_seq_drain_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drain_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_event_output_pending + *(void **) (&snd_seq_event_output_pending_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output_pending"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_extract_output + *(void **) (&snd_seq_extract_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_extract_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_drop_output + *(void **) (&snd_seq_drop_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_drop_output_buffer + *(void **) (&snd_seq_drop_output_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_output_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_drop_input + *(void **) (&snd_seq_drop_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_input"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_drop_input_buffer + *(void **) (&snd_seq_drop_input_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_input_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_sizeof + *(void **) (&snd_seq_remove_events_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_sizeof"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_malloc + *(void **) (&snd_seq_remove_events_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_malloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_free + *(void **) (&snd_seq_remove_events_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_copy + *(void **) (&snd_seq_remove_events_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_condition + *(void **) (&snd_seq_remove_events_get_condition_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_condition"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_queue + *(void **) (&snd_seq_remove_events_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_time + *(void **) (&snd_seq_remove_events_get_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_dest + *(void **) (&snd_seq_remove_events_get_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_dest"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_channel + *(void **) (&snd_seq_remove_events_get_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_channel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_event_type + *(void **) (&snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_event_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_get_tag + *(void **) (&snd_seq_remove_events_get_tag_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_tag"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_condition + *(void **) (&snd_seq_remove_events_set_condition_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_condition"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_queue + *(void **) (&snd_seq_remove_events_set_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_time + *(void **) (&snd_seq_remove_events_set_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_dest + *(void **) (&snd_seq_remove_events_set_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_dest"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_channel + *(void **) (&snd_seq_remove_events_set_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_channel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_event_type + *(void **) (&snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_event_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events_set_tag + *(void **) (&snd_seq_remove_events_set_tag_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_tag"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_remove_events + *(void **) (&snd_seq_remove_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_bit + *(void **) (&snd_seq_set_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_bit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_unset_bit + *(void **) (&snd_seq_unset_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_unset_bit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_change_bit + *(void **) (&snd_seq_change_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_change_bit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_get_bit + *(void **) (&snd_seq_get_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_bit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_control_queue + *(void **) (&snd_seq_control_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_control_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_create_simple_port + *(void **) (&snd_seq_create_simple_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_create_simple_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_delete_simple_port + *(void **) (&snd_seq_delete_simple_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_delete_simple_port"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_connect_from + *(void **) (&snd_seq_connect_from_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_connect_from"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_connect_to + *(void **) (&snd_seq_connect_to_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_connect_to"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_disconnect_from + *(void **) (&snd_seq_disconnect_from_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_disconnect_from"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_disconnect_to + *(void **) (&snd_seq_disconnect_to_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_disconnect_to"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_name + *(void **) (&snd_seq_set_client_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_event_filter + *(void **) (&snd_seq_set_client_event_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_event_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_pool_output + *(void **) (&snd_seq_set_client_pool_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_pool_output_room + *(void **) (&snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool_output_room"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_set_client_pool_input + *(void **) (&snd_seq_set_client_pool_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool_input"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_sync_output_queue + *(void **) (&snd_seq_sync_output_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_sync_output_queue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_parse_address + *(void **) (&snd_seq_parse_address_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_parse_address"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_reset_pool_output + *(void **) (&snd_seq_reset_pool_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_reset_pool_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_seq_reset_pool_input + *(void **) (&snd_seq_reset_pool_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_reset_pool_input"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_new + *(void **) (&snd_midi_event_new_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_resize_buffer + *(void **) (&snd_midi_event_resize_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_resize_buffer"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_free + *(void **) (&snd_midi_event_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_init + *(void **) (&snd_midi_event_init_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_reset_encode + *(void **) (&snd_midi_event_reset_encode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_reset_encode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_reset_decode + *(void **) (&snd_midi_event_reset_decode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_reset_decode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_no_status + *(void **) (&snd_midi_event_no_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_no_status"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_encode + *(void **) (&snd_midi_event_encode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_encode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_encode_byte + *(void **) (&snd_midi_event_encode_byte_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_encode_byte"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// snd_midi_event_decode + *(void **) (&snd_midi_event_decode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_decode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/drivers/alsa/asound-so_wrap.h b/drivers/alsa/asound-so_wrap.h new file mode 100644 index 0000000000..5332d74152 --- /dev/null +++ b/drivers/alsa/asound-so_wrap.h @@ -0,0 +1,5134 @@ +#ifndef DYLIBLOAD_WRAPPER_ASOUND +#define DYLIBLOAD_WRAPPER_ASOUND +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-22 19:22:12 +// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/alsa/asoundlib.h --sys-include <alsa/asoundlib.h> --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header asound-so_wrap.h --output-implementation asound-so_wrap.c +// +#include <stdint.h> + +#define snd_asoundlib_version snd_asoundlib_version_dylibloader_orig_asound +#define snd_dlpath snd_dlpath_dylibloader_orig_asound +#define snd_dlopen snd_dlopen_dylibloader_orig_asound +#define snd_dlsym snd_dlsym_dylibloader_orig_asound +#define snd_dlclose snd_dlclose_dylibloader_orig_asound +#define snd_async_add_handler snd_async_add_handler_dylibloader_orig_asound +#define snd_async_del_handler snd_async_del_handler_dylibloader_orig_asound +#define snd_async_handler_get_fd snd_async_handler_get_fd_dylibloader_orig_asound +#define snd_async_handler_get_signo snd_async_handler_get_signo_dylibloader_orig_asound +#define snd_async_handler_get_callback_private snd_async_handler_get_callback_private_dylibloader_orig_asound +#define snd_shm_area_create snd_shm_area_create_dylibloader_orig_asound +#define snd_shm_area_share snd_shm_area_share_dylibloader_orig_asound +#define snd_shm_area_destroy snd_shm_area_destroy_dylibloader_orig_asound +#define snd_user_file snd_user_file_dylibloader_orig_asound +#define snd_input_stdio_open snd_input_stdio_open_dylibloader_orig_asound +#define snd_input_stdio_attach snd_input_stdio_attach_dylibloader_orig_asound +#define snd_input_buffer_open snd_input_buffer_open_dylibloader_orig_asound +#define snd_input_close snd_input_close_dylibloader_orig_asound +#define snd_input_scanf snd_input_scanf_dylibloader_orig_asound +#define snd_input_gets snd_input_gets_dylibloader_orig_asound +#define snd_input_getc snd_input_getc_dylibloader_orig_asound +#define snd_input_ungetc snd_input_ungetc_dylibloader_orig_asound +#define snd_output_stdio_open snd_output_stdio_open_dylibloader_orig_asound +#define snd_output_stdio_attach snd_output_stdio_attach_dylibloader_orig_asound +#define snd_output_buffer_open snd_output_buffer_open_dylibloader_orig_asound +#define snd_output_buffer_string snd_output_buffer_string_dylibloader_orig_asound +#define snd_output_close snd_output_close_dylibloader_orig_asound +#define snd_output_printf snd_output_printf_dylibloader_orig_asound +#define snd_output_vprintf snd_output_vprintf_dylibloader_orig_asound +#define snd_output_puts snd_output_puts_dylibloader_orig_asound +#define snd_output_putc snd_output_putc_dylibloader_orig_asound +#define snd_output_flush snd_output_flush_dylibloader_orig_asound +#define snd_strerror snd_strerror_dylibloader_orig_asound +#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_orig_asound +#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_orig_asound +#define snd_config_topdir snd_config_topdir_dylibloader_orig_asound +#define snd_config_top snd_config_top_dylibloader_orig_asound +#define snd_config_load snd_config_load_dylibloader_orig_asound +#define snd_config_load_override snd_config_load_override_dylibloader_orig_asound +#define snd_config_save snd_config_save_dylibloader_orig_asound +#define snd_config_update snd_config_update_dylibloader_orig_asound +#define snd_config_update_r snd_config_update_r_dylibloader_orig_asound +#define snd_config_update_free snd_config_update_free_dylibloader_orig_asound +#define snd_config_update_free_global snd_config_update_free_global_dylibloader_orig_asound +#define snd_config_update_ref snd_config_update_ref_dylibloader_orig_asound +#define snd_config_ref snd_config_ref_dylibloader_orig_asound +#define snd_config_unref snd_config_unref_dylibloader_orig_asound +#define snd_config_search snd_config_search_dylibloader_orig_asound +#define snd_config_searchv snd_config_searchv_dylibloader_orig_asound +#define snd_config_search_definition snd_config_search_definition_dylibloader_orig_asound +#define snd_config_expand snd_config_expand_dylibloader_orig_asound +#define snd_config_evaluate snd_config_evaluate_dylibloader_orig_asound +#define snd_config_add snd_config_add_dylibloader_orig_asound +#define snd_config_add_before snd_config_add_before_dylibloader_orig_asound +#define snd_config_add_after snd_config_add_after_dylibloader_orig_asound +#define snd_config_remove snd_config_remove_dylibloader_orig_asound +#define snd_config_delete snd_config_delete_dylibloader_orig_asound +#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_orig_asound +#define snd_config_copy snd_config_copy_dylibloader_orig_asound +#define snd_config_make snd_config_make_dylibloader_orig_asound +#define snd_config_make_integer snd_config_make_integer_dylibloader_orig_asound +#define snd_config_make_integer64 snd_config_make_integer64_dylibloader_orig_asound +#define snd_config_make_real snd_config_make_real_dylibloader_orig_asound +#define snd_config_make_string snd_config_make_string_dylibloader_orig_asound +#define snd_config_make_pointer snd_config_make_pointer_dylibloader_orig_asound +#define snd_config_make_compound snd_config_make_compound_dylibloader_orig_asound +#define snd_config_imake_integer snd_config_imake_integer_dylibloader_orig_asound +#define snd_config_imake_integer64 snd_config_imake_integer64_dylibloader_orig_asound +#define snd_config_imake_real snd_config_imake_real_dylibloader_orig_asound +#define snd_config_imake_string snd_config_imake_string_dylibloader_orig_asound +#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_orig_asound +#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_orig_asound +#define snd_config_get_type snd_config_get_type_dylibloader_orig_asound +#define snd_config_is_array snd_config_is_array_dylibloader_orig_asound +#define snd_config_set_id snd_config_set_id_dylibloader_orig_asound +#define snd_config_set_integer snd_config_set_integer_dylibloader_orig_asound +#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_orig_asound +#define snd_config_set_real snd_config_set_real_dylibloader_orig_asound +#define snd_config_set_string snd_config_set_string_dylibloader_orig_asound +#define snd_config_set_ascii snd_config_set_ascii_dylibloader_orig_asound +#define snd_config_set_pointer snd_config_set_pointer_dylibloader_orig_asound +#define snd_config_get_id snd_config_get_id_dylibloader_orig_asound +#define snd_config_get_integer snd_config_get_integer_dylibloader_orig_asound +#define snd_config_get_integer64 snd_config_get_integer64_dylibloader_orig_asound +#define snd_config_get_real snd_config_get_real_dylibloader_orig_asound +#define snd_config_get_ireal snd_config_get_ireal_dylibloader_orig_asound +#define snd_config_get_string snd_config_get_string_dylibloader_orig_asound +#define snd_config_get_ascii snd_config_get_ascii_dylibloader_orig_asound +#define snd_config_get_pointer snd_config_get_pointer_dylibloader_orig_asound +#define snd_config_test_id snd_config_test_id_dylibloader_orig_asound +#define snd_config_iterator_first snd_config_iterator_first_dylibloader_orig_asound +#define snd_config_iterator_next snd_config_iterator_next_dylibloader_orig_asound +#define snd_config_iterator_end snd_config_iterator_end_dylibloader_orig_asound +#define snd_config_iterator_entry snd_config_iterator_entry_dylibloader_orig_asound +#define snd_config_get_bool_ascii snd_config_get_bool_ascii_dylibloader_orig_asound +#define snd_config_get_bool snd_config_get_bool_dylibloader_orig_asound +#define snd_config_get_ctl_iface_ascii snd_config_get_ctl_iface_ascii_dylibloader_orig_asound +#define snd_config_get_ctl_iface snd_config_get_ctl_iface_dylibloader_orig_asound +#define snd_names_list snd_names_list_dylibloader_orig_asound +#define snd_names_list_free snd_names_list_free_dylibloader_orig_asound +#define snd_pcm_open snd_pcm_open_dylibloader_orig_asound +#define snd_pcm_open_lconf snd_pcm_open_lconf_dylibloader_orig_asound +#define snd_pcm_open_fallback snd_pcm_open_fallback_dylibloader_orig_asound +#define snd_pcm_close snd_pcm_close_dylibloader_orig_asound +#define snd_pcm_name snd_pcm_name_dylibloader_orig_asound +#define snd_pcm_type snd_pcm_type_dylibloader_orig_asound +#define snd_pcm_stream snd_pcm_stream_dylibloader_orig_asound +#define snd_pcm_poll_descriptors_count snd_pcm_poll_descriptors_count_dylibloader_orig_asound +#define snd_pcm_poll_descriptors snd_pcm_poll_descriptors_dylibloader_orig_asound +#define snd_pcm_poll_descriptors_revents snd_pcm_poll_descriptors_revents_dylibloader_orig_asound +#define snd_pcm_nonblock snd_pcm_nonblock_dylibloader_orig_asound +#define snd_async_add_pcm_handler snd_async_add_pcm_handler_dylibloader_orig_asound +#define snd_async_handler_get_pcm snd_async_handler_get_pcm_dylibloader_orig_asound +#define snd_pcm_info snd_pcm_info_dylibloader_orig_asound +#define snd_pcm_hw_params_current snd_pcm_hw_params_current_dylibloader_orig_asound +#define snd_pcm_hw_params snd_pcm_hw_params_dylibloader_orig_asound +#define snd_pcm_hw_free snd_pcm_hw_free_dylibloader_orig_asound +#define snd_pcm_sw_params_current snd_pcm_sw_params_current_dylibloader_orig_asound +#define snd_pcm_sw_params snd_pcm_sw_params_dylibloader_orig_asound +#define snd_pcm_prepare snd_pcm_prepare_dylibloader_orig_asound +#define snd_pcm_reset snd_pcm_reset_dylibloader_orig_asound +#define snd_pcm_status snd_pcm_status_dylibloader_orig_asound +#define snd_pcm_start snd_pcm_start_dylibloader_orig_asound +#define snd_pcm_drop snd_pcm_drop_dylibloader_orig_asound +#define snd_pcm_drain snd_pcm_drain_dylibloader_orig_asound +#define snd_pcm_pause snd_pcm_pause_dylibloader_orig_asound +#define snd_pcm_state snd_pcm_state_dylibloader_orig_asound +#define snd_pcm_hwsync snd_pcm_hwsync_dylibloader_orig_asound +#define snd_pcm_delay snd_pcm_delay_dylibloader_orig_asound +#define snd_pcm_resume snd_pcm_resume_dylibloader_orig_asound +#define snd_pcm_htimestamp snd_pcm_htimestamp_dylibloader_orig_asound +#define snd_pcm_avail snd_pcm_avail_dylibloader_orig_asound +#define snd_pcm_avail_update snd_pcm_avail_update_dylibloader_orig_asound +#define snd_pcm_avail_delay snd_pcm_avail_delay_dylibloader_orig_asound +#define snd_pcm_rewindable snd_pcm_rewindable_dylibloader_orig_asound +#define snd_pcm_rewind snd_pcm_rewind_dylibloader_orig_asound +#define snd_pcm_forwardable snd_pcm_forwardable_dylibloader_orig_asound +#define snd_pcm_forward snd_pcm_forward_dylibloader_orig_asound +#define snd_pcm_writei snd_pcm_writei_dylibloader_orig_asound +#define snd_pcm_readi snd_pcm_readi_dylibloader_orig_asound +#define snd_pcm_writen snd_pcm_writen_dylibloader_orig_asound +#define snd_pcm_readn snd_pcm_readn_dylibloader_orig_asound +#define snd_pcm_wait snd_pcm_wait_dylibloader_orig_asound +#define snd_pcm_link snd_pcm_link_dylibloader_orig_asound +#define snd_pcm_unlink snd_pcm_unlink_dylibloader_orig_asound +#define snd_pcm_query_chmaps snd_pcm_query_chmaps_dylibloader_orig_asound +#define snd_pcm_query_chmaps_from_hw snd_pcm_query_chmaps_from_hw_dylibloader_orig_asound +#define snd_pcm_free_chmaps snd_pcm_free_chmaps_dylibloader_orig_asound +#define snd_pcm_get_chmap snd_pcm_get_chmap_dylibloader_orig_asound +#define snd_pcm_set_chmap snd_pcm_set_chmap_dylibloader_orig_asound +#define snd_pcm_chmap_type_name snd_pcm_chmap_type_name_dylibloader_orig_asound +#define snd_pcm_chmap_name snd_pcm_chmap_name_dylibloader_orig_asound +#define snd_pcm_chmap_long_name snd_pcm_chmap_long_name_dylibloader_orig_asound +#define snd_pcm_chmap_print snd_pcm_chmap_print_dylibloader_orig_asound +#define snd_pcm_chmap_from_string snd_pcm_chmap_from_string_dylibloader_orig_asound +#define snd_pcm_chmap_parse_string snd_pcm_chmap_parse_string_dylibloader_orig_asound +#define snd_pcm_recover snd_pcm_recover_dylibloader_orig_asound +#define snd_pcm_set_params snd_pcm_set_params_dylibloader_orig_asound +#define snd_pcm_get_params snd_pcm_get_params_dylibloader_orig_asound +#define snd_pcm_info_sizeof snd_pcm_info_sizeof_dylibloader_orig_asound +#define snd_pcm_info_malloc snd_pcm_info_malloc_dylibloader_orig_asound +#define snd_pcm_info_free snd_pcm_info_free_dylibloader_orig_asound +#define snd_pcm_info_copy snd_pcm_info_copy_dylibloader_orig_asound +#define snd_pcm_info_get_device snd_pcm_info_get_device_dylibloader_orig_asound +#define snd_pcm_info_get_subdevice snd_pcm_info_get_subdevice_dylibloader_orig_asound +#define snd_pcm_info_get_stream snd_pcm_info_get_stream_dylibloader_orig_asound +#define snd_pcm_info_get_card snd_pcm_info_get_card_dylibloader_orig_asound +#define snd_pcm_info_get_id snd_pcm_info_get_id_dylibloader_orig_asound +#define snd_pcm_info_get_name snd_pcm_info_get_name_dylibloader_orig_asound +#define snd_pcm_info_get_subdevice_name snd_pcm_info_get_subdevice_name_dylibloader_orig_asound +#define snd_pcm_info_get_class snd_pcm_info_get_class_dylibloader_orig_asound +#define snd_pcm_info_get_subclass snd_pcm_info_get_subclass_dylibloader_orig_asound +#define snd_pcm_info_get_subdevices_count snd_pcm_info_get_subdevices_count_dylibloader_orig_asound +#define snd_pcm_info_get_subdevices_avail snd_pcm_info_get_subdevices_avail_dylibloader_orig_asound +#define snd_pcm_info_get_sync snd_pcm_info_get_sync_dylibloader_orig_asound +#define snd_pcm_info_set_device snd_pcm_info_set_device_dylibloader_orig_asound +#define snd_pcm_info_set_subdevice snd_pcm_info_set_subdevice_dylibloader_orig_asound +#define snd_pcm_info_set_stream snd_pcm_info_set_stream_dylibloader_orig_asound +#define snd_pcm_hw_params_any snd_pcm_hw_params_any_dylibloader_orig_asound +#define snd_pcm_hw_params_can_mmap_sample_resolution snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_orig_asound +#define snd_pcm_hw_params_is_double snd_pcm_hw_params_is_double_dylibloader_orig_asound +#define snd_pcm_hw_params_is_batch snd_pcm_hw_params_is_batch_dylibloader_orig_asound +#define snd_pcm_hw_params_is_block_transfer snd_pcm_hw_params_is_block_transfer_dylibloader_orig_asound +#define snd_pcm_hw_params_is_monotonic snd_pcm_hw_params_is_monotonic_dylibloader_orig_asound +#define snd_pcm_hw_params_can_overrange snd_pcm_hw_params_can_overrange_dylibloader_orig_asound +#define snd_pcm_hw_params_can_pause snd_pcm_hw_params_can_pause_dylibloader_orig_asound +#define snd_pcm_hw_params_can_resume snd_pcm_hw_params_can_resume_dylibloader_orig_asound +#define snd_pcm_hw_params_is_half_duplex snd_pcm_hw_params_is_half_duplex_dylibloader_orig_asound +#define snd_pcm_hw_params_is_joint_duplex snd_pcm_hw_params_is_joint_duplex_dylibloader_orig_asound +#define snd_pcm_hw_params_can_sync_start snd_pcm_hw_params_can_sync_start_dylibloader_orig_asound +#define snd_pcm_hw_params_can_disable_period_wakeup snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_orig_asound +#define snd_pcm_hw_params_supports_audio_wallclock_ts snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_orig_asound +#define snd_pcm_hw_params_supports_audio_ts_type snd_pcm_hw_params_supports_audio_ts_type_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_numden snd_pcm_hw_params_get_rate_numden_dylibloader_orig_asound +#define snd_pcm_hw_params_get_sbits snd_pcm_hw_params_get_sbits_dylibloader_orig_asound +#define snd_pcm_hw_params_get_fifo_size snd_pcm_hw_params_get_fifo_size_dylibloader_orig_asound +#define snd_pcm_hw_params_sizeof snd_pcm_hw_params_sizeof_dylibloader_orig_asound +#define snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc_dylibloader_orig_asound +#define snd_pcm_hw_params_free snd_pcm_hw_params_free_dylibloader_orig_asound +#define snd_pcm_hw_params_copy snd_pcm_hw_params_copy_dylibloader_orig_asound +#define snd_pcm_hw_params_get_access snd_pcm_hw_params_get_access_dylibloader_orig_asound +#define snd_pcm_hw_params_test_access snd_pcm_hw_params_test_access_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access_first snd_pcm_hw_params_set_access_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access_last snd_pcm_hw_params_set_access_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_access_mask snd_pcm_hw_params_set_access_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_access_mask snd_pcm_hw_params_get_access_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_format snd_pcm_hw_params_get_format_dylibloader_orig_asound +#define snd_pcm_hw_params_test_format snd_pcm_hw_params_test_format_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format_first snd_pcm_hw_params_set_format_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format_last snd_pcm_hw_params_set_format_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_format_mask snd_pcm_hw_params_set_format_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_format_mask snd_pcm_hw_params_get_format_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_subformat snd_pcm_hw_params_get_subformat_dylibloader_orig_asound +#define snd_pcm_hw_params_test_subformat snd_pcm_hw_params_test_subformat_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat snd_pcm_hw_params_set_subformat_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat_first snd_pcm_hw_params_set_subformat_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat_last snd_pcm_hw_params_set_subformat_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_subformat_mask snd_pcm_hw_params_set_subformat_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_subformat_mask snd_pcm_hw_params_get_subformat_mask_dylibloader_orig_asound +#define snd_pcm_hw_params_get_channels snd_pcm_hw_params_get_channels_dylibloader_orig_asound +#define snd_pcm_hw_params_get_channels_min snd_pcm_hw_params_get_channels_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_channels_max snd_pcm_hw_params_get_channels_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_channels snd_pcm_hw_params_test_channels_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels snd_pcm_hw_params_set_channels_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_min snd_pcm_hw_params_set_channels_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_max snd_pcm_hw_params_set_channels_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_minmax snd_pcm_hw_params_set_channels_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_near snd_pcm_hw_params_set_channels_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_first snd_pcm_hw_params_set_channels_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_channels_last snd_pcm_hw_params_set_channels_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate snd_pcm_hw_params_get_rate_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_min snd_pcm_hw_params_get_rate_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_max snd_pcm_hw_params_get_rate_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_rate snd_pcm_hw_params_test_rate_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate snd_pcm_hw_params_set_rate_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_min snd_pcm_hw_params_set_rate_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_max snd_pcm_hw_params_set_rate_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_minmax snd_pcm_hw_params_set_rate_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_near snd_pcm_hw_params_set_rate_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_first snd_pcm_hw_params_set_rate_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_last snd_pcm_hw_params_set_rate_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_rate_resample snd_pcm_hw_params_set_rate_resample_dylibloader_orig_asound +#define snd_pcm_hw_params_get_rate_resample snd_pcm_hw_params_get_rate_resample_dylibloader_orig_asound +#define snd_pcm_hw_params_set_export_buffer snd_pcm_hw_params_set_export_buffer_dylibloader_orig_asound +#define snd_pcm_hw_params_get_export_buffer snd_pcm_hw_params_get_export_buffer_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_wakeup snd_pcm_hw_params_set_period_wakeup_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_wakeup snd_pcm_hw_params_get_period_wakeup_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_time snd_pcm_hw_params_get_period_time_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_time_min snd_pcm_hw_params_get_period_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_time_max snd_pcm_hw_params_get_period_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_period_time snd_pcm_hw_params_test_period_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time snd_pcm_hw_params_set_period_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_min snd_pcm_hw_params_set_period_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_max snd_pcm_hw_params_set_period_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_minmax snd_pcm_hw_params_set_period_time_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_near snd_pcm_hw_params_set_period_time_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_first snd_pcm_hw_params_set_period_time_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_time_last snd_pcm_hw_params_set_period_time_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_size snd_pcm_hw_params_get_period_size_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_size_min snd_pcm_hw_params_get_period_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_period_size_max snd_pcm_hw_params_get_period_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_period_size snd_pcm_hw_params_test_period_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size snd_pcm_hw_params_set_period_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_min snd_pcm_hw_params_set_period_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_max snd_pcm_hw_params_set_period_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_minmax snd_pcm_hw_params_set_period_size_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_near snd_pcm_hw_params_set_period_size_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_first snd_pcm_hw_params_set_period_size_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_last snd_pcm_hw_params_set_period_size_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_period_size_integer snd_pcm_hw_params_set_period_size_integer_dylibloader_orig_asound +#define snd_pcm_hw_params_get_periods snd_pcm_hw_params_get_periods_dylibloader_orig_asound +#define snd_pcm_hw_params_get_periods_min snd_pcm_hw_params_get_periods_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_periods_max snd_pcm_hw_params_get_periods_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_periods snd_pcm_hw_params_test_periods_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods snd_pcm_hw_params_set_periods_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_min snd_pcm_hw_params_set_periods_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_max snd_pcm_hw_params_set_periods_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_minmax snd_pcm_hw_params_set_periods_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_near snd_pcm_hw_params_set_periods_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_first snd_pcm_hw_params_set_periods_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_last snd_pcm_hw_params_set_periods_last_dylibloader_orig_asound +#define snd_pcm_hw_params_set_periods_integer snd_pcm_hw_params_set_periods_integer_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_time snd_pcm_hw_params_get_buffer_time_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_time_min snd_pcm_hw_params_get_buffer_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_time_max snd_pcm_hw_params_get_buffer_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_buffer_time snd_pcm_hw_params_test_buffer_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time snd_pcm_hw_params_set_buffer_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_min snd_pcm_hw_params_set_buffer_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_max snd_pcm_hw_params_set_buffer_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_minmax snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_near snd_pcm_hw_params_set_buffer_time_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_first snd_pcm_hw_params_set_buffer_time_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_time_last snd_pcm_hw_params_set_buffer_time_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_size snd_pcm_hw_params_get_buffer_size_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_size_min snd_pcm_hw_params_get_buffer_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_buffer_size_max snd_pcm_hw_params_get_buffer_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_buffer_size snd_pcm_hw_params_test_buffer_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size snd_pcm_hw_params_set_buffer_size_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_min snd_pcm_hw_params_set_buffer_size_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_max snd_pcm_hw_params_set_buffer_size_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_minmax snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_near snd_pcm_hw_params_set_buffer_size_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_first snd_pcm_hw_params_set_buffer_size_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_buffer_size_last snd_pcm_hw_params_set_buffer_size_last_dylibloader_orig_asound +#define snd_pcm_hw_params_get_min_align snd_pcm_hw_params_get_min_align_dylibloader_orig_asound +#define snd_pcm_sw_params_sizeof snd_pcm_sw_params_sizeof_dylibloader_orig_asound +#define snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc_dylibloader_orig_asound +#define snd_pcm_sw_params_free snd_pcm_sw_params_free_dylibloader_orig_asound +#define snd_pcm_sw_params_copy snd_pcm_sw_params_copy_dylibloader_orig_asound +#define snd_pcm_sw_params_get_boundary snd_pcm_sw_params_get_boundary_dylibloader_orig_asound +#define snd_pcm_sw_params_set_tstamp_mode snd_pcm_sw_params_set_tstamp_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_get_tstamp_mode snd_pcm_sw_params_get_tstamp_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_set_avail_min snd_pcm_sw_params_set_avail_min_dylibloader_orig_asound +#define snd_pcm_sw_params_get_avail_min snd_pcm_sw_params_get_avail_min_dylibloader_orig_asound +#define snd_pcm_sw_params_set_period_event snd_pcm_sw_params_set_period_event_dylibloader_orig_asound +#define snd_pcm_sw_params_get_period_event snd_pcm_sw_params_get_period_event_dylibloader_orig_asound +#define snd_pcm_sw_params_set_start_threshold snd_pcm_sw_params_set_start_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_get_start_threshold snd_pcm_sw_params_get_start_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_set_stop_threshold snd_pcm_sw_params_set_stop_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_get_stop_threshold snd_pcm_sw_params_get_stop_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_set_silence_threshold snd_pcm_sw_params_set_silence_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_get_silence_threshold snd_pcm_sw_params_get_silence_threshold_dylibloader_orig_asound +#define snd_pcm_sw_params_set_silence_size snd_pcm_sw_params_set_silence_size_dylibloader_orig_asound +#define snd_pcm_sw_params_get_silence_size snd_pcm_sw_params_get_silence_size_dylibloader_orig_asound +#define snd_pcm_access_mask_sizeof snd_pcm_access_mask_sizeof_dylibloader_orig_asound +#define snd_pcm_access_mask_malloc snd_pcm_access_mask_malloc_dylibloader_orig_asound +#define snd_pcm_access_mask_free snd_pcm_access_mask_free_dylibloader_orig_asound +#define snd_pcm_access_mask_copy snd_pcm_access_mask_copy_dylibloader_orig_asound +#define snd_pcm_access_mask_none snd_pcm_access_mask_none_dylibloader_orig_asound +#define snd_pcm_access_mask_any snd_pcm_access_mask_any_dylibloader_orig_asound +#define snd_pcm_access_mask_test snd_pcm_access_mask_test_dylibloader_orig_asound +#define snd_pcm_access_mask_empty snd_pcm_access_mask_empty_dylibloader_orig_asound +#define snd_pcm_access_mask_set snd_pcm_access_mask_set_dylibloader_orig_asound +#define snd_pcm_access_mask_reset snd_pcm_access_mask_reset_dylibloader_orig_asound +#define snd_pcm_format_mask_sizeof snd_pcm_format_mask_sizeof_dylibloader_orig_asound +#define snd_pcm_format_mask_malloc snd_pcm_format_mask_malloc_dylibloader_orig_asound +#define snd_pcm_format_mask_free snd_pcm_format_mask_free_dylibloader_orig_asound +#define snd_pcm_format_mask_copy snd_pcm_format_mask_copy_dylibloader_orig_asound +#define snd_pcm_format_mask_none snd_pcm_format_mask_none_dylibloader_orig_asound +#define snd_pcm_format_mask_any snd_pcm_format_mask_any_dylibloader_orig_asound +#define snd_pcm_format_mask_test snd_pcm_format_mask_test_dylibloader_orig_asound +#define snd_pcm_format_mask_empty snd_pcm_format_mask_empty_dylibloader_orig_asound +#define snd_pcm_format_mask_set snd_pcm_format_mask_set_dylibloader_orig_asound +#define snd_pcm_format_mask_reset snd_pcm_format_mask_reset_dylibloader_orig_asound +#define snd_pcm_subformat_mask_sizeof snd_pcm_subformat_mask_sizeof_dylibloader_orig_asound +#define snd_pcm_subformat_mask_malloc snd_pcm_subformat_mask_malloc_dylibloader_orig_asound +#define snd_pcm_subformat_mask_free snd_pcm_subformat_mask_free_dylibloader_orig_asound +#define snd_pcm_subformat_mask_copy snd_pcm_subformat_mask_copy_dylibloader_orig_asound +#define snd_pcm_subformat_mask_none snd_pcm_subformat_mask_none_dylibloader_orig_asound +#define snd_pcm_subformat_mask_any snd_pcm_subformat_mask_any_dylibloader_orig_asound +#define snd_pcm_subformat_mask_test snd_pcm_subformat_mask_test_dylibloader_orig_asound +#define snd_pcm_subformat_mask_empty snd_pcm_subformat_mask_empty_dylibloader_orig_asound +#define snd_pcm_subformat_mask_set snd_pcm_subformat_mask_set_dylibloader_orig_asound +#define snd_pcm_subformat_mask_reset snd_pcm_subformat_mask_reset_dylibloader_orig_asound +#define snd_pcm_status_sizeof snd_pcm_status_sizeof_dylibloader_orig_asound +#define snd_pcm_status_malloc snd_pcm_status_malloc_dylibloader_orig_asound +#define snd_pcm_status_free snd_pcm_status_free_dylibloader_orig_asound +#define snd_pcm_status_copy snd_pcm_status_copy_dylibloader_orig_asound +#define snd_pcm_status_get_state snd_pcm_status_get_state_dylibloader_orig_asound +#define snd_pcm_status_get_trigger_tstamp snd_pcm_status_get_trigger_tstamp_dylibloader_orig_asound +#define snd_pcm_status_get_trigger_htstamp snd_pcm_status_get_trigger_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_tstamp snd_pcm_status_get_tstamp_dylibloader_orig_asound +#define snd_pcm_status_get_htstamp snd_pcm_status_get_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_audio_htstamp snd_pcm_status_get_audio_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_driver_htstamp snd_pcm_status_get_driver_htstamp_dylibloader_orig_asound +#define snd_pcm_status_get_delay snd_pcm_status_get_delay_dylibloader_orig_asound +#define snd_pcm_status_get_avail snd_pcm_status_get_avail_dylibloader_orig_asound +#define snd_pcm_status_get_avail_max snd_pcm_status_get_avail_max_dylibloader_orig_asound +#define snd_pcm_status_get_overrange snd_pcm_status_get_overrange_dylibloader_orig_asound +#define snd_pcm_type_name snd_pcm_type_name_dylibloader_orig_asound +#define snd_pcm_stream_name snd_pcm_stream_name_dylibloader_orig_asound +#define snd_pcm_access_name snd_pcm_access_name_dylibloader_orig_asound +#define snd_pcm_format_name snd_pcm_format_name_dylibloader_orig_asound +#define snd_pcm_format_description snd_pcm_format_description_dylibloader_orig_asound +#define snd_pcm_subformat_name snd_pcm_subformat_name_dylibloader_orig_asound +#define snd_pcm_subformat_description snd_pcm_subformat_description_dylibloader_orig_asound +#define snd_pcm_format_value snd_pcm_format_value_dylibloader_orig_asound +#define snd_pcm_tstamp_mode_name snd_pcm_tstamp_mode_name_dylibloader_orig_asound +#define snd_pcm_state_name snd_pcm_state_name_dylibloader_orig_asound +#define snd_pcm_dump snd_pcm_dump_dylibloader_orig_asound +#define snd_pcm_dump_hw_setup snd_pcm_dump_hw_setup_dylibloader_orig_asound +#define snd_pcm_dump_sw_setup snd_pcm_dump_sw_setup_dylibloader_orig_asound +#define snd_pcm_dump_setup snd_pcm_dump_setup_dylibloader_orig_asound +#define snd_pcm_hw_params_dump snd_pcm_hw_params_dump_dylibloader_orig_asound +#define snd_pcm_sw_params_dump snd_pcm_sw_params_dump_dylibloader_orig_asound +#define snd_pcm_status_dump snd_pcm_status_dump_dylibloader_orig_asound +#define snd_pcm_mmap_begin snd_pcm_mmap_begin_dylibloader_orig_asound +#define snd_pcm_mmap_commit snd_pcm_mmap_commit_dylibloader_orig_asound +#define snd_pcm_mmap_writei snd_pcm_mmap_writei_dylibloader_orig_asound +#define snd_pcm_mmap_readi snd_pcm_mmap_readi_dylibloader_orig_asound +#define snd_pcm_mmap_writen snd_pcm_mmap_writen_dylibloader_orig_asound +#define snd_pcm_mmap_readn snd_pcm_mmap_readn_dylibloader_orig_asound +#define snd_pcm_format_signed snd_pcm_format_signed_dylibloader_orig_asound +#define snd_pcm_format_unsigned snd_pcm_format_unsigned_dylibloader_orig_asound +#define snd_pcm_format_linear snd_pcm_format_linear_dylibloader_orig_asound +#define snd_pcm_format_float snd_pcm_format_float_dylibloader_orig_asound +#define snd_pcm_format_little_endian snd_pcm_format_little_endian_dylibloader_orig_asound +#define snd_pcm_format_big_endian snd_pcm_format_big_endian_dylibloader_orig_asound +#define snd_pcm_format_cpu_endian snd_pcm_format_cpu_endian_dylibloader_orig_asound +#define snd_pcm_format_width snd_pcm_format_width_dylibloader_orig_asound +#define snd_pcm_format_physical_width snd_pcm_format_physical_width_dylibloader_orig_asound +#define snd_pcm_build_linear_format snd_pcm_build_linear_format_dylibloader_orig_asound +#define snd_pcm_format_size snd_pcm_format_size_dylibloader_orig_asound +#define snd_pcm_format_silence snd_pcm_format_silence_dylibloader_orig_asound +#define snd_pcm_format_silence_16 snd_pcm_format_silence_16_dylibloader_orig_asound +#define snd_pcm_format_silence_32 snd_pcm_format_silence_32_dylibloader_orig_asound +#define snd_pcm_format_silence_64 snd_pcm_format_silence_64_dylibloader_orig_asound +#define snd_pcm_format_set_silence snd_pcm_format_set_silence_dylibloader_orig_asound +#define snd_pcm_bytes_to_frames snd_pcm_bytes_to_frames_dylibloader_orig_asound +#define snd_pcm_frames_to_bytes snd_pcm_frames_to_bytes_dylibloader_orig_asound +#define snd_pcm_bytes_to_samples snd_pcm_bytes_to_samples_dylibloader_orig_asound +#define snd_pcm_samples_to_bytes snd_pcm_samples_to_bytes_dylibloader_orig_asound +#define snd_pcm_area_silence snd_pcm_area_silence_dylibloader_orig_asound +#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_orig_asound +#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_orig_asound +#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_orig_asound +#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_orig_asound +#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_orig_asound +#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_orig_asound +#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_orig_asound +#define snd_pcm_hook_add snd_pcm_hook_add_dylibloader_orig_asound +#define snd_pcm_hook_remove snd_pcm_hook_remove_dylibloader_orig_asound +#define snd_pcm_meter_get_bufsize snd_pcm_meter_get_bufsize_dylibloader_orig_asound +#define snd_pcm_meter_get_channels snd_pcm_meter_get_channels_dylibloader_orig_asound +#define snd_pcm_meter_get_rate snd_pcm_meter_get_rate_dylibloader_orig_asound +#define snd_pcm_meter_get_now snd_pcm_meter_get_now_dylibloader_orig_asound +#define snd_pcm_meter_get_boundary snd_pcm_meter_get_boundary_dylibloader_orig_asound +#define snd_pcm_meter_add_scope snd_pcm_meter_add_scope_dylibloader_orig_asound +#define snd_pcm_meter_search_scope snd_pcm_meter_search_scope_dylibloader_orig_asound +#define snd_pcm_scope_malloc snd_pcm_scope_malloc_dylibloader_orig_asound +#define snd_pcm_scope_set_ops snd_pcm_scope_set_ops_dylibloader_orig_asound +#define snd_pcm_scope_set_name snd_pcm_scope_set_name_dylibloader_orig_asound +#define snd_pcm_scope_get_name snd_pcm_scope_get_name_dylibloader_orig_asound +#define snd_pcm_scope_get_callback_private snd_pcm_scope_get_callback_private_dylibloader_orig_asound +#define snd_pcm_scope_set_callback_private snd_pcm_scope_set_callback_private_dylibloader_orig_asound +#define snd_pcm_scope_s16_open snd_pcm_scope_s16_open_dylibloader_orig_asound +#define snd_pcm_scope_s16_get_channel_buffer snd_pcm_scope_s16_get_channel_buffer_dylibloader_orig_asound +#define snd_spcm_init snd_spcm_init_dylibloader_orig_asound +#define snd_spcm_init_duplex snd_spcm_init_duplex_dylibloader_orig_asound +#define snd_spcm_init_get_params snd_spcm_init_get_params_dylibloader_orig_asound +#define snd_pcm_start_mode_name snd_pcm_start_mode_name_dylibloader_orig_asound +#define snd_pcm_xrun_mode_name snd_pcm_xrun_mode_name_dylibloader_orig_asound +#define snd_pcm_sw_params_set_start_mode snd_pcm_sw_params_set_start_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_get_start_mode snd_pcm_sw_params_get_start_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_set_xrun_mode snd_pcm_sw_params_set_xrun_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_get_xrun_mode snd_pcm_sw_params_get_xrun_mode_dylibloader_orig_asound +#define snd_pcm_sw_params_set_xfer_align snd_pcm_sw_params_set_xfer_align_dylibloader_orig_asound +#define snd_pcm_sw_params_get_xfer_align snd_pcm_sw_params_get_xfer_align_dylibloader_orig_asound +#define snd_pcm_sw_params_set_sleep_min snd_pcm_sw_params_set_sleep_min_dylibloader_orig_asound +#define snd_pcm_sw_params_get_sleep_min snd_pcm_sw_params_get_sleep_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_tick_time snd_pcm_hw_params_get_tick_time_dylibloader_orig_asound +#define snd_pcm_hw_params_get_tick_time_min snd_pcm_hw_params_get_tick_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_get_tick_time_max snd_pcm_hw_params_get_tick_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_test_tick_time snd_pcm_hw_params_test_tick_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time snd_pcm_hw_params_set_tick_time_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_min snd_pcm_hw_params_set_tick_time_min_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_max snd_pcm_hw_params_set_tick_time_max_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_minmax snd_pcm_hw_params_set_tick_time_minmax_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_near snd_pcm_hw_params_set_tick_time_near_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_first snd_pcm_hw_params_set_tick_time_first_dylibloader_orig_asound +#define snd_pcm_hw_params_set_tick_time_last snd_pcm_hw_params_set_tick_time_last_dylibloader_orig_asound +#define snd_rawmidi_open snd_rawmidi_open_dylibloader_orig_asound +#define snd_rawmidi_open_lconf snd_rawmidi_open_lconf_dylibloader_orig_asound +#define snd_rawmidi_close snd_rawmidi_close_dylibloader_orig_asound +#define snd_rawmidi_poll_descriptors_count snd_rawmidi_poll_descriptors_count_dylibloader_orig_asound +#define snd_rawmidi_poll_descriptors snd_rawmidi_poll_descriptors_dylibloader_orig_asound +#define snd_rawmidi_poll_descriptors_revents snd_rawmidi_poll_descriptors_revents_dylibloader_orig_asound +#define snd_rawmidi_nonblock snd_rawmidi_nonblock_dylibloader_orig_asound +#define snd_rawmidi_info_sizeof snd_rawmidi_info_sizeof_dylibloader_orig_asound +#define snd_rawmidi_info_malloc snd_rawmidi_info_malloc_dylibloader_orig_asound +#define snd_rawmidi_info_free snd_rawmidi_info_free_dylibloader_orig_asound +#define snd_rawmidi_info_copy snd_rawmidi_info_copy_dylibloader_orig_asound +#define snd_rawmidi_info_get_device snd_rawmidi_info_get_device_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevice snd_rawmidi_info_get_subdevice_dylibloader_orig_asound +#define snd_rawmidi_info_get_stream snd_rawmidi_info_get_stream_dylibloader_orig_asound +#define snd_rawmidi_info_get_card snd_rawmidi_info_get_card_dylibloader_orig_asound +#define snd_rawmidi_info_get_flags snd_rawmidi_info_get_flags_dylibloader_orig_asound +#define snd_rawmidi_info_get_id snd_rawmidi_info_get_id_dylibloader_orig_asound +#define snd_rawmidi_info_get_name snd_rawmidi_info_get_name_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevice_name snd_rawmidi_info_get_subdevice_name_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevices_count snd_rawmidi_info_get_subdevices_count_dylibloader_orig_asound +#define snd_rawmidi_info_get_subdevices_avail snd_rawmidi_info_get_subdevices_avail_dylibloader_orig_asound +#define snd_rawmidi_info_set_device snd_rawmidi_info_set_device_dylibloader_orig_asound +#define snd_rawmidi_info_set_subdevice snd_rawmidi_info_set_subdevice_dylibloader_orig_asound +#define snd_rawmidi_info_set_stream snd_rawmidi_info_set_stream_dylibloader_orig_asound +#define snd_rawmidi_info snd_rawmidi_info_dylibloader_orig_asound +#define snd_rawmidi_params_sizeof snd_rawmidi_params_sizeof_dylibloader_orig_asound +#define snd_rawmidi_params_malloc snd_rawmidi_params_malloc_dylibloader_orig_asound +#define snd_rawmidi_params_free snd_rawmidi_params_free_dylibloader_orig_asound +#define snd_rawmidi_params_copy snd_rawmidi_params_copy_dylibloader_orig_asound +#define snd_rawmidi_params_set_buffer_size snd_rawmidi_params_set_buffer_size_dylibloader_orig_asound +#define snd_rawmidi_params_get_buffer_size snd_rawmidi_params_get_buffer_size_dylibloader_orig_asound +#define snd_rawmidi_params_set_avail_min snd_rawmidi_params_set_avail_min_dylibloader_orig_asound +#define snd_rawmidi_params_get_avail_min snd_rawmidi_params_get_avail_min_dylibloader_orig_asound +#define snd_rawmidi_params_set_no_active_sensing snd_rawmidi_params_set_no_active_sensing_dylibloader_orig_asound +#define snd_rawmidi_params_get_no_active_sensing snd_rawmidi_params_get_no_active_sensing_dylibloader_orig_asound +#define snd_rawmidi_params snd_rawmidi_params_dylibloader_orig_asound +#define snd_rawmidi_params_current snd_rawmidi_params_current_dylibloader_orig_asound +#define snd_rawmidi_status_sizeof snd_rawmidi_status_sizeof_dylibloader_orig_asound +#define snd_rawmidi_status_malloc snd_rawmidi_status_malloc_dylibloader_orig_asound +#define snd_rawmidi_status_free snd_rawmidi_status_free_dylibloader_orig_asound +#define snd_rawmidi_status_copy snd_rawmidi_status_copy_dylibloader_orig_asound +#define snd_rawmidi_status_get_tstamp snd_rawmidi_status_get_tstamp_dylibloader_orig_asound +#define snd_rawmidi_status_get_avail snd_rawmidi_status_get_avail_dylibloader_orig_asound +#define snd_rawmidi_status_get_xruns snd_rawmidi_status_get_xruns_dylibloader_orig_asound +#define snd_rawmidi_status snd_rawmidi_status_dylibloader_orig_asound +#define snd_rawmidi_drain snd_rawmidi_drain_dylibloader_orig_asound +#define snd_rawmidi_drop snd_rawmidi_drop_dylibloader_orig_asound +#define snd_rawmidi_write snd_rawmidi_write_dylibloader_orig_asound +#define snd_rawmidi_read snd_rawmidi_read_dylibloader_orig_asound +#define snd_rawmidi_name snd_rawmidi_name_dylibloader_orig_asound +#define snd_rawmidi_type snd_rawmidi_type_dylibloader_orig_asound +#define snd_rawmidi_stream snd_rawmidi_stream_dylibloader_orig_asound +#define snd_timer_query_open snd_timer_query_open_dylibloader_orig_asound +#define snd_timer_query_open_lconf snd_timer_query_open_lconf_dylibloader_orig_asound +#define snd_timer_query_close snd_timer_query_close_dylibloader_orig_asound +#define snd_timer_query_next_device snd_timer_query_next_device_dylibloader_orig_asound +#define snd_timer_query_info snd_timer_query_info_dylibloader_orig_asound +#define snd_timer_query_params snd_timer_query_params_dylibloader_orig_asound +#define snd_timer_query_status snd_timer_query_status_dylibloader_orig_asound +#define snd_timer_open snd_timer_open_dylibloader_orig_asound +#define snd_timer_open_lconf snd_timer_open_lconf_dylibloader_orig_asound +#define snd_timer_close snd_timer_close_dylibloader_orig_asound +#define snd_async_add_timer_handler snd_async_add_timer_handler_dylibloader_orig_asound +#define snd_async_handler_get_timer snd_async_handler_get_timer_dylibloader_orig_asound +#define snd_timer_poll_descriptors_count snd_timer_poll_descriptors_count_dylibloader_orig_asound +#define snd_timer_poll_descriptors snd_timer_poll_descriptors_dylibloader_orig_asound +#define snd_timer_poll_descriptors_revents snd_timer_poll_descriptors_revents_dylibloader_orig_asound +#define snd_timer_info snd_timer_info_dylibloader_orig_asound +#define snd_timer_params snd_timer_params_dylibloader_orig_asound +#define snd_timer_status snd_timer_status_dylibloader_orig_asound +#define snd_timer_start snd_timer_start_dylibloader_orig_asound +#define snd_timer_stop snd_timer_stop_dylibloader_orig_asound +#define snd_timer_continue snd_timer_continue_dylibloader_orig_asound +#define snd_timer_read snd_timer_read_dylibloader_orig_asound +#define snd_timer_id_sizeof snd_timer_id_sizeof_dylibloader_orig_asound +#define snd_timer_id_malloc snd_timer_id_malloc_dylibloader_orig_asound +#define snd_timer_id_free snd_timer_id_free_dylibloader_orig_asound +#define snd_timer_id_copy snd_timer_id_copy_dylibloader_orig_asound +#define snd_timer_id_set_class snd_timer_id_set_class_dylibloader_orig_asound +#define snd_timer_id_get_class snd_timer_id_get_class_dylibloader_orig_asound +#define snd_timer_id_set_sclass snd_timer_id_set_sclass_dylibloader_orig_asound +#define snd_timer_id_get_sclass snd_timer_id_get_sclass_dylibloader_orig_asound +#define snd_timer_id_set_card snd_timer_id_set_card_dylibloader_orig_asound +#define snd_timer_id_get_card snd_timer_id_get_card_dylibloader_orig_asound +#define snd_timer_id_set_device snd_timer_id_set_device_dylibloader_orig_asound +#define snd_timer_id_get_device snd_timer_id_get_device_dylibloader_orig_asound +#define snd_timer_id_set_subdevice snd_timer_id_set_subdevice_dylibloader_orig_asound +#define snd_timer_id_get_subdevice snd_timer_id_get_subdevice_dylibloader_orig_asound +#define snd_timer_ginfo_sizeof snd_timer_ginfo_sizeof_dylibloader_orig_asound +#define snd_timer_ginfo_malloc snd_timer_ginfo_malloc_dylibloader_orig_asound +#define snd_timer_ginfo_free snd_timer_ginfo_free_dylibloader_orig_asound +#define snd_timer_ginfo_copy snd_timer_ginfo_copy_dylibloader_orig_asound +#define snd_timer_ginfo_set_tid snd_timer_ginfo_set_tid_dylibloader_orig_asound +#define snd_timer_ginfo_get_tid snd_timer_ginfo_get_tid_dylibloader_orig_asound +#define snd_timer_ginfo_get_flags snd_timer_ginfo_get_flags_dylibloader_orig_asound +#define snd_timer_ginfo_get_card snd_timer_ginfo_get_card_dylibloader_orig_asound +#define snd_timer_ginfo_get_id snd_timer_ginfo_get_id_dylibloader_orig_asound +#define snd_timer_ginfo_get_name snd_timer_ginfo_get_name_dylibloader_orig_asound +#define snd_timer_ginfo_get_resolution snd_timer_ginfo_get_resolution_dylibloader_orig_asound +#define snd_timer_ginfo_get_resolution_min snd_timer_ginfo_get_resolution_min_dylibloader_orig_asound +#define snd_timer_ginfo_get_resolution_max snd_timer_ginfo_get_resolution_max_dylibloader_orig_asound +#define snd_timer_ginfo_get_clients snd_timer_ginfo_get_clients_dylibloader_orig_asound +#define snd_timer_info_sizeof snd_timer_info_sizeof_dylibloader_orig_asound +#define snd_timer_info_malloc snd_timer_info_malloc_dylibloader_orig_asound +#define snd_timer_info_free snd_timer_info_free_dylibloader_orig_asound +#define snd_timer_info_copy snd_timer_info_copy_dylibloader_orig_asound +#define snd_timer_info_is_slave snd_timer_info_is_slave_dylibloader_orig_asound +#define snd_timer_info_get_card snd_timer_info_get_card_dylibloader_orig_asound +#define snd_timer_info_get_id snd_timer_info_get_id_dylibloader_orig_asound +#define snd_timer_info_get_name snd_timer_info_get_name_dylibloader_orig_asound +#define snd_timer_info_get_resolution snd_timer_info_get_resolution_dylibloader_orig_asound +#define snd_timer_params_sizeof snd_timer_params_sizeof_dylibloader_orig_asound +#define snd_timer_params_malloc snd_timer_params_malloc_dylibloader_orig_asound +#define snd_timer_params_free snd_timer_params_free_dylibloader_orig_asound +#define snd_timer_params_copy snd_timer_params_copy_dylibloader_orig_asound +#define snd_timer_params_set_auto_start snd_timer_params_set_auto_start_dylibloader_orig_asound +#define snd_timer_params_get_auto_start snd_timer_params_get_auto_start_dylibloader_orig_asound +#define snd_timer_params_set_exclusive snd_timer_params_set_exclusive_dylibloader_orig_asound +#define snd_timer_params_get_exclusive snd_timer_params_get_exclusive_dylibloader_orig_asound +#define snd_timer_params_set_early_event snd_timer_params_set_early_event_dylibloader_orig_asound +#define snd_timer_params_get_early_event snd_timer_params_get_early_event_dylibloader_orig_asound +#define snd_timer_params_set_ticks snd_timer_params_set_ticks_dylibloader_orig_asound +#define snd_timer_params_get_ticks snd_timer_params_get_ticks_dylibloader_orig_asound +#define snd_timer_params_set_queue_size snd_timer_params_set_queue_size_dylibloader_orig_asound +#define snd_timer_params_get_queue_size snd_timer_params_get_queue_size_dylibloader_orig_asound +#define snd_timer_params_set_filter snd_timer_params_set_filter_dylibloader_orig_asound +#define snd_timer_params_get_filter snd_timer_params_get_filter_dylibloader_orig_asound +#define snd_timer_status_sizeof snd_timer_status_sizeof_dylibloader_orig_asound +#define snd_timer_status_malloc snd_timer_status_malloc_dylibloader_orig_asound +#define snd_timer_status_free snd_timer_status_free_dylibloader_orig_asound +#define snd_timer_status_copy snd_timer_status_copy_dylibloader_orig_asound +#define snd_timer_status_get_timestamp snd_timer_status_get_timestamp_dylibloader_orig_asound +#define snd_timer_status_get_resolution snd_timer_status_get_resolution_dylibloader_orig_asound +#define snd_timer_status_get_lost snd_timer_status_get_lost_dylibloader_orig_asound +#define snd_timer_status_get_overrun snd_timer_status_get_overrun_dylibloader_orig_asound +#define snd_timer_status_get_queue snd_timer_status_get_queue_dylibloader_orig_asound +#define snd_timer_info_get_ticks snd_timer_info_get_ticks_dylibloader_orig_asound +#define snd_hwdep_open snd_hwdep_open_dylibloader_orig_asound +#define snd_hwdep_close snd_hwdep_close_dylibloader_orig_asound +#define snd_hwdep_poll_descriptors snd_hwdep_poll_descriptors_dylibloader_orig_asound +#define snd_hwdep_poll_descriptors_count snd_hwdep_poll_descriptors_count_dylibloader_orig_asound +#define snd_hwdep_poll_descriptors_revents snd_hwdep_poll_descriptors_revents_dylibloader_orig_asound +#define snd_hwdep_nonblock snd_hwdep_nonblock_dylibloader_orig_asound +#define snd_hwdep_info snd_hwdep_info_dylibloader_orig_asound +#define snd_hwdep_dsp_status snd_hwdep_dsp_status_dylibloader_orig_asound +#define snd_hwdep_dsp_load snd_hwdep_dsp_load_dylibloader_orig_asound +#define snd_hwdep_ioctl snd_hwdep_ioctl_dylibloader_orig_asound +#define snd_hwdep_write snd_hwdep_write_dylibloader_orig_asound +#define snd_hwdep_read snd_hwdep_read_dylibloader_orig_asound +#define snd_hwdep_info_sizeof snd_hwdep_info_sizeof_dylibloader_orig_asound +#define snd_hwdep_info_malloc snd_hwdep_info_malloc_dylibloader_orig_asound +#define snd_hwdep_info_free snd_hwdep_info_free_dylibloader_orig_asound +#define snd_hwdep_info_copy snd_hwdep_info_copy_dylibloader_orig_asound +#define snd_hwdep_info_get_device snd_hwdep_info_get_device_dylibloader_orig_asound +#define snd_hwdep_info_get_card snd_hwdep_info_get_card_dylibloader_orig_asound +#define snd_hwdep_info_get_id snd_hwdep_info_get_id_dylibloader_orig_asound +#define snd_hwdep_info_get_name snd_hwdep_info_get_name_dylibloader_orig_asound +#define snd_hwdep_info_get_iface snd_hwdep_info_get_iface_dylibloader_orig_asound +#define snd_hwdep_info_set_device snd_hwdep_info_set_device_dylibloader_orig_asound +#define snd_hwdep_dsp_status_sizeof snd_hwdep_dsp_status_sizeof_dylibloader_orig_asound +#define snd_hwdep_dsp_status_malloc snd_hwdep_dsp_status_malloc_dylibloader_orig_asound +#define snd_hwdep_dsp_status_free snd_hwdep_dsp_status_free_dylibloader_orig_asound +#define snd_hwdep_dsp_status_copy snd_hwdep_dsp_status_copy_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_version snd_hwdep_dsp_status_get_version_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_id snd_hwdep_dsp_status_get_id_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_num_dsps snd_hwdep_dsp_status_get_num_dsps_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_dsp_loaded snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_orig_asound +#define snd_hwdep_dsp_status_get_chip_ready snd_hwdep_dsp_status_get_chip_ready_dylibloader_orig_asound +#define snd_hwdep_dsp_image_sizeof snd_hwdep_dsp_image_sizeof_dylibloader_orig_asound +#define snd_hwdep_dsp_image_malloc snd_hwdep_dsp_image_malloc_dylibloader_orig_asound +#define snd_hwdep_dsp_image_free snd_hwdep_dsp_image_free_dylibloader_orig_asound +#define snd_hwdep_dsp_image_copy snd_hwdep_dsp_image_copy_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_index snd_hwdep_dsp_image_get_index_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_name snd_hwdep_dsp_image_get_name_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_image snd_hwdep_dsp_image_get_image_dylibloader_orig_asound +#define snd_hwdep_dsp_image_get_length snd_hwdep_dsp_image_get_length_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_index snd_hwdep_dsp_image_set_index_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_name snd_hwdep_dsp_image_set_name_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_image snd_hwdep_dsp_image_set_image_dylibloader_orig_asound +#define snd_hwdep_dsp_image_set_length snd_hwdep_dsp_image_set_length_dylibloader_orig_asound +#define snd_card_load snd_card_load_dylibloader_orig_asound +#define snd_card_next snd_card_next_dylibloader_orig_asound +#define snd_card_get_index snd_card_get_index_dylibloader_orig_asound +#define snd_card_get_name snd_card_get_name_dylibloader_orig_asound +#define snd_card_get_longname snd_card_get_longname_dylibloader_orig_asound +#define snd_device_name_hint snd_device_name_hint_dylibloader_orig_asound +#define snd_device_name_free_hint snd_device_name_free_hint_dylibloader_orig_asound +#define snd_device_name_get_hint snd_device_name_get_hint_dylibloader_orig_asound +#define snd_ctl_open snd_ctl_open_dylibloader_orig_asound +#define snd_ctl_open_lconf snd_ctl_open_lconf_dylibloader_orig_asound +#define snd_ctl_open_fallback snd_ctl_open_fallback_dylibloader_orig_asound +#define snd_ctl_close snd_ctl_close_dylibloader_orig_asound +#define snd_ctl_nonblock snd_ctl_nonblock_dylibloader_orig_asound +#define snd_async_add_ctl_handler snd_async_add_ctl_handler_dylibloader_orig_asound +#define snd_async_handler_get_ctl snd_async_handler_get_ctl_dylibloader_orig_asound +#define snd_ctl_poll_descriptors_count snd_ctl_poll_descriptors_count_dylibloader_orig_asound +#define snd_ctl_poll_descriptors snd_ctl_poll_descriptors_dylibloader_orig_asound +#define snd_ctl_poll_descriptors_revents snd_ctl_poll_descriptors_revents_dylibloader_orig_asound +#define snd_ctl_subscribe_events snd_ctl_subscribe_events_dylibloader_orig_asound +#define snd_ctl_card_info snd_ctl_card_info_dylibloader_orig_asound +#define snd_ctl_elem_list snd_ctl_elem_list_dylibloader_orig_asound +#define snd_ctl_elem_info snd_ctl_elem_info_dylibloader_orig_asound +#define snd_ctl_elem_read snd_ctl_elem_read_dylibloader_orig_asound +#define snd_ctl_elem_write snd_ctl_elem_write_dylibloader_orig_asound +#define snd_ctl_elem_lock snd_ctl_elem_lock_dylibloader_orig_asound +#define snd_ctl_elem_unlock snd_ctl_elem_unlock_dylibloader_orig_asound +#define snd_ctl_elem_tlv_read snd_ctl_elem_tlv_read_dylibloader_orig_asound +#define snd_ctl_elem_tlv_write snd_ctl_elem_tlv_write_dylibloader_orig_asound +#define snd_ctl_elem_tlv_command snd_ctl_elem_tlv_command_dylibloader_orig_asound +#define snd_ctl_hwdep_next_device snd_ctl_hwdep_next_device_dylibloader_orig_asound +#define snd_ctl_hwdep_info snd_ctl_hwdep_info_dylibloader_orig_asound +#define snd_ctl_pcm_next_device snd_ctl_pcm_next_device_dylibloader_orig_asound +#define snd_ctl_pcm_info snd_ctl_pcm_info_dylibloader_orig_asound +#define snd_ctl_pcm_prefer_subdevice snd_ctl_pcm_prefer_subdevice_dylibloader_orig_asound +#define snd_ctl_rawmidi_next_device snd_ctl_rawmidi_next_device_dylibloader_orig_asound +#define snd_ctl_rawmidi_info snd_ctl_rawmidi_info_dylibloader_orig_asound +#define snd_ctl_rawmidi_prefer_subdevice snd_ctl_rawmidi_prefer_subdevice_dylibloader_orig_asound +#define snd_ctl_set_power_state snd_ctl_set_power_state_dylibloader_orig_asound +#define snd_ctl_get_power_state snd_ctl_get_power_state_dylibloader_orig_asound +#define snd_ctl_read snd_ctl_read_dylibloader_orig_asound +#define snd_ctl_wait snd_ctl_wait_dylibloader_orig_asound +#define snd_ctl_name snd_ctl_name_dylibloader_orig_asound +#define snd_ctl_type snd_ctl_type_dylibloader_orig_asound +#define snd_ctl_elem_type_name snd_ctl_elem_type_name_dylibloader_orig_asound +#define snd_ctl_elem_iface_name snd_ctl_elem_iface_name_dylibloader_orig_asound +#define snd_ctl_event_type_name snd_ctl_event_type_name_dylibloader_orig_asound +#define snd_ctl_event_elem_get_mask snd_ctl_event_elem_get_mask_dylibloader_orig_asound +#define snd_ctl_event_elem_get_numid snd_ctl_event_elem_get_numid_dylibloader_orig_asound +#define snd_ctl_event_elem_get_id snd_ctl_event_elem_get_id_dylibloader_orig_asound +#define snd_ctl_event_elem_get_interface snd_ctl_event_elem_get_interface_dylibloader_orig_asound +#define snd_ctl_event_elem_get_device snd_ctl_event_elem_get_device_dylibloader_orig_asound +#define snd_ctl_event_elem_get_subdevice snd_ctl_event_elem_get_subdevice_dylibloader_orig_asound +#define snd_ctl_event_elem_get_name snd_ctl_event_elem_get_name_dylibloader_orig_asound +#define snd_ctl_event_elem_get_index snd_ctl_event_elem_get_index_dylibloader_orig_asound +#define snd_ctl_elem_list_alloc_space snd_ctl_elem_list_alloc_space_dylibloader_orig_asound +#define snd_ctl_elem_list_free_space snd_ctl_elem_list_free_space_dylibloader_orig_asound +#define snd_ctl_ascii_elem_id_get snd_ctl_ascii_elem_id_get_dylibloader_orig_asound +#define snd_ctl_ascii_elem_id_parse snd_ctl_ascii_elem_id_parse_dylibloader_orig_asound +#define snd_ctl_ascii_value_parse snd_ctl_ascii_value_parse_dylibloader_orig_asound +#define snd_ctl_elem_id_sizeof snd_ctl_elem_id_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_id_malloc snd_ctl_elem_id_malloc_dylibloader_orig_asound +#define snd_ctl_elem_id_free snd_ctl_elem_id_free_dylibloader_orig_asound +#define snd_ctl_elem_id_clear snd_ctl_elem_id_clear_dylibloader_orig_asound +#define snd_ctl_elem_id_copy snd_ctl_elem_id_copy_dylibloader_orig_asound +#define snd_ctl_elem_id_get_numid snd_ctl_elem_id_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_id_get_interface snd_ctl_elem_id_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_id_get_device snd_ctl_elem_id_get_device_dylibloader_orig_asound +#define snd_ctl_elem_id_get_subdevice snd_ctl_elem_id_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_id_get_name snd_ctl_elem_id_get_name_dylibloader_orig_asound +#define snd_ctl_elem_id_get_index snd_ctl_elem_id_get_index_dylibloader_orig_asound +#define snd_ctl_elem_id_set_numid snd_ctl_elem_id_set_numid_dylibloader_orig_asound +#define snd_ctl_elem_id_set_interface snd_ctl_elem_id_set_interface_dylibloader_orig_asound +#define snd_ctl_elem_id_set_device snd_ctl_elem_id_set_device_dylibloader_orig_asound +#define snd_ctl_elem_id_set_subdevice snd_ctl_elem_id_set_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_id_set_name snd_ctl_elem_id_set_name_dylibloader_orig_asound +#define snd_ctl_elem_id_set_index snd_ctl_elem_id_set_index_dylibloader_orig_asound +#define snd_ctl_card_info_sizeof snd_ctl_card_info_sizeof_dylibloader_orig_asound +#define snd_ctl_card_info_malloc snd_ctl_card_info_malloc_dylibloader_orig_asound +#define snd_ctl_card_info_free snd_ctl_card_info_free_dylibloader_orig_asound +#define snd_ctl_card_info_clear snd_ctl_card_info_clear_dylibloader_orig_asound +#define snd_ctl_card_info_copy snd_ctl_card_info_copy_dylibloader_orig_asound +#define snd_ctl_card_info_get_card snd_ctl_card_info_get_card_dylibloader_orig_asound +#define snd_ctl_card_info_get_id snd_ctl_card_info_get_id_dylibloader_orig_asound +#define snd_ctl_card_info_get_driver snd_ctl_card_info_get_driver_dylibloader_orig_asound +#define snd_ctl_card_info_get_name snd_ctl_card_info_get_name_dylibloader_orig_asound +#define snd_ctl_card_info_get_longname snd_ctl_card_info_get_longname_dylibloader_orig_asound +#define snd_ctl_card_info_get_mixername snd_ctl_card_info_get_mixername_dylibloader_orig_asound +#define snd_ctl_card_info_get_components snd_ctl_card_info_get_components_dylibloader_orig_asound +#define snd_ctl_event_sizeof snd_ctl_event_sizeof_dylibloader_orig_asound +#define snd_ctl_event_malloc snd_ctl_event_malloc_dylibloader_orig_asound +#define snd_ctl_event_free snd_ctl_event_free_dylibloader_orig_asound +#define snd_ctl_event_clear snd_ctl_event_clear_dylibloader_orig_asound +#define snd_ctl_event_copy snd_ctl_event_copy_dylibloader_orig_asound +#define snd_ctl_event_get_type snd_ctl_event_get_type_dylibloader_orig_asound +#define snd_ctl_elem_list_sizeof snd_ctl_elem_list_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_list_malloc snd_ctl_elem_list_malloc_dylibloader_orig_asound +#define snd_ctl_elem_list_free snd_ctl_elem_list_free_dylibloader_orig_asound +#define snd_ctl_elem_list_clear snd_ctl_elem_list_clear_dylibloader_orig_asound +#define snd_ctl_elem_list_copy snd_ctl_elem_list_copy_dylibloader_orig_asound +#define snd_ctl_elem_list_set_offset snd_ctl_elem_list_set_offset_dylibloader_orig_asound +#define snd_ctl_elem_list_get_used snd_ctl_elem_list_get_used_dylibloader_orig_asound +#define snd_ctl_elem_list_get_count snd_ctl_elem_list_get_count_dylibloader_orig_asound +#define snd_ctl_elem_list_get_id snd_ctl_elem_list_get_id_dylibloader_orig_asound +#define snd_ctl_elem_list_get_numid snd_ctl_elem_list_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_list_get_interface snd_ctl_elem_list_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_list_get_device snd_ctl_elem_list_get_device_dylibloader_orig_asound +#define snd_ctl_elem_list_get_subdevice snd_ctl_elem_list_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_list_get_name snd_ctl_elem_list_get_name_dylibloader_orig_asound +#define snd_ctl_elem_list_get_index snd_ctl_elem_list_get_index_dylibloader_orig_asound +#define snd_ctl_elem_info_sizeof snd_ctl_elem_info_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_info_malloc snd_ctl_elem_info_malloc_dylibloader_orig_asound +#define snd_ctl_elem_info_free snd_ctl_elem_info_free_dylibloader_orig_asound +#define snd_ctl_elem_info_clear snd_ctl_elem_info_clear_dylibloader_orig_asound +#define snd_ctl_elem_info_copy snd_ctl_elem_info_copy_dylibloader_orig_asound +#define snd_ctl_elem_info_get_type snd_ctl_elem_info_get_type_dylibloader_orig_asound +#define snd_ctl_elem_info_is_readable snd_ctl_elem_info_is_readable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_writable snd_ctl_elem_info_is_writable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_volatile snd_ctl_elem_info_is_volatile_dylibloader_orig_asound +#define snd_ctl_elem_info_is_inactive snd_ctl_elem_info_is_inactive_dylibloader_orig_asound +#define snd_ctl_elem_info_is_locked snd_ctl_elem_info_is_locked_dylibloader_orig_asound +#define snd_ctl_elem_info_is_tlv_readable snd_ctl_elem_info_is_tlv_readable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_tlv_writable snd_ctl_elem_info_is_tlv_writable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_tlv_commandable snd_ctl_elem_info_is_tlv_commandable_dylibloader_orig_asound +#define snd_ctl_elem_info_is_owner snd_ctl_elem_info_is_owner_dylibloader_orig_asound +#define snd_ctl_elem_info_is_user snd_ctl_elem_info_is_user_dylibloader_orig_asound +#define snd_ctl_elem_info_get_owner snd_ctl_elem_info_get_owner_dylibloader_orig_asound +#define snd_ctl_elem_info_get_count snd_ctl_elem_info_get_count_dylibloader_orig_asound +#define snd_ctl_elem_info_get_min snd_ctl_elem_info_get_min_dylibloader_orig_asound +#define snd_ctl_elem_info_get_max snd_ctl_elem_info_get_max_dylibloader_orig_asound +#define snd_ctl_elem_info_get_step snd_ctl_elem_info_get_step_dylibloader_orig_asound +#define snd_ctl_elem_info_get_min64 snd_ctl_elem_info_get_min64_dylibloader_orig_asound +#define snd_ctl_elem_info_get_max64 snd_ctl_elem_info_get_max64_dylibloader_orig_asound +#define snd_ctl_elem_info_get_step64 snd_ctl_elem_info_get_step64_dylibloader_orig_asound +#define snd_ctl_elem_info_get_items snd_ctl_elem_info_get_items_dylibloader_orig_asound +#define snd_ctl_elem_info_set_item snd_ctl_elem_info_set_item_dylibloader_orig_asound +#define snd_ctl_elem_info_get_item_name snd_ctl_elem_info_get_item_name_dylibloader_orig_asound +#define snd_ctl_elem_info_get_dimensions snd_ctl_elem_info_get_dimensions_dylibloader_orig_asound +#define snd_ctl_elem_info_get_dimension snd_ctl_elem_info_get_dimension_dylibloader_orig_asound +#define snd_ctl_elem_info_set_dimension snd_ctl_elem_info_set_dimension_dylibloader_orig_asound +#define snd_ctl_elem_info_get_id snd_ctl_elem_info_get_id_dylibloader_orig_asound +#define snd_ctl_elem_info_get_numid snd_ctl_elem_info_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_info_get_interface snd_ctl_elem_info_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_info_get_device snd_ctl_elem_info_get_device_dylibloader_orig_asound +#define snd_ctl_elem_info_get_subdevice snd_ctl_elem_info_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_info_get_name snd_ctl_elem_info_get_name_dylibloader_orig_asound +#define snd_ctl_elem_info_get_index snd_ctl_elem_info_get_index_dylibloader_orig_asound +#define snd_ctl_elem_info_set_id snd_ctl_elem_info_set_id_dylibloader_orig_asound +#define snd_ctl_elem_info_set_numid snd_ctl_elem_info_set_numid_dylibloader_orig_asound +#define snd_ctl_elem_info_set_interface snd_ctl_elem_info_set_interface_dylibloader_orig_asound +#define snd_ctl_elem_info_set_device snd_ctl_elem_info_set_device_dylibloader_orig_asound +#define snd_ctl_elem_info_set_subdevice snd_ctl_elem_info_set_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_info_set_name snd_ctl_elem_info_set_name_dylibloader_orig_asound +#define snd_ctl_elem_info_set_index snd_ctl_elem_info_set_index_dylibloader_orig_asound +#define snd_ctl_add_integer_elem_set snd_ctl_add_integer_elem_set_dylibloader_orig_asound +#define snd_ctl_add_integer64_elem_set snd_ctl_add_integer64_elem_set_dylibloader_orig_asound +#define snd_ctl_add_boolean_elem_set snd_ctl_add_boolean_elem_set_dylibloader_orig_asound +#define snd_ctl_add_enumerated_elem_set snd_ctl_add_enumerated_elem_set_dylibloader_orig_asound +#define snd_ctl_add_bytes_elem_set snd_ctl_add_bytes_elem_set_dylibloader_orig_asound +#define snd_ctl_elem_add_integer snd_ctl_elem_add_integer_dylibloader_orig_asound +#define snd_ctl_elem_add_integer64 snd_ctl_elem_add_integer64_dylibloader_orig_asound +#define snd_ctl_elem_add_boolean snd_ctl_elem_add_boolean_dylibloader_orig_asound +#define snd_ctl_elem_add_enumerated snd_ctl_elem_add_enumerated_dylibloader_orig_asound +#define snd_ctl_elem_add_iec958 snd_ctl_elem_add_iec958_dylibloader_orig_asound +#define snd_ctl_elem_remove snd_ctl_elem_remove_dylibloader_orig_asound +#define snd_ctl_elem_value_sizeof snd_ctl_elem_value_sizeof_dylibloader_orig_asound +#define snd_ctl_elem_value_malloc snd_ctl_elem_value_malloc_dylibloader_orig_asound +#define snd_ctl_elem_value_free snd_ctl_elem_value_free_dylibloader_orig_asound +#define snd_ctl_elem_value_clear snd_ctl_elem_value_clear_dylibloader_orig_asound +#define snd_ctl_elem_value_copy snd_ctl_elem_value_copy_dylibloader_orig_asound +#define snd_ctl_elem_value_compare snd_ctl_elem_value_compare_dylibloader_orig_asound +#define snd_ctl_elem_value_get_id snd_ctl_elem_value_get_id_dylibloader_orig_asound +#define snd_ctl_elem_value_get_numid snd_ctl_elem_value_get_numid_dylibloader_orig_asound +#define snd_ctl_elem_value_get_interface snd_ctl_elem_value_get_interface_dylibloader_orig_asound +#define snd_ctl_elem_value_get_device snd_ctl_elem_value_get_device_dylibloader_orig_asound +#define snd_ctl_elem_value_get_subdevice snd_ctl_elem_value_get_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_value_get_name snd_ctl_elem_value_get_name_dylibloader_orig_asound +#define snd_ctl_elem_value_get_index snd_ctl_elem_value_get_index_dylibloader_orig_asound +#define snd_ctl_elem_value_set_id snd_ctl_elem_value_set_id_dylibloader_orig_asound +#define snd_ctl_elem_value_set_numid snd_ctl_elem_value_set_numid_dylibloader_orig_asound +#define snd_ctl_elem_value_set_interface snd_ctl_elem_value_set_interface_dylibloader_orig_asound +#define snd_ctl_elem_value_set_device snd_ctl_elem_value_set_device_dylibloader_orig_asound +#define snd_ctl_elem_value_set_subdevice snd_ctl_elem_value_set_subdevice_dylibloader_orig_asound +#define snd_ctl_elem_value_set_name snd_ctl_elem_value_set_name_dylibloader_orig_asound +#define snd_ctl_elem_value_set_index snd_ctl_elem_value_set_index_dylibloader_orig_asound +#define snd_ctl_elem_value_get_boolean snd_ctl_elem_value_get_boolean_dylibloader_orig_asound +#define snd_ctl_elem_value_get_integer snd_ctl_elem_value_get_integer_dylibloader_orig_asound +#define snd_ctl_elem_value_get_integer64 snd_ctl_elem_value_get_integer64_dylibloader_orig_asound +#define snd_ctl_elem_value_get_enumerated snd_ctl_elem_value_get_enumerated_dylibloader_orig_asound +#define snd_ctl_elem_value_get_byte snd_ctl_elem_value_get_byte_dylibloader_orig_asound +#define snd_ctl_elem_value_set_boolean snd_ctl_elem_value_set_boolean_dylibloader_orig_asound +#define snd_ctl_elem_value_set_integer snd_ctl_elem_value_set_integer_dylibloader_orig_asound +#define snd_ctl_elem_value_set_integer64 snd_ctl_elem_value_set_integer64_dylibloader_orig_asound +#define snd_ctl_elem_value_set_enumerated snd_ctl_elem_value_set_enumerated_dylibloader_orig_asound +#define snd_ctl_elem_value_set_byte snd_ctl_elem_value_set_byte_dylibloader_orig_asound +#define snd_ctl_elem_set_bytes snd_ctl_elem_set_bytes_dylibloader_orig_asound +#define snd_ctl_elem_value_get_bytes snd_ctl_elem_value_get_bytes_dylibloader_orig_asound +#define snd_ctl_elem_value_get_iec958 snd_ctl_elem_value_get_iec958_dylibloader_orig_asound +#define snd_ctl_elem_value_set_iec958 snd_ctl_elem_value_set_iec958_dylibloader_orig_asound +#define snd_tlv_parse_dB_info snd_tlv_parse_dB_info_dylibloader_orig_asound +#define snd_tlv_get_dB_range snd_tlv_get_dB_range_dylibloader_orig_asound +#define snd_tlv_convert_to_dB snd_tlv_convert_to_dB_dylibloader_orig_asound +#define snd_tlv_convert_from_dB snd_tlv_convert_from_dB_dylibloader_orig_asound +#define snd_ctl_get_dB_range snd_ctl_get_dB_range_dylibloader_orig_asound +#define snd_ctl_convert_to_dB snd_ctl_convert_to_dB_dylibloader_orig_asound +#define snd_ctl_convert_from_dB snd_ctl_convert_from_dB_dylibloader_orig_asound +#define snd_hctl_compare_fast snd_hctl_compare_fast_dylibloader_orig_asound +#define snd_hctl_open snd_hctl_open_dylibloader_orig_asound +#define snd_hctl_open_ctl snd_hctl_open_ctl_dylibloader_orig_asound +#define snd_hctl_close snd_hctl_close_dylibloader_orig_asound +#define snd_hctl_nonblock snd_hctl_nonblock_dylibloader_orig_asound +#define snd_hctl_poll_descriptors_count snd_hctl_poll_descriptors_count_dylibloader_orig_asound +#define snd_hctl_poll_descriptors snd_hctl_poll_descriptors_dylibloader_orig_asound +#define snd_hctl_poll_descriptors_revents snd_hctl_poll_descriptors_revents_dylibloader_orig_asound +#define snd_hctl_get_count snd_hctl_get_count_dylibloader_orig_asound +#define snd_hctl_set_compare snd_hctl_set_compare_dylibloader_orig_asound +#define snd_hctl_first_elem snd_hctl_first_elem_dylibloader_orig_asound +#define snd_hctl_last_elem snd_hctl_last_elem_dylibloader_orig_asound +#define snd_hctl_find_elem snd_hctl_find_elem_dylibloader_orig_asound +#define snd_hctl_set_callback snd_hctl_set_callback_dylibloader_orig_asound +#define snd_hctl_set_callback_private snd_hctl_set_callback_private_dylibloader_orig_asound +#define snd_hctl_get_callback_private snd_hctl_get_callback_private_dylibloader_orig_asound +#define snd_hctl_load snd_hctl_load_dylibloader_orig_asound +#define snd_hctl_free snd_hctl_free_dylibloader_orig_asound +#define snd_hctl_handle_events snd_hctl_handle_events_dylibloader_orig_asound +#define snd_hctl_name snd_hctl_name_dylibloader_orig_asound +#define snd_hctl_wait snd_hctl_wait_dylibloader_orig_asound +#define snd_hctl_ctl snd_hctl_ctl_dylibloader_orig_asound +#define snd_hctl_elem_next snd_hctl_elem_next_dylibloader_orig_asound +#define snd_hctl_elem_prev snd_hctl_elem_prev_dylibloader_orig_asound +#define snd_hctl_elem_info snd_hctl_elem_info_dylibloader_orig_asound +#define snd_hctl_elem_read snd_hctl_elem_read_dylibloader_orig_asound +#define snd_hctl_elem_write snd_hctl_elem_write_dylibloader_orig_asound +#define snd_hctl_elem_tlv_read snd_hctl_elem_tlv_read_dylibloader_orig_asound +#define snd_hctl_elem_tlv_write snd_hctl_elem_tlv_write_dylibloader_orig_asound +#define snd_hctl_elem_tlv_command snd_hctl_elem_tlv_command_dylibloader_orig_asound +#define snd_hctl_elem_get_hctl snd_hctl_elem_get_hctl_dylibloader_orig_asound +#define snd_hctl_elem_get_id snd_hctl_elem_get_id_dylibloader_orig_asound +#define snd_hctl_elem_get_numid snd_hctl_elem_get_numid_dylibloader_orig_asound +#define snd_hctl_elem_get_interface snd_hctl_elem_get_interface_dylibloader_orig_asound +#define snd_hctl_elem_get_device snd_hctl_elem_get_device_dylibloader_orig_asound +#define snd_hctl_elem_get_subdevice snd_hctl_elem_get_subdevice_dylibloader_orig_asound +#define snd_hctl_elem_get_name snd_hctl_elem_get_name_dylibloader_orig_asound +#define snd_hctl_elem_get_index snd_hctl_elem_get_index_dylibloader_orig_asound +#define snd_hctl_elem_set_callback snd_hctl_elem_set_callback_dylibloader_orig_asound +#define snd_hctl_elem_get_callback_private snd_hctl_elem_get_callback_private_dylibloader_orig_asound +#define snd_hctl_elem_set_callback_private snd_hctl_elem_set_callback_private_dylibloader_orig_asound +#define snd_sctl_build snd_sctl_build_dylibloader_orig_asound +#define snd_sctl_free snd_sctl_free_dylibloader_orig_asound +#define snd_sctl_install snd_sctl_install_dylibloader_orig_asound +#define snd_sctl_remove snd_sctl_remove_dylibloader_orig_asound +#define snd_mixer_open snd_mixer_open_dylibloader_orig_asound +#define snd_mixer_close snd_mixer_close_dylibloader_orig_asound +#define snd_mixer_first_elem snd_mixer_first_elem_dylibloader_orig_asound +#define snd_mixer_last_elem snd_mixer_last_elem_dylibloader_orig_asound +#define snd_mixer_handle_events snd_mixer_handle_events_dylibloader_orig_asound +#define snd_mixer_attach snd_mixer_attach_dylibloader_orig_asound +#define snd_mixer_attach_hctl snd_mixer_attach_hctl_dylibloader_orig_asound +#define snd_mixer_detach snd_mixer_detach_dylibloader_orig_asound +#define snd_mixer_detach_hctl snd_mixer_detach_hctl_dylibloader_orig_asound +#define snd_mixer_get_hctl snd_mixer_get_hctl_dylibloader_orig_asound +#define snd_mixer_poll_descriptors_count snd_mixer_poll_descriptors_count_dylibloader_orig_asound +#define snd_mixer_poll_descriptors snd_mixer_poll_descriptors_dylibloader_orig_asound +#define snd_mixer_poll_descriptors_revents snd_mixer_poll_descriptors_revents_dylibloader_orig_asound +#define snd_mixer_load snd_mixer_load_dylibloader_orig_asound +#define snd_mixer_free snd_mixer_free_dylibloader_orig_asound +#define snd_mixer_wait snd_mixer_wait_dylibloader_orig_asound +#define snd_mixer_set_compare snd_mixer_set_compare_dylibloader_orig_asound +#define snd_mixer_set_callback snd_mixer_set_callback_dylibloader_orig_asound +#define snd_mixer_get_callback_private snd_mixer_get_callback_private_dylibloader_orig_asound +#define snd_mixer_set_callback_private snd_mixer_set_callback_private_dylibloader_orig_asound +#define snd_mixer_get_count snd_mixer_get_count_dylibloader_orig_asound +#define snd_mixer_class_unregister snd_mixer_class_unregister_dylibloader_orig_asound +#define snd_mixer_elem_next snd_mixer_elem_next_dylibloader_orig_asound +#define snd_mixer_elem_prev snd_mixer_elem_prev_dylibloader_orig_asound +#define snd_mixer_elem_set_callback snd_mixer_elem_set_callback_dylibloader_orig_asound +#define snd_mixer_elem_get_callback_private snd_mixer_elem_get_callback_private_dylibloader_orig_asound +#define snd_mixer_elem_set_callback_private snd_mixer_elem_set_callback_private_dylibloader_orig_asound +#define snd_mixer_elem_get_type snd_mixer_elem_get_type_dylibloader_orig_asound +#define snd_mixer_class_register snd_mixer_class_register_dylibloader_orig_asound +#define snd_mixer_elem_new snd_mixer_elem_new_dylibloader_orig_asound +#define snd_mixer_elem_add snd_mixer_elem_add_dylibloader_orig_asound +#define snd_mixer_elem_remove snd_mixer_elem_remove_dylibloader_orig_asound +#define snd_mixer_elem_free snd_mixer_elem_free_dylibloader_orig_asound +#define snd_mixer_elem_info snd_mixer_elem_info_dylibloader_orig_asound +#define snd_mixer_elem_value snd_mixer_elem_value_dylibloader_orig_asound +#define snd_mixer_elem_attach snd_mixer_elem_attach_dylibloader_orig_asound +#define snd_mixer_elem_detach snd_mixer_elem_detach_dylibloader_orig_asound +#define snd_mixer_elem_empty snd_mixer_elem_empty_dylibloader_orig_asound +#define snd_mixer_elem_get_private snd_mixer_elem_get_private_dylibloader_orig_asound +#define snd_mixer_class_sizeof snd_mixer_class_sizeof_dylibloader_orig_asound +#define snd_mixer_class_malloc snd_mixer_class_malloc_dylibloader_orig_asound +#define snd_mixer_class_free snd_mixer_class_free_dylibloader_orig_asound +#define snd_mixer_class_copy snd_mixer_class_copy_dylibloader_orig_asound +#define snd_mixer_class_get_mixer snd_mixer_class_get_mixer_dylibloader_orig_asound +#define snd_mixer_class_get_event snd_mixer_class_get_event_dylibloader_orig_asound +#define snd_mixer_class_get_private snd_mixer_class_get_private_dylibloader_orig_asound +#define snd_mixer_class_get_compare snd_mixer_class_get_compare_dylibloader_orig_asound +#define snd_mixer_class_set_event snd_mixer_class_set_event_dylibloader_orig_asound +#define snd_mixer_class_set_private snd_mixer_class_set_private_dylibloader_orig_asound +#define snd_mixer_class_set_private_free snd_mixer_class_set_private_free_dylibloader_orig_asound +#define snd_mixer_class_set_compare snd_mixer_class_set_compare_dylibloader_orig_asound +#define snd_mixer_selem_channel_name snd_mixer_selem_channel_name_dylibloader_orig_asound +#define snd_mixer_selem_register snd_mixer_selem_register_dylibloader_orig_asound +#define snd_mixer_selem_get_id snd_mixer_selem_get_id_dylibloader_orig_asound +#define snd_mixer_selem_get_name snd_mixer_selem_get_name_dylibloader_orig_asound +#define snd_mixer_selem_get_index snd_mixer_selem_get_index_dylibloader_orig_asound +#define snd_mixer_find_selem snd_mixer_find_selem_dylibloader_orig_asound +#define snd_mixer_selem_is_active snd_mixer_selem_is_active_dylibloader_orig_asound +#define snd_mixer_selem_is_playback_mono snd_mixer_selem_is_playback_mono_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_channel snd_mixer_selem_has_playback_channel_dylibloader_orig_asound +#define snd_mixer_selem_is_capture_mono snd_mixer_selem_is_capture_mono_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_channel snd_mixer_selem_has_capture_channel_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_group snd_mixer_selem_get_capture_group_dylibloader_orig_asound +#define snd_mixer_selem_has_common_volume snd_mixer_selem_has_common_volume_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_volume snd_mixer_selem_has_playback_volume_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_volume_joined snd_mixer_selem_has_playback_volume_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_volume snd_mixer_selem_has_capture_volume_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_volume_joined snd_mixer_selem_has_capture_volume_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_common_switch snd_mixer_selem_has_common_switch_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_switch snd_mixer_selem_has_playback_switch_dylibloader_orig_asound +#define snd_mixer_selem_has_playback_switch_joined snd_mixer_selem_has_playback_switch_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_switch snd_mixer_selem_has_capture_switch_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_switch_joined snd_mixer_selem_has_capture_switch_joined_dylibloader_orig_asound +#define snd_mixer_selem_has_capture_switch_exclusive snd_mixer_selem_has_capture_switch_exclusive_dylibloader_orig_asound +#define snd_mixer_selem_ask_playback_vol_dB snd_mixer_selem_ask_playback_vol_dB_dylibloader_orig_asound +#define snd_mixer_selem_ask_capture_vol_dB snd_mixer_selem_ask_capture_vol_dB_dylibloader_orig_asound +#define snd_mixer_selem_ask_playback_dB_vol snd_mixer_selem_ask_playback_dB_vol_dylibloader_orig_asound +#define snd_mixer_selem_ask_capture_dB_vol snd_mixer_selem_ask_capture_dB_vol_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_volume snd_mixer_selem_get_playback_volume_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_volume snd_mixer_selem_get_capture_volume_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_dB snd_mixer_selem_get_playback_dB_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_dB snd_mixer_selem_get_capture_dB_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_switch snd_mixer_selem_get_playback_switch_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_switch snd_mixer_selem_get_capture_switch_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_volume snd_mixer_selem_set_playback_volume_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_volume snd_mixer_selem_set_capture_volume_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_dB snd_mixer_selem_set_playback_dB_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_dB snd_mixer_selem_set_capture_dB_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_volume_all snd_mixer_selem_set_playback_volume_all_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_volume_all snd_mixer_selem_set_capture_volume_all_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_dB_all snd_mixer_selem_set_playback_dB_all_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_dB_all snd_mixer_selem_set_capture_dB_all_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_switch snd_mixer_selem_set_playback_switch_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_switch snd_mixer_selem_set_capture_switch_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_switch_all snd_mixer_selem_set_playback_switch_all_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_switch_all snd_mixer_selem_set_capture_switch_all_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_volume_range snd_mixer_selem_get_playback_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_get_playback_dB_range snd_mixer_selem_get_playback_dB_range_dylibloader_orig_asound +#define snd_mixer_selem_set_playback_volume_range snd_mixer_selem_set_playback_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_volume_range snd_mixer_selem_get_capture_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_get_capture_dB_range snd_mixer_selem_get_capture_dB_range_dylibloader_orig_asound +#define snd_mixer_selem_set_capture_volume_range snd_mixer_selem_set_capture_volume_range_dylibloader_orig_asound +#define snd_mixer_selem_is_enumerated snd_mixer_selem_is_enumerated_dylibloader_orig_asound +#define snd_mixer_selem_is_enum_playback snd_mixer_selem_is_enum_playback_dylibloader_orig_asound +#define snd_mixer_selem_is_enum_capture snd_mixer_selem_is_enum_capture_dylibloader_orig_asound +#define snd_mixer_selem_get_enum_items snd_mixer_selem_get_enum_items_dylibloader_orig_asound +#define snd_mixer_selem_get_enum_item_name snd_mixer_selem_get_enum_item_name_dylibloader_orig_asound +#define snd_mixer_selem_get_enum_item snd_mixer_selem_get_enum_item_dylibloader_orig_asound +#define snd_mixer_selem_set_enum_item snd_mixer_selem_set_enum_item_dylibloader_orig_asound +#define snd_mixer_selem_id_sizeof snd_mixer_selem_id_sizeof_dylibloader_orig_asound +#define snd_mixer_selem_id_malloc snd_mixer_selem_id_malloc_dylibloader_orig_asound +#define snd_mixer_selem_id_free snd_mixer_selem_id_free_dylibloader_orig_asound +#define snd_mixer_selem_id_copy snd_mixer_selem_id_copy_dylibloader_orig_asound +#define snd_mixer_selem_id_get_name snd_mixer_selem_id_get_name_dylibloader_orig_asound +#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_orig_asound +#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_orig_asound +#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_orig_asound +#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_orig_asound +#define snd_seq_open snd_seq_open_dylibloader_orig_asound +#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_orig_asound +#define snd_seq_name snd_seq_name_dylibloader_orig_asound +#define snd_seq_type snd_seq_type_dylibloader_orig_asound +#define snd_seq_close snd_seq_close_dylibloader_orig_asound +#define snd_seq_poll_descriptors_count snd_seq_poll_descriptors_count_dylibloader_orig_asound +#define snd_seq_poll_descriptors snd_seq_poll_descriptors_dylibloader_orig_asound +#define snd_seq_poll_descriptors_revents snd_seq_poll_descriptors_revents_dylibloader_orig_asound +#define snd_seq_nonblock snd_seq_nonblock_dylibloader_orig_asound +#define snd_seq_client_id snd_seq_client_id_dylibloader_orig_asound +#define snd_seq_get_output_buffer_size snd_seq_get_output_buffer_size_dylibloader_orig_asound +#define snd_seq_get_input_buffer_size snd_seq_get_input_buffer_size_dylibloader_orig_asound +#define snd_seq_set_output_buffer_size snd_seq_set_output_buffer_size_dylibloader_orig_asound +#define snd_seq_set_input_buffer_size snd_seq_set_input_buffer_size_dylibloader_orig_asound +#define snd_seq_system_info_sizeof snd_seq_system_info_sizeof_dylibloader_orig_asound +#define snd_seq_system_info_malloc snd_seq_system_info_malloc_dylibloader_orig_asound +#define snd_seq_system_info_free snd_seq_system_info_free_dylibloader_orig_asound +#define snd_seq_system_info_copy snd_seq_system_info_copy_dylibloader_orig_asound +#define snd_seq_system_info_get_queues snd_seq_system_info_get_queues_dylibloader_orig_asound +#define snd_seq_system_info_get_clients snd_seq_system_info_get_clients_dylibloader_orig_asound +#define snd_seq_system_info_get_ports snd_seq_system_info_get_ports_dylibloader_orig_asound +#define snd_seq_system_info_get_channels snd_seq_system_info_get_channels_dylibloader_orig_asound +#define snd_seq_system_info_get_cur_clients snd_seq_system_info_get_cur_clients_dylibloader_orig_asound +#define snd_seq_system_info_get_cur_queues snd_seq_system_info_get_cur_queues_dylibloader_orig_asound +#define snd_seq_system_info snd_seq_system_info_dylibloader_orig_asound +#define snd_seq_client_info_sizeof snd_seq_client_info_sizeof_dylibloader_orig_asound +#define snd_seq_client_info_malloc snd_seq_client_info_malloc_dylibloader_orig_asound +#define snd_seq_client_info_free snd_seq_client_info_free_dylibloader_orig_asound +#define snd_seq_client_info_copy snd_seq_client_info_copy_dylibloader_orig_asound +#define snd_seq_client_info_get_client snd_seq_client_info_get_client_dylibloader_orig_asound +#define snd_seq_client_info_get_type snd_seq_client_info_get_type_dylibloader_orig_asound +#define snd_seq_client_info_get_name snd_seq_client_info_get_name_dylibloader_orig_asound +#define snd_seq_client_info_get_broadcast_filter snd_seq_client_info_get_broadcast_filter_dylibloader_orig_asound +#define snd_seq_client_info_get_error_bounce snd_seq_client_info_get_error_bounce_dylibloader_orig_asound +#define snd_seq_client_info_get_card snd_seq_client_info_get_card_dylibloader_orig_asound +#define snd_seq_client_info_get_pid snd_seq_client_info_get_pid_dylibloader_orig_asound +#define snd_seq_client_info_get_event_filter snd_seq_client_info_get_event_filter_dylibloader_orig_asound +#define snd_seq_client_info_get_num_ports snd_seq_client_info_get_num_ports_dylibloader_orig_asound +#define snd_seq_client_info_get_event_lost snd_seq_client_info_get_event_lost_dylibloader_orig_asound +#define snd_seq_client_info_set_client snd_seq_client_info_set_client_dylibloader_orig_asound +#define snd_seq_client_info_set_name snd_seq_client_info_set_name_dylibloader_orig_asound +#define snd_seq_client_info_set_broadcast_filter snd_seq_client_info_set_broadcast_filter_dylibloader_orig_asound +#define snd_seq_client_info_set_error_bounce snd_seq_client_info_set_error_bounce_dylibloader_orig_asound +#define snd_seq_client_info_set_event_filter snd_seq_client_info_set_event_filter_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_clear snd_seq_client_info_event_filter_clear_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_add snd_seq_client_info_event_filter_add_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_del snd_seq_client_info_event_filter_del_dylibloader_orig_asound +#define snd_seq_client_info_event_filter_check snd_seq_client_info_event_filter_check_dylibloader_orig_asound +#define snd_seq_get_client_info snd_seq_get_client_info_dylibloader_orig_asound +#define snd_seq_get_any_client_info snd_seq_get_any_client_info_dylibloader_orig_asound +#define snd_seq_set_client_info snd_seq_set_client_info_dylibloader_orig_asound +#define snd_seq_query_next_client snd_seq_query_next_client_dylibloader_orig_asound +#define snd_seq_client_pool_sizeof snd_seq_client_pool_sizeof_dylibloader_orig_asound +#define snd_seq_client_pool_malloc snd_seq_client_pool_malloc_dylibloader_orig_asound +#define snd_seq_client_pool_free snd_seq_client_pool_free_dylibloader_orig_asound +#define snd_seq_client_pool_copy snd_seq_client_pool_copy_dylibloader_orig_asound +#define snd_seq_client_pool_get_client snd_seq_client_pool_get_client_dylibloader_orig_asound +#define snd_seq_client_pool_get_output_pool snd_seq_client_pool_get_output_pool_dylibloader_orig_asound +#define snd_seq_client_pool_get_input_pool snd_seq_client_pool_get_input_pool_dylibloader_orig_asound +#define snd_seq_client_pool_get_output_room snd_seq_client_pool_get_output_room_dylibloader_orig_asound +#define snd_seq_client_pool_get_output_free snd_seq_client_pool_get_output_free_dylibloader_orig_asound +#define snd_seq_client_pool_get_input_free snd_seq_client_pool_get_input_free_dylibloader_orig_asound +#define snd_seq_client_pool_set_output_pool snd_seq_client_pool_set_output_pool_dylibloader_orig_asound +#define snd_seq_client_pool_set_input_pool snd_seq_client_pool_set_input_pool_dylibloader_orig_asound +#define snd_seq_client_pool_set_output_room snd_seq_client_pool_set_output_room_dylibloader_orig_asound +#define snd_seq_get_client_pool snd_seq_get_client_pool_dylibloader_orig_asound +#define snd_seq_set_client_pool snd_seq_set_client_pool_dylibloader_orig_asound +#define snd_seq_port_info_sizeof snd_seq_port_info_sizeof_dylibloader_orig_asound +#define snd_seq_port_info_malloc snd_seq_port_info_malloc_dylibloader_orig_asound +#define snd_seq_port_info_free snd_seq_port_info_free_dylibloader_orig_asound +#define snd_seq_port_info_copy snd_seq_port_info_copy_dylibloader_orig_asound +#define snd_seq_port_info_get_client snd_seq_port_info_get_client_dylibloader_orig_asound +#define snd_seq_port_info_get_port snd_seq_port_info_get_port_dylibloader_orig_asound +#define snd_seq_port_info_get_addr snd_seq_port_info_get_addr_dylibloader_orig_asound +#define snd_seq_port_info_get_name snd_seq_port_info_get_name_dylibloader_orig_asound +#define snd_seq_port_info_get_capability snd_seq_port_info_get_capability_dylibloader_orig_asound +#define snd_seq_port_info_get_type snd_seq_port_info_get_type_dylibloader_orig_asound +#define snd_seq_port_info_get_midi_channels snd_seq_port_info_get_midi_channels_dylibloader_orig_asound +#define snd_seq_port_info_get_midi_voices snd_seq_port_info_get_midi_voices_dylibloader_orig_asound +#define snd_seq_port_info_get_synth_voices snd_seq_port_info_get_synth_voices_dylibloader_orig_asound +#define snd_seq_port_info_get_read_use snd_seq_port_info_get_read_use_dylibloader_orig_asound +#define snd_seq_port_info_get_write_use snd_seq_port_info_get_write_use_dylibloader_orig_asound +#define snd_seq_port_info_get_port_specified snd_seq_port_info_get_port_specified_dylibloader_orig_asound +#define snd_seq_port_info_get_timestamping snd_seq_port_info_get_timestamping_dylibloader_orig_asound +#define snd_seq_port_info_get_timestamp_real snd_seq_port_info_get_timestamp_real_dylibloader_orig_asound +#define snd_seq_port_info_get_timestamp_queue snd_seq_port_info_get_timestamp_queue_dylibloader_orig_asound +#define snd_seq_port_info_set_client snd_seq_port_info_set_client_dylibloader_orig_asound +#define snd_seq_port_info_set_port snd_seq_port_info_set_port_dylibloader_orig_asound +#define snd_seq_port_info_set_addr snd_seq_port_info_set_addr_dylibloader_orig_asound +#define snd_seq_port_info_set_name snd_seq_port_info_set_name_dylibloader_orig_asound +#define snd_seq_port_info_set_capability snd_seq_port_info_set_capability_dylibloader_orig_asound +#define snd_seq_port_info_set_type snd_seq_port_info_set_type_dylibloader_orig_asound +#define snd_seq_port_info_set_midi_channels snd_seq_port_info_set_midi_channels_dylibloader_orig_asound +#define snd_seq_port_info_set_midi_voices snd_seq_port_info_set_midi_voices_dylibloader_orig_asound +#define snd_seq_port_info_set_synth_voices snd_seq_port_info_set_synth_voices_dylibloader_orig_asound +#define snd_seq_port_info_set_port_specified snd_seq_port_info_set_port_specified_dylibloader_orig_asound +#define snd_seq_port_info_set_timestamping snd_seq_port_info_set_timestamping_dylibloader_orig_asound +#define snd_seq_port_info_set_timestamp_real snd_seq_port_info_set_timestamp_real_dylibloader_orig_asound +#define snd_seq_port_info_set_timestamp_queue snd_seq_port_info_set_timestamp_queue_dylibloader_orig_asound +#define snd_seq_create_port snd_seq_create_port_dylibloader_orig_asound +#define snd_seq_delete_port snd_seq_delete_port_dylibloader_orig_asound +#define snd_seq_get_port_info snd_seq_get_port_info_dylibloader_orig_asound +#define snd_seq_get_any_port_info snd_seq_get_any_port_info_dylibloader_orig_asound +#define snd_seq_set_port_info snd_seq_set_port_info_dylibloader_orig_asound +#define snd_seq_query_next_port snd_seq_query_next_port_dylibloader_orig_asound +#define snd_seq_port_subscribe_sizeof snd_seq_port_subscribe_sizeof_dylibloader_orig_asound +#define snd_seq_port_subscribe_malloc snd_seq_port_subscribe_malloc_dylibloader_orig_asound +#define snd_seq_port_subscribe_free snd_seq_port_subscribe_free_dylibloader_orig_asound +#define snd_seq_port_subscribe_copy snd_seq_port_subscribe_copy_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_sender snd_seq_port_subscribe_get_sender_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_dest snd_seq_port_subscribe_get_dest_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_queue snd_seq_port_subscribe_get_queue_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_exclusive snd_seq_port_subscribe_get_exclusive_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_time_update snd_seq_port_subscribe_get_time_update_dylibloader_orig_asound +#define snd_seq_port_subscribe_get_time_real snd_seq_port_subscribe_get_time_real_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_sender snd_seq_port_subscribe_set_sender_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_dest snd_seq_port_subscribe_set_dest_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_queue snd_seq_port_subscribe_set_queue_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_exclusive snd_seq_port_subscribe_set_exclusive_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_time_update snd_seq_port_subscribe_set_time_update_dylibloader_orig_asound +#define snd_seq_port_subscribe_set_time_real snd_seq_port_subscribe_set_time_real_dylibloader_orig_asound +#define snd_seq_get_port_subscription snd_seq_get_port_subscription_dylibloader_orig_asound +#define snd_seq_subscribe_port snd_seq_subscribe_port_dylibloader_orig_asound +#define snd_seq_unsubscribe_port snd_seq_unsubscribe_port_dylibloader_orig_asound +#define snd_seq_query_subscribe_sizeof snd_seq_query_subscribe_sizeof_dylibloader_orig_asound +#define snd_seq_query_subscribe_malloc snd_seq_query_subscribe_malloc_dylibloader_orig_asound +#define snd_seq_query_subscribe_free snd_seq_query_subscribe_free_dylibloader_orig_asound +#define snd_seq_query_subscribe_copy snd_seq_query_subscribe_copy_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_client snd_seq_query_subscribe_get_client_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_port snd_seq_query_subscribe_get_port_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_root snd_seq_query_subscribe_get_root_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_type snd_seq_query_subscribe_get_type_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_index snd_seq_query_subscribe_get_index_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_num_subs snd_seq_query_subscribe_get_num_subs_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_addr snd_seq_query_subscribe_get_addr_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_queue snd_seq_query_subscribe_get_queue_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_exclusive snd_seq_query_subscribe_get_exclusive_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_time_update snd_seq_query_subscribe_get_time_update_dylibloader_orig_asound +#define snd_seq_query_subscribe_get_time_real snd_seq_query_subscribe_get_time_real_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_client snd_seq_query_subscribe_set_client_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_port snd_seq_query_subscribe_set_port_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_root snd_seq_query_subscribe_set_root_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_type snd_seq_query_subscribe_set_type_dylibloader_orig_asound +#define snd_seq_query_subscribe_set_index snd_seq_query_subscribe_set_index_dylibloader_orig_asound +#define snd_seq_query_port_subscribers snd_seq_query_port_subscribers_dylibloader_orig_asound +#define snd_seq_queue_info_sizeof snd_seq_queue_info_sizeof_dylibloader_orig_asound +#define snd_seq_queue_info_malloc snd_seq_queue_info_malloc_dylibloader_orig_asound +#define snd_seq_queue_info_free snd_seq_queue_info_free_dylibloader_orig_asound +#define snd_seq_queue_info_copy snd_seq_queue_info_copy_dylibloader_orig_asound +#define snd_seq_queue_info_get_queue snd_seq_queue_info_get_queue_dylibloader_orig_asound +#define snd_seq_queue_info_get_name snd_seq_queue_info_get_name_dylibloader_orig_asound +#define snd_seq_queue_info_get_owner snd_seq_queue_info_get_owner_dylibloader_orig_asound +#define snd_seq_queue_info_get_locked snd_seq_queue_info_get_locked_dylibloader_orig_asound +#define snd_seq_queue_info_get_flags snd_seq_queue_info_get_flags_dylibloader_orig_asound +#define snd_seq_queue_info_set_name snd_seq_queue_info_set_name_dylibloader_orig_asound +#define snd_seq_queue_info_set_owner snd_seq_queue_info_set_owner_dylibloader_orig_asound +#define snd_seq_queue_info_set_locked snd_seq_queue_info_set_locked_dylibloader_orig_asound +#define snd_seq_queue_info_set_flags snd_seq_queue_info_set_flags_dylibloader_orig_asound +#define snd_seq_create_queue snd_seq_create_queue_dylibloader_orig_asound +#define snd_seq_alloc_named_queue snd_seq_alloc_named_queue_dylibloader_orig_asound +#define snd_seq_alloc_queue snd_seq_alloc_queue_dylibloader_orig_asound +#define snd_seq_free_queue snd_seq_free_queue_dylibloader_orig_asound +#define snd_seq_get_queue_info snd_seq_get_queue_info_dylibloader_orig_asound +#define snd_seq_set_queue_info snd_seq_set_queue_info_dylibloader_orig_asound +#define snd_seq_query_named_queue snd_seq_query_named_queue_dylibloader_orig_asound +#define snd_seq_get_queue_usage snd_seq_get_queue_usage_dylibloader_orig_asound +#define snd_seq_set_queue_usage snd_seq_set_queue_usage_dylibloader_orig_asound +#define snd_seq_queue_status_sizeof snd_seq_queue_status_sizeof_dylibloader_orig_asound +#define snd_seq_queue_status_malloc snd_seq_queue_status_malloc_dylibloader_orig_asound +#define snd_seq_queue_status_free snd_seq_queue_status_free_dylibloader_orig_asound +#define snd_seq_queue_status_copy snd_seq_queue_status_copy_dylibloader_orig_asound +#define snd_seq_queue_status_get_queue snd_seq_queue_status_get_queue_dylibloader_orig_asound +#define snd_seq_queue_status_get_events snd_seq_queue_status_get_events_dylibloader_orig_asound +#define snd_seq_queue_status_get_tick_time snd_seq_queue_status_get_tick_time_dylibloader_orig_asound +#define snd_seq_queue_status_get_real_time snd_seq_queue_status_get_real_time_dylibloader_orig_asound +#define snd_seq_queue_status_get_status snd_seq_queue_status_get_status_dylibloader_orig_asound +#define snd_seq_get_queue_status snd_seq_get_queue_status_dylibloader_orig_asound +#define snd_seq_queue_tempo_sizeof snd_seq_queue_tempo_sizeof_dylibloader_orig_asound +#define snd_seq_queue_tempo_malloc snd_seq_queue_tempo_malloc_dylibloader_orig_asound +#define snd_seq_queue_tempo_free snd_seq_queue_tempo_free_dylibloader_orig_asound +#define snd_seq_queue_tempo_copy snd_seq_queue_tempo_copy_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_queue snd_seq_queue_tempo_get_queue_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_tempo snd_seq_queue_tempo_get_tempo_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_ppq snd_seq_queue_tempo_get_ppq_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_skew snd_seq_queue_tempo_get_skew_dylibloader_orig_asound +#define snd_seq_queue_tempo_get_skew_base snd_seq_queue_tempo_get_skew_base_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_tempo snd_seq_queue_tempo_set_tempo_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_ppq snd_seq_queue_tempo_set_ppq_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_skew snd_seq_queue_tempo_set_skew_dylibloader_orig_asound +#define snd_seq_queue_tempo_set_skew_base snd_seq_queue_tempo_set_skew_base_dylibloader_orig_asound +#define snd_seq_get_queue_tempo snd_seq_get_queue_tempo_dylibloader_orig_asound +#define snd_seq_set_queue_tempo snd_seq_set_queue_tempo_dylibloader_orig_asound +#define snd_seq_queue_timer_sizeof snd_seq_queue_timer_sizeof_dylibloader_orig_asound +#define snd_seq_queue_timer_malloc snd_seq_queue_timer_malloc_dylibloader_orig_asound +#define snd_seq_queue_timer_free snd_seq_queue_timer_free_dylibloader_orig_asound +#define snd_seq_queue_timer_copy snd_seq_queue_timer_copy_dylibloader_orig_asound +#define snd_seq_queue_timer_get_queue snd_seq_queue_timer_get_queue_dylibloader_orig_asound +#define snd_seq_queue_timer_get_type snd_seq_queue_timer_get_type_dylibloader_orig_asound +#define snd_seq_queue_timer_get_id snd_seq_queue_timer_get_id_dylibloader_orig_asound +#define snd_seq_queue_timer_get_resolution snd_seq_queue_timer_get_resolution_dylibloader_orig_asound +#define snd_seq_queue_timer_set_type snd_seq_queue_timer_set_type_dylibloader_orig_asound +#define snd_seq_queue_timer_set_id snd_seq_queue_timer_set_id_dylibloader_orig_asound +#define snd_seq_queue_timer_set_resolution snd_seq_queue_timer_set_resolution_dylibloader_orig_asound +#define snd_seq_get_queue_timer snd_seq_get_queue_timer_dylibloader_orig_asound +#define snd_seq_set_queue_timer snd_seq_set_queue_timer_dylibloader_orig_asound +#define snd_seq_free_event snd_seq_free_event_dylibloader_orig_asound +#define snd_seq_event_length snd_seq_event_length_dylibloader_orig_asound +#define snd_seq_event_output snd_seq_event_output_dylibloader_orig_asound +#define snd_seq_event_output_buffer snd_seq_event_output_buffer_dylibloader_orig_asound +#define snd_seq_event_output_direct snd_seq_event_output_direct_dylibloader_orig_asound +#define snd_seq_event_input snd_seq_event_input_dylibloader_orig_asound +#define snd_seq_event_input_pending snd_seq_event_input_pending_dylibloader_orig_asound +#define snd_seq_drain_output snd_seq_drain_output_dylibloader_orig_asound +#define snd_seq_event_output_pending snd_seq_event_output_pending_dylibloader_orig_asound +#define snd_seq_extract_output snd_seq_extract_output_dylibloader_orig_asound +#define snd_seq_drop_output snd_seq_drop_output_dylibloader_orig_asound +#define snd_seq_drop_output_buffer snd_seq_drop_output_buffer_dylibloader_orig_asound +#define snd_seq_drop_input snd_seq_drop_input_dylibloader_orig_asound +#define snd_seq_drop_input_buffer snd_seq_drop_input_buffer_dylibloader_orig_asound +#define snd_seq_remove_events_sizeof snd_seq_remove_events_sizeof_dylibloader_orig_asound +#define snd_seq_remove_events_malloc snd_seq_remove_events_malloc_dylibloader_orig_asound +#define snd_seq_remove_events_free snd_seq_remove_events_free_dylibloader_orig_asound +#define snd_seq_remove_events_copy snd_seq_remove_events_copy_dylibloader_orig_asound +#define snd_seq_remove_events_get_condition snd_seq_remove_events_get_condition_dylibloader_orig_asound +#define snd_seq_remove_events_get_queue snd_seq_remove_events_get_queue_dylibloader_orig_asound +#define snd_seq_remove_events_get_time snd_seq_remove_events_get_time_dylibloader_orig_asound +#define snd_seq_remove_events_get_dest snd_seq_remove_events_get_dest_dylibloader_orig_asound +#define snd_seq_remove_events_get_channel snd_seq_remove_events_get_channel_dylibloader_orig_asound +#define snd_seq_remove_events_get_event_type snd_seq_remove_events_get_event_type_dylibloader_orig_asound +#define snd_seq_remove_events_get_tag snd_seq_remove_events_get_tag_dylibloader_orig_asound +#define snd_seq_remove_events_set_condition snd_seq_remove_events_set_condition_dylibloader_orig_asound +#define snd_seq_remove_events_set_queue snd_seq_remove_events_set_queue_dylibloader_orig_asound +#define snd_seq_remove_events_set_time snd_seq_remove_events_set_time_dylibloader_orig_asound +#define snd_seq_remove_events_set_dest snd_seq_remove_events_set_dest_dylibloader_orig_asound +#define snd_seq_remove_events_set_channel snd_seq_remove_events_set_channel_dylibloader_orig_asound +#define snd_seq_remove_events_set_event_type snd_seq_remove_events_set_event_type_dylibloader_orig_asound +#define snd_seq_remove_events_set_tag snd_seq_remove_events_set_tag_dylibloader_orig_asound +#define snd_seq_remove_events snd_seq_remove_events_dylibloader_orig_asound +#define snd_seq_set_bit snd_seq_set_bit_dylibloader_orig_asound +#define snd_seq_unset_bit snd_seq_unset_bit_dylibloader_orig_asound +#define snd_seq_change_bit snd_seq_change_bit_dylibloader_orig_asound +#define snd_seq_get_bit snd_seq_get_bit_dylibloader_orig_asound +#define snd_seq_control_queue snd_seq_control_queue_dylibloader_orig_asound +#define snd_seq_create_simple_port snd_seq_create_simple_port_dylibloader_orig_asound +#define snd_seq_delete_simple_port snd_seq_delete_simple_port_dylibloader_orig_asound +#define snd_seq_connect_from snd_seq_connect_from_dylibloader_orig_asound +#define snd_seq_connect_to snd_seq_connect_to_dylibloader_orig_asound +#define snd_seq_disconnect_from snd_seq_disconnect_from_dylibloader_orig_asound +#define snd_seq_disconnect_to snd_seq_disconnect_to_dylibloader_orig_asound +#define snd_seq_set_client_name snd_seq_set_client_name_dylibloader_orig_asound +#define snd_seq_set_client_event_filter snd_seq_set_client_event_filter_dylibloader_orig_asound +#define snd_seq_set_client_pool_output snd_seq_set_client_pool_output_dylibloader_orig_asound +#define snd_seq_set_client_pool_output_room snd_seq_set_client_pool_output_room_dylibloader_orig_asound +#define snd_seq_set_client_pool_input snd_seq_set_client_pool_input_dylibloader_orig_asound +#define snd_seq_sync_output_queue snd_seq_sync_output_queue_dylibloader_orig_asound +#define snd_seq_parse_address snd_seq_parse_address_dylibloader_orig_asound +#define snd_seq_reset_pool_output snd_seq_reset_pool_output_dylibloader_orig_asound +#define snd_seq_reset_pool_input snd_seq_reset_pool_input_dylibloader_orig_asound +#define snd_midi_event_new snd_midi_event_new_dylibloader_orig_asound +#define snd_midi_event_resize_buffer snd_midi_event_resize_buffer_dylibloader_orig_asound +#define snd_midi_event_free snd_midi_event_free_dylibloader_orig_asound +#define snd_midi_event_init snd_midi_event_init_dylibloader_orig_asound +#define snd_midi_event_reset_encode snd_midi_event_reset_encode_dylibloader_orig_asound +#define snd_midi_event_reset_decode snd_midi_event_reset_decode_dylibloader_orig_asound +#define snd_midi_event_no_status snd_midi_event_no_status_dylibloader_orig_asound +#define snd_midi_event_encode snd_midi_event_encode_dylibloader_orig_asound +#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_orig_asound +#define snd_midi_event_decode snd_midi_event_decode_dylibloader_orig_asound +#include <alsa/asoundlib.h> +#undef snd_asoundlib_version +#undef snd_dlpath +#undef snd_dlopen +#undef snd_dlsym +#undef snd_dlclose +#undef snd_async_add_handler +#undef snd_async_del_handler +#undef snd_async_handler_get_fd +#undef snd_async_handler_get_signo +#undef snd_async_handler_get_callback_private +#undef snd_shm_area_create +#undef snd_shm_area_share +#undef snd_shm_area_destroy +#undef snd_user_file +#undef snd_input_stdio_open +#undef snd_input_stdio_attach +#undef snd_input_buffer_open +#undef snd_input_close +#undef snd_input_scanf +#undef snd_input_gets +#undef snd_input_getc +#undef snd_input_ungetc +#undef snd_output_stdio_open +#undef snd_output_stdio_attach +#undef snd_output_buffer_open +#undef snd_output_buffer_string +#undef snd_output_close +#undef snd_output_printf +#undef snd_output_vprintf +#undef snd_output_puts +#undef snd_output_putc +#undef snd_output_flush +#undef snd_strerror +#undef snd_lib_error_set_handler +#undef snd_lib_error_set_local +#undef snd_config_topdir +#undef snd_config_top +#undef snd_config_load +#undef snd_config_load_override +#undef snd_config_save +#undef snd_config_update +#undef snd_config_update_r +#undef snd_config_update_free +#undef snd_config_update_free_global +#undef snd_config_update_ref +#undef snd_config_ref +#undef snd_config_unref +#undef snd_config_search +#undef snd_config_searchv +#undef snd_config_search_definition +#undef snd_config_expand +#undef snd_config_evaluate +#undef snd_config_add +#undef snd_config_add_before +#undef snd_config_add_after +#undef snd_config_remove +#undef snd_config_delete +#undef snd_config_delete_compound_members +#undef snd_config_copy +#undef snd_config_make +#undef snd_config_make_integer +#undef snd_config_make_integer64 +#undef snd_config_make_real +#undef snd_config_make_string +#undef snd_config_make_pointer +#undef snd_config_make_compound +#undef snd_config_imake_integer +#undef snd_config_imake_integer64 +#undef snd_config_imake_real +#undef snd_config_imake_string +#undef snd_config_imake_safe_string +#undef snd_config_imake_pointer +#undef snd_config_get_type +#undef snd_config_is_array +#undef snd_config_set_id +#undef snd_config_set_integer +#undef snd_config_set_integer64 +#undef snd_config_set_real +#undef snd_config_set_string +#undef snd_config_set_ascii +#undef snd_config_set_pointer +#undef snd_config_get_id +#undef snd_config_get_integer +#undef snd_config_get_integer64 +#undef snd_config_get_real +#undef snd_config_get_ireal +#undef snd_config_get_string +#undef snd_config_get_ascii +#undef snd_config_get_pointer +#undef snd_config_test_id +#undef snd_config_iterator_first +#undef snd_config_iterator_next +#undef snd_config_iterator_end +#undef snd_config_iterator_entry +#undef snd_config_get_bool_ascii +#undef snd_config_get_bool +#undef snd_config_get_ctl_iface_ascii +#undef snd_config_get_ctl_iface +#undef snd_names_list +#undef snd_names_list_free +#undef snd_pcm_open +#undef snd_pcm_open_lconf +#undef snd_pcm_open_fallback +#undef snd_pcm_close +#undef snd_pcm_name +#undef snd_pcm_type +#undef snd_pcm_stream +#undef snd_pcm_poll_descriptors_count +#undef snd_pcm_poll_descriptors +#undef snd_pcm_poll_descriptors_revents +#undef snd_pcm_nonblock +#undef snd_async_add_pcm_handler +#undef snd_async_handler_get_pcm +#undef snd_pcm_info +#undef snd_pcm_hw_params_current +#undef snd_pcm_hw_params +#undef snd_pcm_hw_free +#undef snd_pcm_sw_params_current +#undef snd_pcm_sw_params +#undef snd_pcm_prepare +#undef snd_pcm_reset +#undef snd_pcm_status +#undef snd_pcm_start +#undef snd_pcm_drop +#undef snd_pcm_drain +#undef snd_pcm_pause +#undef snd_pcm_state +#undef snd_pcm_hwsync +#undef snd_pcm_delay +#undef snd_pcm_resume +#undef snd_pcm_htimestamp +#undef snd_pcm_avail +#undef snd_pcm_avail_update +#undef snd_pcm_avail_delay +#undef snd_pcm_rewindable +#undef snd_pcm_rewind +#undef snd_pcm_forwardable +#undef snd_pcm_forward +#undef snd_pcm_writei +#undef snd_pcm_readi +#undef snd_pcm_writen +#undef snd_pcm_readn +#undef snd_pcm_wait +#undef snd_pcm_link +#undef snd_pcm_unlink +#undef snd_pcm_query_chmaps +#undef snd_pcm_query_chmaps_from_hw +#undef snd_pcm_free_chmaps +#undef snd_pcm_get_chmap +#undef snd_pcm_set_chmap +#undef snd_pcm_chmap_type_name +#undef snd_pcm_chmap_name +#undef snd_pcm_chmap_long_name +#undef snd_pcm_chmap_print +#undef snd_pcm_chmap_from_string +#undef snd_pcm_chmap_parse_string +#undef snd_pcm_recover +#undef snd_pcm_set_params +#undef snd_pcm_get_params +#undef snd_pcm_info_sizeof +#undef snd_pcm_info_malloc +#undef snd_pcm_info_free +#undef snd_pcm_info_copy +#undef snd_pcm_info_get_device +#undef snd_pcm_info_get_subdevice +#undef snd_pcm_info_get_stream +#undef snd_pcm_info_get_card +#undef snd_pcm_info_get_id +#undef snd_pcm_info_get_name +#undef snd_pcm_info_get_subdevice_name +#undef snd_pcm_info_get_class +#undef snd_pcm_info_get_subclass +#undef snd_pcm_info_get_subdevices_count +#undef snd_pcm_info_get_subdevices_avail +#undef snd_pcm_info_get_sync +#undef snd_pcm_info_set_device +#undef snd_pcm_info_set_subdevice +#undef snd_pcm_info_set_stream +#undef snd_pcm_hw_params_any +#undef snd_pcm_hw_params_can_mmap_sample_resolution +#undef snd_pcm_hw_params_is_double +#undef snd_pcm_hw_params_is_batch +#undef snd_pcm_hw_params_is_block_transfer +#undef snd_pcm_hw_params_is_monotonic +#undef snd_pcm_hw_params_can_overrange +#undef snd_pcm_hw_params_can_pause +#undef snd_pcm_hw_params_can_resume +#undef snd_pcm_hw_params_is_half_duplex +#undef snd_pcm_hw_params_is_joint_duplex +#undef snd_pcm_hw_params_can_sync_start +#undef snd_pcm_hw_params_can_disable_period_wakeup +#undef snd_pcm_hw_params_supports_audio_wallclock_ts +#undef snd_pcm_hw_params_supports_audio_ts_type +#undef snd_pcm_hw_params_get_rate_numden +#undef snd_pcm_hw_params_get_sbits +#undef snd_pcm_hw_params_get_fifo_size +#undef snd_pcm_hw_params_sizeof +#undef snd_pcm_hw_params_malloc +#undef snd_pcm_hw_params_free +#undef snd_pcm_hw_params_copy +#undef snd_pcm_hw_params_get_access +#undef snd_pcm_hw_params_test_access +#undef snd_pcm_hw_params_set_access +#undef snd_pcm_hw_params_set_access_first +#undef snd_pcm_hw_params_set_access_last +#undef snd_pcm_hw_params_set_access_mask +#undef snd_pcm_hw_params_get_access_mask +#undef snd_pcm_hw_params_get_format +#undef snd_pcm_hw_params_test_format +#undef snd_pcm_hw_params_set_format +#undef snd_pcm_hw_params_set_format_first +#undef snd_pcm_hw_params_set_format_last +#undef snd_pcm_hw_params_set_format_mask +#undef snd_pcm_hw_params_get_format_mask +#undef snd_pcm_hw_params_get_subformat +#undef snd_pcm_hw_params_test_subformat +#undef snd_pcm_hw_params_set_subformat +#undef snd_pcm_hw_params_set_subformat_first +#undef snd_pcm_hw_params_set_subformat_last +#undef snd_pcm_hw_params_set_subformat_mask +#undef snd_pcm_hw_params_get_subformat_mask +#undef snd_pcm_hw_params_get_channels +#undef snd_pcm_hw_params_get_channels_min +#undef snd_pcm_hw_params_get_channels_max +#undef snd_pcm_hw_params_test_channels +#undef snd_pcm_hw_params_set_channels +#undef snd_pcm_hw_params_set_channels_min +#undef snd_pcm_hw_params_set_channels_max +#undef snd_pcm_hw_params_set_channels_minmax +#undef snd_pcm_hw_params_set_channels_near +#undef snd_pcm_hw_params_set_channels_first +#undef snd_pcm_hw_params_set_channels_last +#undef snd_pcm_hw_params_get_rate +#undef snd_pcm_hw_params_get_rate_min +#undef snd_pcm_hw_params_get_rate_max +#undef snd_pcm_hw_params_test_rate +#undef snd_pcm_hw_params_set_rate +#undef snd_pcm_hw_params_set_rate_min +#undef snd_pcm_hw_params_set_rate_max +#undef snd_pcm_hw_params_set_rate_minmax +#undef snd_pcm_hw_params_set_rate_near +#undef snd_pcm_hw_params_set_rate_first +#undef snd_pcm_hw_params_set_rate_last +#undef snd_pcm_hw_params_set_rate_resample +#undef snd_pcm_hw_params_get_rate_resample +#undef snd_pcm_hw_params_set_export_buffer +#undef snd_pcm_hw_params_get_export_buffer +#undef snd_pcm_hw_params_set_period_wakeup +#undef snd_pcm_hw_params_get_period_wakeup +#undef snd_pcm_hw_params_get_period_time +#undef snd_pcm_hw_params_get_period_time_min +#undef snd_pcm_hw_params_get_period_time_max +#undef snd_pcm_hw_params_test_period_time +#undef snd_pcm_hw_params_set_period_time +#undef snd_pcm_hw_params_set_period_time_min +#undef snd_pcm_hw_params_set_period_time_max +#undef snd_pcm_hw_params_set_period_time_minmax +#undef snd_pcm_hw_params_set_period_time_near +#undef snd_pcm_hw_params_set_period_time_first +#undef snd_pcm_hw_params_set_period_time_last +#undef snd_pcm_hw_params_get_period_size +#undef snd_pcm_hw_params_get_period_size_min +#undef snd_pcm_hw_params_get_period_size_max +#undef snd_pcm_hw_params_test_period_size +#undef snd_pcm_hw_params_set_period_size +#undef snd_pcm_hw_params_set_period_size_min +#undef snd_pcm_hw_params_set_period_size_max +#undef snd_pcm_hw_params_set_period_size_minmax +#undef snd_pcm_hw_params_set_period_size_near +#undef snd_pcm_hw_params_set_period_size_first +#undef snd_pcm_hw_params_set_period_size_last +#undef snd_pcm_hw_params_set_period_size_integer +#undef snd_pcm_hw_params_get_periods +#undef snd_pcm_hw_params_get_periods_min +#undef snd_pcm_hw_params_get_periods_max +#undef snd_pcm_hw_params_test_periods +#undef snd_pcm_hw_params_set_periods +#undef snd_pcm_hw_params_set_periods_min +#undef snd_pcm_hw_params_set_periods_max +#undef snd_pcm_hw_params_set_periods_minmax +#undef snd_pcm_hw_params_set_periods_near +#undef snd_pcm_hw_params_set_periods_first +#undef snd_pcm_hw_params_set_periods_last +#undef snd_pcm_hw_params_set_periods_integer +#undef snd_pcm_hw_params_get_buffer_time +#undef snd_pcm_hw_params_get_buffer_time_min +#undef snd_pcm_hw_params_get_buffer_time_max +#undef snd_pcm_hw_params_test_buffer_time +#undef snd_pcm_hw_params_set_buffer_time +#undef snd_pcm_hw_params_set_buffer_time_min +#undef snd_pcm_hw_params_set_buffer_time_max +#undef snd_pcm_hw_params_set_buffer_time_minmax +#undef snd_pcm_hw_params_set_buffer_time_near +#undef snd_pcm_hw_params_set_buffer_time_first +#undef snd_pcm_hw_params_set_buffer_time_last +#undef snd_pcm_hw_params_get_buffer_size +#undef snd_pcm_hw_params_get_buffer_size_min +#undef snd_pcm_hw_params_get_buffer_size_max +#undef snd_pcm_hw_params_test_buffer_size +#undef snd_pcm_hw_params_set_buffer_size +#undef snd_pcm_hw_params_set_buffer_size_min +#undef snd_pcm_hw_params_set_buffer_size_max +#undef snd_pcm_hw_params_set_buffer_size_minmax +#undef snd_pcm_hw_params_set_buffer_size_near +#undef snd_pcm_hw_params_set_buffer_size_first +#undef snd_pcm_hw_params_set_buffer_size_last +#undef snd_pcm_hw_params_get_min_align +#undef snd_pcm_sw_params_sizeof +#undef snd_pcm_sw_params_malloc +#undef snd_pcm_sw_params_free +#undef snd_pcm_sw_params_copy +#undef snd_pcm_sw_params_get_boundary +#undef snd_pcm_sw_params_set_tstamp_mode +#undef snd_pcm_sw_params_get_tstamp_mode +#undef snd_pcm_sw_params_set_avail_min +#undef snd_pcm_sw_params_get_avail_min +#undef snd_pcm_sw_params_set_period_event +#undef snd_pcm_sw_params_get_period_event +#undef snd_pcm_sw_params_set_start_threshold +#undef snd_pcm_sw_params_get_start_threshold +#undef snd_pcm_sw_params_set_stop_threshold +#undef snd_pcm_sw_params_get_stop_threshold +#undef snd_pcm_sw_params_set_silence_threshold +#undef snd_pcm_sw_params_get_silence_threshold +#undef snd_pcm_sw_params_set_silence_size +#undef snd_pcm_sw_params_get_silence_size +#undef snd_pcm_access_mask_sizeof +#undef snd_pcm_access_mask_malloc +#undef snd_pcm_access_mask_free +#undef snd_pcm_access_mask_copy +#undef snd_pcm_access_mask_none +#undef snd_pcm_access_mask_any +#undef snd_pcm_access_mask_test +#undef snd_pcm_access_mask_empty +#undef snd_pcm_access_mask_set +#undef snd_pcm_access_mask_reset +#undef snd_pcm_format_mask_sizeof +#undef snd_pcm_format_mask_malloc +#undef snd_pcm_format_mask_free +#undef snd_pcm_format_mask_copy +#undef snd_pcm_format_mask_none +#undef snd_pcm_format_mask_any +#undef snd_pcm_format_mask_test +#undef snd_pcm_format_mask_empty +#undef snd_pcm_format_mask_set +#undef snd_pcm_format_mask_reset +#undef snd_pcm_subformat_mask_sizeof +#undef snd_pcm_subformat_mask_malloc +#undef snd_pcm_subformat_mask_free +#undef snd_pcm_subformat_mask_copy +#undef snd_pcm_subformat_mask_none +#undef snd_pcm_subformat_mask_any +#undef snd_pcm_subformat_mask_test +#undef snd_pcm_subformat_mask_empty +#undef snd_pcm_subformat_mask_set +#undef snd_pcm_subformat_mask_reset +#undef snd_pcm_status_sizeof +#undef snd_pcm_status_malloc +#undef snd_pcm_status_free +#undef snd_pcm_status_copy +#undef snd_pcm_status_get_state +#undef snd_pcm_status_get_trigger_tstamp +#undef snd_pcm_status_get_trigger_htstamp +#undef snd_pcm_status_get_tstamp +#undef snd_pcm_status_get_htstamp +#undef snd_pcm_status_get_audio_htstamp +#undef snd_pcm_status_get_driver_htstamp +#undef snd_pcm_status_get_delay +#undef snd_pcm_status_get_avail +#undef snd_pcm_status_get_avail_max +#undef snd_pcm_status_get_overrange +#undef snd_pcm_type_name +#undef snd_pcm_stream_name +#undef snd_pcm_access_name +#undef snd_pcm_format_name +#undef snd_pcm_format_description +#undef snd_pcm_subformat_name +#undef snd_pcm_subformat_description +#undef snd_pcm_format_value +#undef snd_pcm_tstamp_mode_name +#undef snd_pcm_state_name +#undef snd_pcm_dump +#undef snd_pcm_dump_hw_setup +#undef snd_pcm_dump_sw_setup +#undef snd_pcm_dump_setup +#undef snd_pcm_hw_params_dump +#undef snd_pcm_sw_params_dump +#undef snd_pcm_status_dump +#undef snd_pcm_mmap_begin +#undef snd_pcm_mmap_commit +#undef snd_pcm_mmap_writei +#undef snd_pcm_mmap_readi +#undef snd_pcm_mmap_writen +#undef snd_pcm_mmap_readn +#undef snd_pcm_format_signed +#undef snd_pcm_format_unsigned +#undef snd_pcm_format_linear +#undef snd_pcm_format_float +#undef snd_pcm_format_little_endian +#undef snd_pcm_format_big_endian +#undef snd_pcm_format_cpu_endian +#undef snd_pcm_format_width +#undef snd_pcm_format_physical_width +#undef snd_pcm_build_linear_format +#undef snd_pcm_format_size +#undef snd_pcm_format_silence +#undef snd_pcm_format_silence_16 +#undef snd_pcm_format_silence_32 +#undef snd_pcm_format_silence_64 +#undef snd_pcm_format_set_silence +#undef snd_pcm_bytes_to_frames +#undef snd_pcm_frames_to_bytes +#undef snd_pcm_bytes_to_samples +#undef snd_pcm_samples_to_bytes +#undef snd_pcm_area_silence +#undef snd_pcm_areas_silence +#undef snd_pcm_area_copy +#undef snd_pcm_areas_copy +#undef snd_pcm_areas_copy_wrap +#undef snd_pcm_hook_get_pcm +#undef snd_pcm_hook_get_private +#undef snd_pcm_hook_set_private +#undef snd_pcm_hook_add +#undef snd_pcm_hook_remove +#undef snd_pcm_meter_get_bufsize +#undef snd_pcm_meter_get_channels +#undef snd_pcm_meter_get_rate +#undef snd_pcm_meter_get_now +#undef snd_pcm_meter_get_boundary +#undef snd_pcm_meter_add_scope +#undef snd_pcm_meter_search_scope +#undef snd_pcm_scope_malloc +#undef snd_pcm_scope_set_ops +#undef snd_pcm_scope_set_name +#undef snd_pcm_scope_get_name +#undef snd_pcm_scope_get_callback_private +#undef snd_pcm_scope_set_callback_private +#undef snd_pcm_scope_s16_open +#undef snd_pcm_scope_s16_get_channel_buffer +#undef snd_spcm_init +#undef snd_spcm_init_duplex +#undef snd_spcm_init_get_params +#undef snd_pcm_start_mode_name +#undef snd_pcm_xrun_mode_name +#undef snd_pcm_sw_params_set_start_mode +#undef snd_pcm_sw_params_get_start_mode +#undef snd_pcm_sw_params_set_xrun_mode +#undef snd_pcm_sw_params_get_xrun_mode +#undef snd_pcm_sw_params_set_xfer_align +#undef snd_pcm_sw_params_get_xfer_align +#undef snd_pcm_sw_params_set_sleep_min +#undef snd_pcm_sw_params_get_sleep_min +#undef snd_pcm_hw_params_get_tick_time +#undef snd_pcm_hw_params_get_tick_time_min +#undef snd_pcm_hw_params_get_tick_time_max +#undef snd_pcm_hw_params_test_tick_time +#undef snd_pcm_hw_params_set_tick_time +#undef snd_pcm_hw_params_set_tick_time_min +#undef snd_pcm_hw_params_set_tick_time_max +#undef snd_pcm_hw_params_set_tick_time_minmax +#undef snd_pcm_hw_params_set_tick_time_near +#undef snd_pcm_hw_params_set_tick_time_first +#undef snd_pcm_hw_params_set_tick_time_last +#undef snd_rawmidi_open +#undef snd_rawmidi_open_lconf +#undef snd_rawmidi_close +#undef snd_rawmidi_poll_descriptors_count +#undef snd_rawmidi_poll_descriptors +#undef snd_rawmidi_poll_descriptors_revents +#undef snd_rawmidi_nonblock +#undef snd_rawmidi_info_sizeof +#undef snd_rawmidi_info_malloc +#undef snd_rawmidi_info_free +#undef snd_rawmidi_info_copy +#undef snd_rawmidi_info_get_device +#undef snd_rawmidi_info_get_subdevice +#undef snd_rawmidi_info_get_stream +#undef snd_rawmidi_info_get_card +#undef snd_rawmidi_info_get_flags +#undef snd_rawmidi_info_get_id +#undef snd_rawmidi_info_get_name +#undef snd_rawmidi_info_get_subdevice_name +#undef snd_rawmidi_info_get_subdevices_count +#undef snd_rawmidi_info_get_subdevices_avail +#undef snd_rawmidi_info_set_device +#undef snd_rawmidi_info_set_subdevice +#undef snd_rawmidi_info_set_stream +#undef snd_rawmidi_info +#undef snd_rawmidi_params_sizeof +#undef snd_rawmidi_params_malloc +#undef snd_rawmidi_params_free +#undef snd_rawmidi_params_copy +#undef snd_rawmidi_params_set_buffer_size +#undef snd_rawmidi_params_get_buffer_size +#undef snd_rawmidi_params_set_avail_min +#undef snd_rawmidi_params_get_avail_min +#undef snd_rawmidi_params_set_no_active_sensing +#undef snd_rawmidi_params_get_no_active_sensing +#undef snd_rawmidi_params +#undef snd_rawmidi_params_current +#undef snd_rawmidi_status_sizeof +#undef snd_rawmidi_status_malloc +#undef snd_rawmidi_status_free +#undef snd_rawmidi_status_copy +#undef snd_rawmidi_status_get_tstamp +#undef snd_rawmidi_status_get_avail +#undef snd_rawmidi_status_get_xruns +#undef snd_rawmidi_status +#undef snd_rawmidi_drain +#undef snd_rawmidi_drop +#undef snd_rawmidi_write +#undef snd_rawmidi_read +#undef snd_rawmidi_name +#undef snd_rawmidi_type +#undef snd_rawmidi_stream +#undef snd_timer_query_open +#undef snd_timer_query_open_lconf +#undef snd_timer_query_close +#undef snd_timer_query_next_device +#undef snd_timer_query_info +#undef snd_timer_query_params +#undef snd_timer_query_status +#undef snd_timer_open +#undef snd_timer_open_lconf +#undef snd_timer_close +#undef snd_async_add_timer_handler +#undef snd_async_handler_get_timer +#undef snd_timer_poll_descriptors_count +#undef snd_timer_poll_descriptors +#undef snd_timer_poll_descriptors_revents +#undef snd_timer_info +#undef snd_timer_params +#undef snd_timer_status +#undef snd_timer_start +#undef snd_timer_stop +#undef snd_timer_continue +#undef snd_timer_read +#undef snd_timer_id_sizeof +#undef snd_timer_id_malloc +#undef snd_timer_id_free +#undef snd_timer_id_copy +#undef snd_timer_id_set_class +#undef snd_timer_id_get_class +#undef snd_timer_id_set_sclass +#undef snd_timer_id_get_sclass +#undef snd_timer_id_set_card +#undef snd_timer_id_get_card +#undef snd_timer_id_set_device +#undef snd_timer_id_get_device +#undef snd_timer_id_set_subdevice +#undef snd_timer_id_get_subdevice +#undef snd_timer_ginfo_sizeof +#undef snd_timer_ginfo_malloc +#undef snd_timer_ginfo_free +#undef snd_timer_ginfo_copy +#undef snd_timer_ginfo_set_tid +#undef snd_timer_ginfo_get_tid +#undef snd_timer_ginfo_get_flags +#undef snd_timer_ginfo_get_card +#undef snd_timer_ginfo_get_id +#undef snd_timer_ginfo_get_name +#undef snd_timer_ginfo_get_resolution +#undef snd_timer_ginfo_get_resolution_min +#undef snd_timer_ginfo_get_resolution_max +#undef snd_timer_ginfo_get_clients +#undef snd_timer_info_sizeof +#undef snd_timer_info_malloc +#undef snd_timer_info_free +#undef snd_timer_info_copy +#undef snd_timer_info_is_slave +#undef snd_timer_info_get_card +#undef snd_timer_info_get_id +#undef snd_timer_info_get_name +#undef snd_timer_info_get_resolution +#undef snd_timer_params_sizeof +#undef snd_timer_params_malloc +#undef snd_timer_params_free +#undef snd_timer_params_copy +#undef snd_timer_params_set_auto_start +#undef snd_timer_params_get_auto_start +#undef snd_timer_params_set_exclusive +#undef snd_timer_params_get_exclusive +#undef snd_timer_params_set_early_event +#undef snd_timer_params_get_early_event +#undef snd_timer_params_set_ticks +#undef snd_timer_params_get_ticks +#undef snd_timer_params_set_queue_size +#undef snd_timer_params_get_queue_size +#undef snd_timer_params_set_filter +#undef snd_timer_params_get_filter +#undef snd_timer_status_sizeof +#undef snd_timer_status_malloc +#undef snd_timer_status_free +#undef snd_timer_status_copy +#undef snd_timer_status_get_timestamp +#undef snd_timer_status_get_resolution +#undef snd_timer_status_get_lost +#undef snd_timer_status_get_overrun +#undef snd_timer_status_get_queue +#undef snd_timer_info_get_ticks +#undef snd_hwdep_open +#undef snd_hwdep_close +#undef snd_hwdep_poll_descriptors +#undef snd_hwdep_poll_descriptors_count +#undef snd_hwdep_poll_descriptors_revents +#undef snd_hwdep_nonblock +#undef snd_hwdep_info +#undef snd_hwdep_dsp_status +#undef snd_hwdep_dsp_load +#undef snd_hwdep_ioctl +#undef snd_hwdep_write +#undef snd_hwdep_read +#undef snd_hwdep_info_sizeof +#undef snd_hwdep_info_malloc +#undef snd_hwdep_info_free +#undef snd_hwdep_info_copy +#undef snd_hwdep_info_get_device +#undef snd_hwdep_info_get_card +#undef snd_hwdep_info_get_id +#undef snd_hwdep_info_get_name +#undef snd_hwdep_info_get_iface +#undef snd_hwdep_info_set_device +#undef snd_hwdep_dsp_status_sizeof +#undef snd_hwdep_dsp_status_malloc +#undef snd_hwdep_dsp_status_free +#undef snd_hwdep_dsp_status_copy +#undef snd_hwdep_dsp_status_get_version +#undef snd_hwdep_dsp_status_get_id +#undef snd_hwdep_dsp_status_get_num_dsps +#undef snd_hwdep_dsp_status_get_dsp_loaded +#undef snd_hwdep_dsp_status_get_chip_ready +#undef snd_hwdep_dsp_image_sizeof +#undef snd_hwdep_dsp_image_malloc +#undef snd_hwdep_dsp_image_free +#undef snd_hwdep_dsp_image_copy +#undef snd_hwdep_dsp_image_get_index +#undef snd_hwdep_dsp_image_get_name +#undef snd_hwdep_dsp_image_get_image +#undef snd_hwdep_dsp_image_get_length +#undef snd_hwdep_dsp_image_set_index +#undef snd_hwdep_dsp_image_set_name +#undef snd_hwdep_dsp_image_set_image +#undef snd_hwdep_dsp_image_set_length +#undef snd_card_load +#undef snd_card_next +#undef snd_card_get_index +#undef snd_card_get_name +#undef snd_card_get_longname +#undef snd_device_name_hint +#undef snd_device_name_free_hint +#undef snd_device_name_get_hint +#undef snd_ctl_open +#undef snd_ctl_open_lconf +#undef snd_ctl_open_fallback +#undef snd_ctl_close +#undef snd_ctl_nonblock +#undef snd_async_add_ctl_handler +#undef snd_async_handler_get_ctl +#undef snd_ctl_poll_descriptors_count +#undef snd_ctl_poll_descriptors +#undef snd_ctl_poll_descriptors_revents +#undef snd_ctl_subscribe_events +#undef snd_ctl_card_info +#undef snd_ctl_elem_list +#undef snd_ctl_elem_info +#undef snd_ctl_elem_read +#undef snd_ctl_elem_write +#undef snd_ctl_elem_lock +#undef snd_ctl_elem_unlock +#undef snd_ctl_elem_tlv_read +#undef snd_ctl_elem_tlv_write +#undef snd_ctl_elem_tlv_command +#undef snd_ctl_hwdep_next_device +#undef snd_ctl_hwdep_info +#undef snd_ctl_pcm_next_device +#undef snd_ctl_pcm_info +#undef snd_ctl_pcm_prefer_subdevice +#undef snd_ctl_rawmidi_next_device +#undef snd_ctl_rawmidi_info +#undef snd_ctl_rawmidi_prefer_subdevice +#undef snd_ctl_set_power_state +#undef snd_ctl_get_power_state +#undef snd_ctl_read +#undef snd_ctl_wait +#undef snd_ctl_name +#undef snd_ctl_type +#undef snd_ctl_elem_type_name +#undef snd_ctl_elem_iface_name +#undef snd_ctl_event_type_name +#undef snd_ctl_event_elem_get_mask +#undef snd_ctl_event_elem_get_numid +#undef snd_ctl_event_elem_get_id +#undef snd_ctl_event_elem_get_interface +#undef snd_ctl_event_elem_get_device +#undef snd_ctl_event_elem_get_subdevice +#undef snd_ctl_event_elem_get_name +#undef snd_ctl_event_elem_get_index +#undef snd_ctl_elem_list_alloc_space +#undef snd_ctl_elem_list_free_space +#undef snd_ctl_ascii_elem_id_get +#undef snd_ctl_ascii_elem_id_parse +#undef snd_ctl_ascii_value_parse +#undef snd_ctl_elem_id_sizeof +#undef snd_ctl_elem_id_malloc +#undef snd_ctl_elem_id_free +#undef snd_ctl_elem_id_clear +#undef snd_ctl_elem_id_copy +#undef snd_ctl_elem_id_get_numid +#undef snd_ctl_elem_id_get_interface +#undef snd_ctl_elem_id_get_device +#undef snd_ctl_elem_id_get_subdevice +#undef snd_ctl_elem_id_get_name +#undef snd_ctl_elem_id_get_index +#undef snd_ctl_elem_id_set_numid +#undef snd_ctl_elem_id_set_interface +#undef snd_ctl_elem_id_set_device +#undef snd_ctl_elem_id_set_subdevice +#undef snd_ctl_elem_id_set_name +#undef snd_ctl_elem_id_set_index +#undef snd_ctl_card_info_sizeof +#undef snd_ctl_card_info_malloc +#undef snd_ctl_card_info_free +#undef snd_ctl_card_info_clear +#undef snd_ctl_card_info_copy +#undef snd_ctl_card_info_get_card +#undef snd_ctl_card_info_get_id +#undef snd_ctl_card_info_get_driver +#undef snd_ctl_card_info_get_name +#undef snd_ctl_card_info_get_longname +#undef snd_ctl_card_info_get_mixername +#undef snd_ctl_card_info_get_components +#undef snd_ctl_event_sizeof +#undef snd_ctl_event_malloc +#undef snd_ctl_event_free +#undef snd_ctl_event_clear +#undef snd_ctl_event_copy +#undef snd_ctl_event_get_type +#undef snd_ctl_elem_list_sizeof +#undef snd_ctl_elem_list_malloc +#undef snd_ctl_elem_list_free +#undef snd_ctl_elem_list_clear +#undef snd_ctl_elem_list_copy +#undef snd_ctl_elem_list_set_offset +#undef snd_ctl_elem_list_get_used +#undef snd_ctl_elem_list_get_count +#undef snd_ctl_elem_list_get_id +#undef snd_ctl_elem_list_get_numid +#undef snd_ctl_elem_list_get_interface +#undef snd_ctl_elem_list_get_device +#undef snd_ctl_elem_list_get_subdevice +#undef snd_ctl_elem_list_get_name +#undef snd_ctl_elem_list_get_index +#undef snd_ctl_elem_info_sizeof +#undef snd_ctl_elem_info_malloc +#undef snd_ctl_elem_info_free +#undef snd_ctl_elem_info_clear +#undef snd_ctl_elem_info_copy +#undef snd_ctl_elem_info_get_type +#undef snd_ctl_elem_info_is_readable +#undef snd_ctl_elem_info_is_writable +#undef snd_ctl_elem_info_is_volatile +#undef snd_ctl_elem_info_is_inactive +#undef snd_ctl_elem_info_is_locked +#undef snd_ctl_elem_info_is_tlv_readable +#undef snd_ctl_elem_info_is_tlv_writable +#undef snd_ctl_elem_info_is_tlv_commandable +#undef snd_ctl_elem_info_is_owner +#undef snd_ctl_elem_info_is_user +#undef snd_ctl_elem_info_get_owner +#undef snd_ctl_elem_info_get_count +#undef snd_ctl_elem_info_get_min +#undef snd_ctl_elem_info_get_max +#undef snd_ctl_elem_info_get_step +#undef snd_ctl_elem_info_get_min64 +#undef snd_ctl_elem_info_get_max64 +#undef snd_ctl_elem_info_get_step64 +#undef snd_ctl_elem_info_get_items +#undef snd_ctl_elem_info_set_item +#undef snd_ctl_elem_info_get_item_name +#undef snd_ctl_elem_info_get_dimensions +#undef snd_ctl_elem_info_get_dimension +#undef snd_ctl_elem_info_set_dimension +#undef snd_ctl_elem_info_get_id +#undef snd_ctl_elem_info_get_numid +#undef snd_ctl_elem_info_get_interface +#undef snd_ctl_elem_info_get_device +#undef snd_ctl_elem_info_get_subdevice +#undef snd_ctl_elem_info_get_name +#undef snd_ctl_elem_info_get_index +#undef snd_ctl_elem_info_set_id +#undef snd_ctl_elem_info_set_numid +#undef snd_ctl_elem_info_set_interface +#undef snd_ctl_elem_info_set_device +#undef snd_ctl_elem_info_set_subdevice +#undef snd_ctl_elem_info_set_name +#undef snd_ctl_elem_info_set_index +#undef snd_ctl_add_integer_elem_set +#undef snd_ctl_add_integer64_elem_set +#undef snd_ctl_add_boolean_elem_set +#undef snd_ctl_add_enumerated_elem_set +#undef snd_ctl_add_bytes_elem_set +#undef snd_ctl_elem_add_integer +#undef snd_ctl_elem_add_integer64 +#undef snd_ctl_elem_add_boolean +#undef snd_ctl_elem_add_enumerated +#undef snd_ctl_elem_add_iec958 +#undef snd_ctl_elem_remove +#undef snd_ctl_elem_value_sizeof +#undef snd_ctl_elem_value_malloc +#undef snd_ctl_elem_value_free +#undef snd_ctl_elem_value_clear +#undef snd_ctl_elem_value_copy +#undef snd_ctl_elem_value_compare +#undef snd_ctl_elem_value_get_id +#undef snd_ctl_elem_value_get_numid +#undef snd_ctl_elem_value_get_interface +#undef snd_ctl_elem_value_get_device +#undef snd_ctl_elem_value_get_subdevice +#undef snd_ctl_elem_value_get_name +#undef snd_ctl_elem_value_get_index +#undef snd_ctl_elem_value_set_id +#undef snd_ctl_elem_value_set_numid +#undef snd_ctl_elem_value_set_interface +#undef snd_ctl_elem_value_set_device +#undef snd_ctl_elem_value_set_subdevice +#undef snd_ctl_elem_value_set_name +#undef snd_ctl_elem_value_set_index +#undef snd_ctl_elem_value_get_boolean +#undef snd_ctl_elem_value_get_integer +#undef snd_ctl_elem_value_get_integer64 +#undef snd_ctl_elem_value_get_enumerated +#undef snd_ctl_elem_value_get_byte +#undef snd_ctl_elem_value_set_boolean +#undef snd_ctl_elem_value_set_integer +#undef snd_ctl_elem_value_set_integer64 +#undef snd_ctl_elem_value_set_enumerated +#undef snd_ctl_elem_value_set_byte +#undef snd_ctl_elem_set_bytes +#undef snd_ctl_elem_value_get_bytes +#undef snd_ctl_elem_value_get_iec958 +#undef snd_ctl_elem_value_set_iec958 +#undef snd_tlv_parse_dB_info +#undef snd_tlv_get_dB_range +#undef snd_tlv_convert_to_dB +#undef snd_tlv_convert_from_dB +#undef snd_ctl_get_dB_range +#undef snd_ctl_convert_to_dB +#undef snd_ctl_convert_from_dB +#undef snd_hctl_compare_fast +#undef snd_hctl_open +#undef snd_hctl_open_ctl +#undef snd_hctl_close +#undef snd_hctl_nonblock +#undef snd_hctl_poll_descriptors_count +#undef snd_hctl_poll_descriptors +#undef snd_hctl_poll_descriptors_revents +#undef snd_hctl_get_count +#undef snd_hctl_set_compare +#undef snd_hctl_first_elem +#undef snd_hctl_last_elem +#undef snd_hctl_find_elem +#undef snd_hctl_set_callback +#undef snd_hctl_set_callback_private +#undef snd_hctl_get_callback_private +#undef snd_hctl_load +#undef snd_hctl_free +#undef snd_hctl_handle_events +#undef snd_hctl_name +#undef snd_hctl_wait +#undef snd_hctl_ctl +#undef snd_hctl_elem_next +#undef snd_hctl_elem_prev +#undef snd_hctl_elem_info +#undef snd_hctl_elem_read +#undef snd_hctl_elem_write +#undef snd_hctl_elem_tlv_read +#undef snd_hctl_elem_tlv_write +#undef snd_hctl_elem_tlv_command +#undef snd_hctl_elem_get_hctl +#undef snd_hctl_elem_get_id +#undef snd_hctl_elem_get_numid +#undef snd_hctl_elem_get_interface +#undef snd_hctl_elem_get_device +#undef snd_hctl_elem_get_subdevice +#undef snd_hctl_elem_get_name +#undef snd_hctl_elem_get_index +#undef snd_hctl_elem_set_callback +#undef snd_hctl_elem_get_callback_private +#undef snd_hctl_elem_set_callback_private +#undef snd_sctl_build +#undef snd_sctl_free +#undef snd_sctl_install +#undef snd_sctl_remove +#undef snd_mixer_open +#undef snd_mixer_close +#undef snd_mixer_first_elem +#undef snd_mixer_last_elem +#undef snd_mixer_handle_events +#undef snd_mixer_attach +#undef snd_mixer_attach_hctl +#undef snd_mixer_detach +#undef snd_mixer_detach_hctl +#undef snd_mixer_get_hctl +#undef snd_mixer_poll_descriptors_count +#undef snd_mixer_poll_descriptors +#undef snd_mixer_poll_descriptors_revents +#undef snd_mixer_load +#undef snd_mixer_free +#undef snd_mixer_wait +#undef snd_mixer_set_compare +#undef snd_mixer_set_callback +#undef snd_mixer_get_callback_private +#undef snd_mixer_set_callback_private +#undef snd_mixer_get_count +#undef snd_mixer_class_unregister +#undef snd_mixer_elem_next +#undef snd_mixer_elem_prev +#undef snd_mixer_elem_set_callback +#undef snd_mixer_elem_get_callback_private +#undef snd_mixer_elem_set_callback_private +#undef snd_mixer_elem_get_type +#undef snd_mixer_class_register +#undef snd_mixer_elem_new +#undef snd_mixer_elem_add +#undef snd_mixer_elem_remove +#undef snd_mixer_elem_free +#undef snd_mixer_elem_info +#undef snd_mixer_elem_value +#undef snd_mixer_elem_attach +#undef snd_mixer_elem_detach +#undef snd_mixer_elem_empty +#undef snd_mixer_elem_get_private +#undef snd_mixer_class_sizeof +#undef snd_mixer_class_malloc +#undef snd_mixer_class_free +#undef snd_mixer_class_copy +#undef snd_mixer_class_get_mixer +#undef snd_mixer_class_get_event +#undef snd_mixer_class_get_private +#undef snd_mixer_class_get_compare +#undef snd_mixer_class_set_event +#undef snd_mixer_class_set_private +#undef snd_mixer_class_set_private_free +#undef snd_mixer_class_set_compare +#undef snd_mixer_selem_channel_name +#undef snd_mixer_selem_register +#undef snd_mixer_selem_get_id +#undef snd_mixer_selem_get_name +#undef snd_mixer_selem_get_index +#undef snd_mixer_find_selem +#undef snd_mixer_selem_is_active +#undef snd_mixer_selem_is_playback_mono +#undef snd_mixer_selem_has_playback_channel +#undef snd_mixer_selem_is_capture_mono +#undef snd_mixer_selem_has_capture_channel +#undef snd_mixer_selem_get_capture_group +#undef snd_mixer_selem_has_common_volume +#undef snd_mixer_selem_has_playback_volume +#undef snd_mixer_selem_has_playback_volume_joined +#undef snd_mixer_selem_has_capture_volume +#undef snd_mixer_selem_has_capture_volume_joined +#undef snd_mixer_selem_has_common_switch +#undef snd_mixer_selem_has_playback_switch +#undef snd_mixer_selem_has_playback_switch_joined +#undef snd_mixer_selem_has_capture_switch +#undef snd_mixer_selem_has_capture_switch_joined +#undef snd_mixer_selem_has_capture_switch_exclusive +#undef snd_mixer_selem_ask_playback_vol_dB +#undef snd_mixer_selem_ask_capture_vol_dB +#undef snd_mixer_selem_ask_playback_dB_vol +#undef snd_mixer_selem_ask_capture_dB_vol +#undef snd_mixer_selem_get_playback_volume +#undef snd_mixer_selem_get_capture_volume +#undef snd_mixer_selem_get_playback_dB +#undef snd_mixer_selem_get_capture_dB +#undef snd_mixer_selem_get_playback_switch +#undef snd_mixer_selem_get_capture_switch +#undef snd_mixer_selem_set_playback_volume +#undef snd_mixer_selem_set_capture_volume +#undef snd_mixer_selem_set_playback_dB +#undef snd_mixer_selem_set_capture_dB +#undef snd_mixer_selem_set_playback_volume_all +#undef snd_mixer_selem_set_capture_volume_all +#undef snd_mixer_selem_set_playback_dB_all +#undef snd_mixer_selem_set_capture_dB_all +#undef snd_mixer_selem_set_playback_switch +#undef snd_mixer_selem_set_capture_switch +#undef snd_mixer_selem_set_playback_switch_all +#undef snd_mixer_selem_set_capture_switch_all +#undef snd_mixer_selem_get_playback_volume_range +#undef snd_mixer_selem_get_playback_dB_range +#undef snd_mixer_selem_set_playback_volume_range +#undef snd_mixer_selem_get_capture_volume_range +#undef snd_mixer_selem_get_capture_dB_range +#undef snd_mixer_selem_set_capture_volume_range +#undef snd_mixer_selem_is_enumerated +#undef snd_mixer_selem_is_enum_playback +#undef snd_mixer_selem_is_enum_capture +#undef snd_mixer_selem_get_enum_items +#undef snd_mixer_selem_get_enum_item_name +#undef snd_mixer_selem_get_enum_item +#undef snd_mixer_selem_set_enum_item +#undef snd_mixer_selem_id_sizeof +#undef snd_mixer_selem_id_malloc +#undef snd_mixer_selem_id_free +#undef snd_mixer_selem_id_copy +#undef snd_mixer_selem_id_get_name +#undef snd_mixer_selem_id_get_index +#undef snd_mixer_selem_id_set_name +#undef snd_mixer_selem_id_set_index +#undef snd_mixer_selem_id_parse +#undef snd_seq_open +#undef snd_seq_open_lconf +#undef snd_seq_name +#undef snd_seq_type +#undef snd_seq_close +#undef snd_seq_poll_descriptors_count +#undef snd_seq_poll_descriptors +#undef snd_seq_poll_descriptors_revents +#undef snd_seq_nonblock +#undef snd_seq_client_id +#undef snd_seq_get_output_buffer_size +#undef snd_seq_get_input_buffer_size +#undef snd_seq_set_output_buffer_size +#undef snd_seq_set_input_buffer_size +#undef snd_seq_system_info_sizeof +#undef snd_seq_system_info_malloc +#undef snd_seq_system_info_free +#undef snd_seq_system_info_copy +#undef snd_seq_system_info_get_queues +#undef snd_seq_system_info_get_clients +#undef snd_seq_system_info_get_ports +#undef snd_seq_system_info_get_channels +#undef snd_seq_system_info_get_cur_clients +#undef snd_seq_system_info_get_cur_queues +#undef snd_seq_system_info +#undef snd_seq_client_info_sizeof +#undef snd_seq_client_info_malloc +#undef snd_seq_client_info_free +#undef snd_seq_client_info_copy +#undef snd_seq_client_info_get_client +#undef snd_seq_client_info_get_type +#undef snd_seq_client_info_get_name +#undef snd_seq_client_info_get_broadcast_filter +#undef snd_seq_client_info_get_error_bounce +#undef snd_seq_client_info_get_card +#undef snd_seq_client_info_get_pid +#undef snd_seq_client_info_get_event_filter +#undef snd_seq_client_info_get_num_ports +#undef snd_seq_client_info_get_event_lost +#undef snd_seq_client_info_set_client +#undef snd_seq_client_info_set_name +#undef snd_seq_client_info_set_broadcast_filter +#undef snd_seq_client_info_set_error_bounce +#undef snd_seq_client_info_set_event_filter +#undef snd_seq_client_info_event_filter_clear +#undef snd_seq_client_info_event_filter_add +#undef snd_seq_client_info_event_filter_del +#undef snd_seq_client_info_event_filter_check +#undef snd_seq_get_client_info +#undef snd_seq_get_any_client_info +#undef snd_seq_set_client_info +#undef snd_seq_query_next_client +#undef snd_seq_client_pool_sizeof +#undef snd_seq_client_pool_malloc +#undef snd_seq_client_pool_free +#undef snd_seq_client_pool_copy +#undef snd_seq_client_pool_get_client +#undef snd_seq_client_pool_get_output_pool +#undef snd_seq_client_pool_get_input_pool +#undef snd_seq_client_pool_get_output_room +#undef snd_seq_client_pool_get_output_free +#undef snd_seq_client_pool_get_input_free +#undef snd_seq_client_pool_set_output_pool +#undef snd_seq_client_pool_set_input_pool +#undef snd_seq_client_pool_set_output_room +#undef snd_seq_get_client_pool +#undef snd_seq_set_client_pool +#undef snd_seq_port_info_sizeof +#undef snd_seq_port_info_malloc +#undef snd_seq_port_info_free +#undef snd_seq_port_info_copy +#undef snd_seq_port_info_get_client +#undef snd_seq_port_info_get_port +#undef snd_seq_port_info_get_addr +#undef snd_seq_port_info_get_name +#undef snd_seq_port_info_get_capability +#undef snd_seq_port_info_get_type +#undef snd_seq_port_info_get_midi_channels +#undef snd_seq_port_info_get_midi_voices +#undef snd_seq_port_info_get_synth_voices +#undef snd_seq_port_info_get_read_use +#undef snd_seq_port_info_get_write_use +#undef snd_seq_port_info_get_port_specified +#undef snd_seq_port_info_get_timestamping +#undef snd_seq_port_info_get_timestamp_real +#undef snd_seq_port_info_get_timestamp_queue +#undef snd_seq_port_info_set_client +#undef snd_seq_port_info_set_port +#undef snd_seq_port_info_set_addr +#undef snd_seq_port_info_set_name +#undef snd_seq_port_info_set_capability +#undef snd_seq_port_info_set_type +#undef snd_seq_port_info_set_midi_channels +#undef snd_seq_port_info_set_midi_voices +#undef snd_seq_port_info_set_synth_voices +#undef snd_seq_port_info_set_port_specified +#undef snd_seq_port_info_set_timestamping +#undef snd_seq_port_info_set_timestamp_real +#undef snd_seq_port_info_set_timestamp_queue +#undef snd_seq_create_port +#undef snd_seq_delete_port +#undef snd_seq_get_port_info +#undef snd_seq_get_any_port_info +#undef snd_seq_set_port_info +#undef snd_seq_query_next_port +#undef snd_seq_port_subscribe_sizeof +#undef snd_seq_port_subscribe_malloc +#undef snd_seq_port_subscribe_free +#undef snd_seq_port_subscribe_copy +#undef snd_seq_port_subscribe_get_sender +#undef snd_seq_port_subscribe_get_dest +#undef snd_seq_port_subscribe_get_queue +#undef snd_seq_port_subscribe_get_exclusive +#undef snd_seq_port_subscribe_get_time_update +#undef snd_seq_port_subscribe_get_time_real +#undef snd_seq_port_subscribe_set_sender +#undef snd_seq_port_subscribe_set_dest +#undef snd_seq_port_subscribe_set_queue +#undef snd_seq_port_subscribe_set_exclusive +#undef snd_seq_port_subscribe_set_time_update +#undef snd_seq_port_subscribe_set_time_real +#undef snd_seq_get_port_subscription +#undef snd_seq_subscribe_port +#undef snd_seq_unsubscribe_port +#undef snd_seq_query_subscribe_sizeof +#undef snd_seq_query_subscribe_malloc +#undef snd_seq_query_subscribe_free +#undef snd_seq_query_subscribe_copy +#undef snd_seq_query_subscribe_get_client +#undef snd_seq_query_subscribe_get_port +#undef snd_seq_query_subscribe_get_root +#undef snd_seq_query_subscribe_get_type +#undef snd_seq_query_subscribe_get_index +#undef snd_seq_query_subscribe_get_num_subs +#undef snd_seq_query_subscribe_get_addr +#undef snd_seq_query_subscribe_get_queue +#undef snd_seq_query_subscribe_get_exclusive +#undef snd_seq_query_subscribe_get_time_update +#undef snd_seq_query_subscribe_get_time_real +#undef snd_seq_query_subscribe_set_client +#undef snd_seq_query_subscribe_set_port +#undef snd_seq_query_subscribe_set_root +#undef snd_seq_query_subscribe_set_type +#undef snd_seq_query_subscribe_set_index +#undef snd_seq_query_port_subscribers +#undef snd_seq_queue_info_sizeof +#undef snd_seq_queue_info_malloc +#undef snd_seq_queue_info_free +#undef snd_seq_queue_info_copy +#undef snd_seq_queue_info_get_queue +#undef snd_seq_queue_info_get_name +#undef snd_seq_queue_info_get_owner +#undef snd_seq_queue_info_get_locked +#undef snd_seq_queue_info_get_flags +#undef snd_seq_queue_info_set_name +#undef snd_seq_queue_info_set_owner +#undef snd_seq_queue_info_set_locked +#undef snd_seq_queue_info_set_flags +#undef snd_seq_create_queue +#undef snd_seq_alloc_named_queue +#undef snd_seq_alloc_queue +#undef snd_seq_free_queue +#undef snd_seq_get_queue_info +#undef snd_seq_set_queue_info +#undef snd_seq_query_named_queue +#undef snd_seq_get_queue_usage +#undef snd_seq_set_queue_usage +#undef snd_seq_queue_status_sizeof +#undef snd_seq_queue_status_malloc +#undef snd_seq_queue_status_free +#undef snd_seq_queue_status_copy +#undef snd_seq_queue_status_get_queue +#undef snd_seq_queue_status_get_events +#undef snd_seq_queue_status_get_tick_time +#undef snd_seq_queue_status_get_real_time +#undef snd_seq_queue_status_get_status +#undef snd_seq_get_queue_status +#undef snd_seq_queue_tempo_sizeof +#undef snd_seq_queue_tempo_malloc +#undef snd_seq_queue_tempo_free +#undef snd_seq_queue_tempo_copy +#undef snd_seq_queue_tempo_get_queue +#undef snd_seq_queue_tempo_get_tempo +#undef snd_seq_queue_tempo_get_ppq +#undef snd_seq_queue_tempo_get_skew +#undef snd_seq_queue_tempo_get_skew_base +#undef snd_seq_queue_tempo_set_tempo +#undef snd_seq_queue_tempo_set_ppq +#undef snd_seq_queue_tempo_set_skew +#undef snd_seq_queue_tempo_set_skew_base +#undef snd_seq_get_queue_tempo +#undef snd_seq_set_queue_tempo +#undef snd_seq_queue_timer_sizeof +#undef snd_seq_queue_timer_malloc +#undef snd_seq_queue_timer_free +#undef snd_seq_queue_timer_copy +#undef snd_seq_queue_timer_get_queue +#undef snd_seq_queue_timer_get_type +#undef snd_seq_queue_timer_get_id +#undef snd_seq_queue_timer_get_resolution +#undef snd_seq_queue_timer_set_type +#undef snd_seq_queue_timer_set_id +#undef snd_seq_queue_timer_set_resolution +#undef snd_seq_get_queue_timer +#undef snd_seq_set_queue_timer +#undef snd_seq_free_event +#undef snd_seq_event_length +#undef snd_seq_event_output +#undef snd_seq_event_output_buffer +#undef snd_seq_event_output_direct +#undef snd_seq_event_input +#undef snd_seq_event_input_pending +#undef snd_seq_drain_output +#undef snd_seq_event_output_pending +#undef snd_seq_extract_output +#undef snd_seq_drop_output +#undef snd_seq_drop_output_buffer +#undef snd_seq_drop_input +#undef snd_seq_drop_input_buffer +#undef snd_seq_remove_events_sizeof +#undef snd_seq_remove_events_malloc +#undef snd_seq_remove_events_free +#undef snd_seq_remove_events_copy +#undef snd_seq_remove_events_get_condition +#undef snd_seq_remove_events_get_queue +#undef snd_seq_remove_events_get_time +#undef snd_seq_remove_events_get_dest +#undef snd_seq_remove_events_get_channel +#undef snd_seq_remove_events_get_event_type +#undef snd_seq_remove_events_get_tag +#undef snd_seq_remove_events_set_condition +#undef snd_seq_remove_events_set_queue +#undef snd_seq_remove_events_set_time +#undef snd_seq_remove_events_set_dest +#undef snd_seq_remove_events_set_channel +#undef snd_seq_remove_events_set_event_type +#undef snd_seq_remove_events_set_tag +#undef snd_seq_remove_events +#undef snd_seq_set_bit +#undef snd_seq_unset_bit +#undef snd_seq_change_bit +#undef snd_seq_get_bit +#undef snd_seq_control_queue +#undef snd_seq_create_simple_port +#undef snd_seq_delete_simple_port +#undef snd_seq_connect_from +#undef snd_seq_connect_to +#undef snd_seq_disconnect_from +#undef snd_seq_disconnect_to +#undef snd_seq_set_client_name +#undef snd_seq_set_client_event_filter +#undef snd_seq_set_client_pool_output +#undef snd_seq_set_client_pool_output_room +#undef snd_seq_set_client_pool_input +#undef snd_seq_sync_output_queue +#undef snd_seq_parse_address +#undef snd_seq_reset_pool_output +#undef snd_seq_reset_pool_input +#undef snd_midi_event_new +#undef snd_midi_event_resize_buffer +#undef snd_midi_event_free +#undef snd_midi_event_init +#undef snd_midi_event_reset_encode +#undef snd_midi_event_reset_decode +#undef snd_midi_event_no_status +#undef snd_midi_event_encode +#undef snd_midi_event_encode_byte +#undef snd_midi_event_decode +#ifdef __cplusplus +extern "C" { +#endif +#define snd_asoundlib_version snd_asoundlib_version_dylibloader_wrapper_asound +#define snd_dlpath snd_dlpath_dylibloader_wrapper_asound +#define snd_dlopen snd_dlopen_dylibloader_wrapper_asound +#define snd_dlsym snd_dlsym_dylibloader_wrapper_asound +#define snd_dlclose snd_dlclose_dylibloader_wrapper_asound +#define snd_async_add_handler snd_async_add_handler_dylibloader_wrapper_asound +#define snd_async_del_handler snd_async_del_handler_dylibloader_wrapper_asound +#define snd_async_handler_get_fd snd_async_handler_get_fd_dylibloader_wrapper_asound +#define snd_async_handler_get_signo snd_async_handler_get_signo_dylibloader_wrapper_asound +#define snd_async_handler_get_callback_private snd_async_handler_get_callback_private_dylibloader_wrapper_asound +#define snd_shm_area_create snd_shm_area_create_dylibloader_wrapper_asound +#define snd_shm_area_share snd_shm_area_share_dylibloader_wrapper_asound +#define snd_shm_area_destroy snd_shm_area_destroy_dylibloader_wrapper_asound +#define snd_user_file snd_user_file_dylibloader_wrapper_asound +#define snd_input_stdio_open snd_input_stdio_open_dylibloader_wrapper_asound +#define snd_input_stdio_attach snd_input_stdio_attach_dylibloader_wrapper_asound +#define snd_input_buffer_open snd_input_buffer_open_dylibloader_wrapper_asound +#define snd_input_close snd_input_close_dylibloader_wrapper_asound +#define snd_input_scanf snd_input_scanf_dylibloader_wrapper_asound +#define snd_input_gets snd_input_gets_dylibloader_wrapper_asound +#define snd_input_getc snd_input_getc_dylibloader_wrapper_asound +#define snd_input_ungetc snd_input_ungetc_dylibloader_wrapper_asound +#define snd_output_stdio_open snd_output_stdio_open_dylibloader_wrapper_asound +#define snd_output_stdio_attach snd_output_stdio_attach_dylibloader_wrapper_asound +#define snd_output_buffer_open snd_output_buffer_open_dylibloader_wrapper_asound +#define snd_output_buffer_string snd_output_buffer_string_dylibloader_wrapper_asound +#define snd_output_close snd_output_close_dylibloader_wrapper_asound +#define snd_output_printf snd_output_printf_dylibloader_wrapper_asound +#define snd_output_vprintf snd_output_vprintf_dylibloader_wrapper_asound +#define snd_output_puts snd_output_puts_dylibloader_wrapper_asound +#define snd_output_putc snd_output_putc_dylibloader_wrapper_asound +#define snd_output_flush snd_output_flush_dylibloader_wrapper_asound +#define snd_strerror snd_strerror_dylibloader_wrapper_asound +#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_wrapper_asound +#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_wrapper_asound +#define snd_config_topdir snd_config_topdir_dylibloader_wrapper_asound +#define snd_config_top snd_config_top_dylibloader_wrapper_asound +#define snd_config_load snd_config_load_dylibloader_wrapper_asound +#define snd_config_load_override snd_config_load_override_dylibloader_wrapper_asound +#define snd_config_save snd_config_save_dylibloader_wrapper_asound +#define snd_config_update snd_config_update_dylibloader_wrapper_asound +#define snd_config_update_r snd_config_update_r_dylibloader_wrapper_asound +#define snd_config_update_free snd_config_update_free_dylibloader_wrapper_asound +#define snd_config_update_free_global snd_config_update_free_global_dylibloader_wrapper_asound +#define snd_config_update_ref snd_config_update_ref_dylibloader_wrapper_asound +#define snd_config_ref snd_config_ref_dylibloader_wrapper_asound +#define snd_config_unref snd_config_unref_dylibloader_wrapper_asound +#define snd_config_search snd_config_search_dylibloader_wrapper_asound +#define snd_config_searchv snd_config_searchv_dylibloader_wrapper_asound +#define snd_config_search_definition snd_config_search_definition_dylibloader_wrapper_asound +#define snd_config_expand snd_config_expand_dylibloader_wrapper_asound +#define snd_config_evaluate snd_config_evaluate_dylibloader_wrapper_asound +#define snd_config_add snd_config_add_dylibloader_wrapper_asound +#define snd_config_add_before snd_config_add_before_dylibloader_wrapper_asound +#define snd_config_add_after snd_config_add_after_dylibloader_wrapper_asound +#define snd_config_remove snd_config_remove_dylibloader_wrapper_asound +#define snd_config_delete snd_config_delete_dylibloader_wrapper_asound +#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_wrapper_asound +#define snd_config_copy snd_config_copy_dylibloader_wrapper_asound +#define snd_config_make snd_config_make_dylibloader_wrapper_asound +#define snd_config_make_integer snd_config_make_integer_dylibloader_wrapper_asound +#define snd_config_make_integer64 snd_config_make_integer64_dylibloader_wrapper_asound +#define snd_config_make_real snd_config_make_real_dylibloader_wrapper_asound +#define snd_config_make_string snd_config_make_string_dylibloader_wrapper_asound +#define snd_config_make_pointer snd_config_make_pointer_dylibloader_wrapper_asound +#define snd_config_make_compound snd_config_make_compound_dylibloader_wrapper_asound +#define snd_config_imake_integer snd_config_imake_integer_dylibloader_wrapper_asound +#define snd_config_imake_integer64 snd_config_imake_integer64_dylibloader_wrapper_asound +#define snd_config_imake_real snd_config_imake_real_dylibloader_wrapper_asound +#define snd_config_imake_string snd_config_imake_string_dylibloader_wrapper_asound +#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_wrapper_asound +#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_wrapper_asound +#define snd_config_get_type snd_config_get_type_dylibloader_wrapper_asound +#define snd_config_is_array snd_config_is_array_dylibloader_wrapper_asound +#define snd_config_set_id snd_config_set_id_dylibloader_wrapper_asound +#define snd_config_set_integer snd_config_set_integer_dylibloader_wrapper_asound +#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_wrapper_asound +#define snd_config_set_real snd_config_set_real_dylibloader_wrapper_asound +#define snd_config_set_string snd_config_set_string_dylibloader_wrapper_asound +#define snd_config_set_ascii snd_config_set_ascii_dylibloader_wrapper_asound +#define snd_config_set_pointer snd_config_set_pointer_dylibloader_wrapper_asound +#define snd_config_get_id snd_config_get_id_dylibloader_wrapper_asound +#define snd_config_get_integer snd_config_get_integer_dylibloader_wrapper_asound +#define snd_config_get_integer64 snd_config_get_integer64_dylibloader_wrapper_asound +#define snd_config_get_real snd_config_get_real_dylibloader_wrapper_asound +#define snd_config_get_ireal snd_config_get_ireal_dylibloader_wrapper_asound +#define snd_config_get_string snd_config_get_string_dylibloader_wrapper_asound +#define snd_config_get_ascii snd_config_get_ascii_dylibloader_wrapper_asound +#define snd_config_get_pointer snd_config_get_pointer_dylibloader_wrapper_asound +#define snd_config_test_id snd_config_test_id_dylibloader_wrapper_asound +#define snd_config_iterator_first snd_config_iterator_first_dylibloader_wrapper_asound +#define snd_config_iterator_next snd_config_iterator_next_dylibloader_wrapper_asound +#define snd_config_iterator_end snd_config_iterator_end_dylibloader_wrapper_asound +#define snd_config_iterator_entry snd_config_iterator_entry_dylibloader_wrapper_asound +#define snd_config_get_bool_ascii snd_config_get_bool_ascii_dylibloader_wrapper_asound +#define snd_config_get_bool snd_config_get_bool_dylibloader_wrapper_asound +#define snd_config_get_ctl_iface_ascii snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound +#define snd_config_get_ctl_iface snd_config_get_ctl_iface_dylibloader_wrapper_asound +#define snd_names_list snd_names_list_dylibloader_wrapper_asound +#define snd_names_list_free snd_names_list_free_dylibloader_wrapper_asound +#define snd_pcm_open snd_pcm_open_dylibloader_wrapper_asound +#define snd_pcm_open_lconf snd_pcm_open_lconf_dylibloader_wrapper_asound +#define snd_pcm_open_fallback snd_pcm_open_fallback_dylibloader_wrapper_asound +#define snd_pcm_close snd_pcm_close_dylibloader_wrapper_asound +#define snd_pcm_name snd_pcm_name_dylibloader_wrapper_asound +#define snd_pcm_type snd_pcm_type_dylibloader_wrapper_asound +#define snd_pcm_stream snd_pcm_stream_dylibloader_wrapper_asound +#define snd_pcm_poll_descriptors_count snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_pcm_poll_descriptors snd_pcm_poll_descriptors_dylibloader_wrapper_asound +#define snd_pcm_poll_descriptors_revents snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_pcm_nonblock snd_pcm_nonblock_dylibloader_wrapper_asound +#define snd_async_add_pcm_handler snd_async_add_pcm_handler_dylibloader_wrapper_asound +#define snd_async_handler_get_pcm snd_async_handler_get_pcm_dylibloader_wrapper_asound +#define snd_pcm_info snd_pcm_info_dylibloader_wrapper_asound +#define snd_pcm_hw_params_current snd_pcm_hw_params_current_dylibloader_wrapper_asound +#define snd_pcm_hw_params snd_pcm_hw_params_dylibloader_wrapper_asound +#define snd_pcm_hw_free snd_pcm_hw_free_dylibloader_wrapper_asound +#define snd_pcm_sw_params_current snd_pcm_sw_params_current_dylibloader_wrapper_asound +#define snd_pcm_sw_params snd_pcm_sw_params_dylibloader_wrapper_asound +#define snd_pcm_prepare snd_pcm_prepare_dylibloader_wrapper_asound +#define snd_pcm_reset snd_pcm_reset_dylibloader_wrapper_asound +#define snd_pcm_status snd_pcm_status_dylibloader_wrapper_asound +#define snd_pcm_start snd_pcm_start_dylibloader_wrapper_asound +#define snd_pcm_drop snd_pcm_drop_dylibloader_wrapper_asound +#define snd_pcm_drain snd_pcm_drain_dylibloader_wrapper_asound +#define snd_pcm_pause snd_pcm_pause_dylibloader_wrapper_asound +#define snd_pcm_state snd_pcm_state_dylibloader_wrapper_asound +#define snd_pcm_hwsync snd_pcm_hwsync_dylibloader_wrapper_asound +#define snd_pcm_delay snd_pcm_delay_dylibloader_wrapper_asound +#define snd_pcm_resume snd_pcm_resume_dylibloader_wrapper_asound +#define snd_pcm_htimestamp snd_pcm_htimestamp_dylibloader_wrapper_asound +#define snd_pcm_avail snd_pcm_avail_dylibloader_wrapper_asound +#define snd_pcm_avail_update snd_pcm_avail_update_dylibloader_wrapper_asound +#define snd_pcm_avail_delay snd_pcm_avail_delay_dylibloader_wrapper_asound +#define snd_pcm_rewindable snd_pcm_rewindable_dylibloader_wrapper_asound +#define snd_pcm_rewind snd_pcm_rewind_dylibloader_wrapper_asound +#define snd_pcm_forwardable snd_pcm_forwardable_dylibloader_wrapper_asound +#define snd_pcm_forward snd_pcm_forward_dylibloader_wrapper_asound +#define snd_pcm_writei snd_pcm_writei_dylibloader_wrapper_asound +#define snd_pcm_readi snd_pcm_readi_dylibloader_wrapper_asound +#define snd_pcm_writen snd_pcm_writen_dylibloader_wrapper_asound +#define snd_pcm_readn snd_pcm_readn_dylibloader_wrapper_asound +#define snd_pcm_wait snd_pcm_wait_dylibloader_wrapper_asound +#define snd_pcm_link snd_pcm_link_dylibloader_wrapper_asound +#define snd_pcm_unlink snd_pcm_unlink_dylibloader_wrapper_asound +#define snd_pcm_query_chmaps snd_pcm_query_chmaps_dylibloader_wrapper_asound +#define snd_pcm_query_chmaps_from_hw snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound +#define snd_pcm_free_chmaps snd_pcm_free_chmaps_dylibloader_wrapper_asound +#define snd_pcm_get_chmap snd_pcm_get_chmap_dylibloader_wrapper_asound +#define snd_pcm_set_chmap snd_pcm_set_chmap_dylibloader_wrapper_asound +#define snd_pcm_chmap_type_name snd_pcm_chmap_type_name_dylibloader_wrapper_asound +#define snd_pcm_chmap_name snd_pcm_chmap_name_dylibloader_wrapper_asound +#define snd_pcm_chmap_long_name snd_pcm_chmap_long_name_dylibloader_wrapper_asound +#define snd_pcm_chmap_print snd_pcm_chmap_print_dylibloader_wrapper_asound +#define snd_pcm_chmap_from_string snd_pcm_chmap_from_string_dylibloader_wrapper_asound +#define snd_pcm_chmap_parse_string snd_pcm_chmap_parse_string_dylibloader_wrapper_asound +#define snd_pcm_recover snd_pcm_recover_dylibloader_wrapper_asound +#define snd_pcm_set_params snd_pcm_set_params_dylibloader_wrapper_asound +#define snd_pcm_get_params snd_pcm_get_params_dylibloader_wrapper_asound +#define snd_pcm_info_sizeof snd_pcm_info_sizeof_dylibloader_wrapper_asound +#define snd_pcm_info_malloc snd_pcm_info_malloc_dylibloader_wrapper_asound +#define snd_pcm_info_free snd_pcm_info_free_dylibloader_wrapper_asound +#define snd_pcm_info_copy snd_pcm_info_copy_dylibloader_wrapper_asound +#define snd_pcm_info_get_device snd_pcm_info_get_device_dylibloader_wrapper_asound +#define snd_pcm_info_get_subdevice snd_pcm_info_get_subdevice_dylibloader_wrapper_asound +#define snd_pcm_info_get_stream snd_pcm_info_get_stream_dylibloader_wrapper_asound +#define snd_pcm_info_get_card snd_pcm_info_get_card_dylibloader_wrapper_asound +#define snd_pcm_info_get_id snd_pcm_info_get_id_dylibloader_wrapper_asound +#define snd_pcm_info_get_name snd_pcm_info_get_name_dylibloader_wrapper_asound +#define snd_pcm_info_get_subdevice_name snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound +#define snd_pcm_info_get_class snd_pcm_info_get_class_dylibloader_wrapper_asound +#define snd_pcm_info_get_subclass snd_pcm_info_get_subclass_dylibloader_wrapper_asound +#define snd_pcm_info_get_subdevices_count snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound +#define snd_pcm_info_get_subdevices_avail snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound +#define snd_pcm_info_get_sync snd_pcm_info_get_sync_dylibloader_wrapper_asound +#define snd_pcm_info_set_device snd_pcm_info_set_device_dylibloader_wrapper_asound +#define snd_pcm_info_set_subdevice snd_pcm_info_set_subdevice_dylibloader_wrapper_asound +#define snd_pcm_info_set_stream snd_pcm_info_set_stream_dylibloader_wrapper_asound +#define snd_pcm_hw_params_any snd_pcm_hw_params_any_dylibloader_wrapper_asound +#define snd_pcm_hw_params_can_mmap_sample_resolution snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound +#define snd_pcm_hw_params_is_double snd_pcm_hw_params_is_double_dylibloader_wrapper_asound +#define snd_pcm_hw_params_is_batch snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound +#define snd_pcm_hw_params_is_block_transfer snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound +#define snd_pcm_hw_params_is_monotonic snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound +#define snd_pcm_hw_params_can_overrange snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound +#define snd_pcm_hw_params_can_pause snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound +#define snd_pcm_hw_params_can_resume snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound +#define snd_pcm_hw_params_is_half_duplex snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound +#define snd_pcm_hw_params_is_joint_duplex snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound +#define snd_pcm_hw_params_can_sync_start snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound +#define snd_pcm_hw_params_can_disable_period_wakeup snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound +#define snd_pcm_hw_params_supports_audio_wallclock_ts snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound +#define snd_pcm_hw_params_supports_audio_ts_type snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_rate_numden snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_sbits snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_fifo_size snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_sizeof snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound +#define snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc_dylibloader_wrapper_asound +#define snd_pcm_hw_params_free snd_pcm_hw_params_free_dylibloader_wrapper_asound +#define snd_pcm_hw_params_copy snd_pcm_hw_params_copy_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_access snd_pcm_hw_params_get_access_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_access snd_pcm_hw_params_test_access_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_access_first snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_access_last snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_access_mask snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_access_mask snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_format snd_pcm_hw_params_get_format_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_format snd_pcm_hw_params_test_format_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_format_first snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_format_last snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_format_mask snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_format_mask snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_subformat snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_subformat snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_subformat snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_subformat_first snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_subformat_last snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_subformat_mask snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_subformat_mask snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_channels snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_channels_min snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_channels_max snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_channels snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels_min snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels_max snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels_minmax snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels_near snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels_first snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_channels_last snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_rate snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_rate_min snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_rate_max snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_rate snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_min snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_max snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_minmax snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_near snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_first snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_last snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_rate_resample snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_rate_resample snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_export_buffer snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_export_buffer snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_wakeup snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_wakeup snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_time snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_time_min snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_time_max snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_period_time snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time_min snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time_max snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time_minmax snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time_near snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time_first snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_time_last snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_size snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_size_min snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_period_size_max snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_period_size snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_min snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_max snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_minmax snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_near snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_first snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_last snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_period_size_integer snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_periods snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_periods_min snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_periods_max snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_periods snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_min snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_max snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_minmax snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_near snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_first snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_last snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_periods_integer snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_buffer_time snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_buffer_time_min snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_buffer_time_max snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_buffer_time snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time_min snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time_max snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time_minmax snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time_near snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time_first snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_time_last snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_buffer_size snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_buffer_size_min snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_buffer_size_max snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_buffer_size snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size_min snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size_max snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size_minmax snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size_near snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size_first snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_buffer_size_last snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_min_align snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound +#define snd_pcm_sw_params_sizeof snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound +#define snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc_dylibloader_wrapper_asound +#define snd_pcm_sw_params_free snd_pcm_sw_params_free_dylibloader_wrapper_asound +#define snd_pcm_sw_params_copy snd_pcm_sw_params_copy_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_boundary snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_tstamp_mode snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_tstamp_mode snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_avail_min snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_avail_min snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_period_event snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_period_event snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_start_threshold snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_start_threshold snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_stop_threshold snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_stop_threshold snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_silence_threshold snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_silence_threshold snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_silence_size snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_silence_size snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound +#define snd_pcm_access_mask_sizeof snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound +#define snd_pcm_access_mask_malloc snd_pcm_access_mask_malloc_dylibloader_wrapper_asound +#define snd_pcm_access_mask_free snd_pcm_access_mask_free_dylibloader_wrapper_asound +#define snd_pcm_access_mask_copy snd_pcm_access_mask_copy_dylibloader_wrapper_asound +#define snd_pcm_access_mask_none snd_pcm_access_mask_none_dylibloader_wrapper_asound +#define snd_pcm_access_mask_any snd_pcm_access_mask_any_dylibloader_wrapper_asound +#define snd_pcm_access_mask_test snd_pcm_access_mask_test_dylibloader_wrapper_asound +#define snd_pcm_access_mask_empty snd_pcm_access_mask_empty_dylibloader_wrapper_asound +#define snd_pcm_access_mask_set snd_pcm_access_mask_set_dylibloader_wrapper_asound +#define snd_pcm_access_mask_reset snd_pcm_access_mask_reset_dylibloader_wrapper_asound +#define snd_pcm_format_mask_sizeof snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound +#define snd_pcm_format_mask_malloc snd_pcm_format_mask_malloc_dylibloader_wrapper_asound +#define snd_pcm_format_mask_free snd_pcm_format_mask_free_dylibloader_wrapper_asound +#define snd_pcm_format_mask_copy snd_pcm_format_mask_copy_dylibloader_wrapper_asound +#define snd_pcm_format_mask_none snd_pcm_format_mask_none_dylibloader_wrapper_asound +#define snd_pcm_format_mask_any snd_pcm_format_mask_any_dylibloader_wrapper_asound +#define snd_pcm_format_mask_test snd_pcm_format_mask_test_dylibloader_wrapper_asound +#define snd_pcm_format_mask_empty snd_pcm_format_mask_empty_dylibloader_wrapper_asound +#define snd_pcm_format_mask_set snd_pcm_format_mask_set_dylibloader_wrapper_asound +#define snd_pcm_format_mask_reset snd_pcm_format_mask_reset_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_sizeof snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_malloc snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_free snd_pcm_subformat_mask_free_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_copy snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_none snd_pcm_subformat_mask_none_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_any snd_pcm_subformat_mask_any_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_test snd_pcm_subformat_mask_test_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_empty snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_set snd_pcm_subformat_mask_set_dylibloader_wrapper_asound +#define snd_pcm_subformat_mask_reset snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound +#define snd_pcm_status_sizeof snd_pcm_status_sizeof_dylibloader_wrapper_asound +#define snd_pcm_status_malloc snd_pcm_status_malloc_dylibloader_wrapper_asound +#define snd_pcm_status_free snd_pcm_status_free_dylibloader_wrapper_asound +#define snd_pcm_status_copy snd_pcm_status_copy_dylibloader_wrapper_asound +#define snd_pcm_status_get_state snd_pcm_status_get_state_dylibloader_wrapper_asound +#define snd_pcm_status_get_trigger_tstamp snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound +#define snd_pcm_status_get_trigger_htstamp snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound +#define snd_pcm_status_get_tstamp snd_pcm_status_get_tstamp_dylibloader_wrapper_asound +#define snd_pcm_status_get_htstamp snd_pcm_status_get_htstamp_dylibloader_wrapper_asound +#define snd_pcm_status_get_audio_htstamp snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound +#define snd_pcm_status_get_driver_htstamp snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound +#define snd_pcm_status_get_delay snd_pcm_status_get_delay_dylibloader_wrapper_asound +#define snd_pcm_status_get_avail snd_pcm_status_get_avail_dylibloader_wrapper_asound +#define snd_pcm_status_get_avail_max snd_pcm_status_get_avail_max_dylibloader_wrapper_asound +#define snd_pcm_status_get_overrange snd_pcm_status_get_overrange_dylibloader_wrapper_asound +#define snd_pcm_type_name snd_pcm_type_name_dylibloader_wrapper_asound +#define snd_pcm_stream_name snd_pcm_stream_name_dylibloader_wrapper_asound +#define snd_pcm_access_name snd_pcm_access_name_dylibloader_wrapper_asound +#define snd_pcm_format_name snd_pcm_format_name_dylibloader_wrapper_asound +#define snd_pcm_format_description snd_pcm_format_description_dylibloader_wrapper_asound +#define snd_pcm_subformat_name snd_pcm_subformat_name_dylibloader_wrapper_asound +#define snd_pcm_subformat_description snd_pcm_subformat_description_dylibloader_wrapper_asound +#define snd_pcm_format_value snd_pcm_format_value_dylibloader_wrapper_asound +#define snd_pcm_tstamp_mode_name snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound +#define snd_pcm_state_name snd_pcm_state_name_dylibloader_wrapper_asound +#define snd_pcm_dump snd_pcm_dump_dylibloader_wrapper_asound +#define snd_pcm_dump_hw_setup snd_pcm_dump_hw_setup_dylibloader_wrapper_asound +#define snd_pcm_dump_sw_setup snd_pcm_dump_sw_setup_dylibloader_wrapper_asound +#define snd_pcm_dump_setup snd_pcm_dump_setup_dylibloader_wrapper_asound +#define snd_pcm_hw_params_dump snd_pcm_hw_params_dump_dylibloader_wrapper_asound +#define snd_pcm_sw_params_dump snd_pcm_sw_params_dump_dylibloader_wrapper_asound +#define snd_pcm_status_dump snd_pcm_status_dump_dylibloader_wrapper_asound +#define snd_pcm_mmap_begin snd_pcm_mmap_begin_dylibloader_wrapper_asound +#define snd_pcm_mmap_commit snd_pcm_mmap_commit_dylibloader_wrapper_asound +#define snd_pcm_mmap_writei snd_pcm_mmap_writei_dylibloader_wrapper_asound +#define snd_pcm_mmap_readi snd_pcm_mmap_readi_dylibloader_wrapper_asound +#define snd_pcm_mmap_writen snd_pcm_mmap_writen_dylibloader_wrapper_asound +#define snd_pcm_mmap_readn snd_pcm_mmap_readn_dylibloader_wrapper_asound +#define snd_pcm_format_signed snd_pcm_format_signed_dylibloader_wrapper_asound +#define snd_pcm_format_unsigned snd_pcm_format_unsigned_dylibloader_wrapper_asound +#define snd_pcm_format_linear snd_pcm_format_linear_dylibloader_wrapper_asound +#define snd_pcm_format_float snd_pcm_format_float_dylibloader_wrapper_asound +#define snd_pcm_format_little_endian snd_pcm_format_little_endian_dylibloader_wrapper_asound +#define snd_pcm_format_big_endian snd_pcm_format_big_endian_dylibloader_wrapper_asound +#define snd_pcm_format_cpu_endian snd_pcm_format_cpu_endian_dylibloader_wrapper_asound +#define snd_pcm_format_width snd_pcm_format_width_dylibloader_wrapper_asound +#define snd_pcm_format_physical_width snd_pcm_format_physical_width_dylibloader_wrapper_asound +#define snd_pcm_build_linear_format snd_pcm_build_linear_format_dylibloader_wrapper_asound +#define snd_pcm_format_size snd_pcm_format_size_dylibloader_wrapper_asound +#define snd_pcm_format_silence snd_pcm_format_silence_dylibloader_wrapper_asound +#define snd_pcm_format_silence_16 snd_pcm_format_silence_16_dylibloader_wrapper_asound +#define snd_pcm_format_silence_32 snd_pcm_format_silence_32_dylibloader_wrapper_asound +#define snd_pcm_format_silence_64 snd_pcm_format_silence_64_dylibloader_wrapper_asound +#define snd_pcm_format_set_silence snd_pcm_format_set_silence_dylibloader_wrapper_asound +#define snd_pcm_bytes_to_frames snd_pcm_bytes_to_frames_dylibloader_wrapper_asound +#define snd_pcm_frames_to_bytes snd_pcm_frames_to_bytes_dylibloader_wrapper_asound +#define snd_pcm_bytes_to_samples snd_pcm_bytes_to_samples_dylibloader_wrapper_asound +#define snd_pcm_samples_to_bytes snd_pcm_samples_to_bytes_dylibloader_wrapper_asound +#define snd_pcm_area_silence snd_pcm_area_silence_dylibloader_wrapper_asound +#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_wrapper_asound +#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_wrapper_asound +#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_wrapper_asound +#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound +#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_wrapper_asound +#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_wrapper_asound +#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_wrapper_asound +#define snd_pcm_hook_add snd_pcm_hook_add_dylibloader_wrapper_asound +#define snd_pcm_hook_remove snd_pcm_hook_remove_dylibloader_wrapper_asound +#define snd_pcm_meter_get_bufsize snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound +#define snd_pcm_meter_get_channels snd_pcm_meter_get_channels_dylibloader_wrapper_asound +#define snd_pcm_meter_get_rate snd_pcm_meter_get_rate_dylibloader_wrapper_asound +#define snd_pcm_meter_get_now snd_pcm_meter_get_now_dylibloader_wrapper_asound +#define snd_pcm_meter_get_boundary snd_pcm_meter_get_boundary_dylibloader_wrapper_asound +#define snd_pcm_meter_add_scope snd_pcm_meter_add_scope_dylibloader_wrapper_asound +#define snd_pcm_meter_search_scope snd_pcm_meter_search_scope_dylibloader_wrapper_asound +#define snd_pcm_scope_malloc snd_pcm_scope_malloc_dylibloader_wrapper_asound +#define snd_pcm_scope_set_ops snd_pcm_scope_set_ops_dylibloader_wrapper_asound +#define snd_pcm_scope_set_name snd_pcm_scope_set_name_dylibloader_wrapper_asound +#define snd_pcm_scope_get_name snd_pcm_scope_get_name_dylibloader_wrapper_asound +#define snd_pcm_scope_get_callback_private snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound +#define snd_pcm_scope_set_callback_private snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound +#define snd_pcm_scope_s16_open snd_pcm_scope_s16_open_dylibloader_wrapper_asound +#define snd_pcm_scope_s16_get_channel_buffer snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound +#define snd_spcm_init snd_spcm_init_dylibloader_wrapper_asound +#define snd_spcm_init_duplex snd_spcm_init_duplex_dylibloader_wrapper_asound +#define snd_spcm_init_get_params snd_spcm_init_get_params_dylibloader_wrapper_asound +#define snd_pcm_start_mode_name snd_pcm_start_mode_name_dylibloader_wrapper_asound +#define snd_pcm_xrun_mode_name snd_pcm_xrun_mode_name_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_start_mode snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_start_mode snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_xrun_mode snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_xrun_mode snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_xfer_align snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_xfer_align snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound +#define snd_pcm_sw_params_set_sleep_min snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound +#define snd_pcm_sw_params_get_sleep_min snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_tick_time snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_tick_time_min snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_get_tick_time_max snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_test_tick_time snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time_min snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time_max snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time_minmax snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time_near snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time_first snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound +#define snd_pcm_hw_params_set_tick_time_last snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound +#define snd_rawmidi_open snd_rawmidi_open_dylibloader_wrapper_asound +#define snd_rawmidi_open_lconf snd_rawmidi_open_lconf_dylibloader_wrapper_asound +#define snd_rawmidi_close snd_rawmidi_close_dylibloader_wrapper_asound +#define snd_rawmidi_poll_descriptors_count snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_rawmidi_poll_descriptors snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound +#define snd_rawmidi_poll_descriptors_revents snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_rawmidi_nonblock snd_rawmidi_nonblock_dylibloader_wrapper_asound +#define snd_rawmidi_info_sizeof snd_rawmidi_info_sizeof_dylibloader_wrapper_asound +#define snd_rawmidi_info_malloc snd_rawmidi_info_malloc_dylibloader_wrapper_asound +#define snd_rawmidi_info_free snd_rawmidi_info_free_dylibloader_wrapper_asound +#define snd_rawmidi_info_copy snd_rawmidi_info_copy_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_device snd_rawmidi_info_get_device_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_subdevice snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_stream snd_rawmidi_info_get_stream_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_card snd_rawmidi_info_get_card_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_flags snd_rawmidi_info_get_flags_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_id snd_rawmidi_info_get_id_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_name snd_rawmidi_info_get_name_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_subdevice_name snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_subdevices_count snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound +#define snd_rawmidi_info_get_subdevices_avail snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound +#define snd_rawmidi_info_set_device snd_rawmidi_info_set_device_dylibloader_wrapper_asound +#define snd_rawmidi_info_set_subdevice snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound +#define snd_rawmidi_info_set_stream snd_rawmidi_info_set_stream_dylibloader_wrapper_asound +#define snd_rawmidi_info snd_rawmidi_info_dylibloader_wrapper_asound +#define snd_rawmidi_params_sizeof snd_rawmidi_params_sizeof_dylibloader_wrapper_asound +#define snd_rawmidi_params_malloc snd_rawmidi_params_malloc_dylibloader_wrapper_asound +#define snd_rawmidi_params_free snd_rawmidi_params_free_dylibloader_wrapper_asound +#define snd_rawmidi_params_copy snd_rawmidi_params_copy_dylibloader_wrapper_asound +#define snd_rawmidi_params_set_buffer_size snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound +#define snd_rawmidi_params_get_buffer_size snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound +#define snd_rawmidi_params_set_avail_min snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound +#define snd_rawmidi_params_get_avail_min snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound +#define snd_rawmidi_params_set_no_active_sensing snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound +#define snd_rawmidi_params_get_no_active_sensing snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound +#define snd_rawmidi_params snd_rawmidi_params_dylibloader_wrapper_asound +#define snd_rawmidi_params_current snd_rawmidi_params_current_dylibloader_wrapper_asound +#define snd_rawmidi_status_sizeof snd_rawmidi_status_sizeof_dylibloader_wrapper_asound +#define snd_rawmidi_status_malloc snd_rawmidi_status_malloc_dylibloader_wrapper_asound +#define snd_rawmidi_status_free snd_rawmidi_status_free_dylibloader_wrapper_asound +#define snd_rawmidi_status_copy snd_rawmidi_status_copy_dylibloader_wrapper_asound +#define snd_rawmidi_status_get_tstamp snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound +#define snd_rawmidi_status_get_avail snd_rawmidi_status_get_avail_dylibloader_wrapper_asound +#define snd_rawmidi_status_get_xruns snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound +#define snd_rawmidi_status snd_rawmidi_status_dylibloader_wrapper_asound +#define snd_rawmidi_drain snd_rawmidi_drain_dylibloader_wrapper_asound +#define snd_rawmidi_drop snd_rawmidi_drop_dylibloader_wrapper_asound +#define snd_rawmidi_write snd_rawmidi_write_dylibloader_wrapper_asound +#define snd_rawmidi_read snd_rawmidi_read_dylibloader_wrapper_asound +#define snd_rawmidi_name snd_rawmidi_name_dylibloader_wrapper_asound +#define snd_rawmidi_type snd_rawmidi_type_dylibloader_wrapper_asound +#define snd_rawmidi_stream snd_rawmidi_stream_dylibloader_wrapper_asound +#define snd_timer_query_open snd_timer_query_open_dylibloader_wrapper_asound +#define snd_timer_query_open_lconf snd_timer_query_open_lconf_dylibloader_wrapper_asound +#define snd_timer_query_close snd_timer_query_close_dylibloader_wrapper_asound +#define snd_timer_query_next_device snd_timer_query_next_device_dylibloader_wrapper_asound +#define snd_timer_query_info snd_timer_query_info_dylibloader_wrapper_asound +#define snd_timer_query_params snd_timer_query_params_dylibloader_wrapper_asound +#define snd_timer_query_status snd_timer_query_status_dylibloader_wrapper_asound +#define snd_timer_open snd_timer_open_dylibloader_wrapper_asound +#define snd_timer_open_lconf snd_timer_open_lconf_dylibloader_wrapper_asound +#define snd_timer_close snd_timer_close_dylibloader_wrapper_asound +#define snd_async_add_timer_handler snd_async_add_timer_handler_dylibloader_wrapper_asound +#define snd_async_handler_get_timer snd_async_handler_get_timer_dylibloader_wrapper_asound +#define snd_timer_poll_descriptors_count snd_timer_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_timer_poll_descriptors snd_timer_poll_descriptors_dylibloader_wrapper_asound +#define snd_timer_poll_descriptors_revents snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_timer_info snd_timer_info_dylibloader_wrapper_asound +#define snd_timer_params snd_timer_params_dylibloader_wrapper_asound +#define snd_timer_status snd_timer_status_dylibloader_wrapper_asound +#define snd_timer_start snd_timer_start_dylibloader_wrapper_asound +#define snd_timer_stop snd_timer_stop_dylibloader_wrapper_asound +#define snd_timer_continue snd_timer_continue_dylibloader_wrapper_asound +#define snd_timer_read snd_timer_read_dylibloader_wrapper_asound +#define snd_timer_id_sizeof snd_timer_id_sizeof_dylibloader_wrapper_asound +#define snd_timer_id_malloc snd_timer_id_malloc_dylibloader_wrapper_asound +#define snd_timer_id_free snd_timer_id_free_dylibloader_wrapper_asound +#define snd_timer_id_copy snd_timer_id_copy_dylibloader_wrapper_asound +#define snd_timer_id_set_class snd_timer_id_set_class_dylibloader_wrapper_asound +#define snd_timer_id_get_class snd_timer_id_get_class_dylibloader_wrapper_asound +#define snd_timer_id_set_sclass snd_timer_id_set_sclass_dylibloader_wrapper_asound +#define snd_timer_id_get_sclass snd_timer_id_get_sclass_dylibloader_wrapper_asound +#define snd_timer_id_set_card snd_timer_id_set_card_dylibloader_wrapper_asound +#define snd_timer_id_get_card snd_timer_id_get_card_dylibloader_wrapper_asound +#define snd_timer_id_set_device snd_timer_id_set_device_dylibloader_wrapper_asound +#define snd_timer_id_get_device snd_timer_id_get_device_dylibloader_wrapper_asound +#define snd_timer_id_set_subdevice snd_timer_id_set_subdevice_dylibloader_wrapper_asound +#define snd_timer_id_get_subdevice snd_timer_id_get_subdevice_dylibloader_wrapper_asound +#define snd_timer_ginfo_sizeof snd_timer_ginfo_sizeof_dylibloader_wrapper_asound +#define snd_timer_ginfo_malloc snd_timer_ginfo_malloc_dylibloader_wrapper_asound +#define snd_timer_ginfo_free snd_timer_ginfo_free_dylibloader_wrapper_asound +#define snd_timer_ginfo_copy snd_timer_ginfo_copy_dylibloader_wrapper_asound +#define snd_timer_ginfo_set_tid snd_timer_ginfo_set_tid_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_tid snd_timer_ginfo_get_tid_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_flags snd_timer_ginfo_get_flags_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_card snd_timer_ginfo_get_card_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_id snd_timer_ginfo_get_id_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_name snd_timer_ginfo_get_name_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_resolution snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_resolution_min snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_resolution_max snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound +#define snd_timer_ginfo_get_clients snd_timer_ginfo_get_clients_dylibloader_wrapper_asound +#define snd_timer_info_sizeof snd_timer_info_sizeof_dylibloader_wrapper_asound +#define snd_timer_info_malloc snd_timer_info_malloc_dylibloader_wrapper_asound +#define snd_timer_info_free snd_timer_info_free_dylibloader_wrapper_asound +#define snd_timer_info_copy snd_timer_info_copy_dylibloader_wrapper_asound +#define snd_timer_info_is_slave snd_timer_info_is_slave_dylibloader_wrapper_asound +#define snd_timer_info_get_card snd_timer_info_get_card_dylibloader_wrapper_asound +#define snd_timer_info_get_id snd_timer_info_get_id_dylibloader_wrapper_asound +#define snd_timer_info_get_name snd_timer_info_get_name_dylibloader_wrapper_asound +#define snd_timer_info_get_resolution snd_timer_info_get_resolution_dylibloader_wrapper_asound +#define snd_timer_params_sizeof snd_timer_params_sizeof_dylibloader_wrapper_asound +#define snd_timer_params_malloc snd_timer_params_malloc_dylibloader_wrapper_asound +#define snd_timer_params_free snd_timer_params_free_dylibloader_wrapper_asound +#define snd_timer_params_copy snd_timer_params_copy_dylibloader_wrapper_asound +#define snd_timer_params_set_auto_start snd_timer_params_set_auto_start_dylibloader_wrapper_asound +#define snd_timer_params_get_auto_start snd_timer_params_get_auto_start_dylibloader_wrapper_asound +#define snd_timer_params_set_exclusive snd_timer_params_set_exclusive_dylibloader_wrapper_asound +#define snd_timer_params_get_exclusive snd_timer_params_get_exclusive_dylibloader_wrapper_asound +#define snd_timer_params_set_early_event snd_timer_params_set_early_event_dylibloader_wrapper_asound +#define snd_timer_params_get_early_event snd_timer_params_get_early_event_dylibloader_wrapper_asound +#define snd_timer_params_set_ticks snd_timer_params_set_ticks_dylibloader_wrapper_asound +#define snd_timer_params_get_ticks snd_timer_params_get_ticks_dylibloader_wrapper_asound +#define snd_timer_params_set_queue_size snd_timer_params_set_queue_size_dylibloader_wrapper_asound +#define snd_timer_params_get_queue_size snd_timer_params_get_queue_size_dylibloader_wrapper_asound +#define snd_timer_params_set_filter snd_timer_params_set_filter_dylibloader_wrapper_asound +#define snd_timer_params_get_filter snd_timer_params_get_filter_dylibloader_wrapper_asound +#define snd_timer_status_sizeof snd_timer_status_sizeof_dylibloader_wrapper_asound +#define snd_timer_status_malloc snd_timer_status_malloc_dylibloader_wrapper_asound +#define snd_timer_status_free snd_timer_status_free_dylibloader_wrapper_asound +#define snd_timer_status_copy snd_timer_status_copy_dylibloader_wrapper_asound +#define snd_timer_status_get_timestamp snd_timer_status_get_timestamp_dylibloader_wrapper_asound +#define snd_timer_status_get_resolution snd_timer_status_get_resolution_dylibloader_wrapper_asound +#define snd_timer_status_get_lost snd_timer_status_get_lost_dylibloader_wrapper_asound +#define snd_timer_status_get_overrun snd_timer_status_get_overrun_dylibloader_wrapper_asound +#define snd_timer_status_get_queue snd_timer_status_get_queue_dylibloader_wrapper_asound +#define snd_timer_info_get_ticks snd_timer_info_get_ticks_dylibloader_wrapper_asound +#define snd_hwdep_open snd_hwdep_open_dylibloader_wrapper_asound +#define snd_hwdep_close snd_hwdep_close_dylibloader_wrapper_asound +#define snd_hwdep_poll_descriptors snd_hwdep_poll_descriptors_dylibloader_wrapper_asound +#define snd_hwdep_poll_descriptors_count snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_hwdep_poll_descriptors_revents snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_hwdep_nonblock snd_hwdep_nonblock_dylibloader_wrapper_asound +#define snd_hwdep_info snd_hwdep_info_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status snd_hwdep_dsp_status_dylibloader_wrapper_asound +#define snd_hwdep_dsp_load snd_hwdep_dsp_load_dylibloader_wrapper_asound +#define snd_hwdep_ioctl snd_hwdep_ioctl_dylibloader_wrapper_asound +#define snd_hwdep_write snd_hwdep_write_dylibloader_wrapper_asound +#define snd_hwdep_read snd_hwdep_read_dylibloader_wrapper_asound +#define snd_hwdep_info_sizeof snd_hwdep_info_sizeof_dylibloader_wrapper_asound +#define snd_hwdep_info_malloc snd_hwdep_info_malloc_dylibloader_wrapper_asound +#define snd_hwdep_info_free snd_hwdep_info_free_dylibloader_wrapper_asound +#define snd_hwdep_info_copy snd_hwdep_info_copy_dylibloader_wrapper_asound +#define snd_hwdep_info_get_device snd_hwdep_info_get_device_dylibloader_wrapper_asound +#define snd_hwdep_info_get_card snd_hwdep_info_get_card_dylibloader_wrapper_asound +#define snd_hwdep_info_get_id snd_hwdep_info_get_id_dylibloader_wrapper_asound +#define snd_hwdep_info_get_name snd_hwdep_info_get_name_dylibloader_wrapper_asound +#define snd_hwdep_info_get_iface snd_hwdep_info_get_iface_dylibloader_wrapper_asound +#define snd_hwdep_info_set_device snd_hwdep_info_set_device_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_sizeof snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_malloc snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_free snd_hwdep_dsp_status_free_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_copy snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_get_version snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_get_id snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_get_num_dsps snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_get_dsp_loaded snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound +#define snd_hwdep_dsp_status_get_chip_ready snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_sizeof snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_malloc snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_free snd_hwdep_dsp_image_free_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_copy snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_get_index snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_get_name snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_get_image snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_get_length snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_set_index snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_set_name snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_set_image snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound +#define snd_hwdep_dsp_image_set_length snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound +#define snd_card_load snd_card_load_dylibloader_wrapper_asound +#define snd_card_next snd_card_next_dylibloader_wrapper_asound +#define snd_card_get_index snd_card_get_index_dylibloader_wrapper_asound +#define snd_card_get_name snd_card_get_name_dylibloader_wrapper_asound +#define snd_card_get_longname snd_card_get_longname_dylibloader_wrapper_asound +#define snd_device_name_hint snd_device_name_hint_dylibloader_wrapper_asound +#define snd_device_name_free_hint snd_device_name_free_hint_dylibloader_wrapper_asound +#define snd_device_name_get_hint snd_device_name_get_hint_dylibloader_wrapper_asound +#define snd_ctl_open snd_ctl_open_dylibloader_wrapper_asound +#define snd_ctl_open_lconf snd_ctl_open_lconf_dylibloader_wrapper_asound +#define snd_ctl_open_fallback snd_ctl_open_fallback_dylibloader_wrapper_asound +#define snd_ctl_close snd_ctl_close_dylibloader_wrapper_asound +#define snd_ctl_nonblock snd_ctl_nonblock_dylibloader_wrapper_asound +#define snd_async_add_ctl_handler snd_async_add_ctl_handler_dylibloader_wrapper_asound +#define snd_async_handler_get_ctl snd_async_handler_get_ctl_dylibloader_wrapper_asound +#define snd_ctl_poll_descriptors_count snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_ctl_poll_descriptors snd_ctl_poll_descriptors_dylibloader_wrapper_asound +#define snd_ctl_poll_descriptors_revents snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_ctl_subscribe_events snd_ctl_subscribe_events_dylibloader_wrapper_asound +#define snd_ctl_card_info snd_ctl_card_info_dylibloader_wrapper_asound +#define snd_ctl_elem_list snd_ctl_elem_list_dylibloader_wrapper_asound +#define snd_ctl_elem_info snd_ctl_elem_info_dylibloader_wrapper_asound +#define snd_ctl_elem_read snd_ctl_elem_read_dylibloader_wrapper_asound +#define snd_ctl_elem_write snd_ctl_elem_write_dylibloader_wrapper_asound +#define snd_ctl_elem_lock snd_ctl_elem_lock_dylibloader_wrapper_asound +#define snd_ctl_elem_unlock snd_ctl_elem_unlock_dylibloader_wrapper_asound +#define snd_ctl_elem_tlv_read snd_ctl_elem_tlv_read_dylibloader_wrapper_asound +#define snd_ctl_elem_tlv_write snd_ctl_elem_tlv_write_dylibloader_wrapper_asound +#define snd_ctl_elem_tlv_command snd_ctl_elem_tlv_command_dylibloader_wrapper_asound +#define snd_ctl_hwdep_next_device snd_ctl_hwdep_next_device_dylibloader_wrapper_asound +#define snd_ctl_hwdep_info snd_ctl_hwdep_info_dylibloader_wrapper_asound +#define snd_ctl_pcm_next_device snd_ctl_pcm_next_device_dylibloader_wrapper_asound +#define snd_ctl_pcm_info snd_ctl_pcm_info_dylibloader_wrapper_asound +#define snd_ctl_pcm_prefer_subdevice snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound +#define snd_ctl_rawmidi_next_device snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound +#define snd_ctl_rawmidi_info snd_ctl_rawmidi_info_dylibloader_wrapper_asound +#define snd_ctl_rawmidi_prefer_subdevice snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound +#define snd_ctl_set_power_state snd_ctl_set_power_state_dylibloader_wrapper_asound +#define snd_ctl_get_power_state snd_ctl_get_power_state_dylibloader_wrapper_asound +#define snd_ctl_read snd_ctl_read_dylibloader_wrapper_asound +#define snd_ctl_wait snd_ctl_wait_dylibloader_wrapper_asound +#define snd_ctl_name snd_ctl_name_dylibloader_wrapper_asound +#define snd_ctl_type snd_ctl_type_dylibloader_wrapper_asound +#define snd_ctl_elem_type_name snd_ctl_elem_type_name_dylibloader_wrapper_asound +#define snd_ctl_elem_iface_name snd_ctl_elem_iface_name_dylibloader_wrapper_asound +#define snd_ctl_event_type_name snd_ctl_event_type_name_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_mask snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_numid snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_id snd_ctl_event_elem_get_id_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_interface snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_device snd_ctl_event_elem_get_device_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_subdevice snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_name snd_ctl_event_elem_get_name_dylibloader_wrapper_asound +#define snd_ctl_event_elem_get_index snd_ctl_event_elem_get_index_dylibloader_wrapper_asound +#define snd_ctl_elem_list_alloc_space snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound +#define snd_ctl_elem_list_free_space snd_ctl_elem_list_free_space_dylibloader_wrapper_asound +#define snd_ctl_ascii_elem_id_get snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound +#define snd_ctl_ascii_elem_id_parse snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound +#define snd_ctl_ascii_value_parse snd_ctl_ascii_value_parse_dylibloader_wrapper_asound +#define snd_ctl_elem_id_sizeof snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound +#define snd_ctl_elem_id_malloc snd_ctl_elem_id_malloc_dylibloader_wrapper_asound +#define snd_ctl_elem_id_free snd_ctl_elem_id_free_dylibloader_wrapper_asound +#define snd_ctl_elem_id_clear snd_ctl_elem_id_clear_dylibloader_wrapper_asound +#define snd_ctl_elem_id_copy snd_ctl_elem_id_copy_dylibloader_wrapper_asound +#define snd_ctl_elem_id_get_numid snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_id_get_interface snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_id_get_device snd_ctl_elem_id_get_device_dylibloader_wrapper_asound +#define snd_ctl_elem_id_get_subdevice snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_id_get_name snd_ctl_elem_id_get_name_dylibloader_wrapper_asound +#define snd_ctl_elem_id_get_index snd_ctl_elem_id_get_index_dylibloader_wrapper_asound +#define snd_ctl_elem_id_set_numid snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_id_set_interface snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_id_set_device snd_ctl_elem_id_set_device_dylibloader_wrapper_asound +#define snd_ctl_elem_id_set_subdevice snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_id_set_name snd_ctl_elem_id_set_name_dylibloader_wrapper_asound +#define snd_ctl_elem_id_set_index snd_ctl_elem_id_set_index_dylibloader_wrapper_asound +#define snd_ctl_card_info_sizeof snd_ctl_card_info_sizeof_dylibloader_wrapper_asound +#define snd_ctl_card_info_malloc snd_ctl_card_info_malloc_dylibloader_wrapper_asound +#define snd_ctl_card_info_free snd_ctl_card_info_free_dylibloader_wrapper_asound +#define snd_ctl_card_info_clear snd_ctl_card_info_clear_dylibloader_wrapper_asound +#define snd_ctl_card_info_copy snd_ctl_card_info_copy_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_card snd_ctl_card_info_get_card_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_id snd_ctl_card_info_get_id_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_driver snd_ctl_card_info_get_driver_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_name snd_ctl_card_info_get_name_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_longname snd_ctl_card_info_get_longname_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_mixername snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound +#define snd_ctl_card_info_get_components snd_ctl_card_info_get_components_dylibloader_wrapper_asound +#define snd_ctl_event_sizeof snd_ctl_event_sizeof_dylibloader_wrapper_asound +#define snd_ctl_event_malloc snd_ctl_event_malloc_dylibloader_wrapper_asound +#define snd_ctl_event_free snd_ctl_event_free_dylibloader_wrapper_asound +#define snd_ctl_event_clear snd_ctl_event_clear_dylibloader_wrapper_asound +#define snd_ctl_event_copy snd_ctl_event_copy_dylibloader_wrapper_asound +#define snd_ctl_event_get_type snd_ctl_event_get_type_dylibloader_wrapper_asound +#define snd_ctl_elem_list_sizeof snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound +#define snd_ctl_elem_list_malloc snd_ctl_elem_list_malloc_dylibloader_wrapper_asound +#define snd_ctl_elem_list_free snd_ctl_elem_list_free_dylibloader_wrapper_asound +#define snd_ctl_elem_list_clear snd_ctl_elem_list_clear_dylibloader_wrapper_asound +#define snd_ctl_elem_list_copy snd_ctl_elem_list_copy_dylibloader_wrapper_asound +#define snd_ctl_elem_list_set_offset snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_used snd_ctl_elem_list_get_used_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_count snd_ctl_elem_list_get_count_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_id snd_ctl_elem_list_get_id_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_numid snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_interface snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_device snd_ctl_elem_list_get_device_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_subdevice snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_name snd_ctl_elem_list_get_name_dylibloader_wrapper_asound +#define snd_ctl_elem_list_get_index snd_ctl_elem_list_get_index_dylibloader_wrapper_asound +#define snd_ctl_elem_info_sizeof snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound +#define snd_ctl_elem_info_malloc snd_ctl_elem_info_malloc_dylibloader_wrapper_asound +#define snd_ctl_elem_info_free snd_ctl_elem_info_free_dylibloader_wrapper_asound +#define snd_ctl_elem_info_clear snd_ctl_elem_info_clear_dylibloader_wrapper_asound +#define snd_ctl_elem_info_copy snd_ctl_elem_info_copy_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_type snd_ctl_elem_info_get_type_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_readable snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_writable snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_volatile snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_inactive snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_locked snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_tlv_readable snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_tlv_writable snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_tlv_commandable snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_owner snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound +#define snd_ctl_elem_info_is_user snd_ctl_elem_info_is_user_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_owner snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_count snd_ctl_elem_info_get_count_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_min snd_ctl_elem_info_get_min_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_max snd_ctl_elem_info_get_max_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_step snd_ctl_elem_info_get_step_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_min64 snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_max64 snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_step64 snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_items snd_ctl_elem_info_get_items_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_item snd_ctl_elem_info_set_item_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_item_name snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_dimensions snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_dimension snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_dimension snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_id snd_ctl_elem_info_get_id_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_numid snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_interface snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_device snd_ctl_elem_info_get_device_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_subdevice snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_name snd_ctl_elem_info_get_name_dylibloader_wrapper_asound +#define snd_ctl_elem_info_get_index snd_ctl_elem_info_get_index_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_id snd_ctl_elem_info_set_id_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_numid snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_interface snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_device snd_ctl_elem_info_set_device_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_subdevice snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_name snd_ctl_elem_info_set_name_dylibloader_wrapper_asound +#define snd_ctl_elem_info_set_index snd_ctl_elem_info_set_index_dylibloader_wrapper_asound +#define snd_ctl_add_integer_elem_set snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound +#define snd_ctl_add_integer64_elem_set snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound +#define snd_ctl_add_boolean_elem_set snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound +#define snd_ctl_add_enumerated_elem_set snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound +#define snd_ctl_add_bytes_elem_set snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound +#define snd_ctl_elem_add_integer snd_ctl_elem_add_integer_dylibloader_wrapper_asound +#define snd_ctl_elem_add_integer64 snd_ctl_elem_add_integer64_dylibloader_wrapper_asound +#define snd_ctl_elem_add_boolean snd_ctl_elem_add_boolean_dylibloader_wrapper_asound +#define snd_ctl_elem_add_enumerated snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound +#define snd_ctl_elem_add_iec958 snd_ctl_elem_add_iec958_dylibloader_wrapper_asound +#define snd_ctl_elem_remove snd_ctl_elem_remove_dylibloader_wrapper_asound +#define snd_ctl_elem_value_sizeof snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound +#define snd_ctl_elem_value_malloc snd_ctl_elem_value_malloc_dylibloader_wrapper_asound +#define snd_ctl_elem_value_free snd_ctl_elem_value_free_dylibloader_wrapper_asound +#define snd_ctl_elem_value_clear snd_ctl_elem_value_clear_dylibloader_wrapper_asound +#define snd_ctl_elem_value_copy snd_ctl_elem_value_copy_dylibloader_wrapper_asound +#define snd_ctl_elem_value_compare snd_ctl_elem_value_compare_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_id snd_ctl_elem_value_get_id_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_numid snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_interface snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_device snd_ctl_elem_value_get_device_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_subdevice snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_name snd_ctl_elem_value_get_name_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_index snd_ctl_elem_value_get_index_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_id snd_ctl_elem_value_set_id_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_numid snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_interface snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_device snd_ctl_elem_value_set_device_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_subdevice snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_name snd_ctl_elem_value_set_name_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_index snd_ctl_elem_value_set_index_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_boolean snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_integer snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_integer64 snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_enumerated snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_byte snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_boolean snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_integer snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_integer64 snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_enumerated snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_byte snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound +#define snd_ctl_elem_set_bytes snd_ctl_elem_set_bytes_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_bytes snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound +#define snd_ctl_elem_value_get_iec958 snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound +#define snd_ctl_elem_value_set_iec958 snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound +#define snd_tlv_parse_dB_info snd_tlv_parse_dB_info_dylibloader_wrapper_asound +#define snd_tlv_get_dB_range snd_tlv_get_dB_range_dylibloader_wrapper_asound +#define snd_tlv_convert_to_dB snd_tlv_convert_to_dB_dylibloader_wrapper_asound +#define snd_tlv_convert_from_dB snd_tlv_convert_from_dB_dylibloader_wrapper_asound +#define snd_ctl_get_dB_range snd_ctl_get_dB_range_dylibloader_wrapper_asound +#define snd_ctl_convert_to_dB snd_ctl_convert_to_dB_dylibloader_wrapper_asound +#define snd_ctl_convert_from_dB snd_ctl_convert_from_dB_dylibloader_wrapper_asound +#define snd_hctl_compare_fast snd_hctl_compare_fast_dylibloader_wrapper_asound +#define snd_hctl_open snd_hctl_open_dylibloader_wrapper_asound +#define snd_hctl_open_ctl snd_hctl_open_ctl_dylibloader_wrapper_asound +#define snd_hctl_close snd_hctl_close_dylibloader_wrapper_asound +#define snd_hctl_nonblock snd_hctl_nonblock_dylibloader_wrapper_asound +#define snd_hctl_poll_descriptors_count snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_hctl_poll_descriptors snd_hctl_poll_descriptors_dylibloader_wrapper_asound +#define snd_hctl_poll_descriptors_revents snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_hctl_get_count snd_hctl_get_count_dylibloader_wrapper_asound +#define snd_hctl_set_compare snd_hctl_set_compare_dylibloader_wrapper_asound +#define snd_hctl_first_elem snd_hctl_first_elem_dylibloader_wrapper_asound +#define snd_hctl_last_elem snd_hctl_last_elem_dylibloader_wrapper_asound +#define snd_hctl_find_elem snd_hctl_find_elem_dylibloader_wrapper_asound +#define snd_hctl_set_callback snd_hctl_set_callback_dylibloader_wrapper_asound +#define snd_hctl_set_callback_private snd_hctl_set_callback_private_dylibloader_wrapper_asound +#define snd_hctl_get_callback_private snd_hctl_get_callback_private_dylibloader_wrapper_asound +#define snd_hctl_load snd_hctl_load_dylibloader_wrapper_asound +#define snd_hctl_free snd_hctl_free_dylibloader_wrapper_asound +#define snd_hctl_handle_events snd_hctl_handle_events_dylibloader_wrapper_asound +#define snd_hctl_name snd_hctl_name_dylibloader_wrapper_asound +#define snd_hctl_wait snd_hctl_wait_dylibloader_wrapper_asound +#define snd_hctl_ctl snd_hctl_ctl_dylibloader_wrapper_asound +#define snd_hctl_elem_next snd_hctl_elem_next_dylibloader_wrapper_asound +#define snd_hctl_elem_prev snd_hctl_elem_prev_dylibloader_wrapper_asound +#define snd_hctl_elem_info snd_hctl_elem_info_dylibloader_wrapper_asound +#define snd_hctl_elem_read snd_hctl_elem_read_dylibloader_wrapper_asound +#define snd_hctl_elem_write snd_hctl_elem_write_dylibloader_wrapper_asound +#define snd_hctl_elem_tlv_read snd_hctl_elem_tlv_read_dylibloader_wrapper_asound +#define snd_hctl_elem_tlv_write snd_hctl_elem_tlv_write_dylibloader_wrapper_asound +#define snd_hctl_elem_tlv_command snd_hctl_elem_tlv_command_dylibloader_wrapper_asound +#define snd_hctl_elem_get_hctl snd_hctl_elem_get_hctl_dylibloader_wrapper_asound +#define snd_hctl_elem_get_id snd_hctl_elem_get_id_dylibloader_wrapper_asound +#define snd_hctl_elem_get_numid snd_hctl_elem_get_numid_dylibloader_wrapper_asound +#define snd_hctl_elem_get_interface snd_hctl_elem_get_interface_dylibloader_wrapper_asound +#define snd_hctl_elem_get_device snd_hctl_elem_get_device_dylibloader_wrapper_asound +#define snd_hctl_elem_get_subdevice snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound +#define snd_hctl_elem_get_name snd_hctl_elem_get_name_dylibloader_wrapper_asound +#define snd_hctl_elem_get_index snd_hctl_elem_get_index_dylibloader_wrapper_asound +#define snd_hctl_elem_set_callback snd_hctl_elem_set_callback_dylibloader_wrapper_asound +#define snd_hctl_elem_get_callback_private snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound +#define snd_hctl_elem_set_callback_private snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound +#define snd_sctl_build snd_sctl_build_dylibloader_wrapper_asound +#define snd_sctl_free snd_sctl_free_dylibloader_wrapper_asound +#define snd_sctl_install snd_sctl_install_dylibloader_wrapper_asound +#define snd_sctl_remove snd_sctl_remove_dylibloader_wrapper_asound +#define snd_mixer_open snd_mixer_open_dylibloader_wrapper_asound +#define snd_mixer_close snd_mixer_close_dylibloader_wrapper_asound +#define snd_mixer_first_elem snd_mixer_first_elem_dylibloader_wrapper_asound +#define snd_mixer_last_elem snd_mixer_last_elem_dylibloader_wrapper_asound +#define snd_mixer_handle_events snd_mixer_handle_events_dylibloader_wrapper_asound +#define snd_mixer_attach snd_mixer_attach_dylibloader_wrapper_asound +#define snd_mixer_attach_hctl snd_mixer_attach_hctl_dylibloader_wrapper_asound +#define snd_mixer_detach snd_mixer_detach_dylibloader_wrapper_asound +#define snd_mixer_detach_hctl snd_mixer_detach_hctl_dylibloader_wrapper_asound +#define snd_mixer_get_hctl snd_mixer_get_hctl_dylibloader_wrapper_asound +#define snd_mixer_poll_descriptors_count snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_mixer_poll_descriptors snd_mixer_poll_descriptors_dylibloader_wrapper_asound +#define snd_mixer_poll_descriptors_revents snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_mixer_load snd_mixer_load_dylibloader_wrapper_asound +#define snd_mixer_free snd_mixer_free_dylibloader_wrapper_asound +#define snd_mixer_wait snd_mixer_wait_dylibloader_wrapper_asound +#define snd_mixer_set_compare snd_mixer_set_compare_dylibloader_wrapper_asound +#define snd_mixer_set_callback snd_mixer_set_callback_dylibloader_wrapper_asound +#define snd_mixer_get_callback_private snd_mixer_get_callback_private_dylibloader_wrapper_asound +#define snd_mixer_set_callback_private snd_mixer_set_callback_private_dylibloader_wrapper_asound +#define snd_mixer_get_count snd_mixer_get_count_dylibloader_wrapper_asound +#define snd_mixer_class_unregister snd_mixer_class_unregister_dylibloader_wrapper_asound +#define snd_mixer_elem_next snd_mixer_elem_next_dylibloader_wrapper_asound +#define snd_mixer_elem_prev snd_mixer_elem_prev_dylibloader_wrapper_asound +#define snd_mixer_elem_set_callback snd_mixer_elem_set_callback_dylibloader_wrapper_asound +#define snd_mixer_elem_get_callback_private snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound +#define snd_mixer_elem_set_callback_private snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound +#define snd_mixer_elem_get_type snd_mixer_elem_get_type_dylibloader_wrapper_asound +#define snd_mixer_class_register snd_mixer_class_register_dylibloader_wrapper_asound +#define snd_mixer_elem_new snd_mixer_elem_new_dylibloader_wrapper_asound +#define snd_mixer_elem_add snd_mixer_elem_add_dylibloader_wrapper_asound +#define snd_mixer_elem_remove snd_mixer_elem_remove_dylibloader_wrapper_asound +#define snd_mixer_elem_free snd_mixer_elem_free_dylibloader_wrapper_asound +#define snd_mixer_elem_info snd_mixer_elem_info_dylibloader_wrapper_asound +#define snd_mixer_elem_value snd_mixer_elem_value_dylibloader_wrapper_asound +#define snd_mixer_elem_attach snd_mixer_elem_attach_dylibloader_wrapper_asound +#define snd_mixer_elem_detach snd_mixer_elem_detach_dylibloader_wrapper_asound +#define snd_mixer_elem_empty snd_mixer_elem_empty_dylibloader_wrapper_asound +#define snd_mixer_elem_get_private snd_mixer_elem_get_private_dylibloader_wrapper_asound +#define snd_mixer_class_sizeof snd_mixer_class_sizeof_dylibloader_wrapper_asound +#define snd_mixer_class_malloc snd_mixer_class_malloc_dylibloader_wrapper_asound +#define snd_mixer_class_free snd_mixer_class_free_dylibloader_wrapper_asound +#define snd_mixer_class_copy snd_mixer_class_copy_dylibloader_wrapper_asound +#define snd_mixer_class_get_mixer snd_mixer_class_get_mixer_dylibloader_wrapper_asound +#define snd_mixer_class_get_event snd_mixer_class_get_event_dylibloader_wrapper_asound +#define snd_mixer_class_get_private snd_mixer_class_get_private_dylibloader_wrapper_asound +#define snd_mixer_class_get_compare snd_mixer_class_get_compare_dylibloader_wrapper_asound +#define snd_mixer_class_set_event snd_mixer_class_set_event_dylibloader_wrapper_asound +#define snd_mixer_class_set_private snd_mixer_class_set_private_dylibloader_wrapper_asound +#define snd_mixer_class_set_private_free snd_mixer_class_set_private_free_dylibloader_wrapper_asound +#define snd_mixer_class_set_compare snd_mixer_class_set_compare_dylibloader_wrapper_asound +#define snd_mixer_selem_channel_name snd_mixer_selem_channel_name_dylibloader_wrapper_asound +#define snd_mixer_selem_register snd_mixer_selem_register_dylibloader_wrapper_asound +#define snd_mixer_selem_get_id snd_mixer_selem_get_id_dylibloader_wrapper_asound +#define snd_mixer_selem_get_name snd_mixer_selem_get_name_dylibloader_wrapper_asound +#define snd_mixer_selem_get_index snd_mixer_selem_get_index_dylibloader_wrapper_asound +#define snd_mixer_find_selem snd_mixer_find_selem_dylibloader_wrapper_asound +#define snd_mixer_selem_is_active snd_mixer_selem_is_active_dylibloader_wrapper_asound +#define snd_mixer_selem_is_playback_mono snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound +#define snd_mixer_selem_has_playback_channel snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound +#define snd_mixer_selem_is_capture_mono snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound +#define snd_mixer_selem_has_capture_channel snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound +#define snd_mixer_selem_get_capture_group snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound +#define snd_mixer_selem_has_common_volume snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_has_playback_volume snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_has_playback_volume_joined snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound +#define snd_mixer_selem_has_capture_volume snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_has_capture_volume_joined snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound +#define snd_mixer_selem_has_common_switch snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_has_playback_switch snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_has_playback_switch_joined snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound +#define snd_mixer_selem_has_capture_switch snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_has_capture_switch_joined snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound +#define snd_mixer_selem_has_capture_switch_exclusive snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound +#define snd_mixer_selem_ask_playback_vol_dB snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound +#define snd_mixer_selem_ask_capture_vol_dB snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound +#define snd_mixer_selem_ask_playback_dB_vol snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound +#define snd_mixer_selem_ask_capture_dB_vol snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound +#define snd_mixer_selem_get_playback_volume snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_get_capture_volume snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_get_playback_dB snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound +#define snd_mixer_selem_get_capture_dB snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound +#define snd_mixer_selem_get_playback_switch snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_get_capture_switch snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_volume snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_volume snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_dB snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_dB snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_volume_all snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_volume_all snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_dB_all snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_dB_all snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_switch snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_switch snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_switch_all snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_switch_all snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound +#define snd_mixer_selem_get_playback_volume_range snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound +#define snd_mixer_selem_get_playback_dB_range snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound +#define snd_mixer_selem_set_playback_volume_range snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound +#define snd_mixer_selem_get_capture_volume_range snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound +#define snd_mixer_selem_get_capture_dB_range snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound +#define snd_mixer_selem_set_capture_volume_range snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound +#define snd_mixer_selem_is_enumerated snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound +#define snd_mixer_selem_is_enum_playback snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound +#define snd_mixer_selem_is_enum_capture snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound +#define snd_mixer_selem_get_enum_items snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound +#define snd_mixer_selem_get_enum_item_name snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound +#define snd_mixer_selem_get_enum_item snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound +#define snd_mixer_selem_set_enum_item snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound +#define snd_mixer_selem_id_sizeof snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound +#define snd_mixer_selem_id_malloc snd_mixer_selem_id_malloc_dylibloader_wrapper_asound +#define snd_mixer_selem_id_free snd_mixer_selem_id_free_dylibloader_wrapper_asound +#define snd_mixer_selem_id_copy snd_mixer_selem_id_copy_dylibloader_wrapper_asound +#define snd_mixer_selem_id_get_name snd_mixer_selem_id_get_name_dylibloader_wrapper_asound +#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_wrapper_asound +#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_wrapper_asound +#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_wrapper_asound +#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_wrapper_asound +#define snd_seq_open snd_seq_open_dylibloader_wrapper_asound +#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_wrapper_asound +#define snd_seq_name snd_seq_name_dylibloader_wrapper_asound +#define snd_seq_type snd_seq_type_dylibloader_wrapper_asound +#define snd_seq_close snd_seq_close_dylibloader_wrapper_asound +#define snd_seq_poll_descriptors_count snd_seq_poll_descriptors_count_dylibloader_wrapper_asound +#define snd_seq_poll_descriptors snd_seq_poll_descriptors_dylibloader_wrapper_asound +#define snd_seq_poll_descriptors_revents snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound +#define snd_seq_nonblock snd_seq_nonblock_dylibloader_wrapper_asound +#define snd_seq_client_id snd_seq_client_id_dylibloader_wrapper_asound +#define snd_seq_get_output_buffer_size snd_seq_get_output_buffer_size_dylibloader_wrapper_asound +#define snd_seq_get_input_buffer_size snd_seq_get_input_buffer_size_dylibloader_wrapper_asound +#define snd_seq_set_output_buffer_size snd_seq_set_output_buffer_size_dylibloader_wrapper_asound +#define snd_seq_set_input_buffer_size snd_seq_set_input_buffer_size_dylibloader_wrapper_asound +#define snd_seq_system_info_sizeof snd_seq_system_info_sizeof_dylibloader_wrapper_asound +#define snd_seq_system_info_malloc snd_seq_system_info_malloc_dylibloader_wrapper_asound +#define snd_seq_system_info_free snd_seq_system_info_free_dylibloader_wrapper_asound +#define snd_seq_system_info_copy snd_seq_system_info_copy_dylibloader_wrapper_asound +#define snd_seq_system_info_get_queues snd_seq_system_info_get_queues_dylibloader_wrapper_asound +#define snd_seq_system_info_get_clients snd_seq_system_info_get_clients_dylibloader_wrapper_asound +#define snd_seq_system_info_get_ports snd_seq_system_info_get_ports_dylibloader_wrapper_asound +#define snd_seq_system_info_get_channels snd_seq_system_info_get_channels_dylibloader_wrapper_asound +#define snd_seq_system_info_get_cur_clients snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound +#define snd_seq_system_info_get_cur_queues snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound +#define snd_seq_system_info snd_seq_system_info_dylibloader_wrapper_asound +#define snd_seq_client_info_sizeof snd_seq_client_info_sizeof_dylibloader_wrapper_asound +#define snd_seq_client_info_malloc snd_seq_client_info_malloc_dylibloader_wrapper_asound +#define snd_seq_client_info_free snd_seq_client_info_free_dylibloader_wrapper_asound +#define snd_seq_client_info_copy snd_seq_client_info_copy_dylibloader_wrapper_asound +#define snd_seq_client_info_get_client snd_seq_client_info_get_client_dylibloader_wrapper_asound +#define snd_seq_client_info_get_type snd_seq_client_info_get_type_dylibloader_wrapper_asound +#define snd_seq_client_info_get_name snd_seq_client_info_get_name_dylibloader_wrapper_asound +#define snd_seq_client_info_get_broadcast_filter snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound +#define snd_seq_client_info_get_error_bounce snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound +#define snd_seq_client_info_get_card snd_seq_client_info_get_card_dylibloader_wrapper_asound +#define snd_seq_client_info_get_pid snd_seq_client_info_get_pid_dylibloader_wrapper_asound +#define snd_seq_client_info_get_event_filter snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound +#define snd_seq_client_info_get_num_ports snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound +#define snd_seq_client_info_get_event_lost snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound +#define snd_seq_client_info_set_client snd_seq_client_info_set_client_dylibloader_wrapper_asound +#define snd_seq_client_info_set_name snd_seq_client_info_set_name_dylibloader_wrapper_asound +#define snd_seq_client_info_set_broadcast_filter snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound +#define snd_seq_client_info_set_error_bounce snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound +#define snd_seq_client_info_set_event_filter snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound +#define snd_seq_client_info_event_filter_clear snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound +#define snd_seq_client_info_event_filter_add snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound +#define snd_seq_client_info_event_filter_del snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound +#define snd_seq_client_info_event_filter_check snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound +#define snd_seq_get_client_info snd_seq_get_client_info_dylibloader_wrapper_asound +#define snd_seq_get_any_client_info snd_seq_get_any_client_info_dylibloader_wrapper_asound +#define snd_seq_set_client_info snd_seq_set_client_info_dylibloader_wrapper_asound +#define snd_seq_query_next_client snd_seq_query_next_client_dylibloader_wrapper_asound +#define snd_seq_client_pool_sizeof snd_seq_client_pool_sizeof_dylibloader_wrapper_asound +#define snd_seq_client_pool_malloc snd_seq_client_pool_malloc_dylibloader_wrapper_asound +#define snd_seq_client_pool_free snd_seq_client_pool_free_dylibloader_wrapper_asound +#define snd_seq_client_pool_copy snd_seq_client_pool_copy_dylibloader_wrapper_asound +#define snd_seq_client_pool_get_client snd_seq_client_pool_get_client_dylibloader_wrapper_asound +#define snd_seq_client_pool_get_output_pool snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound +#define snd_seq_client_pool_get_input_pool snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound +#define snd_seq_client_pool_get_output_room snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound +#define snd_seq_client_pool_get_output_free snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound +#define snd_seq_client_pool_get_input_free snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound +#define snd_seq_client_pool_set_output_pool snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound +#define snd_seq_client_pool_set_input_pool snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound +#define snd_seq_client_pool_set_output_room snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound +#define snd_seq_get_client_pool snd_seq_get_client_pool_dylibloader_wrapper_asound +#define snd_seq_set_client_pool snd_seq_set_client_pool_dylibloader_wrapper_asound +#define snd_seq_port_info_sizeof snd_seq_port_info_sizeof_dylibloader_wrapper_asound +#define snd_seq_port_info_malloc snd_seq_port_info_malloc_dylibloader_wrapper_asound +#define snd_seq_port_info_free snd_seq_port_info_free_dylibloader_wrapper_asound +#define snd_seq_port_info_copy snd_seq_port_info_copy_dylibloader_wrapper_asound +#define snd_seq_port_info_get_client snd_seq_port_info_get_client_dylibloader_wrapper_asound +#define snd_seq_port_info_get_port snd_seq_port_info_get_port_dylibloader_wrapper_asound +#define snd_seq_port_info_get_addr snd_seq_port_info_get_addr_dylibloader_wrapper_asound +#define snd_seq_port_info_get_name snd_seq_port_info_get_name_dylibloader_wrapper_asound +#define snd_seq_port_info_get_capability snd_seq_port_info_get_capability_dylibloader_wrapper_asound +#define snd_seq_port_info_get_type snd_seq_port_info_get_type_dylibloader_wrapper_asound +#define snd_seq_port_info_get_midi_channels snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound +#define snd_seq_port_info_get_midi_voices snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound +#define snd_seq_port_info_get_synth_voices snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound +#define snd_seq_port_info_get_read_use snd_seq_port_info_get_read_use_dylibloader_wrapper_asound +#define snd_seq_port_info_get_write_use snd_seq_port_info_get_write_use_dylibloader_wrapper_asound +#define snd_seq_port_info_get_port_specified snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound +#define snd_seq_port_info_get_timestamping snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound +#define snd_seq_port_info_get_timestamp_real snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound +#define snd_seq_port_info_get_timestamp_queue snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound +#define snd_seq_port_info_set_client snd_seq_port_info_set_client_dylibloader_wrapper_asound +#define snd_seq_port_info_set_port snd_seq_port_info_set_port_dylibloader_wrapper_asound +#define snd_seq_port_info_set_addr snd_seq_port_info_set_addr_dylibloader_wrapper_asound +#define snd_seq_port_info_set_name snd_seq_port_info_set_name_dylibloader_wrapper_asound +#define snd_seq_port_info_set_capability snd_seq_port_info_set_capability_dylibloader_wrapper_asound +#define snd_seq_port_info_set_type snd_seq_port_info_set_type_dylibloader_wrapper_asound +#define snd_seq_port_info_set_midi_channels snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound +#define snd_seq_port_info_set_midi_voices snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound +#define snd_seq_port_info_set_synth_voices snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound +#define snd_seq_port_info_set_port_specified snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound +#define snd_seq_port_info_set_timestamping snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound +#define snd_seq_port_info_set_timestamp_real snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound +#define snd_seq_port_info_set_timestamp_queue snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound +#define snd_seq_create_port snd_seq_create_port_dylibloader_wrapper_asound +#define snd_seq_delete_port snd_seq_delete_port_dylibloader_wrapper_asound +#define snd_seq_get_port_info snd_seq_get_port_info_dylibloader_wrapper_asound +#define snd_seq_get_any_port_info snd_seq_get_any_port_info_dylibloader_wrapper_asound +#define snd_seq_set_port_info snd_seq_set_port_info_dylibloader_wrapper_asound +#define snd_seq_query_next_port snd_seq_query_next_port_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_sizeof snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_malloc snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_free snd_seq_port_subscribe_free_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_copy snd_seq_port_subscribe_copy_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_get_sender snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_get_dest snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_get_queue snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_get_exclusive snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_get_time_update snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_get_time_real snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_set_sender snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_set_dest snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_set_queue snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_set_exclusive snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_set_time_update snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound +#define snd_seq_port_subscribe_set_time_real snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound +#define snd_seq_get_port_subscription snd_seq_get_port_subscription_dylibloader_wrapper_asound +#define snd_seq_subscribe_port snd_seq_subscribe_port_dylibloader_wrapper_asound +#define snd_seq_unsubscribe_port snd_seq_unsubscribe_port_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_sizeof snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_malloc snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_free snd_seq_query_subscribe_free_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_copy snd_seq_query_subscribe_copy_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_client snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_port snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_root snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_type snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_index snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_num_subs snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_addr snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_queue snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_exclusive snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_time_update snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_get_time_real snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_set_client snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_set_port snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_set_root snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_set_type snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound +#define snd_seq_query_subscribe_set_index snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound +#define snd_seq_query_port_subscribers snd_seq_query_port_subscribers_dylibloader_wrapper_asound +#define snd_seq_queue_info_sizeof snd_seq_queue_info_sizeof_dylibloader_wrapper_asound +#define snd_seq_queue_info_malloc snd_seq_queue_info_malloc_dylibloader_wrapper_asound +#define snd_seq_queue_info_free snd_seq_queue_info_free_dylibloader_wrapper_asound +#define snd_seq_queue_info_copy snd_seq_queue_info_copy_dylibloader_wrapper_asound +#define snd_seq_queue_info_get_queue snd_seq_queue_info_get_queue_dylibloader_wrapper_asound +#define snd_seq_queue_info_get_name snd_seq_queue_info_get_name_dylibloader_wrapper_asound +#define snd_seq_queue_info_get_owner snd_seq_queue_info_get_owner_dylibloader_wrapper_asound +#define snd_seq_queue_info_get_locked snd_seq_queue_info_get_locked_dylibloader_wrapper_asound +#define snd_seq_queue_info_get_flags snd_seq_queue_info_get_flags_dylibloader_wrapper_asound +#define snd_seq_queue_info_set_name snd_seq_queue_info_set_name_dylibloader_wrapper_asound +#define snd_seq_queue_info_set_owner snd_seq_queue_info_set_owner_dylibloader_wrapper_asound +#define snd_seq_queue_info_set_locked snd_seq_queue_info_set_locked_dylibloader_wrapper_asound +#define snd_seq_queue_info_set_flags snd_seq_queue_info_set_flags_dylibloader_wrapper_asound +#define snd_seq_create_queue snd_seq_create_queue_dylibloader_wrapper_asound +#define snd_seq_alloc_named_queue snd_seq_alloc_named_queue_dylibloader_wrapper_asound +#define snd_seq_alloc_queue snd_seq_alloc_queue_dylibloader_wrapper_asound +#define snd_seq_free_queue snd_seq_free_queue_dylibloader_wrapper_asound +#define snd_seq_get_queue_info snd_seq_get_queue_info_dylibloader_wrapper_asound +#define snd_seq_set_queue_info snd_seq_set_queue_info_dylibloader_wrapper_asound +#define snd_seq_query_named_queue snd_seq_query_named_queue_dylibloader_wrapper_asound +#define snd_seq_get_queue_usage snd_seq_get_queue_usage_dylibloader_wrapper_asound +#define snd_seq_set_queue_usage snd_seq_set_queue_usage_dylibloader_wrapper_asound +#define snd_seq_queue_status_sizeof snd_seq_queue_status_sizeof_dylibloader_wrapper_asound +#define snd_seq_queue_status_malloc snd_seq_queue_status_malloc_dylibloader_wrapper_asound +#define snd_seq_queue_status_free snd_seq_queue_status_free_dylibloader_wrapper_asound +#define snd_seq_queue_status_copy snd_seq_queue_status_copy_dylibloader_wrapper_asound +#define snd_seq_queue_status_get_queue snd_seq_queue_status_get_queue_dylibloader_wrapper_asound +#define snd_seq_queue_status_get_events snd_seq_queue_status_get_events_dylibloader_wrapper_asound +#define snd_seq_queue_status_get_tick_time snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound +#define snd_seq_queue_status_get_real_time snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound +#define snd_seq_queue_status_get_status snd_seq_queue_status_get_status_dylibloader_wrapper_asound +#define snd_seq_get_queue_status snd_seq_get_queue_status_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_sizeof snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_malloc snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_free snd_seq_queue_tempo_free_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_copy snd_seq_queue_tempo_copy_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_get_queue snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_get_tempo snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_get_ppq snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_get_skew snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_get_skew_base snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_set_tempo snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_set_ppq snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_set_skew snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound +#define snd_seq_queue_tempo_set_skew_base snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound +#define snd_seq_get_queue_tempo snd_seq_get_queue_tempo_dylibloader_wrapper_asound +#define snd_seq_set_queue_tempo snd_seq_set_queue_tempo_dylibloader_wrapper_asound +#define snd_seq_queue_timer_sizeof snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound +#define snd_seq_queue_timer_malloc snd_seq_queue_timer_malloc_dylibloader_wrapper_asound +#define snd_seq_queue_timer_free snd_seq_queue_timer_free_dylibloader_wrapper_asound +#define snd_seq_queue_timer_copy snd_seq_queue_timer_copy_dylibloader_wrapper_asound +#define snd_seq_queue_timer_get_queue snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound +#define snd_seq_queue_timer_get_type snd_seq_queue_timer_get_type_dylibloader_wrapper_asound +#define snd_seq_queue_timer_get_id snd_seq_queue_timer_get_id_dylibloader_wrapper_asound +#define snd_seq_queue_timer_get_resolution snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound +#define snd_seq_queue_timer_set_type snd_seq_queue_timer_set_type_dylibloader_wrapper_asound +#define snd_seq_queue_timer_set_id snd_seq_queue_timer_set_id_dylibloader_wrapper_asound +#define snd_seq_queue_timer_set_resolution snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound +#define snd_seq_get_queue_timer snd_seq_get_queue_timer_dylibloader_wrapper_asound +#define snd_seq_set_queue_timer snd_seq_set_queue_timer_dylibloader_wrapper_asound +#define snd_seq_free_event snd_seq_free_event_dylibloader_wrapper_asound +#define snd_seq_event_length snd_seq_event_length_dylibloader_wrapper_asound +#define snd_seq_event_output snd_seq_event_output_dylibloader_wrapper_asound +#define snd_seq_event_output_buffer snd_seq_event_output_buffer_dylibloader_wrapper_asound +#define snd_seq_event_output_direct snd_seq_event_output_direct_dylibloader_wrapper_asound +#define snd_seq_event_input snd_seq_event_input_dylibloader_wrapper_asound +#define snd_seq_event_input_pending snd_seq_event_input_pending_dylibloader_wrapper_asound +#define snd_seq_drain_output snd_seq_drain_output_dylibloader_wrapper_asound +#define snd_seq_event_output_pending snd_seq_event_output_pending_dylibloader_wrapper_asound +#define snd_seq_extract_output snd_seq_extract_output_dylibloader_wrapper_asound +#define snd_seq_drop_output snd_seq_drop_output_dylibloader_wrapper_asound +#define snd_seq_drop_output_buffer snd_seq_drop_output_buffer_dylibloader_wrapper_asound +#define snd_seq_drop_input snd_seq_drop_input_dylibloader_wrapper_asound +#define snd_seq_drop_input_buffer snd_seq_drop_input_buffer_dylibloader_wrapper_asound +#define snd_seq_remove_events_sizeof snd_seq_remove_events_sizeof_dylibloader_wrapper_asound +#define snd_seq_remove_events_malloc snd_seq_remove_events_malloc_dylibloader_wrapper_asound +#define snd_seq_remove_events_free snd_seq_remove_events_free_dylibloader_wrapper_asound +#define snd_seq_remove_events_copy snd_seq_remove_events_copy_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_condition snd_seq_remove_events_get_condition_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_queue snd_seq_remove_events_get_queue_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_time snd_seq_remove_events_get_time_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_dest snd_seq_remove_events_get_dest_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_channel snd_seq_remove_events_get_channel_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_event_type snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound +#define snd_seq_remove_events_get_tag snd_seq_remove_events_get_tag_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_condition snd_seq_remove_events_set_condition_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_queue snd_seq_remove_events_set_queue_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_time snd_seq_remove_events_set_time_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_dest snd_seq_remove_events_set_dest_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_channel snd_seq_remove_events_set_channel_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_event_type snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound +#define snd_seq_remove_events_set_tag snd_seq_remove_events_set_tag_dylibloader_wrapper_asound +#define snd_seq_remove_events snd_seq_remove_events_dylibloader_wrapper_asound +#define snd_seq_set_bit snd_seq_set_bit_dylibloader_wrapper_asound +#define snd_seq_unset_bit snd_seq_unset_bit_dylibloader_wrapper_asound +#define snd_seq_change_bit snd_seq_change_bit_dylibloader_wrapper_asound +#define snd_seq_get_bit snd_seq_get_bit_dylibloader_wrapper_asound +#define snd_seq_control_queue snd_seq_control_queue_dylibloader_wrapper_asound +#define snd_seq_create_simple_port snd_seq_create_simple_port_dylibloader_wrapper_asound +#define snd_seq_delete_simple_port snd_seq_delete_simple_port_dylibloader_wrapper_asound +#define snd_seq_connect_from snd_seq_connect_from_dylibloader_wrapper_asound +#define snd_seq_connect_to snd_seq_connect_to_dylibloader_wrapper_asound +#define snd_seq_disconnect_from snd_seq_disconnect_from_dylibloader_wrapper_asound +#define snd_seq_disconnect_to snd_seq_disconnect_to_dylibloader_wrapper_asound +#define snd_seq_set_client_name snd_seq_set_client_name_dylibloader_wrapper_asound +#define snd_seq_set_client_event_filter snd_seq_set_client_event_filter_dylibloader_wrapper_asound +#define snd_seq_set_client_pool_output snd_seq_set_client_pool_output_dylibloader_wrapper_asound +#define snd_seq_set_client_pool_output_room snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound +#define snd_seq_set_client_pool_input snd_seq_set_client_pool_input_dylibloader_wrapper_asound +#define snd_seq_sync_output_queue snd_seq_sync_output_queue_dylibloader_wrapper_asound +#define snd_seq_parse_address snd_seq_parse_address_dylibloader_wrapper_asound +#define snd_seq_reset_pool_output snd_seq_reset_pool_output_dylibloader_wrapper_asound +#define snd_seq_reset_pool_input snd_seq_reset_pool_input_dylibloader_wrapper_asound +#define snd_midi_event_new snd_midi_event_new_dylibloader_wrapper_asound +#define snd_midi_event_resize_buffer snd_midi_event_resize_buffer_dylibloader_wrapper_asound +#define snd_midi_event_free snd_midi_event_free_dylibloader_wrapper_asound +#define snd_midi_event_init snd_midi_event_init_dylibloader_wrapper_asound +#define snd_midi_event_reset_encode snd_midi_event_reset_encode_dylibloader_wrapper_asound +#define snd_midi_event_reset_decode snd_midi_event_reset_decode_dylibloader_wrapper_asound +#define snd_midi_event_no_status snd_midi_event_no_status_dylibloader_wrapper_asound +#define snd_midi_event_encode snd_midi_event_encode_dylibloader_wrapper_asound +#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_wrapper_asound +#define snd_midi_event_decode snd_midi_event_decode_dylibloader_wrapper_asound +extern const char* (*snd_asoundlib_version_dylibloader_wrapper_asound)( void); +extern int (*snd_dlpath_dylibloader_wrapper_asound)( char*, size_t,const char*); +extern void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int, char*, size_t); +extern void* (*snd_dlsym_dylibloader_wrapper_asound)( void*,const char*,const char*); +extern int (*snd_dlclose_dylibloader_wrapper_asound)( void*); +extern int (*snd_async_add_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, int, snd_async_callback_t, void*); +extern int (*snd_async_del_handler_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern int (*snd_async_handler_get_fd_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern int (*snd_async_handler_get_signo_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern void* (*snd_async_handler_get_callback_private_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern struct snd_shm_area* (*snd_shm_area_create_dylibloader_wrapper_asound)( int, void*); +extern struct snd_shm_area* (*snd_shm_area_share_dylibloader_wrapper_asound)(struct snd_shm_area*); +extern int (*snd_shm_area_destroy_dylibloader_wrapper_asound)(struct snd_shm_area*); +extern int (*snd_user_file_dylibloader_wrapper_asound)(const char*, char**); +extern int (*snd_input_stdio_open_dylibloader_wrapper_asound)( snd_input_t**,const char*,const char*); +extern int (*snd_input_stdio_attach_dylibloader_wrapper_asound)( snd_input_t**, FILE*, int); +extern int (*snd_input_buffer_open_dylibloader_wrapper_asound)( snd_input_t**,const char*, ssize_t); +extern int (*snd_input_close_dylibloader_wrapper_asound)( snd_input_t*); +extern int (*snd_input_scanf_dylibloader_wrapper_asound)( snd_input_t*,const char*,...); +extern char* (*snd_input_gets_dylibloader_wrapper_asound)( snd_input_t*, char*, size_t); +extern int (*snd_input_getc_dylibloader_wrapper_asound)( snd_input_t*); +extern int (*snd_input_ungetc_dylibloader_wrapper_asound)( snd_input_t*, int); +extern int (*snd_output_stdio_open_dylibloader_wrapper_asound)( snd_output_t**,const char*,const char*); +extern int (*snd_output_stdio_attach_dylibloader_wrapper_asound)( snd_output_t**, FILE*, int); +extern int (*snd_output_buffer_open_dylibloader_wrapper_asound)( snd_output_t**); +extern size_t (*snd_output_buffer_string_dylibloader_wrapper_asound)( snd_output_t*, char**); +extern int (*snd_output_close_dylibloader_wrapper_asound)( snd_output_t*); +extern int (*snd_output_printf_dylibloader_wrapper_asound)( snd_output_t*,const char*,...); +extern int (*snd_output_vprintf_dylibloader_wrapper_asound)( snd_output_t*,const char*, va_list); +extern int (*snd_output_puts_dylibloader_wrapper_asound)( snd_output_t*,const char*); +extern int (*snd_output_putc_dylibloader_wrapper_asound)( snd_output_t*, int); +extern int (*snd_output_flush_dylibloader_wrapper_asound)( snd_output_t*); +extern const char* (*snd_strerror_dylibloader_wrapper_asound)( int); +extern int (*snd_lib_error_set_handler_dylibloader_wrapper_asound)( snd_lib_error_handler_t); +extern snd_local_error_handler_t (*snd_lib_error_set_local_dylibloader_wrapper_asound)( snd_local_error_handler_t); +extern const char* (*snd_config_topdir_dylibloader_wrapper_asound)( void); +extern int (*snd_config_top_dylibloader_wrapper_asound)( snd_config_t**); +extern int (*snd_config_load_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*); +extern int (*snd_config_load_override_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*); +extern int (*snd_config_save_dylibloader_wrapper_asound)( snd_config_t*, snd_output_t*); +extern int (*snd_config_update_dylibloader_wrapper_asound)( void); +extern int (*snd_config_update_r_dylibloader_wrapper_asound)( snd_config_t**, snd_config_update_t**,const char*); +extern int (*snd_config_update_free_dylibloader_wrapper_asound)( snd_config_update_t*); +extern int (*snd_config_update_free_global_dylibloader_wrapper_asound)( void); +extern int (*snd_config_update_ref_dylibloader_wrapper_asound)( snd_config_t**); +extern void (*snd_config_ref_dylibloader_wrapper_asound)( snd_config_t*); +extern void (*snd_config_unref_dylibloader_wrapper_asound)( snd_config_t*); +extern int (*snd_config_search_dylibloader_wrapper_asound)( snd_config_t*,const char*, snd_config_t**); +extern int (*snd_config_searchv_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t**,...); +extern int (*snd_config_search_definition_dylibloader_wrapper_asound)( snd_config_t*,const char*,const char*, snd_config_t**); +extern int (*snd_config_expand_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*,const char*, snd_config_t*, snd_config_t**); +extern int (*snd_config_evaluate_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*, snd_config_t*, snd_config_t**); +extern int (*snd_config_add_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*); +extern int (*snd_config_add_before_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*); +extern int (*snd_config_add_after_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*); +extern int (*snd_config_remove_dylibloader_wrapper_asound)( snd_config_t*); +extern int (*snd_config_delete_dylibloader_wrapper_asound)( snd_config_t*); +extern int (*snd_config_delete_compound_members_dylibloader_wrapper_asound)(const snd_config_t*); +extern int (*snd_config_copy_dylibloader_wrapper_asound)( snd_config_t**, snd_config_t*); +extern int (*snd_config_make_dylibloader_wrapper_asound)( snd_config_t**,const char*, snd_config_type_t); +extern int (*snd_config_make_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*); +extern int (*snd_config_make_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*); +extern int (*snd_config_make_real_dylibloader_wrapper_asound)( snd_config_t**,const char*); +extern int (*snd_config_make_string_dylibloader_wrapper_asound)( snd_config_t**,const char*); +extern int (*snd_config_make_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*); +extern int (*snd_config_make_compound_dylibloader_wrapper_asound)( snd_config_t**,const char*, int); +extern int (*snd_config_imake_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long); +extern int (*snd_config_imake_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long long); +extern int (*snd_config_imake_real_dylibloader_wrapper_asound)( snd_config_t**,const char*,const double); +extern int (*snd_config_imake_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*); +extern int (*snd_config_imake_safe_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*); +extern int (*snd_config_imake_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const void*); +extern snd_config_type_t (*snd_config_get_type_dylibloader_wrapper_asound)(const snd_config_t*); +extern int (*snd_config_is_array_dylibloader_wrapper_asound)(const snd_config_t*); +extern int (*snd_config_set_id_dylibloader_wrapper_asound)( snd_config_t*,const char*); +extern int (*snd_config_set_integer_dylibloader_wrapper_asound)( snd_config_t*, long); +extern int (*snd_config_set_integer64_dylibloader_wrapper_asound)( snd_config_t*, long long); +extern int (*snd_config_set_real_dylibloader_wrapper_asound)( snd_config_t*, double); +extern int (*snd_config_set_string_dylibloader_wrapper_asound)( snd_config_t*,const char*); +extern int (*snd_config_set_ascii_dylibloader_wrapper_asound)( snd_config_t*,const char*); +extern int (*snd_config_set_pointer_dylibloader_wrapper_asound)( snd_config_t*,const void*); +extern int (*snd_config_get_id_dylibloader_wrapper_asound)(const snd_config_t*,const char**); +extern int (*snd_config_get_integer_dylibloader_wrapper_asound)(const snd_config_t*, long*); +extern int (*snd_config_get_integer64_dylibloader_wrapper_asound)(const snd_config_t*, long long*); +extern int (*snd_config_get_real_dylibloader_wrapper_asound)(const snd_config_t*, double*); +extern int (*snd_config_get_ireal_dylibloader_wrapper_asound)(const snd_config_t*, double*); +extern int (*snd_config_get_string_dylibloader_wrapper_asound)(const snd_config_t*,const char**); +extern int (*snd_config_get_ascii_dylibloader_wrapper_asound)(const snd_config_t*, char**); +extern int (*snd_config_get_pointer_dylibloader_wrapper_asound)(const snd_config_t*,const void**); +extern int (*snd_config_test_id_dylibloader_wrapper_asound)(const snd_config_t*,const char*); +extern snd_config_iterator_t (*snd_config_iterator_first_dylibloader_wrapper_asound)(const snd_config_t*); +extern snd_config_iterator_t (*snd_config_iterator_next_dylibloader_wrapper_asound)(const snd_config_iterator_t); +extern snd_config_iterator_t (*snd_config_iterator_end_dylibloader_wrapper_asound)(const snd_config_t*); +extern snd_config_t* (*snd_config_iterator_entry_dylibloader_wrapper_asound)(const snd_config_iterator_t); +extern int (*snd_config_get_bool_ascii_dylibloader_wrapper_asound)(const char*); +extern int (*snd_config_get_bool_dylibloader_wrapper_asound)(const snd_config_t*); +extern int (*snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound)(const char*); +extern int (*snd_config_get_ctl_iface_dylibloader_wrapper_asound)(const snd_config_t*); +extern int (*snd_names_list_dylibloader_wrapper_asound)(const char*, snd_devname_t**); +extern void (*snd_names_list_free_dylibloader_wrapper_asound)( snd_devname_t*); +extern int (*snd_pcm_open_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int); +extern int (*snd_pcm_open_lconf_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int, snd_config_t*); +extern int (*snd_pcm_open_fallback_dylibloader_wrapper_asound)( snd_pcm_t**, snd_config_t*,const char*,const char*, snd_pcm_stream_t, int); +extern int (*snd_pcm_close_dylibloader_wrapper_asound)( snd_pcm_t*); +extern const char* (*snd_pcm_name_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_type_t (*snd_pcm_type_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_stream_t (*snd_pcm_stream_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_poll_descriptors_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int); +extern int (*snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_pcm_nonblock_dylibloader_wrapper_asound)( snd_pcm_t*, int); +extern int (*snd_async_add_pcm_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_pcm_t*, snd_async_callback_t, void*); +extern snd_pcm_t* (*snd_async_handler_get_pcm_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern int (*snd_pcm_info_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_info_t*); +extern int (*snd_pcm_hw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_free_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_sw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*); +extern int (*snd_pcm_sw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*); +extern int (*snd_pcm_prepare_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_reset_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_status_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_status_t*); +extern int (*snd_pcm_start_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_drop_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_drain_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_pause_dylibloader_wrapper_asound)( snd_pcm_t*, int); +extern snd_pcm_state_t (*snd_pcm_state_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_hwsync_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*); +extern int (*snd_pcm_resume_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_htimestamp_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_htimestamp_t*); +extern snd_pcm_sframes_t (*snd_pcm_avail_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_sframes_t (*snd_pcm_avail_update_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_avail_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*, snd_pcm_sframes_t*); +extern snd_pcm_sframes_t (*snd_pcm_rewindable_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_sframes_t (*snd_pcm_rewind_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_forwardable_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_sframes_t (*snd_pcm_forward_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +extern int (*snd_pcm_wait_dylibloader_wrapper_asound)( snd_pcm_t*, int); +extern int (*snd_pcm_link_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*); +extern int (*snd_pcm_unlink_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound)( int, int, int, snd_pcm_stream_t); +extern void (*snd_pcm_free_chmaps_dylibloader_wrapper_asound)( snd_pcm_chmap_query_t**); +extern snd_pcm_chmap_t* (*snd_pcm_get_chmap_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_set_chmap_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_chmap_t*); +extern const char* (*snd_pcm_chmap_type_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_type); +extern const char* (*snd_pcm_chmap_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position); +extern const char* (*snd_pcm_chmap_long_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position); +extern int (*snd_pcm_chmap_print_dylibloader_wrapper_asound)(const snd_pcm_chmap_t*, size_t, char*); +extern unsigned int (*snd_pcm_chmap_from_string_dylibloader_wrapper_asound)(const char*); +extern snd_pcm_chmap_t* (*snd_pcm_chmap_parse_string_dylibloader_wrapper_asound)(const char*); +extern int (*snd_pcm_recover_dylibloader_wrapper_asound)( snd_pcm_t*, int, int); +extern int (*snd_pcm_set_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int); +extern int (*snd_pcm_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +extern size_t (*snd_pcm_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_info_malloc_dylibloader_wrapper_asound)( snd_pcm_info_t**); +extern void (*snd_pcm_info_free_dylibloader_wrapper_asound)( snd_pcm_info_t*); +extern void (*snd_pcm_info_copy_dylibloader_wrapper_asound)( snd_pcm_info_t*,const snd_pcm_info_t*); +extern unsigned int (*snd_pcm_info_get_device_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern unsigned int (*snd_pcm_info_get_subdevice_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern snd_pcm_stream_t (*snd_pcm_info_get_stream_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern int (*snd_pcm_info_get_card_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern const char* (*snd_pcm_info_get_id_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern const char* (*snd_pcm_info_get_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern const char* (*snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern snd_pcm_class_t (*snd_pcm_info_get_class_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern snd_pcm_subclass_t (*snd_pcm_info_get_subclass_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern unsigned int (*snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern unsigned int (*snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern snd_pcm_sync_id_t (*snd_pcm_info_get_sync_dylibloader_wrapper_asound)(const snd_pcm_info_t*); +extern void (*snd_pcm_info_set_device_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int); +extern void (*snd_pcm_info_set_subdevice_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int); +extern void (*snd_pcm_info_set_stream_dylibloader_wrapper_asound)( snd_pcm_info_t*, snd_pcm_stream_t); +extern int (*snd_pcm_hw_params_any_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_is_double_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, int); +extern int (*snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, unsigned int*); +extern int (*snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*); +extern size_t (*snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_hw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_hw_params_t**); +extern void (*snd_pcm_hw_params_free_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*); +extern void (*snd_pcm_hw_params_copy_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*,const snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_get_access_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_access_t*); +extern int (*snd_pcm_hw_params_test_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t); +extern int (*snd_pcm_hw_params_set_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t); +extern int (*snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*); +extern int (*snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*); +extern int (*snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_mask_t*); +extern int (*snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_access_mask_t*); +extern int (*snd_pcm_hw_params_get_format_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_format_t*); +extern int (*snd_pcm_hw_params_test_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t); +extern int (*snd_pcm_hw_params_set_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t); +extern int (*snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*); +extern int (*snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*); +extern int (*snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_mask_t*); +extern void (*snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_format_mask_t*); +extern int (*snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_subformat_t*); +extern int (*snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t); +extern int (*snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t); +extern int (*snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*); +extern int (*snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*); +extern int (*snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*); +extern void (*snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*); +extern int (*snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +extern int (*snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +extern int (*snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, unsigned int*); +extern int (*snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +extern int (*snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +extern int (*snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int); +extern int (*snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int); +extern int (*snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int); +extern int (*snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*); +extern int (*snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*); +extern int (*snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*); +extern size_t (*snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_sw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_sw_params_t**); +extern void (*snd_pcm_sw_params_free_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*); +extern void (*snd_pcm_sw_params_copy_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*,const snd_pcm_sw_params_t*); +extern int (*snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_tstamp_t); +extern int (*snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_tstamp_t*); +extern int (*snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, int); +extern int (*snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, int*); +extern int (*snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern size_t (*snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_access_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_access_mask_t**); +extern void (*snd_pcm_access_mask_free_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*); +extern void (*snd_pcm_access_mask_copy_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*,const snd_pcm_access_mask_t*); +extern void (*snd_pcm_access_mask_none_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*); +extern void (*snd_pcm_access_mask_any_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*); +extern int (*snd_pcm_access_mask_test_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*, snd_pcm_access_t); +extern int (*snd_pcm_access_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*); +extern void (*snd_pcm_access_mask_set_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t); +extern void (*snd_pcm_access_mask_reset_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t); +extern size_t (*snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_format_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_format_mask_t**); +extern void (*snd_pcm_format_mask_free_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*); +extern void (*snd_pcm_format_mask_copy_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*,const snd_pcm_format_mask_t*); +extern void (*snd_pcm_format_mask_none_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*); +extern void (*snd_pcm_format_mask_any_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*); +extern int (*snd_pcm_format_mask_test_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*, snd_pcm_format_t); +extern int (*snd_pcm_format_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*); +extern void (*snd_pcm_format_mask_set_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t); +extern void (*snd_pcm_format_mask_reset_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t); +extern size_t (*snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t**); +extern void (*snd_pcm_subformat_mask_free_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*); +extern void (*snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*,const snd_pcm_subformat_mask_t*); +extern void (*snd_pcm_subformat_mask_none_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*); +extern void (*snd_pcm_subformat_mask_any_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*); +extern int (*snd_pcm_subformat_mask_test_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*, snd_pcm_subformat_t); +extern int (*snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*); +extern void (*snd_pcm_subformat_mask_set_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t); +extern void (*snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t); +extern size_t (*snd_pcm_status_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_pcm_status_malloc_dylibloader_wrapper_asound)( snd_pcm_status_t**); +extern void (*snd_pcm_status_free_dylibloader_wrapper_asound)( snd_pcm_status_t*); +extern void (*snd_pcm_status_copy_dylibloader_wrapper_asound)( snd_pcm_status_t*,const snd_pcm_status_t*); +extern snd_pcm_state_t (*snd_pcm_status_get_state_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +extern void (*snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*); +extern void (*snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +extern void (*snd_pcm_status_get_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*); +extern void (*snd_pcm_status_get_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +extern void (*snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +extern void (*snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*); +extern snd_pcm_sframes_t (*snd_pcm_status_get_delay_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +extern snd_pcm_uframes_t (*snd_pcm_status_get_avail_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +extern snd_pcm_uframes_t (*snd_pcm_status_get_avail_max_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +extern snd_pcm_uframes_t (*snd_pcm_status_get_overrange_dylibloader_wrapper_asound)(const snd_pcm_status_t*); +extern const char* (*snd_pcm_type_name_dylibloader_wrapper_asound)( snd_pcm_type_t); +extern const char* (*snd_pcm_stream_name_dylibloader_wrapper_asound)(const snd_pcm_stream_t); +extern const char* (*snd_pcm_access_name_dylibloader_wrapper_asound)(const snd_pcm_access_t); +extern const char* (*snd_pcm_format_name_dylibloader_wrapper_asound)(const snd_pcm_format_t); +extern const char* (*snd_pcm_format_description_dylibloader_wrapper_asound)(const snd_pcm_format_t); +extern const char* (*snd_pcm_subformat_name_dylibloader_wrapper_asound)(const snd_pcm_subformat_t); +extern const char* (*snd_pcm_subformat_description_dylibloader_wrapper_asound)(const snd_pcm_subformat_t); +extern snd_pcm_format_t (*snd_pcm_format_value_dylibloader_wrapper_asound)(const char*); +extern const char* (*snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound)(const snd_pcm_tstamp_t); +extern const char* (*snd_pcm_state_name_dylibloader_wrapper_asound)(const snd_pcm_state_t); +extern int (*snd_pcm_dump_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +extern int (*snd_pcm_dump_hw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +extern int (*snd_pcm_dump_sw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +extern int (*snd_pcm_dump_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*); +extern int (*snd_pcm_hw_params_dump_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_output_t*); +extern int (*snd_pcm_sw_params_dump_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*, snd_output_t*); +extern int (*snd_pcm_status_dump_dylibloader_wrapper_asound)( snd_pcm_status_t*, snd_output_t*); +extern int (*snd_pcm_mmap_begin_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_channel_area_t**, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +extern snd_pcm_sframes_t (*snd_pcm_mmap_commit_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_mmap_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_mmap_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_mmap_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +extern snd_pcm_sframes_t (*snd_pcm_mmap_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t); +extern int (*snd_pcm_format_signed_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_unsigned_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_linear_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_float_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_little_endian_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_big_endian_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_cpu_endian_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_width_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_physical_width_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern snd_pcm_format_t (*snd_pcm_build_linear_format_dylibloader_wrapper_asound)( int, int, int, int); +extern ssize_t (*snd_pcm_format_size_dylibloader_wrapper_asound)( snd_pcm_format_t, size_t); +extern uint8_t (*snd_pcm_format_silence_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern uint16_t (*snd_pcm_format_silence_16_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern uint32_t (*snd_pcm_format_silence_32_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern uint64_t (*snd_pcm_format_silence_64_dylibloader_wrapper_asound)( snd_pcm_format_t); +extern int (*snd_pcm_format_set_silence_dylibloader_wrapper_asound)( snd_pcm_format_t, void*, unsigned int); +extern snd_pcm_sframes_t (*snd_pcm_bytes_to_frames_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t); +extern ssize_t (*snd_pcm_frames_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t); +extern long (*snd_pcm_bytes_to_samples_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t); +extern ssize_t (*snd_pcm_samples_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, long); +extern int (*snd_pcm_area_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t); +extern int (*snd_pcm_areas_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t); +extern int (*snd_pcm_area_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t); +extern int (*snd_pcm_areas_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t); +extern int (*snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const unsigned int, snd_pcm_uframes_t,const snd_pcm_format_t); +extern snd_pcm_t* (*snd_pcm_hook_get_pcm_dylibloader_wrapper_asound)( snd_pcm_hook_t*); +extern void* (*snd_pcm_hook_get_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*); +extern void (*snd_pcm_hook_set_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*, void*); +extern int (*snd_pcm_hook_add_dylibloader_wrapper_asound)( snd_pcm_hook_t**, snd_pcm_t*, snd_pcm_hook_type_t, snd_pcm_hook_func_t, void*); +extern int (*snd_pcm_hook_remove_dylibloader_wrapper_asound)( snd_pcm_hook_t*); +extern snd_pcm_uframes_t (*snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound)( snd_pcm_t*); +extern unsigned int (*snd_pcm_meter_get_channels_dylibloader_wrapper_asound)( snd_pcm_t*); +extern unsigned int (*snd_pcm_meter_get_rate_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_uframes_t (*snd_pcm_meter_get_now_dylibloader_wrapper_asound)( snd_pcm_t*); +extern snd_pcm_uframes_t (*snd_pcm_meter_get_boundary_dylibloader_wrapper_asound)( snd_pcm_t*); +extern int (*snd_pcm_meter_add_scope_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_scope_t*); +extern snd_pcm_scope_t* (*snd_pcm_meter_search_scope_dylibloader_wrapper_asound)( snd_pcm_t*,const char*); +extern int (*snd_pcm_scope_malloc_dylibloader_wrapper_asound)( snd_pcm_scope_t**); +extern void (*snd_pcm_scope_set_ops_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const snd_pcm_scope_ops_t*); +extern void (*snd_pcm_scope_set_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const char*); +extern const char* (*snd_pcm_scope_get_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*); +extern void* (*snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*); +extern void (*snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*, void*); +extern int (*snd_pcm_scope_s16_open_dylibloader_wrapper_asound)( snd_pcm_t*,const char*, snd_pcm_scope_t**); +extern int16_t* (*snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound)( snd_pcm_scope_t*, unsigned int); +extern int (*snd_spcm_init_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t); +extern int (*snd_spcm_init_duplex_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t, snd_spcm_duplex_type_t); +extern int (*snd_spcm_init_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int*, snd_pcm_uframes_t*, snd_pcm_uframes_t*); +extern const char* (*snd_pcm_start_mode_name_dylibloader_wrapper_asound)( snd_pcm_start_t); +extern const char* (*snd_pcm_xrun_mode_name_dylibloader_wrapper_asound)( snd_pcm_xrun_t); +extern int (*snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_start_t); +extern snd_pcm_start_t (*snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*); +extern int (*snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_xrun_t); +extern snd_pcm_xrun_t (*snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*); +extern int (*snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t); +extern int (*snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*); +extern int (*snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, unsigned int); +extern int (*snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, unsigned int*); +extern int (*snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int); +extern int (*snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*); +extern int (*snd_rawmidi_open_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int); +extern int (*snd_rawmidi_open_lconf_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int, snd_config_t*); +extern int (*snd_rawmidi_close_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern int (*snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern int (*snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int); +extern int (*snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_rawmidi_nonblock_dylibloader_wrapper_asound)( snd_rawmidi_t*, int); +extern size_t (*snd_rawmidi_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_rawmidi_info_malloc_dylibloader_wrapper_asound)( snd_rawmidi_info_t**); +extern void (*snd_rawmidi_info_free_dylibloader_wrapper_asound)( snd_rawmidi_info_t*); +extern void (*snd_rawmidi_info_copy_dylibloader_wrapper_asound)( snd_rawmidi_info_t*,const snd_rawmidi_info_t*); +extern unsigned int (*snd_rawmidi_info_get_device_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern unsigned int (*snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern snd_rawmidi_stream_t (*snd_rawmidi_info_get_stream_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern int (*snd_rawmidi_info_get_card_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern unsigned int (*snd_rawmidi_info_get_flags_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern const char* (*snd_rawmidi_info_get_id_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern const char* (*snd_rawmidi_info_get_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern const char* (*snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern unsigned int (*snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern unsigned int (*snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*); +extern void (*snd_rawmidi_info_set_device_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int); +extern void (*snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int); +extern void (*snd_rawmidi_info_set_stream_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, snd_rawmidi_stream_t); +extern int (*snd_rawmidi_info_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_info_t*); +extern size_t (*snd_rawmidi_params_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_rawmidi_params_malloc_dylibloader_wrapper_asound)( snd_rawmidi_params_t**); +extern void (*snd_rawmidi_params_free_dylibloader_wrapper_asound)( snd_rawmidi_params_t*); +extern void (*snd_rawmidi_params_copy_dylibloader_wrapper_asound)( snd_rawmidi_params_t*,const snd_rawmidi_params_t*); +extern int (*snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t); +extern size_t (*snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*); +extern int (*snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t); +extern size_t (*snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*); +extern int (*snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, int); +extern int (*snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*); +extern int (*snd_rawmidi_params_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*); +extern int (*snd_rawmidi_params_current_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*); +extern size_t (*snd_rawmidi_status_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_rawmidi_status_malloc_dylibloader_wrapper_asound)( snd_rawmidi_status_t**); +extern void (*snd_rawmidi_status_free_dylibloader_wrapper_asound)( snd_rawmidi_status_t*); +extern void (*snd_rawmidi_status_copy_dylibloader_wrapper_asound)( snd_rawmidi_status_t*,const snd_rawmidi_status_t*); +extern void (*snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*, snd_htimestamp_t*); +extern size_t (*snd_rawmidi_status_get_avail_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*); +extern size_t (*snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*); +extern int (*snd_rawmidi_status_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_status_t*); +extern int (*snd_rawmidi_drain_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern int (*snd_rawmidi_drop_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern ssize_t (*snd_rawmidi_write_dylibloader_wrapper_asound)( snd_rawmidi_t*,const void*, size_t); +extern ssize_t (*snd_rawmidi_read_dylibloader_wrapper_asound)( snd_rawmidi_t*, void*, size_t); +extern const char* (*snd_rawmidi_name_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern snd_rawmidi_type_t (*snd_rawmidi_type_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern snd_rawmidi_stream_t (*snd_rawmidi_stream_dylibloader_wrapper_asound)( snd_rawmidi_t*); +extern int (*snd_timer_query_open_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int); +extern int (*snd_timer_query_open_lconf_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int, snd_config_t*); +extern int (*snd_timer_query_close_dylibloader_wrapper_asound)( snd_timer_query_t*); +extern int (*snd_timer_query_next_device_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_id_t*); +extern int (*snd_timer_query_info_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_ginfo_t*); +extern int (*snd_timer_query_params_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gparams_t*); +extern int (*snd_timer_query_status_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gstatus_t*); +extern int (*snd_timer_open_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int); +extern int (*snd_timer_open_lconf_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int, snd_config_t*); +extern int (*snd_timer_close_dylibloader_wrapper_asound)( snd_timer_t*); +extern int (*snd_async_add_timer_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_timer_t*, snd_async_callback_t, void*); +extern snd_timer_t* (*snd_async_handler_get_timer_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern int (*snd_timer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_timer_t*); +extern int (*snd_timer_poll_descriptors_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int); +extern int (*snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_timer_info_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_info_t*); +extern int (*snd_timer_params_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_params_t*); +extern int (*snd_timer_status_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_status_t*); +extern int (*snd_timer_start_dylibloader_wrapper_asound)( snd_timer_t*); +extern int (*snd_timer_stop_dylibloader_wrapper_asound)( snd_timer_t*); +extern int (*snd_timer_continue_dylibloader_wrapper_asound)( snd_timer_t*); +extern ssize_t (*snd_timer_read_dylibloader_wrapper_asound)( snd_timer_t*, void*, size_t); +extern size_t (*snd_timer_id_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_timer_id_malloc_dylibloader_wrapper_asound)( snd_timer_id_t**); +extern void (*snd_timer_id_free_dylibloader_wrapper_asound)( snd_timer_id_t*); +extern void (*snd_timer_id_copy_dylibloader_wrapper_asound)( snd_timer_id_t*,const snd_timer_id_t*); +extern void (*snd_timer_id_set_class_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +extern int (*snd_timer_id_get_class_dylibloader_wrapper_asound)( snd_timer_id_t*); +extern void (*snd_timer_id_set_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +extern int (*snd_timer_id_get_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*); +extern void (*snd_timer_id_set_card_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +extern int (*snd_timer_id_get_card_dylibloader_wrapper_asound)( snd_timer_id_t*); +extern void (*snd_timer_id_set_device_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +extern int (*snd_timer_id_get_device_dylibloader_wrapper_asound)( snd_timer_id_t*); +extern void (*snd_timer_id_set_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*, int); +extern int (*snd_timer_id_get_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*); +extern size_t (*snd_timer_ginfo_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_timer_ginfo_malloc_dylibloader_wrapper_asound)( snd_timer_ginfo_t**); +extern void (*snd_timer_ginfo_free_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern void (*snd_timer_ginfo_copy_dylibloader_wrapper_asound)( snd_timer_ginfo_t*,const snd_timer_ginfo_t*); +extern int (*snd_timer_ginfo_set_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*, snd_timer_id_t*); +extern snd_timer_id_t* (*snd_timer_ginfo_get_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern unsigned int (*snd_timer_ginfo_get_flags_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern int (*snd_timer_ginfo_get_card_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern char* (*snd_timer_ginfo_get_id_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern char* (*snd_timer_ginfo_get_name_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern unsigned long (*snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern unsigned long (*snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern unsigned long (*snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern unsigned int (*snd_timer_ginfo_get_clients_dylibloader_wrapper_asound)( snd_timer_ginfo_t*); +extern size_t (*snd_timer_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_timer_info_malloc_dylibloader_wrapper_asound)( snd_timer_info_t**); +extern void (*snd_timer_info_free_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern void (*snd_timer_info_copy_dylibloader_wrapper_asound)( snd_timer_info_t*,const snd_timer_info_t*); +extern int (*snd_timer_info_is_slave_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern int (*snd_timer_info_get_card_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern const char* (*snd_timer_info_get_id_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern const char* (*snd_timer_info_get_name_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern long (*snd_timer_info_get_resolution_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern size_t (*snd_timer_params_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_timer_params_malloc_dylibloader_wrapper_asound)( snd_timer_params_t**); +extern void (*snd_timer_params_free_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern void (*snd_timer_params_copy_dylibloader_wrapper_asound)( snd_timer_params_t*,const snd_timer_params_t*); +extern int (*snd_timer_params_set_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*, int); +extern int (*snd_timer_params_get_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern int (*snd_timer_params_set_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*, int); +extern int (*snd_timer_params_get_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern int (*snd_timer_params_set_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*, int); +extern int (*snd_timer_params_get_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern void (*snd_timer_params_set_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*, long); +extern long (*snd_timer_params_get_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern void (*snd_timer_params_set_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*, long); +extern long (*snd_timer_params_get_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern void (*snd_timer_params_set_filter_dylibloader_wrapper_asound)( snd_timer_params_t*, unsigned int); +extern unsigned int (*snd_timer_params_get_filter_dylibloader_wrapper_asound)( snd_timer_params_t*); +extern size_t (*snd_timer_status_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_timer_status_malloc_dylibloader_wrapper_asound)( snd_timer_status_t**); +extern void (*snd_timer_status_free_dylibloader_wrapper_asound)( snd_timer_status_t*); +extern void (*snd_timer_status_copy_dylibloader_wrapper_asound)( snd_timer_status_t*,const snd_timer_status_t*); +extern snd_htimestamp_t (*snd_timer_status_get_timestamp_dylibloader_wrapper_asound)( snd_timer_status_t*); +extern long (*snd_timer_status_get_resolution_dylibloader_wrapper_asound)( snd_timer_status_t*); +extern long (*snd_timer_status_get_lost_dylibloader_wrapper_asound)( snd_timer_status_t*); +extern long (*snd_timer_status_get_overrun_dylibloader_wrapper_asound)( snd_timer_status_t*); +extern long (*snd_timer_status_get_queue_dylibloader_wrapper_asound)( snd_timer_status_t*); +extern long (*snd_timer_info_get_ticks_dylibloader_wrapper_asound)( snd_timer_info_t*); +extern int (*snd_hwdep_open_dylibloader_wrapper_asound)( snd_hwdep_t**,const char*, int); +extern int (*snd_hwdep_close_dylibloader_wrapper_asound)( snd_hwdep_t*); +extern int (*snd_hwdep_poll_descriptors_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int); +extern int (*snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hwdep_t*); +extern int (*snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_hwdep_nonblock_dylibloader_wrapper_asound)( snd_hwdep_t*, int); +extern int (*snd_hwdep_info_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_info_t*); +extern int (*snd_hwdep_dsp_status_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_status_t*); +extern int (*snd_hwdep_dsp_load_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_image_t*); +extern int (*snd_hwdep_ioctl_dylibloader_wrapper_asound)( snd_hwdep_t*, unsigned int, void*); +extern ssize_t (*snd_hwdep_write_dylibloader_wrapper_asound)( snd_hwdep_t*,const void*, size_t); +extern ssize_t (*snd_hwdep_read_dylibloader_wrapper_asound)( snd_hwdep_t*, void*, size_t); +extern size_t (*snd_hwdep_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_hwdep_info_malloc_dylibloader_wrapper_asound)( snd_hwdep_info_t**); +extern void (*snd_hwdep_info_free_dylibloader_wrapper_asound)( snd_hwdep_info_t*); +extern void (*snd_hwdep_info_copy_dylibloader_wrapper_asound)( snd_hwdep_info_t*,const snd_hwdep_info_t*); +extern unsigned int (*snd_hwdep_info_get_device_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +extern int (*snd_hwdep_info_get_card_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +extern const char* (*snd_hwdep_info_get_id_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +extern const char* (*snd_hwdep_info_get_name_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +extern snd_hwdep_iface_t (*snd_hwdep_info_get_iface_dylibloader_wrapper_asound)(const snd_hwdep_info_t*); +extern void (*snd_hwdep_info_set_device_dylibloader_wrapper_asound)( snd_hwdep_info_t*, unsigned int); +extern size_t (*snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t**); +extern void (*snd_hwdep_dsp_status_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*); +extern void (*snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*,const snd_hwdep_dsp_status_t*); +extern unsigned int (*snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +extern const char* (*snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +extern unsigned int (*snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +extern unsigned int (*snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +extern unsigned int (*snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*); +extern size_t (*snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t**); +extern void (*snd_hwdep_dsp_image_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*); +extern void (*snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const snd_hwdep_dsp_image_t*); +extern unsigned int (*snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +extern const char* (*snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +extern const void* (*snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +extern size_t (*snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*); +extern void (*snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, unsigned int); +extern void (*snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const char*); +extern void (*snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, void*); +extern void (*snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, size_t); +extern int (*snd_card_load_dylibloader_wrapper_asound)( int); +extern int (*snd_card_next_dylibloader_wrapper_asound)( int*); +extern int (*snd_card_get_index_dylibloader_wrapper_asound)(const char*); +extern int (*snd_card_get_name_dylibloader_wrapper_asound)( int, char**); +extern int (*snd_card_get_longname_dylibloader_wrapper_asound)( int, char**); +extern int (*snd_device_name_hint_dylibloader_wrapper_asound)( int,const char*, void***); +extern int (*snd_device_name_free_hint_dylibloader_wrapper_asound)( void**); +extern char* (*snd_device_name_get_hint_dylibloader_wrapper_asound)(const void*,const char*); +extern int (*snd_ctl_open_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int); +extern int (*snd_ctl_open_lconf_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int, snd_config_t*); +extern int (*snd_ctl_open_fallback_dylibloader_wrapper_asound)( snd_ctl_t**, snd_config_t*,const char*,const char*, int); +extern int (*snd_ctl_close_dylibloader_wrapper_asound)( snd_ctl_t*); +extern int (*snd_ctl_nonblock_dylibloader_wrapper_asound)( snd_ctl_t*, int); +extern int (*snd_async_add_ctl_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_ctl_t*, snd_async_callback_t, void*); +extern snd_ctl_t* (*snd_async_handler_get_ctl_dylibloader_wrapper_asound)( snd_async_handler_t*); +extern int (*snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_ctl_t*); +extern int (*snd_ctl_poll_descriptors_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int); +extern int (*snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_ctl_subscribe_events_dylibloader_wrapper_asound)( snd_ctl_t*, int); +extern int (*snd_ctl_card_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_card_info_t*); +extern int (*snd_ctl_elem_list_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_list_t*); +extern int (*snd_ctl_elem_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*); +extern int (*snd_ctl_elem_write_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*); +extern int (*snd_ctl_elem_lock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*); +extern int (*snd_ctl_elem_unlock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*); +extern int (*snd_ctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int*, unsigned int); +extern int (*snd_ctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*); +extern int (*snd_ctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*); +extern int (*snd_ctl_hwdep_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*); +extern int (*snd_ctl_hwdep_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_hwdep_info_t*); +extern int (*snd_ctl_pcm_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*); +extern int (*snd_ctl_pcm_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_pcm_info_t*); +extern int (*snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int); +extern int (*snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*); +extern int (*snd_ctl_rawmidi_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_rawmidi_info_t*); +extern int (*snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int); +extern int (*snd_ctl_set_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int); +extern int (*snd_ctl_get_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int*); +extern int (*snd_ctl_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_event_t*); +extern int (*snd_ctl_wait_dylibloader_wrapper_asound)( snd_ctl_t*, int); +extern const char* (*snd_ctl_name_dylibloader_wrapper_asound)( snd_ctl_t*); +extern snd_ctl_type_t (*snd_ctl_type_dylibloader_wrapper_asound)( snd_ctl_t*); +extern const char* (*snd_ctl_elem_type_name_dylibloader_wrapper_asound)( snd_ctl_elem_type_t); +extern const char* (*snd_ctl_elem_iface_name_dylibloader_wrapper_asound)( snd_ctl_elem_iface_t); +extern const char* (*snd_ctl_event_type_name_dylibloader_wrapper_asound)( snd_ctl_event_type_t); +extern unsigned int (*snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern unsigned int (*snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern void (*snd_ctl_event_elem_get_id_dylibloader_wrapper_asound)(const snd_ctl_event_t*, snd_ctl_elem_id_t*); +extern snd_ctl_elem_iface_t (*snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern unsigned int (*snd_ctl_event_elem_get_device_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern unsigned int (*snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern const char* (*snd_ctl_event_elem_get_name_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern unsigned int (*snd_ctl_event_elem_get_index_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern int (*snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int); +extern void (*snd_ctl_elem_list_free_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*); +extern char* (*snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*); +extern int (*snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*); +extern int (*snd_ctl_ascii_value_parse_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*, snd_ctl_elem_info_t*,const char*); +extern size_t (*snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_ctl_elem_id_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_id_t**); +extern void (*snd_ctl_elem_id_free_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*); +extern void (*snd_ctl_elem_id_clear_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*); +extern void (*snd_ctl_elem_id_copy_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +extern snd_ctl_elem_iface_t (*snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_id_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +extern const char* (*snd_ctl_elem_id_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_id_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*); +extern void (*snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +extern void (*snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, snd_ctl_elem_iface_t); +extern void (*snd_ctl_elem_id_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +extern void (*snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +extern void (*snd_ctl_elem_id_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*); +extern void (*snd_ctl_elem_id_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int); +extern size_t (*snd_ctl_card_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_ctl_card_info_malloc_dylibloader_wrapper_asound)( snd_ctl_card_info_t**); +extern void (*snd_ctl_card_info_free_dylibloader_wrapper_asound)( snd_ctl_card_info_t*); +extern void (*snd_ctl_card_info_clear_dylibloader_wrapper_asound)( snd_ctl_card_info_t*); +extern void (*snd_ctl_card_info_copy_dylibloader_wrapper_asound)( snd_ctl_card_info_t*,const snd_ctl_card_info_t*); +extern int (*snd_ctl_card_info_get_card_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern const char* (*snd_ctl_card_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern const char* (*snd_ctl_card_info_get_driver_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern const char* (*snd_ctl_card_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern const char* (*snd_ctl_card_info_get_longname_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern const char* (*snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern const char* (*snd_ctl_card_info_get_components_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*); +extern size_t (*snd_ctl_event_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_ctl_event_malloc_dylibloader_wrapper_asound)( snd_ctl_event_t**); +extern void (*snd_ctl_event_free_dylibloader_wrapper_asound)( snd_ctl_event_t*); +extern void (*snd_ctl_event_clear_dylibloader_wrapper_asound)( snd_ctl_event_t*); +extern void (*snd_ctl_event_copy_dylibloader_wrapper_asound)( snd_ctl_event_t*,const snd_ctl_event_t*); +extern snd_ctl_event_type_t (*snd_ctl_event_get_type_dylibloader_wrapper_asound)(const snd_ctl_event_t*); +extern size_t (*snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_ctl_elem_list_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_list_t**); +extern void (*snd_ctl_elem_list_free_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*); +extern void (*snd_ctl_elem_list_clear_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*); +extern void (*snd_ctl_elem_list_copy_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*,const snd_ctl_elem_list_t*); +extern void (*snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int); +extern unsigned int (*snd_ctl_elem_list_get_used_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*); +extern unsigned int (*snd_ctl_elem_list_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*); +extern void (*snd_ctl_elem_list_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int, snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +extern snd_ctl_elem_iface_t (*snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +extern unsigned int (*snd_ctl_elem_list_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +extern unsigned int (*snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +extern const char* (*snd_ctl_elem_list_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +extern unsigned int (*snd_ctl_elem_list_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int); +extern size_t (*snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_ctl_elem_info_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_info_t**); +extern void (*snd_ctl_elem_info_free_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*); +extern void (*snd_ctl_elem_info_clear_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*); +extern void (*snd_ctl_elem_info_copy_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_info_t*); +extern snd_ctl_elem_type_t (*snd_ctl_elem_info_get_type_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_is_user_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern pid_t (*snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern unsigned int (*snd_ctl_elem_info_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern long (*snd_ctl_elem_info_get_min_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern long (*snd_ctl_elem_info_get_max_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern long (*snd_ctl_elem_info_get_step_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern long long (*snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern long long (*snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern long long (*snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern unsigned int (*snd_ctl_elem_info_get_items_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern void (*snd_ctl_elem_info_set_item_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +extern const char* (*snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern int (*snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, unsigned int); +extern int (*snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const int [4]); +extern void (*snd_ctl_elem_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern snd_ctl_elem_iface_t (*snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern unsigned int (*snd_ctl_elem_info_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern unsigned int (*snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern const char* (*snd_ctl_elem_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern unsigned int (*snd_ctl_elem_info_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*); +extern void (*snd_ctl_elem_info_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_id_t*); +extern void (*snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +extern void (*snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, snd_ctl_elem_iface_t); +extern void (*snd_ctl_elem_info_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +extern void (*snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +extern void (*snd_ctl_elem_info_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const char*); +extern void (*snd_ctl_elem_info_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int); +extern int (*snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long, long, long); +extern int (*snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long long, long long, long long); +extern int (*snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int); +extern int (*snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, unsigned int,const char* []); +extern int (*snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int); +extern int (*snd_ctl_elem_add_integer_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long, long, long); +extern int (*snd_ctl_elem_add_integer64_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long long, long long, long long); +extern int (*snd_ctl_elem_add_boolean_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int); +extern int (*snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, unsigned int,const char* []); +extern int (*snd_ctl_elem_add_iec958_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*); +extern int (*snd_ctl_elem_remove_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*); +extern size_t (*snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_ctl_elem_value_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_value_t**); +extern void (*snd_ctl_elem_value_free_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*); +extern void (*snd_ctl_elem_value_clear_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*); +extern void (*snd_ctl_elem_value_copy_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*); +extern int (*snd_ctl_elem_value_compare_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*); +extern void (*snd_ctl_elem_value_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_ctl_elem_id_t*); +extern unsigned int (*snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern snd_ctl_elem_iface_t (*snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern unsigned int (*snd_ctl_elem_value_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern unsigned int (*snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern const char* (*snd_ctl_elem_value_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern unsigned int (*snd_ctl_elem_value_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern void (*snd_ctl_elem_value_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_id_t*); +extern void (*snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +extern void (*snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, snd_ctl_elem_iface_t); +extern void (*snd_ctl_elem_value_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +extern void (*snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +extern void (*snd_ctl_elem_value_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const char*); +extern void (*snd_ctl_elem_value_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int); +extern int (*snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +extern long (*snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +extern long long (*snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +extern unsigned int (*snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +extern unsigned char (*snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int); +extern void (*snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long); +extern void (*snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long); +extern void (*snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long long); +extern void (*snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned int); +extern void (*snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned char); +extern void (*snd_ctl_elem_set_bytes_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, void*, size_t); +extern const void* (*snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*); +extern void (*snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_aes_iec958_t*); +extern void (*snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_aes_iec958_t*); +extern int (*snd_tlv_parse_dB_info_dylibloader_wrapper_asound)( unsigned int*, unsigned int, unsigned int**); +extern int (*snd_tlv_get_dB_range_dylibloader_wrapper_asound)( unsigned int*, long, long, long*, long*); +extern int (*snd_tlv_convert_to_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*); +extern int (*snd_tlv_convert_from_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*, int); +extern int (*snd_ctl_get_dB_range_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long*, long*); +extern int (*snd_ctl_convert_to_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*); +extern int (*snd_ctl_convert_from_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*, int); +extern int (*snd_hctl_compare_fast_dylibloader_wrapper_asound)(const snd_hctl_elem_t*,const snd_hctl_elem_t*); +extern int (*snd_hctl_open_dylibloader_wrapper_asound)( snd_hctl_t**,const char*, int); +extern int (*snd_hctl_open_ctl_dylibloader_wrapper_asound)( snd_hctl_t**, snd_ctl_t*); +extern int (*snd_hctl_close_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_nonblock_dylibloader_wrapper_asound)( snd_hctl_t*, int); +extern int (*snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_poll_descriptors_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int); +extern int (*snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int, unsigned short*); +extern unsigned int (*snd_hctl_get_count_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_set_compare_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_compare_t); +extern snd_hctl_elem_t* (*snd_hctl_first_elem_dylibloader_wrapper_asound)( snd_hctl_t*); +extern snd_hctl_elem_t* (*snd_hctl_last_elem_dylibloader_wrapper_asound)( snd_hctl_t*); +extern snd_hctl_elem_t* (*snd_hctl_find_elem_dylibloader_wrapper_asound)( snd_hctl_t*,const snd_ctl_elem_id_t*); +extern void (*snd_hctl_set_callback_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_callback_t); +extern void (*snd_hctl_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*, void*); +extern void* (*snd_hctl_get_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_load_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_free_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_handle_events_dylibloader_wrapper_asound)( snd_hctl_t*); +extern const char* (*snd_hctl_name_dylibloader_wrapper_asound)( snd_hctl_t*); +extern int (*snd_hctl_wait_dylibloader_wrapper_asound)( snd_hctl_t*, int); +extern snd_ctl_t* (*snd_hctl_ctl_dylibloader_wrapper_asound)( snd_hctl_t*); +extern snd_hctl_elem_t* (*snd_hctl_elem_next_dylibloader_wrapper_asound)( snd_hctl_elem_t*); +extern snd_hctl_elem_t* (*snd_hctl_elem_prev_dylibloader_wrapper_asound)( snd_hctl_elem_t*); +extern int (*snd_hctl_elem_info_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_info_t*); +extern int (*snd_hctl_elem_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*); +extern int (*snd_hctl_elem_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*); +extern int (*snd_hctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, unsigned int*, unsigned int); +extern int (*snd_hctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*); +extern int (*snd_hctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*); +extern snd_hctl_t* (*snd_hctl_elem_get_hctl_dylibloader_wrapper_asound)( snd_hctl_elem_t*); +extern void (*snd_hctl_elem_get_id_dylibloader_wrapper_asound)(const snd_hctl_elem_t*, snd_ctl_elem_id_t*); +extern unsigned int (*snd_hctl_elem_get_numid_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern snd_ctl_elem_iface_t (*snd_hctl_elem_get_interface_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern unsigned int (*snd_hctl_elem_get_device_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern unsigned int (*snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern const char* (*snd_hctl_elem_get_name_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern unsigned int (*snd_hctl_elem_get_index_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern void (*snd_hctl_elem_set_callback_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_hctl_elem_callback_t); +extern void* (*snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_hctl_elem_t*); +extern void (*snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_elem_t*, void*); +extern int (*snd_sctl_build_dylibloader_wrapper_asound)( snd_sctl_t**, snd_ctl_t*, snd_config_t*, snd_config_t*, int); +extern int (*snd_sctl_free_dylibloader_wrapper_asound)( snd_sctl_t*); +extern int (*snd_sctl_install_dylibloader_wrapper_asound)( snd_sctl_t*); +extern int (*snd_sctl_remove_dylibloader_wrapper_asound)( snd_sctl_t*); +extern int (*snd_mixer_open_dylibloader_wrapper_asound)( snd_mixer_t**, int); +extern int (*snd_mixer_close_dylibloader_wrapper_asound)( snd_mixer_t*); +extern snd_mixer_elem_t* (*snd_mixer_first_elem_dylibloader_wrapper_asound)( snd_mixer_t*); +extern snd_mixer_elem_t* (*snd_mixer_last_elem_dylibloader_wrapper_asound)( snd_mixer_t*); +extern int (*snd_mixer_handle_events_dylibloader_wrapper_asound)( snd_mixer_t*); +extern int (*snd_mixer_attach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*); +extern int (*snd_mixer_attach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*); +extern int (*snd_mixer_detach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*); +extern int (*snd_mixer_detach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*); +extern int (*snd_mixer_get_hctl_dylibloader_wrapper_asound)( snd_mixer_t*,const char*, snd_hctl_t**); +extern int (*snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_mixer_t*); +extern int (*snd_mixer_poll_descriptors_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int); +extern int (*snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_mixer_load_dylibloader_wrapper_asound)( snd_mixer_t*); +extern void (*snd_mixer_free_dylibloader_wrapper_asound)( snd_mixer_t*); +extern int (*snd_mixer_wait_dylibloader_wrapper_asound)( snd_mixer_t*, int); +extern int (*snd_mixer_set_compare_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_compare_t); +extern void (*snd_mixer_set_callback_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_callback_t); +extern void* (*snd_mixer_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_t*); +extern void (*snd_mixer_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_t*, void*); +extern unsigned int (*snd_mixer_get_count_dylibloader_wrapper_asound)(const snd_mixer_t*); +extern int (*snd_mixer_class_unregister_dylibloader_wrapper_asound)( snd_mixer_class_t*); +extern snd_mixer_elem_t* (*snd_mixer_elem_next_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern snd_mixer_elem_t* (*snd_mixer_elem_prev_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern void (*snd_mixer_elem_set_callback_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_elem_callback_t); +extern void* (*snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*); +extern void (*snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_elem_t*, void*); +extern snd_mixer_elem_type_t (*snd_mixer_elem_get_type_dylibloader_wrapper_asound)(const snd_mixer_elem_t*); +extern int (*snd_mixer_class_register_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_t*); +extern int (*snd_mixer_elem_new_dylibloader_wrapper_asound)( snd_mixer_elem_t**, snd_mixer_elem_type_t, int, void*, void*); +extern int (*snd_mixer_elem_add_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_class_t*); +extern int (*snd_mixer_elem_remove_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern void (*snd_mixer_elem_free_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_elem_info_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_elem_value_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_elem_attach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*); +extern int (*snd_mixer_elem_detach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*); +extern int (*snd_mixer_elem_empty_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern void* (*snd_mixer_elem_get_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*); +extern size_t (*snd_mixer_class_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_mixer_class_malloc_dylibloader_wrapper_asound)( snd_mixer_class_t**); +extern void (*snd_mixer_class_free_dylibloader_wrapper_asound)( snd_mixer_class_t*); +extern void (*snd_mixer_class_copy_dylibloader_wrapper_asound)( snd_mixer_class_t*,const snd_mixer_class_t*); +extern snd_mixer_t* (*snd_mixer_class_get_mixer_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +extern snd_mixer_event_t (*snd_mixer_class_get_event_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +extern void* (*snd_mixer_class_get_private_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +extern snd_mixer_compare_t (*snd_mixer_class_get_compare_dylibloader_wrapper_asound)(const snd_mixer_class_t*); +extern int (*snd_mixer_class_set_event_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_event_t); +extern int (*snd_mixer_class_set_private_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*); +extern int (*snd_mixer_class_set_private_free_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*); +extern int (*snd_mixer_class_set_compare_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_compare_t); +extern const char* (*snd_mixer_selem_channel_name_dylibloader_wrapper_asound)( snd_mixer_selem_channel_id_t); +extern int (*snd_mixer_selem_register_dylibloader_wrapper_asound)( snd_mixer_t*,struct snd_mixer_selem_regopt*, snd_mixer_class_t**); +extern void (*snd_mixer_selem_get_id_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_id_t*); +extern const char* (*snd_mixer_selem_get_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern unsigned int (*snd_mixer_selem_get_index_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern snd_mixer_elem_t* (*snd_mixer_find_selem_dylibloader_wrapper_asound)( snd_mixer_t*,const snd_mixer_selem_id_t*); +extern int (*snd_mixer_selem_is_active_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t); +extern int (*snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t); +extern int (*snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*); +extern int (*snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*); +extern int (*snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*); +extern int (*snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*); +extern int (*snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +extern int (*snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +extern int (*snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +extern int (*snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*); +extern int (*snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*); +extern int (*snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*); +extern int (*snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long); +extern int (*snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long); +extern int (*snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int); +extern int (*snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int); +extern int (*snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long); +extern int (*snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long); +extern int (*snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int); +extern int (*snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int); +extern int (*snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int); +extern int (*snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int); +extern int (*snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int); +extern int (*snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int); +extern int (*snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +extern int (*snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +extern int (*snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long); +extern int (*snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +extern int (*snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*); +extern int (*snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long); +extern int (*snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound)( snd_mixer_elem_t*); +extern int (*snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*, unsigned int, size_t, char*); +extern int (*snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int*); +extern int (*snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int); +extern size_t (*snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_mixer_selem_id_malloc_dylibloader_wrapper_asound)( snd_mixer_selem_id_t**); +extern void (*snd_mixer_selem_id_free_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*); +extern void (*snd_mixer_selem_id_copy_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const snd_mixer_selem_id_t*); +extern const char* (*snd_mixer_selem_id_get_name_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*); +extern unsigned int (*snd_mixer_selem_id_get_index_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*); +extern void (*snd_mixer_selem_id_set_name_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*); +extern void (*snd_mixer_selem_id_set_index_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*, unsigned int); +extern int (*snd_mixer_selem_id_parse_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*); +extern int (*snd_seq_open_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int); +extern int (*snd_seq_open_lconf_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int, snd_config_t*); +extern const char* (*snd_seq_name_dylibloader_wrapper_asound)( snd_seq_t*); +extern snd_seq_type_t (*snd_seq_type_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_close_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_poll_descriptors_count_dylibloader_wrapper_asound)( snd_seq_t*, short); +extern int (*snd_seq_poll_descriptors_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, short); +extern int (*snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, unsigned short*); +extern int (*snd_seq_nonblock_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_client_id_dylibloader_wrapper_asound)( snd_seq_t*); +extern size_t (*snd_seq_get_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*); +extern size_t (*snd_seq_get_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_set_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +extern int (*snd_seq_set_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +extern size_t (*snd_seq_system_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_system_info_malloc_dylibloader_wrapper_asound)( snd_seq_system_info_t**); +extern void (*snd_seq_system_info_free_dylibloader_wrapper_asound)( snd_seq_system_info_t*); +extern void (*snd_seq_system_info_copy_dylibloader_wrapper_asound)( snd_seq_system_info_t*,const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_get_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_get_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_get_ports_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_get_channels_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*); +extern int (*snd_seq_system_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_system_info_t*); +extern size_t (*snd_seq_client_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_client_info_malloc_dylibloader_wrapper_asound)( snd_seq_client_info_t**); +extern void (*snd_seq_client_info_free_dylibloader_wrapper_asound)( snd_seq_client_info_t*); +extern void (*snd_seq_client_info_copy_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_client_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern snd_seq_client_type_t (*snd_seq_client_info_get_type_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern const char* (*snd_seq_client_info_get_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_card_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_pid_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern const unsigned char* (*snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern int (*snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound)(const snd_seq_client_info_t*); +extern void (*snd_seq_client_info_set_client_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +extern void (*snd_seq_client_info_set_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const char*); +extern void (*snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +extern void (*snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +extern void (*snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, unsigned char*); +extern void (*snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound)( snd_seq_client_info_t*); +extern void (*snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +extern void (*snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +extern int (*snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int); +extern int (*snd_seq_get_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*); +extern int (*snd_seq_get_any_client_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_client_info_t*); +extern int (*snd_seq_set_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*); +extern int (*snd_seq_query_next_client_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*); +extern size_t (*snd_seq_client_pool_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_client_pool_malloc_dylibloader_wrapper_asound)( snd_seq_client_pool_t**); +extern void (*snd_seq_client_pool_free_dylibloader_wrapper_asound)( snd_seq_client_pool_t*); +extern void (*snd_seq_client_pool_copy_dylibloader_wrapper_asound)( snd_seq_client_pool_t*,const snd_seq_client_pool_t*); +extern int (*snd_seq_client_pool_get_client_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +extern size_t (*snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +extern size_t (*snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +extern size_t (*snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +extern size_t (*snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +extern size_t (*snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*); +extern void (*snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t); +extern void (*snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t); +extern void (*snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t); +extern int (*snd_seq_get_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*); +extern int (*snd_seq_set_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*); +extern size_t (*snd_seq_port_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_port_info_malloc_dylibloader_wrapper_asound)( snd_seq_port_info_t**); +extern void (*snd_seq_port_info_free_dylibloader_wrapper_asound)( snd_seq_port_info_t*); +extern void (*snd_seq_port_info_copy_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_client_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_port_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern const snd_seq_addr_t* (*snd_seq_port_info_get_addr_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern const char* (*snd_seq_port_info_get_name_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern unsigned int (*snd_seq_port_info_get_capability_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern unsigned int (*snd_seq_port_info_get_type_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_read_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_write_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern int (*snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound)(const snd_seq_port_info_t*); +extern void (*snd_seq_port_info_set_client_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_port_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_addr_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_addr_t*); +extern void (*snd_seq_port_info_set_name_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const char*); +extern void (*snd_seq_port_info_set_capability_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int); +extern void (*snd_seq_port_info_set_type_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int); +extern void (*snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern void (*snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int); +extern int (*snd_seq_create_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*); +extern int (*snd_seq_delete_port_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_get_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*); +extern int (*snd_seq_get_any_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, int, snd_seq_port_info_t*); +extern int (*snd_seq_set_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*); +extern int (*snd_seq_query_next_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*); +extern size_t (*snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t**); +extern void (*snd_seq_port_subscribe_free_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*); +extern void (*snd_seq_port_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_port_subscribe_t*); +extern const snd_seq_addr_t* (*snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +extern const snd_seq_addr_t* (*snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +extern int (*snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +extern int (*snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +extern int (*snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +extern int (*snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*); +extern void (*snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*); +extern void (*snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*); +extern void (*snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +extern void (*snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +extern void (*snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +extern void (*snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int); +extern int (*snd_seq_get_port_subscription_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*); +extern int (*snd_seq_subscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*); +extern int (*snd_seq_unsubscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*); +extern size_t (*snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t**); +extern void (*snd_seq_query_subscribe_free_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*); +extern void (*snd_seq_query_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern const snd_seq_addr_t* (*snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern snd_seq_query_subs_type_t (*snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern const snd_seq_addr_t* (*snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern int (*snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*); +extern void (*snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int); +extern void (*snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int); +extern void (*snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_addr_t*); +extern void (*snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, snd_seq_query_subs_type_t); +extern void (*snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int); +extern int (*snd_seq_query_port_subscribers_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_query_subscribe_t*); +extern size_t (*snd_seq_queue_info_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_queue_info_malloc_dylibloader_wrapper_asound)( snd_seq_queue_info_t**); +extern void (*snd_seq_queue_info_free_dylibloader_wrapper_asound)( snd_seq_queue_info_t*); +extern void (*snd_seq_queue_info_copy_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const snd_seq_queue_info_t*); +extern int (*snd_seq_queue_info_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +extern const char* (*snd_seq_queue_info_get_name_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +extern int (*snd_seq_queue_info_get_owner_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +extern int (*snd_seq_queue_info_get_locked_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +extern unsigned int (*snd_seq_queue_info_get_flags_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*); +extern void (*snd_seq_queue_info_set_name_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const char*); +extern void (*snd_seq_queue_info_set_owner_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int); +extern void (*snd_seq_queue_info_set_locked_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int); +extern void (*snd_seq_queue_info_set_flags_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, unsigned int); +extern int (*snd_seq_create_queue_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_queue_info_t*); +extern int (*snd_seq_alloc_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*); +extern int (*snd_seq_alloc_queue_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_free_queue_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_get_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*); +extern int (*snd_seq_set_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*); +extern int (*snd_seq_query_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*); +extern int (*snd_seq_get_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_set_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int, int); +extern size_t (*snd_seq_queue_status_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_queue_status_malloc_dylibloader_wrapper_asound)( snd_seq_queue_status_t**); +extern void (*snd_seq_queue_status_free_dylibloader_wrapper_asound)( snd_seq_queue_status_t*); +extern void (*snd_seq_queue_status_copy_dylibloader_wrapper_asound)( snd_seq_queue_status_t*,const snd_seq_queue_status_t*); +extern int (*snd_seq_queue_status_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +extern int (*snd_seq_queue_status_get_events_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +extern snd_seq_tick_time_t (*snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +extern const snd_seq_real_time_t* (*snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +extern unsigned int (*snd_seq_queue_status_get_status_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*); +extern int (*snd_seq_get_queue_status_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_status_t*); +extern size_t (*snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t**); +extern void (*snd_seq_queue_tempo_free_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*); +extern void (*snd_seq_queue_tempo_copy_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*,const snd_seq_queue_tempo_t*); +extern int (*snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +extern unsigned int (*snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +extern int (*snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +extern unsigned int (*snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +extern unsigned int (*snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*); +extern void (*snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int); +extern void (*snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, int); +extern void (*snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int); +extern void (*snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int); +extern int (*snd_seq_get_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*); +extern int (*snd_seq_set_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*); +extern size_t (*snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_queue_timer_malloc_dylibloader_wrapper_asound)( snd_seq_queue_timer_t**); +extern void (*snd_seq_queue_timer_free_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*); +extern void (*snd_seq_queue_timer_copy_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_seq_queue_timer_t*); +extern int (*snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +extern snd_seq_queue_timer_type_t (*snd_seq_queue_timer_get_type_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +extern const snd_timer_id_t* (*snd_seq_queue_timer_get_id_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +extern unsigned int (*snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*); +extern void (*snd_seq_queue_timer_set_type_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, snd_seq_queue_timer_type_t); +extern void (*snd_seq_queue_timer_set_id_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_timer_id_t*); +extern void (*snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, unsigned int); +extern int (*snd_seq_get_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*); +extern int (*snd_seq_set_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*); +extern int (*snd_seq_free_event_dylibloader_wrapper_asound)( snd_seq_event_t*); +extern ssize_t (*snd_seq_event_length_dylibloader_wrapper_asound)( snd_seq_event_t*); +extern int (*snd_seq_event_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*); +extern int (*snd_seq_event_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*); +extern int (*snd_seq_event_output_direct_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*); +extern int (*snd_seq_event_input_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**); +extern int (*snd_seq_event_input_pending_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_drain_output_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_event_output_pending_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_extract_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**); +extern int (*snd_seq_drop_output_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_drop_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_drop_input_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_drop_input_buffer_dylibloader_wrapper_asound)( snd_seq_t*); +extern size_t (*snd_seq_remove_events_sizeof_dylibloader_wrapper_asound)( void); +extern int (*snd_seq_remove_events_malloc_dylibloader_wrapper_asound)( snd_seq_remove_events_t**); +extern void (*snd_seq_remove_events_free_dylibloader_wrapper_asound)( snd_seq_remove_events_t*); +extern void (*snd_seq_remove_events_copy_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_remove_events_t*); +extern unsigned int (*snd_seq_remove_events_get_condition_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern int (*snd_seq_remove_events_get_queue_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern const snd_seq_timestamp_t* (*snd_seq_remove_events_get_time_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern const snd_seq_addr_t* (*snd_seq_remove_events_get_dest_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern int (*snd_seq_remove_events_get_channel_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern int (*snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern int (*snd_seq_remove_events_get_tag_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*); +extern void (*snd_seq_remove_events_set_condition_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, unsigned int); +extern void (*snd_seq_remove_events_set_queue_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +extern void (*snd_seq_remove_events_set_time_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_timestamp_t*); +extern void (*snd_seq_remove_events_set_dest_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_addr_t*); +extern void (*snd_seq_remove_events_set_channel_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +extern void (*snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +extern void (*snd_seq_remove_events_set_tag_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int); +extern int (*snd_seq_remove_events_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_remove_events_t*); +extern void (*snd_seq_set_bit_dylibloader_wrapper_asound)( int, void*); +extern void (*snd_seq_unset_bit_dylibloader_wrapper_asound)( int, void*); +extern int (*snd_seq_change_bit_dylibloader_wrapper_asound)( int, void*); +extern int (*snd_seq_get_bit_dylibloader_wrapper_asound)( int, void*); +extern int (*snd_seq_control_queue_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int, snd_seq_event_t*); +extern int (*snd_seq_create_simple_port_dylibloader_wrapper_asound)( snd_seq_t*,const char*, unsigned int, unsigned int); +extern int (*snd_seq_delete_simple_port_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_connect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +extern int (*snd_seq_connect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +extern int (*snd_seq_disconnect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +extern int (*snd_seq_disconnect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int); +extern int (*snd_seq_set_client_name_dylibloader_wrapper_asound)( snd_seq_t*,const char*); +extern int (*snd_seq_set_client_event_filter_dylibloader_wrapper_asound)( snd_seq_t*, int); +extern int (*snd_seq_set_client_pool_output_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +extern int (*snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +extern int (*snd_seq_set_client_pool_input_dylibloader_wrapper_asound)( snd_seq_t*, size_t); +extern int (*snd_seq_sync_output_queue_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_parse_address_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_addr_t*,const char*); +extern int (*snd_seq_reset_pool_output_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_seq_reset_pool_input_dylibloader_wrapper_asound)( snd_seq_t*); +extern int (*snd_midi_event_new_dylibloader_wrapper_asound)( size_t, snd_midi_event_t**); +extern int (*snd_midi_event_resize_buffer_dylibloader_wrapper_asound)( snd_midi_event_t*, size_t); +extern void (*snd_midi_event_free_dylibloader_wrapper_asound)( snd_midi_event_t*); +extern void (*snd_midi_event_init_dylibloader_wrapper_asound)( snd_midi_event_t*); +extern void (*snd_midi_event_reset_encode_dylibloader_wrapper_asound)( snd_midi_event_t*); +extern void (*snd_midi_event_reset_decode_dylibloader_wrapper_asound)( snd_midi_event_t*); +extern void (*snd_midi_event_no_status_dylibloader_wrapper_asound)( snd_midi_event_t*, int); +extern long (*snd_midi_event_encode_dylibloader_wrapper_asound)( snd_midi_event_t*,const unsigned char*, long, snd_seq_event_t*); +extern int (*snd_midi_event_encode_byte_dylibloader_wrapper_asound)( snd_midi_event_t*, int, snd_seq_event_t*); +extern long (*snd_midi_event_decode_dylibloader_wrapper_asound)( snd_midi_event_t*, unsigned char*, long,const snd_seq_event_t*); +int initialize_asound(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 5b0d2233e0..61475c74e7 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -37,8 +37,14 @@ #include <errno.h> +#ifdef PULSEAUDIO_ENABLED +extern "C" { +extern int initialize_pulse(int verbose); +} +#endif + Error AudioDriverALSA::init_device() { - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); speaker_mode = SPEAKER_MODE_STEREO; channels = 2; @@ -104,7 +110,7 @@ Error AudioDriverALSA::init_device() { // In ALSA the period size seems to be the one that will determine the actual latency // Ref: https://www.alsa-project.org/main/index.php/FramesPeriods unsigned int periods = 2; - int latency = GLOBAL_GET("audio/output_latency"); + int latency = GLOBAL_GET("audio/driver/output_latency"); buffer_frames = closest_power_of_2(latency * mix_rate / 1000); buffer_size = buffer_frames * periods; period_size = buffer_frames; @@ -147,13 +153,28 @@ Error AudioDriverALSA::init_device() { } Error AudioDriverALSA::init() { +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif +#ifdef PULSEAUDIO_ENABLED + // On pulse enabled systems Alsa will silently use pulse. + // It doesn't matter if this fails as that likely means there is no pulse + initialize_pulse(dylibloader_verbose); +#endif + + if (initialize_asound(dylibloader_verbose)) { + return ERR_CANT_OPEN; + } + active = false; thread_exited = false; exit_thread = false; Error err = init_device(); if (err == OK) { - thread = Thread::create(AudioDriverALSA::thread_func, this); + thread.start(AudioDriverALSA::thread_func, this); } return err; @@ -291,16 +312,10 @@ void AudioDriverALSA::set_device(String device) { } void AudioDriverALSA::lock() { - if (!thread) { - return; - } mutex.lock(); } void AudioDriverALSA::unlock() { - if (!thread) { - return; - } mutex.unlock(); } @@ -312,13 +327,8 @@ void AudioDriverALSA::finish_device() { } void AudioDriverALSA::finish() { - if (thread) { - exit_thread = true; - Thread::wait_to_finish(thread); - - memdelete(thread); - thread = nullptr; - } + exit_thread = true; + thread.wait_to_finish(); finish_device(); } diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index 7441229704..ca97e76bc2 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -37,10 +37,10 @@ #include "core/os/thread.h" #include "servers/audio_server.h" -#include <alsa/asoundlib.h> +#include "asound-so_wrap.h" class AudioDriverALSA : public AudioDriver { - Thread *thread = nullptr; + Thread thread; Mutex mutex; snd_pcm_t *pcm_handle = nullptr; diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index 2e1034fc66..245ea07730 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/drivers/alsamidi/midi_driver_alsamidi.cpp @@ -150,19 +150,14 @@ Error MIDIDriverALSAMidi::open() { snd_device_name_free_hint(hints); exit_thread = false; - thread = Thread::create(MIDIDriverALSAMidi::thread_func, this); + thread.start(MIDIDriverALSAMidi::thread_func, this); return OK; } void MIDIDriverALSAMidi::close() { - if (thread) { - exit_thread = true; - Thread::wait_to_finish(thread); - - memdelete(thread); - thread = nullptr; - } + exit_thread = true; + thread.wait_to_finish(); for (int i = 0; i < connected_inputs.size(); i++) { snd_rawmidi_t *midi_in = connected_inputs[i]; @@ -198,8 +193,6 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() { } MIDIDriverALSAMidi::MIDIDriverALSAMidi() { - thread = nullptr; - exit_thread = false; } diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h index 1ce0d397df..c327712ee7 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -38,11 +38,11 @@ #include "core/os/thread.h" #include "core/templates/vector.h" -#include <alsa/asoundlib.h> +#include "../alsa/asound-so_wrap.h" #include <stdio.h> class MIDIDriverALSAMidi : public MIDIDriver { - Thread *thread; + Thread thread; Mutex mutex; Vector<snd_rawmidi_t *> connected_inputs; diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 6f88107086..baa60f5526 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -116,7 +116,7 @@ Error AudioDriverCoreAudio::init() { break; } - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); zeromem(&strdesc, sizeof(strdesc)); strdesc.mFormatID = kAudioFormatLinearPCM; @@ -131,7 +131,7 @@ Error AudioDriverCoreAudio::init() { result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc)); ERR_FAIL_COND_V(result != noErr, FAILED); - int latency = GLOBAL_GET("audio/output_latency"); + int latency = GLOBAL_GET("audio/driver/output_latency"); // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) buffer_frames = closest_power_of_2(latency * mix_rate / 1000); @@ -157,7 +157,7 @@ Error AudioDriverCoreAudio::init() { result = AudioUnitInitialize(audio_unit); ERR_FAIL_COND_V(result != noErr, FAILED); - if (GLOBAL_GET("audio/enable_audio_input")) { + if (GLOBAL_GET("audio/driver/enable_input")) { return capture_init(); } return OK; @@ -403,7 +403,7 @@ Error AudioDriverCoreAudio::capture_init() { break; } - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); zeromem(&strdesc, sizeof(strdesc)); strdesc.mFormatID = kAudioFormatLinearPCM; diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 2c95c7dbec..a76520dcdb 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -40,14 +40,37 @@ class RasterizerSceneDummy : public RendererSceneRender { public: + GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } + void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {} + void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {} + void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {} + void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {} + void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} + void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {} + void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {} + void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {} + void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override {} + void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {} + void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {} + void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {} + void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {} + + uint32_t geometry_instance_get_pair_mask() override { return 0; } + void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {} + void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) override {} + + void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} + /* SHADOW ATLAS API */ RID shadow_atlas_create() override { return RID(); } - void shadow_atlas_set_size(RID p_atlas, int p_size) override {} + void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) override {} void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {} bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; } - void directional_shadow_atlas_set_size(int p_size) override {} + void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) override {} int get_directional_light_shadow_size(RID p_light_intance) override { return 0; } void set_directional_shadow_count(int p_count) override {} @@ -57,11 +80,11 @@ public: int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; } AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); } uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; } - void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) override {} /* SKY API */ - RID sky_create() override { return RID(); } + RID sky_allocate() override { return RID(); } + void sky_initialize(RID p_rid) override {} void sky_set_radiance_size(RID p_sky, int p_radiance_size) override {} void sky_set_mode(RID p_sky, RS::SkyMode p_samples) override {} void sky_set_material(RID p_sky, RID p_material) override {} @@ -69,8 +92,8 @@ public: /* ENVIRONMENT API */ - RID environment_create() override { return RID(); } - + RID environment_allocate() override { return RID(); } + void environment_initialize(RID p_rid) override {} void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {} void environment_set_sky(RID p_env, RID p_sky) override {} void environment_set_sky_custom_fov(RID p_env, float p_scale) override {} @@ -89,21 +112,20 @@ public: void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {} void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} - void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} + void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {} void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {} + void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override {} void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {} void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {} void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {} - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {} + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) override {} void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {} void environment_set_volumetric_fog_filter_active(bool p_enable) override {} - void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) override {} - void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) override {} Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } @@ -111,8 +133,8 @@ public: RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; } int environment_get_canvas_max_layer(RID p_env) const override { return 0; } - RID camera_effects_create() override { return RID(); } - + RID camera_effects_allocate() override { return RID(); } + void camera_effects_initialize(RID p_rid) override {} void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {} void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override {} @@ -129,6 +151,7 @@ public: void light_instance_mark_visible(RID p_light_instance) override {} RID reflection_atlas_create() override { return RID(); } + int reflection_atlas_get_size(RID p_ref_atlas) const override { return 0; } void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {} RID reflection_probe_instance_create(RID p_probe) override { return RID(); } @@ -142,19 +165,19 @@ public: RID decal_instance_create(RID p_decal) override { return RID(); } void decal_instance_set_transform(RID p_decal, const Transform &p_transform) override {} + RID lightmap_instance_create(RID p_lightmap) override { return RID(); } + void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) override {} + RID gi_probe_instance_create(RID p_gi_probe) override { return RID(); } void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) override {} bool gi_probe_needs_update(RID p_probe) const override { return false; } - void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) override {} + void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} void gi_probe_set_quality(RS::GIProbeQuality) override {} - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) override {} - void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) override {} - void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) override {} - void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) override {} - void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) override {} - void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) override {} + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override {} + void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} + void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} void set_scene_pass(uint64_t p_pass) override {} void set_time(double p_time, double p_step) override {} @@ -162,6 +185,7 @@ public: RID render_buffers_create() override { return RID(); } void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) override {} + void gi_set_use_half_resolution(bool p_enable) override {} void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {} bool screen_space_roughness_limiter_is_active() const override { return false; } @@ -183,61 +207,48 @@ public: class RasterizerStorageDummy : public RendererStorage { public: + bool can_create_resources_async() const override { return false; } + /* TEXTURE API */ struct DummyTexture { - int width = 0; - int height = 0; - uint32_t flags = 0; - Image::Format format = Image::Format::FORMAT_MAX; Ref<Image> image; - String path; - }; - - struct DummySurface { - uint32_t format = 0; - RS::PrimitiveType primitive = RS::PrimitiveType::PRIMITIVE_MAX; - Vector<uint8_t> array; - int vertex_count = 0; - Vector<uint8_t> index_array; - int index_count = 0; - AABB aabb; - Vector<Vector<uint8_t>> blend_shapes; - Vector<AABB> bone_aabbs; - }; - - struct DummyMesh { - Vector<DummySurface> surfaces; - int blend_shape_count = 0; - RS::BlendShapeMode blend_shape_mode = RS::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED; }; - mutable RID_PtrOwner<DummyTexture> texture_owner; - mutable RID_PtrOwner<DummyMesh> mesh_owner; - RID texture_2d_create(const Ref<Image> &p_image) override { return RID(); } - RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override { return RID(); } - RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override { return RID(); } - RID texture_proxy_create(RID p_base) override { return RID(); } + RID texture_allocate() override { + DummyTexture *texture = memnew(DummyTexture); + ERR_FAIL_COND_V(!texture, RID()); + return texture_owner.make_rid(texture); + } + void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override { + DummyTexture *t = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!t); + t->image = p_image->duplicate(); + } + void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override {} void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {} void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {} + void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override {} void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {} + void texture_proxy_initialize(RID p_texture, RID p_base) override {} void texture_proxy_update(RID p_proxy, RID p_base) override {} - RID texture_2d_placeholder_create() override { return RID(); } - RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) override { return RID(); } - RID texture_3d_placeholder_create() override { return RID(); } + void texture_2d_placeholder_initialize(RID p_texture) override {} + void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override {} + void texture_3d_placeholder_initialize(RID p_texture) override {} + + Ref<Image> texture_2d_get(RID p_texture) const override { + DummyTexture *t = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!t, Ref<Image>()); + return t->image; + } - Ref<Image> texture_2d_get(RID p_texture) const override { return Ref<Image>(); } Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override { return Ref<Image>(); } Vector<Ref<Image>> texture_3d_get(RID p_texture) const override { return Vector<Ref<Image>>(); } void texture_replace(RID p_texture, RID p_by_texture) override {} void texture_set_size_override(RID p_texture, int p_width, int p_height) override {} -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - void texture_bind(RID p_texture, uint32_t p_texture_no) = 0; -#endif void texture_set_path(RID p_texture, const String &p_path) override {} String texture_get_path(RID p_texture) const override { return String(); } @@ -255,113 +266,18 @@ public: /* CANVAS TEXTURE API */ - RID canvas_texture_create() override { return RID(); } + RID canvas_texture_allocate() override { return RID(); } + void canvas_texture_initialize(RID p_rid) override {} void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override {} void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override {} void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {} void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {} -#if 0 - RID texture_create() override { - DummyTexture *texture = memnew(DummyTexture); - ERR_FAIL_COND_V(!texture, RID()); - return texture_owner.make_rid(texture); - } - - void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, RenderingServer::TextureType p_type = RS::TEXTURE_TYPE_2D, uint32_t p_flags = RS::TEXTURE_FLAGS_DEFAULT) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->width = p_width; - t->height = p_height; - t->flags = p_flags; - t->format = p_format; - t->image = Ref<Image>(memnew(Image)); - t->image->create(p_width, p_height, false, p_format); - } - void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_level) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->width = p_image->get_width(); - t->height = p_image->get_height(); - t->format = p_image->get_format(); - t->image->create(t->width, t->height, false, t->format, p_image->get_data()); - } - - void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_level) override { - DummyTexture *t = texture_owner.getornull(p_texture); - - ERR_FAIL_COND(!t); - ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object."); - ERR_FAIL_COND(t->format != p_image->get_format()); - ERR_FAIL_COND(src_w <= 0 || src_h <= 0); - ERR_FAIL_COND(src_x < 0 || src_y < 0 || src_x + src_w > p_image->get_width() || src_y + src_h > p_image->get_height()); - ERR_FAIL_COND(dst_x < 0 || dst_y < 0 || dst_x + src_w > t->width || dst_y + src_h > t->height); - - t->image->blit_rect(p_image, Rect2(src_x, src_y, src_w, src_h), Vector2(dst_x, dst_y)); - } - - Ref<Image> texture_get_data(RID p_texture, int p_level) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, Ref<Image>()); - return t->image; - } - void texture_set_flags(RID p_texture, uint32_t p_flags) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->flags = p_flags; - } - uint32_t texture_get_flags(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, 0); - return t->flags; - } - Image::Format texture_get_format(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, Image::FORMAT_RGB8); - return t->format; - } - - RenderingServer::TextureType texture_get_type(RID p_texture) const override { return RS::TEXTURE_TYPE_2D; } - uint32_t texture_get_texid(RID p_texture) const override { return 0; } - uint32_t texture_get_width(RID p_texture) const override { return 0; } - uint32_t texture_get_height(RID p_texture) const override { return 0; } - uint32_t texture_get_depth(RID p_texture) const override { return 0; } - void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) override {} - void texture_bind(RID p_texture, uint32_t p_texture_no) override {} - - void texture_set_path(RID p_texture, const String &p_path) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->path = p_path; - } - String texture_get_path(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, String()); - return t->path; - } - - void texture_set_shrink_all_x2_on_set_data(bool p_enable) override {} - - void texture_debug_usage(List<RS::TextureInfo> *r_info) override {} - - RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const override { return RID(); } - - void texture_set_detect_3d_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {} - void texture_set_detect_srgb_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {} - void texture_set_detect_normal_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {} - - void textures_keep_original(bool p_enable) override {} - - void texture_set_proxy(RID p_proxy, RID p_base) override {} - Size2 texture_size_with_proxy(RID p_texture) const override { return Size2(); } - void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {} -#endif - /* SHADER API */ - RID shader_create() override { return RID(); } - + RID shader_allocate() override { return RID(); } + void shader_initialize(RID p_rid) override {} void shader_set_code(RID p_shader, const String &p_code) override {} String shader_get_code(RID p_shader) const override { return ""; } void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} @@ -370,10 +286,12 @@ public: RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const override { return RID(); } Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); } - /* COMMON MATERIAL API */ + RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); }; - RID material_create() override { return RID(); } + /* COMMON MATERIAL API */ + RID material_allocate() override { return RID(); } + void material_initialize(RID p_rid) override {} void material_set_render_priority(RID p_material, int priority) override {} void material_set_shader(RID p_shader_material, RID p_shader) override {} @@ -385,153 +303,49 @@ public: bool material_is_animated(RID p_material) override { return false; } bool material_casts_shadows(RID p_material) override { return false; } void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {} - void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) override {} + void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {} /* MESH API */ - RID mesh_create() override { - DummyMesh *mesh = memnew(DummyMesh); - ERR_FAIL_COND_V(!mesh, RID()); - mesh->blend_shape_count = 0; - mesh->blend_shape_mode = RS::BLEND_SHAPE_MODE_NORMALIZED; - return mesh_owner.make_rid(mesh); - } + RID mesh_allocate() override { return RID(); } + void mesh_initialize(RID p_rid) override {} + void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {} + bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; } + RID mesh_instance_create(RID p_base) override { return RID(); } + void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override {} + void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override {} + void mesh_instance_check_for_update(RID p_mesh_instance) override {} + void update_mesh_instances() override {} + void reflection_probe_set_lod_threshold(RID p_probe, float p_ratio) override {} + float reflection_probe_get_lod_threshold(RID p_probe) const override { return 0.0; } void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override {} -#if 0 - void mesh_add_surface(RID p_mesh, uint32_t p_format, RS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - - m->surfaces.push_back(DummySurface()); - DummySurface *s = &m->surfaces.write[m->surfaces.size() - 1]; - s->format = p_format; - s->primitive = p_primitive; - s->array = p_array; - s->vertex_count = p_vertex_count; - s->index_array = p_index_array; - s->index_count = p_index_count; - s->aabb = p_aabb; - s->blend_shapes = p_blend_shapes; - s->bone_aabbs = p_bone_aabbs; - } + int mesh_get_blend_shape_count(RID p_mesh) const override { return 0; } - void mesh_set_blend_shape_count(RID p_mesh, int p_amount) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - m->blend_shape_count = p_amount; - } -#endif - - int mesh_get_blend_shape_count(RID p_mesh) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - return m->blend_shape_count; - } - - void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - m->blend_shape_mode = p_mode; - } - RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, RS::BLEND_SHAPE_MODE_NORMALIZED); - return m->blend_shape_mode; - } + void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {} + RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { return RS::BLEND_SHAPE_MODE_NORMALIZED; } void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {} void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {} RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); } -#if 0 - int mesh_surface_get_array_len(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - - return m->surfaces[p_surface].vertex_count; - } - int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - - return m->surfaces[p_surface].index_count; - } - - Vector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<uint8_t>()); - - return m->surfaces[p_surface].array; - } - Vector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<uint8_t>()); - - return m->surfaces[p_surface].index_array; - } - - uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - - return m->surfaces[p_surface].format; - } - RS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, RS::PRIMITIVE_POINTS); - - return m->surfaces[p_surface].primitive; - } - - AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, AABB()); - - return m->surfaces[p_surface].aabb; - } - Vector<Vector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<Vector<uint8_t> >()); - - return m->surfaces[p_surface].blend_shapes; - } - Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<AABB>()); - - return m->surfaces[p_surface].bone_aabbs; - } - - void mesh_remove_surface(RID p_mesh, int p_index) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - ERR_FAIL_COND(p_index >= m->surfaces.size()); - - m->surfaces.remove(p_index); - } -#endif - RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override { return RS::SurfaceData(); } - int mesh_get_surface_count(RID p_mesh) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - return m->surfaces.size(); - } + int mesh_get_surface_count(RID p_mesh) const override { return 0; } void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override {} AABB mesh_get_custom_aabb(RID p_mesh) const override { return AABB(); } AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); } + void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override {} void mesh_clear(RID p_mesh) override {} /* MULTIMESH API */ - RID multimesh_create() override { return RID(); } - - void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {} + RID multimesh_allocate() override { return RID(); } + void multimesh_initialize(RID p_rid) override {} + void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {} int multimesh_get_instance_count(RID p_multimesh) const override { return 0; } void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override {} @@ -555,7 +369,8 @@ public: /* IMMEDIATE API */ - RID immediate_create() override { return RID(); } + RID immediate_allocate() override { return RID(); } + void immediate_initialize(RID p_rid) override {} void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) override {} void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) override {} void immediate_normal(RID p_immediate, const Vector3 &p_normal) override {} @@ -571,8 +386,9 @@ public: /* SKELETON API */ - RID skeleton_create() override { return RID(); } - void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {} + RID skeleton_allocate() override { return RID(); } + void skeleton_initialize(RID p_rid) override {} + void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {} void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override {} int skeleton_get_bone_count(RID p_skeleton) const override { return 0; } void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) override {} @@ -582,7 +398,14 @@ public: /* Light API */ - RID light_create(RS::LightType p_type) override { return RID(); } + RID directional_light_allocate() override { return RID(); } + void directional_light_initialize(RID p_rid) override {} + RID omni_light_allocate() override { return RID(); } + void omni_light_initialize(RID p_rid) override {} + RID spot_light_allocate() override { return RID(); } + void spot_light_initialize(RID p_rid) override {} + RID reflection_probe_allocate() override { return RID(); } + void reflection_probe_initialize(RID p_rid) override {} void light_set_color(RID p_light, const Color &p_color) override {} void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {} @@ -620,8 +443,6 @@ public: /* PROBE API */ - RID reflection_probe_create() override { return RID(); } - void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override {} void reflection_probe_set_intensity(RID p_probe, float p_intensity) override {} void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override {} @@ -644,12 +465,13 @@ public: float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; } bool reflection_probe_renders_shadows(RID p_probe) const override { return false; } - void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) override {} - void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) override {} + void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {} + void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override {} /* DECAL API */ - RID decal_create() override { return RID(); } + RID decal_allocate() override { return RID(); } + void decal_initialize(RID p_rid) override {} void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {} void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {} void decal_set_emission_energy(RID p_decal, float p_energy) override {} @@ -664,9 +486,9 @@ public: /* GI PROBE API */ - RID gi_probe_create() override { return RID(); } - - void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {} + RID gi_probe_allocate() override { return RID(); } + void gi_probe_initialize(RID p_rid) override {} + void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {} AABB gi_probe_get_bounds(RID p_gi_probe) const override { return AABB(); } Vector3i gi_probe_get_octree_size(RID p_gi_probe) const override { return Vector3i(); } @@ -710,72 +532,8 @@ public: uint32_t gi_probe_get_version(RID p_gi_probe) override { return 0; } /* LIGHTMAP CAPTURE */ -#if 0 - struct Instantiable { - SelfList<RendererSceneRender::InstanceBase>::List instance_list; - - _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) override { - SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first(); - while (instances) override { - //instances->self()->base_changed(p_aabb, p_materials); - instances = instances->next(); - } - } - - _FORCE_INLINE_ void instance_remove_deps() override { - SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first(); - while (instances) override { - SelfList<RendererSceneRender::InstanceBase> *next = instances->next(); - //instances->self()->base_removed(); - instances = next; - } - } - - Instantiable() override {} - ~Instantiable() override { - } - }; - - struct LightmapCapture : public Instantiable { - Vector<LightmapCaptureOctree> octree; - AABB bounds; - Transform cell_xform; - int cell_subdiv; - float energy; - LightmapCapture() override { - energy = 1.0; - cell_subdiv = 1; - } - }; - - mutable RID_PtrOwner<LightmapCapture> lightmap_capture_data_owner; - void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) override {} - AABB lightmap_capture_get_bounds(RID p_capture) const override { return AABB(); } - void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) override {} - RID lightmap_capture_create() override { - LightmapCapture *capture = memnew(LightmapCapture); - return lightmap_capture_data_owner.make_rid(capture); - } - Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const override { - const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture); - ERR_FAIL_COND_V(!capture, Vector<uint8_t>()); - return Vector<uint8_t>(); - } - void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) override {} - Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const override { return Transform(); } - void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) override {} - int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const override { return 0; } - void lightmap_capture_set_energy(RID p_capture, float p_energy) override {} - float lightmap_capture_get_energy(RID p_capture) const override { return 0.0; } - const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const override { - const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture); - ERR_FAIL_COND_V(!capture, nullptr); - return &capture->octree; - } -#endif - - RID lightmap_create() override { return RID(); } - + RID lightmap_allocate() override { return RID(); } + void lightmap_initialize(RID p_rid) override {} void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {} void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {} void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override {} @@ -792,8 +550,8 @@ public: /* PARTICLES */ - RID particles_create() override { return RID(); } - + RID particles_allocate() override { return RID(); } + void particles_initialize(RID p_rid) override {} void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {} void particles_set_emitting(RID p_particles, bool p_emitting) override {} void particles_set_amount(RID p_particles, int p_amount) override {} @@ -828,14 +586,15 @@ public: int particles_get_draw_passes(RID p_particles) const override { return 0; } RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override { return RID(); } - void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) override {} - void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) override {} + void particles_add_collision(RID p_particles, RID p_instance) override {} + void particles_remove_collision(RID p_particles, RID p_instance) override {} void update_particles() override {} /* PARTICLES COLLISION */ - RID particles_collision_create() override { return RID(); } + RID particles_collision_allocate() override { return RID(); } + void particles_collision_initialize(RID p_rid) override {} void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) override {} void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) override {} void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) override {} @@ -850,6 +609,10 @@ public: bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; } RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override { return RID(); } + RID particles_collision_instance_create(RID p_collision) override { return RID(); }; + void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) override{}; + void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override{}; + /* GLOBAL VARIABLES */ void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override {} @@ -890,14 +653,7 @@ public: void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {} Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); } - RS::InstanceType get_base_type(RID p_rid) const override { - if (mesh_owner.owns(p_rid)) { - return RS::INSTANCE_MESH; - } - - return RS::INSTANCE_NONE; - } - + RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; } bool free(RID p_rid) override { if (texture_owner.owns(p_rid)) { // delete the texture @@ -905,13 +661,6 @@ public: texture_owner.free(p_rid); memdelete(texture); } - - if (mesh_owner.owns(p_rid)) { - // delete the mesh - DummyMesh *mesh = mesh_owner.getornull(p_rid); - mesh_owner.free(p_rid); - memdelete(mesh); - } return true; } diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp index 2484e6d140..f148e42845 100644 --- a/drivers/dummy/texture_loader_dummy.cpp +++ b/drivers/dummy/texture_loader_dummy.cpp @@ -35,7 +35,7 @@ #include <string.h> -RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { unsigned int width = 8; unsigned int height = 8; diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h index 3b71b5824f..00e6b9cc53 100644 --- a/drivers/dummy/texture_loader_dummy.h +++ b/drivers/dummy/texture_loader_dummy.h @@ -36,7 +36,7 @@ class ResourceFormatDummyTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/drivers/pulseaudio/SCsub b/drivers/pulseaudio/SCsub index 91e1140b75..467d1448dc 100644 --- a/drivers/pulseaudio/SCsub +++ b/drivers/pulseaudio/SCsub @@ -2,4 +2,7 @@ Import("env") +if "pulseaudio" in env and env["pulseaudio"]: + env.add_source_files(env.drivers_sources, "pulse-so_wrap.c") + env.add_source_files(env.drivers_sources, "*.cpp") diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 440b7d7f53..5e87bc019b 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -179,7 +179,7 @@ Error AudioDriverPulseAudio::init_device() { break; } - int latency = GLOBAL_GET("audio/output_latency"); + int latency = GLOBAL_GET("audio/driver/output_latency"); buffer_frames = closest_power_of_2(latency * mix_rate / 1000); pa_buffer_size = buffer_frames * pa_map.channels; @@ -233,11 +233,20 @@ Error AudioDriverPulseAudio::init_device() { } Error AudioDriverPulseAudio::init() { +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + if (initialize_pulse(dylibloader_verbose)) { + return ERR_CANT_OPEN; + } + active = false; thread_exited = false; exit_thread = false; - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); pa_ml = pa_mainloop_new(); ERR_FAIL_COND_V(pa_ml == nullptr, ERR_CANT_OPEN); @@ -287,7 +296,7 @@ Error AudioDriverPulseAudio::init() { Error err = init_device(); if (err == OK) { - thread = Thread::create(AudioDriverPulseAudio::thread_func, this); + thread.start(AudioDriverPulseAudio::thread_func, this); } return OK; @@ -581,16 +590,10 @@ void AudioDriverPulseAudio::set_device(String device) { } void AudioDriverPulseAudio::lock() { - if (!thread) { - return; - } mutex.lock(); } void AudioDriverPulseAudio::unlock() { - if (!thread) { - return; - } mutex.unlock(); } @@ -603,12 +606,12 @@ void AudioDriverPulseAudio::finish_device() { } void AudioDriverPulseAudio::finish() { - if (!thread) { + if (!thread.is_started()) { return; } exit_thread = true; - Thread::wait_to_finish(thread); + thread.wait_to_finish(); finish_device(); @@ -622,10 +625,6 @@ void AudioDriverPulseAudio::finish() { pa_mainloop_free(pa_ml); pa_ml = nullptr; } - - memdelete(thread); - - thread = nullptr; } Error AudioDriverPulseAudio::capture_init_device() { diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 71ab2ef1c8..fa9b573d94 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -37,10 +37,10 @@ #include "core/os/thread.h" #include "servers/audio_server.h" -#include <pulse/pulseaudio.h> +#include "pulse-so_wrap.h" class AudioDriverPulseAudio : public AudioDriver { - Thread *thread = nullptr; + Thread thread; Mutex mutex; pa_mainloop *pa_ml = nullptr; diff --git a/drivers/pulseaudio/pulse-so_wrap.c b/drivers/pulseaudio/pulse-so_wrap.c new file mode 100644 index 0000000000..12bdcc704e --- /dev/null +++ b/drivers/pulseaudio/pulse-so_wrap.c @@ -0,0 +1,3950 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:31 +// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include <pulse/pulseaudio.h> --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-so_wrap.h --output-implementation pulse-so_wrap.c +// +#include <stdint.h> + +#define pa_get_library_version pa_get_library_version_dylibloader_orig_pulse +#define pa_bytes_per_second pa_bytes_per_second_dylibloader_orig_pulse +#define pa_frame_size pa_frame_size_dylibloader_orig_pulse +#define pa_sample_size pa_sample_size_dylibloader_orig_pulse +#define pa_sample_size_of_format pa_sample_size_of_format_dylibloader_orig_pulse +#define pa_bytes_to_usec pa_bytes_to_usec_dylibloader_orig_pulse +#define pa_usec_to_bytes pa_usec_to_bytes_dylibloader_orig_pulse +#define pa_sample_spec_init pa_sample_spec_init_dylibloader_orig_pulse +#define pa_sample_format_valid pa_sample_format_valid_dylibloader_orig_pulse +#define pa_sample_rate_valid pa_sample_rate_valid_dylibloader_orig_pulse +#define pa_channels_valid pa_channels_valid_dylibloader_orig_pulse +#define pa_sample_spec_valid pa_sample_spec_valid_dylibloader_orig_pulse +#define pa_sample_spec_equal pa_sample_spec_equal_dylibloader_orig_pulse +#define pa_sample_format_to_string pa_sample_format_to_string_dylibloader_orig_pulse +#define pa_parse_sample_format pa_parse_sample_format_dylibloader_orig_pulse +#define pa_sample_spec_snprint pa_sample_spec_snprint_dylibloader_orig_pulse +#define pa_bytes_snprint pa_bytes_snprint_dylibloader_orig_pulse +#define pa_sample_format_is_le pa_sample_format_is_le_dylibloader_orig_pulse +#define pa_sample_format_is_be pa_sample_format_is_be_dylibloader_orig_pulse +#define pa_direction_valid pa_direction_valid_dylibloader_orig_pulse +#define pa_direction_to_string pa_direction_to_string_dylibloader_orig_pulse +#define pa_mainloop_api_once pa_mainloop_api_once_dylibloader_orig_pulse +#define pa_proplist_new pa_proplist_new_dylibloader_orig_pulse +#define pa_proplist_free pa_proplist_free_dylibloader_orig_pulse +#define pa_proplist_key_valid pa_proplist_key_valid_dylibloader_orig_pulse +#define pa_proplist_sets pa_proplist_sets_dylibloader_orig_pulse +#define pa_proplist_setp pa_proplist_setp_dylibloader_orig_pulse +#define pa_proplist_setf pa_proplist_setf_dylibloader_orig_pulse +#define pa_proplist_set pa_proplist_set_dylibloader_orig_pulse +#define pa_proplist_gets pa_proplist_gets_dylibloader_orig_pulse +#define pa_proplist_get pa_proplist_get_dylibloader_orig_pulse +#define pa_proplist_update pa_proplist_update_dylibloader_orig_pulse +#define pa_proplist_unset pa_proplist_unset_dylibloader_orig_pulse +#define pa_proplist_unset_many pa_proplist_unset_many_dylibloader_orig_pulse +#define pa_proplist_iterate pa_proplist_iterate_dylibloader_orig_pulse +#define pa_proplist_to_string pa_proplist_to_string_dylibloader_orig_pulse +#define pa_proplist_to_string_sep pa_proplist_to_string_sep_dylibloader_orig_pulse +#define pa_proplist_from_string pa_proplist_from_string_dylibloader_orig_pulse +#define pa_proplist_contains pa_proplist_contains_dylibloader_orig_pulse +#define pa_proplist_clear pa_proplist_clear_dylibloader_orig_pulse +#define pa_proplist_copy pa_proplist_copy_dylibloader_orig_pulse +#define pa_proplist_size pa_proplist_size_dylibloader_orig_pulse +#define pa_proplist_isempty pa_proplist_isempty_dylibloader_orig_pulse +#define pa_proplist_equal pa_proplist_equal_dylibloader_orig_pulse +#define pa_channel_map_init pa_channel_map_init_dylibloader_orig_pulse +#define pa_channel_map_init_mono pa_channel_map_init_mono_dylibloader_orig_pulse +#define pa_channel_map_init_stereo pa_channel_map_init_stereo_dylibloader_orig_pulse +#define pa_channel_map_init_auto pa_channel_map_init_auto_dylibloader_orig_pulse +#define pa_channel_map_init_extend pa_channel_map_init_extend_dylibloader_orig_pulse +#define pa_channel_position_to_string pa_channel_position_to_string_dylibloader_orig_pulse +#define pa_channel_position_from_string pa_channel_position_from_string_dylibloader_orig_pulse +#define pa_channel_position_to_pretty_string pa_channel_position_to_pretty_string_dylibloader_orig_pulse +#define pa_channel_map_snprint pa_channel_map_snprint_dylibloader_orig_pulse +#define pa_channel_map_parse pa_channel_map_parse_dylibloader_orig_pulse +#define pa_channel_map_equal pa_channel_map_equal_dylibloader_orig_pulse +#define pa_channel_map_valid pa_channel_map_valid_dylibloader_orig_pulse +#define pa_channel_map_compatible pa_channel_map_compatible_dylibloader_orig_pulse +#define pa_channel_map_superset pa_channel_map_superset_dylibloader_orig_pulse +#define pa_channel_map_can_balance pa_channel_map_can_balance_dylibloader_orig_pulse +#define pa_channel_map_can_fade pa_channel_map_can_fade_dylibloader_orig_pulse +#define pa_channel_map_can_lfe_balance pa_channel_map_can_lfe_balance_dylibloader_orig_pulse +#define pa_channel_map_to_name pa_channel_map_to_name_dylibloader_orig_pulse +#define pa_channel_map_to_pretty_name pa_channel_map_to_pretty_name_dylibloader_orig_pulse +#define pa_channel_map_has_position pa_channel_map_has_position_dylibloader_orig_pulse +#define pa_channel_map_mask pa_channel_map_mask_dylibloader_orig_pulse +#define pa_encoding_to_string pa_encoding_to_string_dylibloader_orig_pulse +#define pa_encoding_from_string pa_encoding_from_string_dylibloader_orig_pulse +#define pa_format_info_new pa_format_info_new_dylibloader_orig_pulse +#define pa_format_info_copy pa_format_info_copy_dylibloader_orig_pulse +#define pa_format_info_free pa_format_info_free_dylibloader_orig_pulse +#define pa_format_info_valid pa_format_info_valid_dylibloader_orig_pulse +#define pa_format_info_is_pcm pa_format_info_is_pcm_dylibloader_orig_pulse +#define pa_format_info_is_compatible pa_format_info_is_compatible_dylibloader_orig_pulse +#define pa_format_info_snprint pa_format_info_snprint_dylibloader_orig_pulse +#define pa_format_info_from_string pa_format_info_from_string_dylibloader_orig_pulse +#define pa_format_info_from_sample_spec pa_format_info_from_sample_spec_dylibloader_orig_pulse +#define pa_format_info_to_sample_spec pa_format_info_to_sample_spec_dylibloader_orig_pulse +#define pa_format_info_get_prop_type pa_format_info_get_prop_type_dylibloader_orig_pulse +#define pa_format_info_get_prop_int pa_format_info_get_prop_int_dylibloader_orig_pulse +#define pa_format_info_get_prop_int_range pa_format_info_get_prop_int_range_dylibloader_orig_pulse +#define pa_format_info_get_prop_int_array pa_format_info_get_prop_int_array_dylibloader_orig_pulse +#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_orig_pulse +#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_orig_pulse +#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_orig_pulse +#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_orig_pulse +#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_orig_pulse +#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_orig_pulse +#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_orig_pulse +#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_orig_pulse +#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_orig_pulse +#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_orig_pulse +#define pa_format_info_set_prop_string pa_format_info_set_prop_string_dylibloader_orig_pulse +#define pa_format_info_set_prop_string_array pa_format_info_set_prop_string_array_dylibloader_orig_pulse +#define pa_format_info_set_sample_format pa_format_info_set_sample_format_dylibloader_orig_pulse +#define pa_format_info_set_rate pa_format_info_set_rate_dylibloader_orig_pulse +#define pa_format_info_set_channels pa_format_info_set_channels_dylibloader_orig_pulse +#define pa_format_info_set_channel_map pa_format_info_set_channel_map_dylibloader_orig_pulse +#define pa_operation_ref pa_operation_ref_dylibloader_orig_pulse +#define pa_operation_unref pa_operation_unref_dylibloader_orig_pulse +#define pa_operation_cancel pa_operation_cancel_dylibloader_orig_pulse +#define pa_operation_get_state pa_operation_get_state_dylibloader_orig_pulse +#define pa_operation_set_state_callback pa_operation_set_state_callback_dylibloader_orig_pulse +#define pa_context_new pa_context_new_dylibloader_orig_pulse +#define pa_context_new_with_proplist pa_context_new_with_proplist_dylibloader_orig_pulse +#define pa_context_unref pa_context_unref_dylibloader_orig_pulse +#define pa_context_ref pa_context_ref_dylibloader_orig_pulse +#define pa_context_set_state_callback pa_context_set_state_callback_dylibloader_orig_pulse +#define pa_context_set_event_callback pa_context_set_event_callback_dylibloader_orig_pulse +#define pa_context_errno pa_context_errno_dylibloader_orig_pulse +#define pa_context_is_pending pa_context_is_pending_dylibloader_orig_pulse +#define pa_context_get_state pa_context_get_state_dylibloader_orig_pulse +#define pa_context_connect pa_context_connect_dylibloader_orig_pulse +#define pa_context_disconnect pa_context_disconnect_dylibloader_orig_pulse +#define pa_context_drain pa_context_drain_dylibloader_orig_pulse +#define pa_context_exit_daemon pa_context_exit_daemon_dylibloader_orig_pulse +#define pa_context_set_default_sink pa_context_set_default_sink_dylibloader_orig_pulse +#define pa_context_set_default_source pa_context_set_default_source_dylibloader_orig_pulse +#define pa_context_is_local pa_context_is_local_dylibloader_orig_pulse +#define pa_context_set_name pa_context_set_name_dylibloader_orig_pulse +#define pa_context_get_server pa_context_get_server_dylibloader_orig_pulse +#define pa_context_get_protocol_version pa_context_get_protocol_version_dylibloader_orig_pulse +#define pa_context_get_server_protocol_version pa_context_get_server_protocol_version_dylibloader_orig_pulse +#define pa_context_proplist_update pa_context_proplist_update_dylibloader_orig_pulse +#define pa_context_proplist_remove pa_context_proplist_remove_dylibloader_orig_pulse +#define pa_context_get_index pa_context_get_index_dylibloader_orig_pulse +#define pa_context_rttime_new pa_context_rttime_new_dylibloader_orig_pulse +#define pa_context_rttime_restart pa_context_rttime_restart_dylibloader_orig_pulse +#define pa_context_get_tile_size pa_context_get_tile_size_dylibloader_orig_pulse +#define pa_context_load_cookie_from_file pa_context_load_cookie_from_file_dylibloader_orig_pulse +#define pa_cvolume_equal pa_cvolume_equal_dylibloader_orig_pulse +#define pa_cvolume_init pa_cvolume_init_dylibloader_orig_pulse +#define pa_cvolume_set pa_cvolume_set_dylibloader_orig_pulse +#define pa_cvolume_snprint pa_cvolume_snprint_dylibloader_orig_pulse +#define pa_sw_cvolume_snprint_dB pa_sw_cvolume_snprint_dB_dylibloader_orig_pulse +#define pa_cvolume_snprint_verbose pa_cvolume_snprint_verbose_dylibloader_orig_pulse +#define pa_volume_snprint pa_volume_snprint_dylibloader_orig_pulse +#define pa_sw_volume_snprint_dB pa_sw_volume_snprint_dB_dylibloader_orig_pulse +#define pa_volume_snprint_verbose pa_volume_snprint_verbose_dylibloader_orig_pulse +#define pa_cvolume_avg pa_cvolume_avg_dylibloader_orig_pulse +#define pa_cvolume_avg_mask pa_cvolume_avg_mask_dylibloader_orig_pulse +#define pa_cvolume_max pa_cvolume_max_dylibloader_orig_pulse +#define pa_cvolume_max_mask pa_cvolume_max_mask_dylibloader_orig_pulse +#define pa_cvolume_min pa_cvolume_min_dylibloader_orig_pulse +#define pa_cvolume_min_mask pa_cvolume_min_mask_dylibloader_orig_pulse +#define pa_cvolume_valid pa_cvolume_valid_dylibloader_orig_pulse +#define pa_cvolume_channels_equal_to pa_cvolume_channels_equal_to_dylibloader_orig_pulse +#define pa_sw_volume_multiply pa_sw_volume_multiply_dylibloader_orig_pulse +#define pa_sw_cvolume_multiply pa_sw_cvolume_multiply_dylibloader_orig_pulse +#define pa_sw_cvolume_multiply_scalar pa_sw_cvolume_multiply_scalar_dylibloader_orig_pulse +#define pa_sw_volume_divide pa_sw_volume_divide_dylibloader_orig_pulse +#define pa_sw_cvolume_divide pa_sw_cvolume_divide_dylibloader_orig_pulse +#define pa_sw_cvolume_divide_scalar pa_sw_cvolume_divide_scalar_dylibloader_orig_pulse +#define pa_sw_volume_from_dB pa_sw_volume_from_dB_dylibloader_orig_pulse +#define pa_sw_volume_to_dB pa_sw_volume_to_dB_dylibloader_orig_pulse +#define pa_sw_volume_from_linear pa_sw_volume_from_linear_dylibloader_orig_pulse +#define pa_sw_volume_to_linear pa_sw_volume_to_linear_dylibloader_orig_pulse +#define pa_cvolume_remap pa_cvolume_remap_dylibloader_orig_pulse +#define pa_cvolume_compatible pa_cvolume_compatible_dylibloader_orig_pulse +#define pa_cvolume_compatible_with_channel_map pa_cvolume_compatible_with_channel_map_dylibloader_orig_pulse +#define pa_cvolume_get_balance pa_cvolume_get_balance_dylibloader_orig_pulse +#define pa_cvolume_set_balance pa_cvolume_set_balance_dylibloader_orig_pulse +#define pa_cvolume_get_fade pa_cvolume_get_fade_dylibloader_orig_pulse +#define pa_cvolume_set_fade pa_cvolume_set_fade_dylibloader_orig_pulse +#define pa_cvolume_get_lfe_balance pa_cvolume_get_lfe_balance_dylibloader_orig_pulse +#define pa_cvolume_set_lfe_balance pa_cvolume_set_lfe_balance_dylibloader_orig_pulse +#define pa_cvolume_scale pa_cvolume_scale_dylibloader_orig_pulse +#define pa_cvolume_scale_mask pa_cvolume_scale_mask_dylibloader_orig_pulse +#define pa_cvolume_set_position pa_cvolume_set_position_dylibloader_orig_pulse +#define pa_cvolume_get_position pa_cvolume_get_position_dylibloader_orig_pulse +#define pa_cvolume_merge pa_cvolume_merge_dylibloader_orig_pulse +#define pa_cvolume_inc_clamp pa_cvolume_inc_clamp_dylibloader_orig_pulse +#define pa_cvolume_inc pa_cvolume_inc_dylibloader_orig_pulse +#define pa_cvolume_dec pa_cvolume_dec_dylibloader_orig_pulse +#define pa_stream_new pa_stream_new_dylibloader_orig_pulse +#define pa_stream_new_with_proplist pa_stream_new_with_proplist_dylibloader_orig_pulse +#define pa_stream_new_extended pa_stream_new_extended_dylibloader_orig_pulse +#define pa_stream_unref pa_stream_unref_dylibloader_orig_pulse +#define pa_stream_ref pa_stream_ref_dylibloader_orig_pulse +#define pa_stream_get_state pa_stream_get_state_dylibloader_orig_pulse +#define pa_stream_get_context pa_stream_get_context_dylibloader_orig_pulse +#define pa_stream_get_index pa_stream_get_index_dylibloader_orig_pulse +#define pa_stream_get_device_index pa_stream_get_device_index_dylibloader_orig_pulse +#define pa_stream_get_device_name pa_stream_get_device_name_dylibloader_orig_pulse +#define pa_stream_is_suspended pa_stream_is_suspended_dylibloader_orig_pulse +#define pa_stream_is_corked pa_stream_is_corked_dylibloader_orig_pulse +#define pa_stream_connect_playback pa_stream_connect_playback_dylibloader_orig_pulse +#define pa_stream_connect_record pa_stream_connect_record_dylibloader_orig_pulse +#define pa_stream_disconnect pa_stream_disconnect_dylibloader_orig_pulse +#define pa_stream_begin_write pa_stream_begin_write_dylibloader_orig_pulse +#define pa_stream_cancel_write pa_stream_cancel_write_dylibloader_orig_pulse +#define pa_stream_write pa_stream_write_dylibloader_orig_pulse +#define pa_stream_write_ext_free pa_stream_write_ext_free_dylibloader_orig_pulse +#define pa_stream_peek pa_stream_peek_dylibloader_orig_pulse +#define pa_stream_drop pa_stream_drop_dylibloader_orig_pulse +#define pa_stream_writable_size pa_stream_writable_size_dylibloader_orig_pulse +#define pa_stream_readable_size pa_stream_readable_size_dylibloader_orig_pulse +#define pa_stream_drain pa_stream_drain_dylibloader_orig_pulse +#define pa_stream_update_timing_info pa_stream_update_timing_info_dylibloader_orig_pulse +#define pa_stream_set_state_callback pa_stream_set_state_callback_dylibloader_orig_pulse +#define pa_stream_set_write_callback pa_stream_set_write_callback_dylibloader_orig_pulse +#define pa_stream_set_read_callback pa_stream_set_read_callback_dylibloader_orig_pulse +#define pa_stream_set_overflow_callback pa_stream_set_overflow_callback_dylibloader_orig_pulse +#define pa_stream_get_underflow_index pa_stream_get_underflow_index_dylibloader_orig_pulse +#define pa_stream_set_underflow_callback pa_stream_set_underflow_callback_dylibloader_orig_pulse +#define pa_stream_set_started_callback pa_stream_set_started_callback_dylibloader_orig_pulse +#define pa_stream_set_latency_update_callback pa_stream_set_latency_update_callback_dylibloader_orig_pulse +#define pa_stream_set_moved_callback pa_stream_set_moved_callback_dylibloader_orig_pulse +#define pa_stream_set_suspended_callback pa_stream_set_suspended_callback_dylibloader_orig_pulse +#define pa_stream_set_event_callback pa_stream_set_event_callback_dylibloader_orig_pulse +#define pa_stream_set_buffer_attr_callback pa_stream_set_buffer_attr_callback_dylibloader_orig_pulse +#define pa_stream_cork pa_stream_cork_dylibloader_orig_pulse +#define pa_stream_flush pa_stream_flush_dylibloader_orig_pulse +#define pa_stream_prebuf pa_stream_prebuf_dylibloader_orig_pulse +#define pa_stream_trigger pa_stream_trigger_dylibloader_orig_pulse +#define pa_stream_set_name pa_stream_set_name_dylibloader_orig_pulse +#define pa_stream_get_time pa_stream_get_time_dylibloader_orig_pulse +#define pa_stream_get_latency pa_stream_get_latency_dylibloader_orig_pulse +#define pa_stream_get_timing_info pa_stream_get_timing_info_dylibloader_orig_pulse +#define pa_stream_get_sample_spec pa_stream_get_sample_spec_dylibloader_orig_pulse +#define pa_stream_get_channel_map pa_stream_get_channel_map_dylibloader_orig_pulse +#define pa_stream_get_format_info pa_stream_get_format_info_dylibloader_orig_pulse +#define pa_stream_get_buffer_attr pa_stream_get_buffer_attr_dylibloader_orig_pulse +#define pa_stream_set_buffer_attr pa_stream_set_buffer_attr_dylibloader_orig_pulse +#define pa_stream_update_sample_rate pa_stream_update_sample_rate_dylibloader_orig_pulse +#define pa_stream_proplist_update pa_stream_proplist_update_dylibloader_orig_pulse +#define pa_stream_proplist_remove pa_stream_proplist_remove_dylibloader_orig_pulse +#define pa_stream_set_monitor_stream pa_stream_set_monitor_stream_dylibloader_orig_pulse +#define pa_stream_get_monitor_stream pa_stream_get_monitor_stream_dylibloader_orig_pulse +#define pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name_dylibloader_orig_pulse +#define pa_context_get_sink_info_by_index pa_context_get_sink_info_by_index_dylibloader_orig_pulse +#define pa_context_get_sink_info_list pa_context_get_sink_info_list_dylibloader_orig_pulse +#define pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name_dylibloader_orig_pulse +#define pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_mute_by_name pa_context_set_sink_mute_by_name_dylibloader_orig_pulse +#define pa_context_suspend_sink_by_name pa_context_suspend_sink_by_name_dylibloader_orig_pulse +#define pa_context_suspend_sink_by_index pa_context_suspend_sink_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_port_by_index pa_context_set_sink_port_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_port_by_name pa_context_set_sink_port_by_name_dylibloader_orig_pulse +#define pa_context_get_source_info_by_name pa_context_get_source_info_by_name_dylibloader_orig_pulse +#define pa_context_get_source_info_by_index pa_context_get_source_info_by_index_dylibloader_orig_pulse +#define pa_context_get_source_info_list pa_context_get_source_info_list_dylibloader_orig_pulse +#define pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index_dylibloader_orig_pulse +#define pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name_dylibloader_orig_pulse +#define pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index_dylibloader_orig_pulse +#define pa_context_set_source_mute_by_name pa_context_set_source_mute_by_name_dylibloader_orig_pulse +#define pa_context_suspend_source_by_name pa_context_suspend_source_by_name_dylibloader_orig_pulse +#define pa_context_suspend_source_by_index pa_context_suspend_source_by_index_dylibloader_orig_pulse +#define pa_context_set_source_port_by_index pa_context_set_source_port_by_index_dylibloader_orig_pulse +#define pa_context_set_source_port_by_name pa_context_set_source_port_by_name_dylibloader_orig_pulse +#define pa_context_get_server_info pa_context_get_server_info_dylibloader_orig_pulse +#define pa_context_get_module_info pa_context_get_module_info_dylibloader_orig_pulse +#define pa_context_get_module_info_list pa_context_get_module_info_list_dylibloader_orig_pulse +#define pa_context_load_module pa_context_load_module_dylibloader_orig_pulse +#define pa_context_unload_module pa_context_unload_module_dylibloader_orig_pulse +#define pa_context_get_client_info pa_context_get_client_info_dylibloader_orig_pulse +#define pa_context_get_client_info_list pa_context_get_client_info_list_dylibloader_orig_pulse +#define pa_context_kill_client pa_context_kill_client_dylibloader_orig_pulse +#define pa_context_get_card_info_by_index pa_context_get_card_info_by_index_dylibloader_orig_pulse +#define pa_context_get_card_info_by_name pa_context_get_card_info_by_name_dylibloader_orig_pulse +#define pa_context_get_card_info_list pa_context_get_card_info_list_dylibloader_orig_pulse +#define pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index_dylibloader_orig_pulse +#define pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name_dylibloader_orig_pulse +#define pa_context_set_port_latency_offset pa_context_set_port_latency_offset_dylibloader_orig_pulse +#define pa_context_get_sink_input_info pa_context_get_sink_input_info_dylibloader_orig_pulse +#define pa_context_get_sink_input_info_list pa_context_get_sink_input_info_list_dylibloader_orig_pulse +#define pa_context_move_sink_input_by_name pa_context_move_sink_input_by_name_dylibloader_orig_pulse +#define pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_input_volume pa_context_set_sink_input_volume_dylibloader_orig_pulse +#define pa_context_set_sink_input_mute pa_context_set_sink_input_mute_dylibloader_orig_pulse +#define pa_context_kill_sink_input pa_context_kill_sink_input_dylibloader_orig_pulse +#define pa_context_get_source_output_info pa_context_get_source_output_info_dylibloader_orig_pulse +#define pa_context_get_source_output_info_list pa_context_get_source_output_info_list_dylibloader_orig_pulse +#define pa_context_move_source_output_by_name pa_context_move_source_output_by_name_dylibloader_orig_pulse +#define pa_context_move_source_output_by_index pa_context_move_source_output_by_index_dylibloader_orig_pulse +#define pa_context_set_source_output_volume pa_context_set_source_output_volume_dylibloader_orig_pulse +#define pa_context_set_source_output_mute pa_context_set_source_output_mute_dylibloader_orig_pulse +#define pa_context_kill_source_output pa_context_kill_source_output_dylibloader_orig_pulse +#define pa_context_stat pa_context_stat_dylibloader_orig_pulse +#define pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name_dylibloader_orig_pulse +#define pa_context_get_sample_info_by_index pa_context_get_sample_info_by_index_dylibloader_orig_pulse +#define pa_context_get_sample_info_list pa_context_get_sample_info_list_dylibloader_orig_pulse +#define pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name_dylibloader_orig_pulse +#define pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index_dylibloader_orig_pulse +#define pa_context_get_autoload_info_list pa_context_get_autoload_info_list_dylibloader_orig_pulse +#define pa_context_add_autoload pa_context_add_autoload_dylibloader_orig_pulse +#define pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name_dylibloader_orig_pulse +#define pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index_dylibloader_orig_pulse +#define pa_context_subscribe pa_context_subscribe_dylibloader_orig_pulse +#define pa_context_set_subscribe_callback pa_context_set_subscribe_callback_dylibloader_orig_pulse +#define pa_stream_connect_upload pa_stream_connect_upload_dylibloader_orig_pulse +#define pa_stream_finish_upload pa_stream_finish_upload_dylibloader_orig_pulse +#define pa_context_remove_sample pa_context_remove_sample_dylibloader_orig_pulse +#define pa_context_play_sample pa_context_play_sample_dylibloader_orig_pulse +#define pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist_dylibloader_orig_pulse +#define pa_strerror pa_strerror_dylibloader_orig_pulse +#define pa_xmalloc pa_xmalloc_dylibloader_orig_pulse +#define pa_xmalloc0 pa_xmalloc0_dylibloader_orig_pulse +#define pa_xrealloc pa_xrealloc_dylibloader_orig_pulse +#define pa_xfree pa_xfree_dylibloader_orig_pulse +#define pa_xstrdup pa_xstrdup_dylibloader_orig_pulse +#define pa_xstrndup pa_xstrndup_dylibloader_orig_pulse +#define pa_xmemdup pa_xmemdup_dylibloader_orig_pulse +#define pa_utf8_valid pa_utf8_valid_dylibloader_orig_pulse +#define pa_ascii_valid pa_ascii_valid_dylibloader_orig_pulse +#define pa_utf8_filter pa_utf8_filter_dylibloader_orig_pulse +#define pa_ascii_filter pa_ascii_filter_dylibloader_orig_pulse +#define pa_utf8_to_locale pa_utf8_to_locale_dylibloader_orig_pulse +#define pa_locale_to_utf8 pa_locale_to_utf8_dylibloader_orig_pulse +#define pa_threaded_mainloop_new pa_threaded_mainloop_new_dylibloader_orig_pulse +#define pa_threaded_mainloop_free pa_threaded_mainloop_free_dylibloader_orig_pulse +#define pa_threaded_mainloop_start pa_threaded_mainloop_start_dylibloader_orig_pulse +#define pa_threaded_mainloop_stop pa_threaded_mainloop_stop_dylibloader_orig_pulse +#define pa_threaded_mainloop_lock pa_threaded_mainloop_lock_dylibloader_orig_pulse +#define pa_threaded_mainloop_unlock pa_threaded_mainloop_unlock_dylibloader_orig_pulse +#define pa_threaded_mainloop_wait pa_threaded_mainloop_wait_dylibloader_orig_pulse +#define pa_threaded_mainloop_signal pa_threaded_mainloop_signal_dylibloader_orig_pulse +#define pa_threaded_mainloop_accept pa_threaded_mainloop_accept_dylibloader_orig_pulse +#define pa_threaded_mainloop_get_retval pa_threaded_mainloop_get_retval_dylibloader_orig_pulse +#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_orig_pulse +#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_orig_pulse +#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_orig_pulse +#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_orig_pulse +#define pa_mainloop_new pa_mainloop_new_dylibloader_orig_pulse +#define pa_mainloop_free pa_mainloop_free_dylibloader_orig_pulse +#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_orig_pulse +#define pa_mainloop_poll pa_mainloop_poll_dylibloader_orig_pulse +#define pa_mainloop_dispatch pa_mainloop_dispatch_dylibloader_orig_pulse +#define pa_mainloop_get_retval pa_mainloop_get_retval_dylibloader_orig_pulse +#define pa_mainloop_iterate pa_mainloop_iterate_dylibloader_orig_pulse +#define pa_mainloop_run pa_mainloop_run_dylibloader_orig_pulse +#define pa_mainloop_get_api pa_mainloop_get_api_dylibloader_orig_pulse +#define pa_mainloop_quit pa_mainloop_quit_dylibloader_orig_pulse +#define pa_mainloop_wakeup pa_mainloop_wakeup_dylibloader_orig_pulse +#define pa_mainloop_set_poll_func pa_mainloop_set_poll_func_dylibloader_orig_pulse +#define pa_signal_init pa_signal_init_dylibloader_orig_pulse +#define pa_signal_done pa_signal_done_dylibloader_orig_pulse +#define pa_signal_new pa_signal_new_dylibloader_orig_pulse +#define pa_signal_free pa_signal_free_dylibloader_orig_pulse +#define pa_signal_set_destroy pa_signal_set_destroy_dylibloader_orig_pulse +#define pa_get_user_name pa_get_user_name_dylibloader_orig_pulse +#define pa_get_host_name pa_get_host_name_dylibloader_orig_pulse +#define pa_get_fqdn pa_get_fqdn_dylibloader_orig_pulse +#define pa_get_home_dir pa_get_home_dir_dylibloader_orig_pulse +#define pa_get_binary_name pa_get_binary_name_dylibloader_orig_pulse +#define pa_path_get_filename pa_path_get_filename_dylibloader_orig_pulse +#define pa_msleep pa_msleep_dylibloader_orig_pulse +#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_orig_pulse +#define pa_gettimeofday pa_gettimeofday_dylibloader_orig_pulse +#define pa_timeval_diff pa_timeval_diff_dylibloader_orig_pulse +#define pa_timeval_cmp pa_timeval_cmp_dylibloader_orig_pulse +#define pa_timeval_age pa_timeval_age_dylibloader_orig_pulse +#define pa_timeval_add pa_timeval_add_dylibloader_orig_pulse +#define pa_timeval_sub pa_timeval_sub_dylibloader_orig_pulse +#define pa_timeval_store pa_timeval_store_dylibloader_orig_pulse +#define pa_timeval_load pa_timeval_load_dylibloader_orig_pulse +#define pa_rtclock_now pa_rtclock_now_dylibloader_orig_pulse +#include <pulse/pulseaudio.h> +#undef pa_get_library_version +#undef pa_bytes_per_second +#undef pa_frame_size +#undef pa_sample_size +#undef pa_sample_size_of_format +#undef pa_bytes_to_usec +#undef pa_usec_to_bytes +#undef pa_sample_spec_init +#undef pa_sample_format_valid +#undef pa_sample_rate_valid +#undef pa_channels_valid +#undef pa_sample_spec_valid +#undef pa_sample_spec_equal +#undef pa_sample_format_to_string +#undef pa_parse_sample_format +#undef pa_sample_spec_snprint +#undef pa_bytes_snprint +#undef pa_sample_format_is_le +#undef pa_sample_format_is_be +#undef pa_direction_valid +#undef pa_direction_to_string +#undef pa_mainloop_api_once +#undef pa_proplist_new +#undef pa_proplist_free +#undef pa_proplist_key_valid +#undef pa_proplist_sets +#undef pa_proplist_setp +#undef pa_proplist_setf +#undef pa_proplist_set +#undef pa_proplist_gets +#undef pa_proplist_get +#undef pa_proplist_update +#undef pa_proplist_unset +#undef pa_proplist_unset_many +#undef pa_proplist_iterate +#undef pa_proplist_to_string +#undef pa_proplist_to_string_sep +#undef pa_proplist_from_string +#undef pa_proplist_contains +#undef pa_proplist_clear +#undef pa_proplist_copy +#undef pa_proplist_size +#undef pa_proplist_isempty +#undef pa_proplist_equal +#undef pa_channel_map_init +#undef pa_channel_map_init_mono +#undef pa_channel_map_init_stereo +#undef pa_channel_map_init_auto +#undef pa_channel_map_init_extend +#undef pa_channel_position_to_string +#undef pa_channel_position_from_string +#undef pa_channel_position_to_pretty_string +#undef pa_channel_map_snprint +#undef pa_channel_map_parse +#undef pa_channel_map_equal +#undef pa_channel_map_valid +#undef pa_channel_map_compatible +#undef pa_channel_map_superset +#undef pa_channel_map_can_balance +#undef pa_channel_map_can_fade +#undef pa_channel_map_can_lfe_balance +#undef pa_channel_map_to_name +#undef pa_channel_map_to_pretty_name +#undef pa_channel_map_has_position +#undef pa_channel_map_mask +#undef pa_encoding_to_string +#undef pa_encoding_from_string +#undef pa_format_info_new +#undef pa_format_info_copy +#undef pa_format_info_free +#undef pa_format_info_valid +#undef pa_format_info_is_pcm +#undef pa_format_info_is_compatible +#undef pa_format_info_snprint +#undef pa_format_info_from_string +#undef pa_format_info_from_sample_spec +#undef pa_format_info_to_sample_spec +#undef pa_format_info_get_prop_type +#undef pa_format_info_get_prop_int +#undef pa_format_info_get_prop_int_range +#undef pa_format_info_get_prop_int_array +#undef pa_format_info_get_prop_string +#undef pa_format_info_get_prop_string_array +#undef pa_format_info_free_string_array +#undef pa_format_info_get_sample_format +#undef pa_format_info_get_rate +#undef pa_format_info_get_channels +#undef pa_format_info_get_channel_map +#undef pa_format_info_set_prop_int +#undef pa_format_info_set_prop_int_array +#undef pa_format_info_set_prop_int_range +#undef pa_format_info_set_prop_string +#undef pa_format_info_set_prop_string_array +#undef pa_format_info_set_sample_format +#undef pa_format_info_set_rate +#undef pa_format_info_set_channels +#undef pa_format_info_set_channel_map +#undef pa_operation_ref +#undef pa_operation_unref +#undef pa_operation_cancel +#undef pa_operation_get_state +#undef pa_operation_set_state_callback +#undef pa_context_new +#undef pa_context_new_with_proplist +#undef pa_context_unref +#undef pa_context_ref +#undef pa_context_set_state_callback +#undef pa_context_set_event_callback +#undef pa_context_errno +#undef pa_context_is_pending +#undef pa_context_get_state +#undef pa_context_connect +#undef pa_context_disconnect +#undef pa_context_drain +#undef pa_context_exit_daemon +#undef pa_context_set_default_sink +#undef pa_context_set_default_source +#undef pa_context_is_local +#undef pa_context_set_name +#undef pa_context_get_server +#undef pa_context_get_protocol_version +#undef pa_context_get_server_protocol_version +#undef pa_context_proplist_update +#undef pa_context_proplist_remove +#undef pa_context_get_index +#undef pa_context_rttime_new +#undef pa_context_rttime_restart +#undef pa_context_get_tile_size +#undef pa_context_load_cookie_from_file +#undef pa_cvolume_equal +#undef pa_cvolume_init +#undef pa_cvolume_set +#undef pa_cvolume_snprint +#undef pa_sw_cvolume_snprint_dB +#undef pa_cvolume_snprint_verbose +#undef pa_volume_snprint +#undef pa_sw_volume_snprint_dB +#undef pa_volume_snprint_verbose +#undef pa_cvolume_avg +#undef pa_cvolume_avg_mask +#undef pa_cvolume_max +#undef pa_cvolume_max_mask +#undef pa_cvolume_min +#undef pa_cvolume_min_mask +#undef pa_cvolume_valid +#undef pa_cvolume_channels_equal_to +#undef pa_sw_volume_multiply +#undef pa_sw_cvolume_multiply +#undef pa_sw_cvolume_multiply_scalar +#undef pa_sw_volume_divide +#undef pa_sw_cvolume_divide +#undef pa_sw_cvolume_divide_scalar +#undef pa_sw_volume_from_dB +#undef pa_sw_volume_to_dB +#undef pa_sw_volume_from_linear +#undef pa_sw_volume_to_linear +#undef pa_cvolume_remap +#undef pa_cvolume_compatible +#undef pa_cvolume_compatible_with_channel_map +#undef pa_cvolume_get_balance +#undef pa_cvolume_set_balance +#undef pa_cvolume_get_fade +#undef pa_cvolume_set_fade +#undef pa_cvolume_get_lfe_balance +#undef pa_cvolume_set_lfe_balance +#undef pa_cvolume_scale +#undef pa_cvolume_scale_mask +#undef pa_cvolume_set_position +#undef pa_cvolume_get_position +#undef pa_cvolume_merge +#undef pa_cvolume_inc_clamp +#undef pa_cvolume_inc +#undef pa_cvolume_dec +#undef pa_stream_new +#undef pa_stream_new_with_proplist +#undef pa_stream_new_extended +#undef pa_stream_unref +#undef pa_stream_ref +#undef pa_stream_get_state +#undef pa_stream_get_context +#undef pa_stream_get_index +#undef pa_stream_get_device_index +#undef pa_stream_get_device_name +#undef pa_stream_is_suspended +#undef pa_stream_is_corked +#undef pa_stream_connect_playback +#undef pa_stream_connect_record +#undef pa_stream_disconnect +#undef pa_stream_begin_write +#undef pa_stream_cancel_write +#undef pa_stream_write +#undef pa_stream_write_ext_free +#undef pa_stream_peek +#undef pa_stream_drop +#undef pa_stream_writable_size +#undef pa_stream_readable_size +#undef pa_stream_drain +#undef pa_stream_update_timing_info +#undef pa_stream_set_state_callback +#undef pa_stream_set_write_callback +#undef pa_stream_set_read_callback +#undef pa_stream_set_overflow_callback +#undef pa_stream_get_underflow_index +#undef pa_stream_set_underflow_callback +#undef pa_stream_set_started_callback +#undef pa_stream_set_latency_update_callback +#undef pa_stream_set_moved_callback +#undef pa_stream_set_suspended_callback +#undef pa_stream_set_event_callback +#undef pa_stream_set_buffer_attr_callback +#undef pa_stream_cork +#undef pa_stream_flush +#undef pa_stream_prebuf +#undef pa_stream_trigger +#undef pa_stream_set_name +#undef pa_stream_get_time +#undef pa_stream_get_latency +#undef pa_stream_get_timing_info +#undef pa_stream_get_sample_spec +#undef pa_stream_get_channel_map +#undef pa_stream_get_format_info +#undef pa_stream_get_buffer_attr +#undef pa_stream_set_buffer_attr +#undef pa_stream_update_sample_rate +#undef pa_stream_proplist_update +#undef pa_stream_proplist_remove +#undef pa_stream_set_monitor_stream +#undef pa_stream_get_monitor_stream +#undef pa_context_get_sink_info_by_name +#undef pa_context_get_sink_info_by_index +#undef pa_context_get_sink_info_list +#undef pa_context_set_sink_volume_by_index +#undef pa_context_set_sink_volume_by_name +#undef pa_context_set_sink_mute_by_index +#undef pa_context_set_sink_mute_by_name +#undef pa_context_suspend_sink_by_name +#undef pa_context_suspend_sink_by_index +#undef pa_context_set_sink_port_by_index +#undef pa_context_set_sink_port_by_name +#undef pa_context_get_source_info_by_name +#undef pa_context_get_source_info_by_index +#undef pa_context_get_source_info_list +#undef pa_context_set_source_volume_by_index +#undef pa_context_set_source_volume_by_name +#undef pa_context_set_source_mute_by_index +#undef pa_context_set_source_mute_by_name +#undef pa_context_suspend_source_by_name +#undef pa_context_suspend_source_by_index +#undef pa_context_set_source_port_by_index +#undef pa_context_set_source_port_by_name +#undef pa_context_get_server_info +#undef pa_context_get_module_info +#undef pa_context_get_module_info_list +#undef pa_context_load_module +#undef pa_context_unload_module +#undef pa_context_get_client_info +#undef pa_context_get_client_info_list +#undef pa_context_kill_client +#undef pa_context_get_card_info_by_index +#undef pa_context_get_card_info_by_name +#undef pa_context_get_card_info_list +#undef pa_context_set_card_profile_by_index +#undef pa_context_set_card_profile_by_name +#undef pa_context_set_port_latency_offset +#undef pa_context_get_sink_input_info +#undef pa_context_get_sink_input_info_list +#undef pa_context_move_sink_input_by_name +#undef pa_context_move_sink_input_by_index +#undef pa_context_set_sink_input_volume +#undef pa_context_set_sink_input_mute +#undef pa_context_kill_sink_input +#undef pa_context_get_source_output_info +#undef pa_context_get_source_output_info_list +#undef pa_context_move_source_output_by_name +#undef pa_context_move_source_output_by_index +#undef pa_context_set_source_output_volume +#undef pa_context_set_source_output_mute +#undef pa_context_kill_source_output +#undef pa_context_stat +#undef pa_context_get_sample_info_by_name +#undef pa_context_get_sample_info_by_index +#undef pa_context_get_sample_info_list +#undef pa_context_get_autoload_info_by_name +#undef pa_context_get_autoload_info_by_index +#undef pa_context_get_autoload_info_list +#undef pa_context_add_autoload +#undef pa_context_remove_autoload_by_name +#undef pa_context_remove_autoload_by_index +#undef pa_context_subscribe +#undef pa_context_set_subscribe_callback +#undef pa_stream_connect_upload +#undef pa_stream_finish_upload +#undef pa_context_remove_sample +#undef pa_context_play_sample +#undef pa_context_play_sample_with_proplist +#undef pa_strerror +#undef pa_xmalloc +#undef pa_xmalloc0 +#undef pa_xrealloc +#undef pa_xfree +#undef pa_xstrdup +#undef pa_xstrndup +#undef pa_xmemdup +#undef pa_utf8_valid +#undef pa_ascii_valid +#undef pa_utf8_filter +#undef pa_ascii_filter +#undef pa_utf8_to_locale +#undef pa_locale_to_utf8 +#undef pa_threaded_mainloop_new +#undef pa_threaded_mainloop_free +#undef pa_threaded_mainloop_start +#undef pa_threaded_mainloop_stop +#undef pa_threaded_mainloop_lock +#undef pa_threaded_mainloop_unlock +#undef pa_threaded_mainloop_wait +#undef pa_threaded_mainloop_signal +#undef pa_threaded_mainloop_accept +#undef pa_threaded_mainloop_get_retval +#undef pa_threaded_mainloop_get_api +#undef pa_threaded_mainloop_in_thread +#undef pa_threaded_mainloop_set_name +#undef pa_threaded_mainloop_once_unlocked +#undef pa_mainloop_new +#undef pa_mainloop_free +#undef pa_mainloop_prepare +#undef pa_mainloop_poll +#undef pa_mainloop_dispatch +#undef pa_mainloop_get_retval +#undef pa_mainloop_iterate +#undef pa_mainloop_run +#undef pa_mainloop_get_api +#undef pa_mainloop_quit +#undef pa_mainloop_wakeup +#undef pa_mainloop_set_poll_func +#undef pa_signal_init +#undef pa_signal_done +#undef pa_signal_new +#undef pa_signal_free +#undef pa_signal_set_destroy +#undef pa_get_user_name +#undef pa_get_host_name +#undef pa_get_fqdn +#undef pa_get_home_dir +#undef pa_get_binary_name +#undef pa_path_get_filename +#undef pa_msleep +#undef pa_thread_make_realtime +#undef pa_gettimeofday +#undef pa_timeval_diff +#undef pa_timeval_cmp +#undef pa_timeval_age +#undef pa_timeval_add +#undef pa_timeval_sub +#undef pa_timeval_store +#undef pa_timeval_load +#undef pa_rtclock_now +#include <dlfcn.h> +#include <stdio.h> +const char* (*pa_get_library_version_dylibloader_wrapper_pulse)( void); +size_t (*pa_bytes_per_second_dylibloader_wrapper_pulse)(const pa_sample_spec*); +size_t (*pa_frame_size_dylibloader_wrapper_pulse)(const pa_sample_spec*); +size_t (*pa_sample_size_dylibloader_wrapper_pulse)(const pa_sample_spec*); +size_t (*pa_sample_size_of_format_dylibloader_wrapper_pulse)( pa_sample_format_t); +pa_usec_t (*pa_bytes_to_usec_dylibloader_wrapper_pulse)( uint64_t,const pa_sample_spec*); +size_t (*pa_usec_to_bytes_dylibloader_wrapper_pulse)( pa_usec_t,const pa_sample_spec*); +pa_sample_spec* (*pa_sample_spec_init_dylibloader_wrapper_pulse)( pa_sample_spec*); +int (*pa_sample_format_valid_dylibloader_wrapper_pulse)( unsigned); +int (*pa_sample_rate_valid_dylibloader_wrapper_pulse)( uint32_t); +int (*pa_channels_valid_dylibloader_wrapper_pulse)( uint8_t); +int (*pa_sample_spec_valid_dylibloader_wrapper_pulse)(const pa_sample_spec*); +int (*pa_sample_spec_equal_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_sample_spec*); +const char* (*pa_sample_format_to_string_dylibloader_wrapper_pulse)( pa_sample_format_t); +pa_sample_format_t (*pa_parse_sample_format_dylibloader_wrapper_pulse)(const char*); +char* (*pa_sample_spec_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_sample_spec*); +char* (*pa_bytes_snprint_dylibloader_wrapper_pulse)( char*, size_t, unsigned); +int (*pa_sample_format_is_le_dylibloader_wrapper_pulse)( pa_sample_format_t); +int (*pa_sample_format_is_be_dylibloader_wrapper_pulse)( pa_sample_format_t); +int (*pa_direction_valid_dylibloader_wrapper_pulse)( pa_direction_t); +const char* (*pa_direction_to_string_dylibloader_wrapper_pulse)( pa_direction_t); +void (*pa_mainloop_api_once_dylibloader_wrapper_pulse)( pa_mainloop_api*, void*, void*); +pa_proplist* (*pa_proplist_new_dylibloader_wrapper_pulse)( void); +void (*pa_proplist_free_dylibloader_wrapper_pulse)( pa_proplist*); +int (*pa_proplist_key_valid_dylibloader_wrapper_pulse)(const char*); +int (*pa_proplist_sets_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*); +int (*pa_proplist_setp_dylibloader_wrapper_pulse)( pa_proplist*,const char*); +int (*pa_proplist_setf_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*,...); +int (*pa_proplist_set_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void*, size_t); +const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)(const pa_proplist*,const char*); +int (*pa_proplist_get_dylibloader_wrapper_pulse)(const pa_proplist*,const char*,const void**, size_t*); +void (*pa_proplist_update_dylibloader_wrapper_pulse)( pa_proplist*, pa_update_mode_t,const pa_proplist*); +int (*pa_proplist_unset_dylibloader_wrapper_pulse)( pa_proplist*,const char*); +int (*pa_proplist_unset_many_dylibloader_wrapper_pulse)( pa_proplist*,const char* []); +const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)(const pa_proplist*, void**); +char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)(const pa_proplist*); +char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)(const pa_proplist*,const char*); +pa_proplist* (*pa_proplist_from_string_dylibloader_wrapper_pulse)(const char*); +int (*pa_proplist_contains_dylibloader_wrapper_pulse)(const pa_proplist*,const char*); +void (*pa_proplist_clear_dylibloader_wrapper_pulse)( pa_proplist*); +pa_proplist* (*pa_proplist_copy_dylibloader_wrapper_pulse)(const pa_proplist*); +unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)(const pa_proplist*); +int (*pa_proplist_isempty_dylibloader_wrapper_pulse)(const pa_proplist*); +int (*pa_proplist_equal_dylibloader_wrapper_pulse)(const pa_proplist*,const pa_proplist*); +pa_channel_map* (*pa_channel_map_init_dylibloader_wrapper_pulse)( pa_channel_map*); +pa_channel_map* (*pa_channel_map_init_mono_dylibloader_wrapper_pulse)( pa_channel_map*); +pa_channel_map* (*pa_channel_map_init_stereo_dylibloader_wrapper_pulse)( pa_channel_map*); +pa_channel_map* (*pa_channel_map_init_auto_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t); +pa_channel_map* (*pa_channel_map_init_extend_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t); +const char* (*pa_channel_position_to_string_dylibloader_wrapper_pulse)( pa_channel_position_t); +pa_channel_position_t (*pa_channel_position_from_string_dylibloader_wrapper_pulse)(const char*); +const char* (*pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse)( pa_channel_position_t); +char* (*pa_channel_map_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_channel_map*); +pa_channel_map* (*pa_channel_map_parse_dylibloader_wrapper_pulse)( pa_channel_map*,const char*); +int (*pa_channel_map_equal_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*); +int (*pa_channel_map_valid_dylibloader_wrapper_pulse)(const pa_channel_map*); +int (*pa_channel_map_compatible_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_sample_spec*); +int (*pa_channel_map_superset_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*); +int (*pa_channel_map_can_balance_dylibloader_wrapper_pulse)(const pa_channel_map*); +int (*pa_channel_map_can_fade_dylibloader_wrapper_pulse)(const pa_channel_map*); +int (*pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse)(const pa_channel_map*); +const char* (*pa_channel_map_to_name_dylibloader_wrapper_pulse)(const pa_channel_map*); +const char* (*pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse)(const pa_channel_map*); +int (*pa_channel_map_has_position_dylibloader_wrapper_pulse)(const pa_channel_map*, pa_channel_position_t); +pa_channel_position_mask_t (*pa_channel_map_mask_dylibloader_wrapper_pulse)(const pa_channel_map*); +const char* (*pa_encoding_to_string_dylibloader_wrapper_pulse)( pa_encoding_t); +pa_encoding_t (*pa_encoding_from_string_dylibloader_wrapper_pulse)(const char*); +pa_format_info* (*pa_format_info_new_dylibloader_wrapper_pulse)( void); +pa_format_info* (*pa_format_info_copy_dylibloader_wrapper_pulse)(const pa_format_info*); +void (*pa_format_info_free_dylibloader_wrapper_pulse)( pa_format_info*); +int (*pa_format_info_valid_dylibloader_wrapper_pulse)(const pa_format_info*); +int (*pa_format_info_is_pcm_dylibloader_wrapper_pulse)(const pa_format_info*); +int (*pa_format_info_is_compatible_dylibloader_wrapper_pulse)(const pa_format_info*,const pa_format_info*); +char* (*pa_format_info_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_format_info*); +pa_format_info* (*pa_format_info_from_string_dylibloader_wrapper_pulse)(const char*); +pa_format_info* (*pa_format_info_from_sample_spec_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_channel_map*); +int (*pa_format_info_to_sample_spec_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_spec*, pa_channel_map*); +pa_prop_type_t (*pa_format_info_get_prop_type_dylibloader_wrapper_pulse)(const pa_format_info*,const char*); +int (*pa_format_info_get_prop_int_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*); +int (*pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*, int*); +int (*pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int**, int*); +int (*pa_format_info_get_prop_string_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char**); +int (*pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char***, int*); +void (*pa_format_info_free_string_array_dylibloader_wrapper_pulse)( char**, int); +int (*pa_format_info_get_sample_format_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_format_t*); +int (*pa_format_info_get_rate_dylibloader_wrapper_pulse)(const pa_format_info*, uint32_t*); +int (*pa_format_info_get_channels_dylibloader_wrapper_pulse)(const pa_format_info*, uint8_t*); +int (*pa_format_info_get_channel_map_dylibloader_wrapper_pulse)(const pa_format_info*, pa_channel_map*); +void (*pa_format_info_set_prop_int_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int); +void (*pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const int*, int); +void (*pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int, int); +void (*pa_format_info_set_prop_string_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char*); +void (*pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char**, int); +void (*pa_format_info_set_sample_format_dylibloader_wrapper_pulse)( pa_format_info*, pa_sample_format_t); +void (*pa_format_info_set_rate_dylibloader_wrapper_pulse)( pa_format_info*, int); +void (*pa_format_info_set_channels_dylibloader_wrapper_pulse)( pa_format_info*, int); +void (*pa_format_info_set_channel_map_dylibloader_wrapper_pulse)( pa_format_info*,const pa_channel_map*); +pa_operation* (*pa_operation_ref_dylibloader_wrapper_pulse)( pa_operation*); +void (*pa_operation_unref_dylibloader_wrapper_pulse)( pa_operation*); +void (*pa_operation_cancel_dylibloader_wrapper_pulse)( pa_operation*); +pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)(const pa_operation*); +void (*pa_operation_set_state_callback_dylibloader_wrapper_pulse)( pa_operation*, pa_operation_notify_cb_t, void*); +pa_context* (*pa_context_new_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*); +pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*,const pa_proplist*); +void (*pa_context_unref_dylibloader_wrapper_pulse)( pa_context*); +pa_context* (*pa_context_ref_dylibloader_wrapper_pulse)( pa_context*); +void (*pa_context_set_state_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*); +void (*pa_context_set_event_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_event_cb_t, void*); +int (*pa_context_errno_dylibloader_wrapper_pulse)(const pa_context*); +int (*pa_context_is_pending_dylibloader_wrapper_pulse)(const pa_context*); +pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)(const pa_context*); +int (*pa_context_connect_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_flags_t,const pa_spawn_api*); +void (*pa_context_disconnect_dylibloader_wrapper_pulse)( pa_context*); +pa_operation* (*pa_context_drain_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*); +pa_operation* (*pa_context_exit_daemon_dylibloader_wrapper_pulse)( pa_context*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_default_sink_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_default_source_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +int (*pa_context_is_local_dylibloader_wrapper_pulse)(const pa_context*); +pa_operation* (*pa_context_set_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +const char* (*pa_context_get_server_dylibloader_wrapper_pulse)(const pa_context*); +uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)(const pa_context*); +uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)(const pa_context*); +pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t,const pa_proplist*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_proplist_remove_dylibloader_wrapper_pulse)( pa_context*,const char* [], pa_context_success_cb_t, void*); +uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)(const pa_context*); +pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)(const pa_context*, pa_usec_t, pa_time_event_cb_t, void*); +void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)(const pa_context*, pa_time_event*, pa_usec_t); +size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)(const pa_context*,const pa_sample_spec*); +int (*pa_context_load_cookie_from_file_dylibloader_wrapper_pulse)( pa_context*,const char*); +int (*pa_cvolume_equal_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_cvolume*); +pa_cvolume* (*pa_cvolume_init_dylibloader_wrapper_pulse)( pa_cvolume*); +pa_cvolume* (*pa_cvolume_set_dylibloader_wrapper_pulse)( pa_cvolume*, unsigned, pa_volume_t); +char* (*pa_cvolume_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*); +char* (*pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*); +char* (*pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*,const pa_channel_map*, int); +char* (*pa_volume_snprint_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t); +char* (*pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t); +char* (*pa_volume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t, int); +pa_volume_t (*pa_cvolume_avg_dylibloader_wrapper_pulse)(const pa_cvolume*); +pa_volume_t (*pa_cvolume_avg_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t); +pa_volume_t (*pa_cvolume_max_dylibloader_wrapper_pulse)(const pa_cvolume*); +pa_volume_t (*pa_cvolume_max_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t); +pa_volume_t (*pa_cvolume_min_dylibloader_wrapper_pulse)(const pa_cvolume*); +pa_volume_t (*pa_cvolume_min_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t); +int (*pa_cvolume_valid_dylibloader_wrapper_pulse)(const pa_cvolume*); +int (*pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse)(const pa_cvolume*, pa_volume_t); +pa_volume_t (*pa_sw_volume_multiply_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t); +pa_cvolume* (*pa_sw_cvolume_multiply_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*); +pa_cvolume* (*pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t); +pa_volume_t (*pa_sw_volume_divide_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t); +pa_cvolume* (*pa_sw_cvolume_divide_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*); +pa_cvolume* (*pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t); +pa_volume_t (*pa_sw_volume_from_dB_dylibloader_wrapper_pulse)( double); +double (*pa_sw_volume_to_dB_dylibloader_wrapper_pulse)( pa_volume_t); +pa_volume_t (*pa_sw_volume_from_linear_dylibloader_wrapper_pulse)( double); +double (*pa_sw_volume_to_linear_dylibloader_wrapper_pulse)( pa_volume_t); +pa_cvolume* (*pa_cvolume_remap_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*,const pa_channel_map*); +int (*pa_cvolume_compatible_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_sample_spec*); +int (*pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +float (*pa_cvolume_get_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +pa_cvolume* (*pa_cvolume_set_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float); +float (*pa_cvolume_get_fade_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +pa_cvolume* (*pa_cvolume_set_fade_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float); +float (*pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +pa_cvolume* (*pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float); +pa_cvolume* (*pa_cvolume_scale_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t); +pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t,const pa_channel_map*, pa_channel_position_mask_t); +pa_cvolume* (*pa_cvolume_set_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t, pa_volume_t); +pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_t); +pa_cvolume* (*pa_cvolume_merge_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*); +pa_cvolume* (*pa_cvolume_inc_clamp_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_volume_t); +pa_cvolume* (*pa_cvolume_inc_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t); +pa_cvolume* (*pa_cvolume_dec_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t); +pa_stream* (*pa_stream_new_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*); +pa_stream* (*pa_stream_new_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*, pa_proplist*); +pa_stream* (*pa_stream_new_extended_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_format_info**, unsigned int, pa_proplist*); +void (*pa_stream_unref_dylibloader_wrapper_pulse)( pa_stream*); +pa_stream* (*pa_stream_ref_dylibloader_wrapper_pulse)( pa_stream*); +pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)(const pa_stream*); +pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)(const pa_stream*); +uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)(const pa_stream*); +uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)(const pa_stream*); +const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)(const pa_stream*); +int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)(const pa_stream*); +int (*pa_stream_is_corked_dylibloader_wrapper_pulse)(const pa_stream*); +int (*pa_stream_connect_playback_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t,const pa_cvolume*, pa_stream*); +int (*pa_stream_connect_record_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t); +int (*pa_stream_disconnect_dylibloader_wrapper_pulse)( pa_stream*); +int (*pa_stream_begin_write_dylibloader_wrapper_pulse)( pa_stream*, void**, size_t*); +int (*pa_stream_cancel_write_dylibloader_wrapper_pulse)( pa_stream*); +int (*pa_stream_write_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t); +int (*pa_stream_write_ext_free_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, void*, int64_t, pa_seek_mode_t); +int (*pa_stream_peek_dylibloader_wrapper_pulse)( pa_stream*,const void**, size_t*); +int (*pa_stream_drop_dylibloader_wrapper_pulse)( pa_stream*); +size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)(const pa_stream*); +size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)(const pa_stream*); +pa_operation* (*pa_stream_drain_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_update_timing_info_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +void (*pa_stream_set_state_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +void (*pa_stream_set_write_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*); +void (*pa_stream_set_read_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*); +void (*pa_stream_set_overflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)(const pa_stream*); +void (*pa_stream_set_underflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +void (*pa_stream_set_started_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +void (*pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +void (*pa_stream_set_moved_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +void (*pa_stream_set_suspended_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +void (*pa_stream_set_event_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_event_cb_t, void*); +void (*pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +pa_operation* (*pa_stream_cork_dylibloader_wrapper_pulse)( pa_stream*, int, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_flush_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_prebuf_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_trigger_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_set_name_dylibloader_wrapper_pulse)( pa_stream*,const char*, pa_stream_success_cb_t, void*); +int (*pa_stream_get_time_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*); +int (*pa_stream_get_latency_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*, int*); +const pa_timing_info* (*pa_stream_get_timing_info_dylibloader_wrapper_pulse)( pa_stream*); +const pa_sample_spec* (*pa_stream_get_sample_spec_dylibloader_wrapper_pulse)( pa_stream*); +const pa_channel_map* (*pa_stream_get_channel_map_dylibloader_wrapper_pulse)( pa_stream*); +const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)(const pa_stream*); +const pa_buffer_attr* (*pa_stream_get_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*); +pa_operation* (*pa_stream_set_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*,const pa_buffer_attr*, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_update_sample_rate_dylibloader_wrapper_pulse)( pa_stream*, uint32_t, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_proplist_update_dylibloader_wrapper_pulse)( pa_stream*, pa_update_mode_t, pa_proplist*, pa_stream_success_cb_t, void*); +pa_operation* (*pa_stream_proplist_remove_dylibloader_wrapper_pulse)( pa_stream*,const char* [], pa_stream_success_cb_t, void*); +int (*pa_stream_set_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*, uint32_t); +uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)(const pa_stream*); +pa_operation* (*pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sink_info_cb_t, void*); +pa_operation* (*pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_info_cb_t, void*); +pa_operation* (*pa_context_get_sink_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_info_cb_t, void*); +pa_operation* (*pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_get_source_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_source_info_cb_t, void*); +pa_operation* (*pa_context_get_source_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_info_cb_t, void*); +pa_operation* (*pa_context_get_source_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_info_cb_t, void*); +pa_operation* (*pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_suspend_source_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_suspend_source_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_get_server_info_dylibloader_wrapper_pulse)( pa_context*, pa_server_info_cb_t, void*); +pa_operation* (*pa_context_get_module_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_module_info_cb_t, void*); +pa_operation* (*pa_context_get_module_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_module_info_cb_t, void*); +pa_operation* (*pa_context_load_module_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_index_cb_t, void*); +pa_operation* (*pa_context_unload_module_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_get_client_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_client_info_cb_t, void*); +pa_operation* (*pa_context_get_client_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_client_info_cb_t, void*); +pa_operation* (*pa_context_kill_client_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_get_card_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_card_info_cb_t, void*); +pa_operation* (*pa_context_get_card_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_card_info_cb_t, void*); +pa_operation* (*pa_context_get_card_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_card_info_cb_t, void*); +pa_operation* (*pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_port_latency_offset_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, int64_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_get_sink_input_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_input_info_cb_t, void*); +pa_operation* (*pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_input_info_cb_t, void*); +pa_operation* (*pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_input_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_sink_input_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_kill_sink_input_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_get_source_output_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_output_info_cb_t, void*); +pa_operation* (*pa_context_get_source_output_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_output_info_cb_t, void*); +pa_operation* (*pa_context_move_source_output_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_move_source_output_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_output_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_set_source_output_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_kill_source_output_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_stat_dylibloader_wrapper_pulse)( pa_context*, pa_stat_info_cb_t, void*); +pa_operation* (*pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sample_info_cb_t, void*); +pa_operation* (*pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sample_info_cb_t, void*); +pa_operation* (*pa_context_get_sample_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sample_info_cb_t, void*); +pa_operation* (*pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_autoload_info_cb_t, void*); +pa_operation* (*pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_autoload_info_cb_t, void*); +pa_operation* (*pa_context_get_autoload_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_autoload_info_cb_t, void*); +pa_operation* (*pa_context_add_autoload_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t,const char*,const char*, pa_context_index_cb_t, void*); +pa_operation* (*pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_subscribe_dylibloader_wrapper_pulse)( pa_context*, pa_subscription_mask_t, pa_context_success_cb_t, void*); +void (*pa_context_set_subscribe_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_subscribe_cb_t, void*); +int (*pa_stream_connect_upload_dylibloader_wrapper_pulse)( pa_stream*, size_t); +int (*pa_stream_finish_upload_dylibloader_wrapper_pulse)( pa_stream*); +pa_operation* (*pa_context_remove_sample_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_play_sample_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_context_success_cb_t, void*); +pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t,const pa_proplist*, pa_context_play_sample_cb_t, void*); +const char* (*pa_strerror_dylibloader_wrapper_pulse)( int); +void* (*pa_xmalloc_dylibloader_wrapper_pulse)( size_t); +void* (*pa_xmalloc0_dylibloader_wrapper_pulse)( size_t); +void* (*pa_xrealloc_dylibloader_wrapper_pulse)( void*, size_t); +void (*pa_xfree_dylibloader_wrapper_pulse)( void*); +char* (*pa_xstrdup_dylibloader_wrapper_pulse)(const char*); +char* (*pa_xstrndup_dylibloader_wrapper_pulse)(const char*, size_t); +void* (*pa_xmemdup_dylibloader_wrapper_pulse)(const void*, size_t); +char* (*pa_utf8_valid_dylibloader_wrapper_pulse)(const char*); +char* (*pa_ascii_valid_dylibloader_wrapper_pulse)(const char*); +char* (*pa_utf8_filter_dylibloader_wrapper_pulse)(const char*); +char* (*pa_ascii_filter_dylibloader_wrapper_pulse)(const char*); +char* (*pa_utf8_to_locale_dylibloader_wrapper_pulse)(const char*); +char* (*pa_locale_to_utf8_dylibloader_wrapper_pulse)(const char*); +pa_threaded_mainloop* (*pa_threaded_mainloop_new_dylibloader_wrapper_pulse)( void); +void (*pa_threaded_mainloop_free_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +int (*pa_threaded_mainloop_start_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +void (*pa_threaded_mainloop_stop_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +void (*pa_threaded_mainloop_lock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +void (*pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +void (*pa_threaded_mainloop_wait_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +void (*pa_threaded_mainloop_signal_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, int); +void (*pa_threaded_mainloop_accept_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_threaded_mainloop*); +pa_mainloop_api* (*pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +int (*pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +void (*pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse)( pa_threaded_mainloop*,const char*); +void (*pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, void*, void*); +pa_mainloop* (*pa_mainloop_new_dylibloader_wrapper_pulse)( void); +void (*pa_mainloop_free_dylibloader_wrapper_pulse)( pa_mainloop*); +int (*pa_mainloop_prepare_dylibloader_wrapper_pulse)( pa_mainloop*, int); +int (*pa_mainloop_poll_dylibloader_wrapper_pulse)( pa_mainloop*); +int (*pa_mainloop_dispatch_dylibloader_wrapper_pulse)( pa_mainloop*); +int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_mainloop*); +int (*pa_mainloop_iterate_dylibloader_wrapper_pulse)( pa_mainloop*, int, int*); +int (*pa_mainloop_run_dylibloader_wrapper_pulse)( pa_mainloop*, int*); +pa_mainloop_api* (*pa_mainloop_get_api_dylibloader_wrapper_pulse)( pa_mainloop*); +void (*pa_mainloop_quit_dylibloader_wrapper_pulse)( pa_mainloop*, int); +void (*pa_mainloop_wakeup_dylibloader_wrapper_pulse)( pa_mainloop*); +void (*pa_mainloop_set_poll_func_dylibloader_wrapper_pulse)( pa_mainloop*, pa_poll_func, void*); +int (*pa_signal_init_dylibloader_wrapper_pulse)( pa_mainloop_api*); +void (*pa_signal_done_dylibloader_wrapper_pulse)( void); +pa_signal_event* (*pa_signal_new_dylibloader_wrapper_pulse)( int, pa_signal_cb_t, void*); +void (*pa_signal_free_dylibloader_wrapper_pulse)( pa_signal_event*); +void (*pa_signal_set_destroy_dylibloader_wrapper_pulse)( pa_signal_event*, pa_signal_destroy_cb_t); +char* (*pa_get_user_name_dylibloader_wrapper_pulse)( char*, size_t); +char* (*pa_get_host_name_dylibloader_wrapper_pulse)( char*, size_t); +char* (*pa_get_fqdn_dylibloader_wrapper_pulse)( char*, size_t); +char* (*pa_get_home_dir_dylibloader_wrapper_pulse)( char*, size_t); +char* (*pa_get_binary_name_dylibloader_wrapper_pulse)( char*, size_t); +char* (*pa_path_get_filename_dylibloader_wrapper_pulse)(const char*); +int (*pa_msleep_dylibloader_wrapper_pulse)( unsigned long); +int (*pa_thread_make_realtime_dylibloader_wrapper_pulse)( int); +struct timeval* (*pa_gettimeofday_dylibloader_wrapper_pulse)(struct timeval*); +pa_usec_t (*pa_timeval_diff_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*); +int (*pa_timeval_cmp_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*); +pa_usec_t (*pa_timeval_age_dylibloader_wrapper_pulse)(struct timeval*); +struct timeval* (*pa_timeval_add_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t); +struct timeval* (*pa_timeval_sub_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t); +struct timeval* (*pa_timeval_store_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t); +pa_usec_t (*pa_timeval_load_dylibloader_wrapper_pulse)(struct timeval*); +pa_usec_t (*pa_rtclock_now_dylibloader_wrapper_pulse)( void); +int initialize_pulse(int verbose) { + void *handle; + char *error; + handle = dlopen("libpulse.so.0", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// pa_get_library_version + *(void **) (&pa_get_library_version_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_library_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_bytes_per_second + *(void **) (&pa_bytes_per_second_dylibloader_wrapper_pulse) = dlsym(handle, "pa_bytes_per_second"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_frame_size + *(void **) (&pa_frame_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_frame_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_size + *(void **) (&pa_sample_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_size_of_format + *(void **) (&pa_sample_size_of_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_size_of_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_bytes_to_usec + *(void **) (&pa_bytes_to_usec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_bytes_to_usec"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_usec_to_bytes + *(void **) (&pa_usec_to_bytes_dylibloader_wrapper_pulse) = dlsym(handle, "pa_usec_to_bytes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_spec_init + *(void **) (&pa_sample_spec_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_format_valid + *(void **) (&pa_sample_format_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_rate_valid + *(void **) (&pa_sample_rate_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_rate_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channels_valid + *(void **) (&pa_channels_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channels_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_spec_valid + *(void **) (&pa_sample_spec_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_spec_equal + *(void **) (&pa_sample_spec_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_equal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_format_to_string + *(void **) (&pa_sample_format_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_to_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_parse_sample_format + *(void **) (&pa_parse_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_parse_sample_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_spec_snprint + *(void **) (&pa_sample_spec_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_snprint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_bytes_snprint + *(void **) (&pa_bytes_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_bytes_snprint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_format_is_le + *(void **) (&pa_sample_format_is_le_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_is_le"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sample_format_is_be + *(void **) (&pa_sample_format_is_be_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_is_be"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_direction_valid + *(void **) (&pa_direction_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_direction_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_direction_to_string + *(void **) (&pa_direction_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_direction_to_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_api_once + *(void **) (&pa_mainloop_api_once_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_api_once"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_new + *(void **) (&pa_proplist_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_free + *(void **) (&pa_proplist_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_key_valid + *(void **) (&pa_proplist_key_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_key_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_sets + *(void **) (&pa_proplist_sets_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_sets"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_setp + *(void **) (&pa_proplist_setp_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_setp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_setf + *(void **) (&pa_proplist_setf_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_setf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_set + *(void **) (&pa_proplist_set_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_gets + *(void **) (&pa_proplist_gets_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_gets"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_get + *(void **) (&pa_proplist_get_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_get"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_update + *(void **) (&pa_proplist_update_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_unset + *(void **) (&pa_proplist_unset_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_unset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_unset_many + *(void **) (&pa_proplist_unset_many_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_unset_many"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_iterate + *(void **) (&pa_proplist_iterate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_iterate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_to_string + *(void **) (&pa_proplist_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_to_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_to_string_sep + *(void **) (&pa_proplist_to_string_sep_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_to_string_sep"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_from_string + *(void **) (&pa_proplist_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_contains + *(void **) (&pa_proplist_contains_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_contains"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_clear + *(void **) (&pa_proplist_clear_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_clear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_copy + *(void **) (&pa_proplist_copy_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_size + *(void **) (&pa_proplist_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_isempty + *(void **) (&pa_proplist_isempty_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_isempty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_proplist_equal + *(void **) (&pa_proplist_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_equal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_init + *(void **) (&pa_channel_map_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_init_mono + *(void **) (&pa_channel_map_init_mono_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_mono"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_init_stereo + *(void **) (&pa_channel_map_init_stereo_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_stereo"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_init_auto + *(void **) (&pa_channel_map_init_auto_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_auto"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_init_extend + *(void **) (&pa_channel_map_init_extend_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_extend"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_position_to_string + *(void **) (&pa_channel_position_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_position_to_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_position_from_string + *(void **) (&pa_channel_position_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_position_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_position_to_pretty_string + *(void **) (&pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_position_to_pretty_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_snprint + *(void **) (&pa_channel_map_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_snprint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_parse + *(void **) (&pa_channel_map_parse_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_parse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_equal + *(void **) (&pa_channel_map_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_equal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_valid + *(void **) (&pa_channel_map_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_compatible + *(void **) (&pa_channel_map_compatible_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_compatible"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_superset + *(void **) (&pa_channel_map_superset_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_superset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_can_balance + *(void **) (&pa_channel_map_can_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_can_balance"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_can_fade + *(void **) (&pa_channel_map_can_fade_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_can_fade"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_can_lfe_balance + *(void **) (&pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_can_lfe_balance"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_to_name + *(void **) (&pa_channel_map_to_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_to_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_to_pretty_name + *(void **) (&pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_to_pretty_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_has_position + *(void **) (&pa_channel_map_has_position_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_has_position"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_channel_map_mask + *(void **) (&pa_channel_map_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_encoding_to_string + *(void **) (&pa_encoding_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_encoding_to_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_encoding_from_string + *(void **) (&pa_encoding_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_encoding_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_new + *(void **) (&pa_format_info_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_copy + *(void **) (&pa_format_info_copy_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_copy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_free + *(void **) (&pa_format_info_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_valid + *(void **) (&pa_format_info_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_is_pcm + *(void **) (&pa_format_info_is_pcm_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_is_pcm"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_is_compatible + *(void **) (&pa_format_info_is_compatible_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_is_compatible"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_snprint + *(void **) (&pa_format_info_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_snprint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_from_string + *(void **) (&pa_format_info_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_from_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_from_sample_spec + *(void **) (&pa_format_info_from_sample_spec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_from_sample_spec"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_to_sample_spec + *(void **) (&pa_format_info_to_sample_spec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_to_sample_spec"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_prop_type + *(void **) (&pa_format_info_get_prop_type_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_type"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_prop_int + *(void **) (&pa_format_info_get_prop_int_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_int"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_prop_int_range + *(void **) (&pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_int_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_prop_int_array + *(void **) (&pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_int_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_prop_string + *(void **) (&pa_format_info_get_prop_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_prop_string_array + *(void **) (&pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_string_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_free_string_array + *(void **) (&pa_format_info_free_string_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_free_string_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_sample_format + *(void **) (&pa_format_info_get_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_sample_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_rate + *(void **) (&pa_format_info_get_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_channels + *(void **) (&pa_format_info_get_channels_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_get_channel_map + *(void **) (&pa_format_info_get_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_channel_map"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_prop_int + *(void **) (&pa_format_info_set_prop_int_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_prop_int_array + *(void **) (&pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_prop_int_range + *(void **) (&pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int_range"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_prop_string + *(void **) (&pa_format_info_set_prop_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_prop_string_array + *(void **) (&pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_string_array"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_sample_format + *(void **) (&pa_format_info_set_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_sample_format"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_rate + *(void **) (&pa_format_info_set_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_channels + *(void **) (&pa_format_info_set_channels_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_channels"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_format_info_set_channel_map + *(void **) (&pa_format_info_set_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_channel_map"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_operation_ref + *(void **) (&pa_operation_ref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_operation_unref + *(void **) (&pa_operation_unref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_operation_cancel + *(void **) (&pa_operation_cancel_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_cancel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_operation_get_state + *(void **) (&pa_operation_get_state_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_get_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_operation_set_state_callback + *(void **) (&pa_operation_set_state_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_set_state_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_new + *(void **) (&pa_context_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_new_with_proplist + *(void **) (&pa_context_new_with_proplist_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_new_with_proplist"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_unref + *(void **) (&pa_context_unref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_ref + *(void **) (&pa_context_ref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_state_callback + *(void **) (&pa_context_set_state_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_state_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_event_callback + *(void **) (&pa_context_set_event_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_event_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_errno + *(void **) (&pa_context_errno_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_errno"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_is_pending + *(void **) (&pa_context_is_pending_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_is_pending"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_state + *(void **) (&pa_context_get_state_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_connect + *(void **) (&pa_context_connect_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_connect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_disconnect + *(void **) (&pa_context_disconnect_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_drain + *(void **) (&pa_context_drain_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_drain"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_exit_daemon + *(void **) (&pa_context_exit_daemon_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_exit_daemon"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_default_sink + *(void **) (&pa_context_set_default_sink_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_default_sink"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_default_source + *(void **) (&pa_context_set_default_source_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_default_source"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_is_local + *(void **) (&pa_context_is_local_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_is_local"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_name + *(void **) (&pa_context_set_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_server + *(void **) (&pa_context_get_server_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_server"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_protocol_version + *(void **) (&pa_context_get_protocol_version_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_protocol_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_server_protocol_version + *(void **) (&pa_context_get_server_protocol_version_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_server_protocol_version"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_proplist_update + *(void **) (&pa_context_proplist_update_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_proplist_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_proplist_remove + *(void **) (&pa_context_proplist_remove_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_proplist_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_index + *(void **) (&pa_context_get_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_rttime_new + *(void **) (&pa_context_rttime_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_rttime_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_rttime_restart + *(void **) (&pa_context_rttime_restart_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_rttime_restart"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_tile_size + *(void **) (&pa_context_get_tile_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_tile_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_load_cookie_from_file + *(void **) (&pa_context_load_cookie_from_file_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_load_cookie_from_file"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_equal + *(void **) (&pa_cvolume_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_equal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_init + *(void **) (&pa_cvolume_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_set + *(void **) (&pa_cvolume_set_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_snprint + *(void **) (&pa_cvolume_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_snprint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_cvolume_snprint_dB + *(void **) (&pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_snprint_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_snprint_verbose + *(void **) (&pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_snprint_verbose"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_volume_snprint + *(void **) (&pa_volume_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_volume_snprint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_snprint_dB + *(void **) (&pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_snprint_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_volume_snprint_verbose + *(void **) (&pa_volume_snprint_verbose_dylibloader_wrapper_pulse) = dlsym(handle, "pa_volume_snprint_verbose"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_avg + *(void **) (&pa_cvolume_avg_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_avg"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_avg_mask + *(void **) (&pa_cvolume_avg_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_avg_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_max + *(void **) (&pa_cvolume_max_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_max"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_max_mask + *(void **) (&pa_cvolume_max_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_max_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_min + *(void **) (&pa_cvolume_min_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_min"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_min_mask + *(void **) (&pa_cvolume_min_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_min_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_valid + *(void **) (&pa_cvolume_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_channels_equal_to + *(void **) (&pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_channels_equal_to"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_multiply + *(void **) (&pa_sw_volume_multiply_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_multiply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_cvolume_multiply + *(void **) (&pa_sw_cvolume_multiply_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_multiply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_cvolume_multiply_scalar + *(void **) (&pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_multiply_scalar"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_divide + *(void **) (&pa_sw_volume_divide_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_divide"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_cvolume_divide + *(void **) (&pa_sw_cvolume_divide_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_divide"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_cvolume_divide_scalar + *(void **) (&pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_divide_scalar"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_from_dB + *(void **) (&pa_sw_volume_from_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_from_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_to_dB + *(void **) (&pa_sw_volume_to_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_to_dB"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_from_linear + *(void **) (&pa_sw_volume_from_linear_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_from_linear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_sw_volume_to_linear + *(void **) (&pa_sw_volume_to_linear_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_to_linear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_remap + *(void **) (&pa_cvolume_remap_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_remap"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_compatible + *(void **) (&pa_cvolume_compatible_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_compatible"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_compatible_with_channel_map + *(void **) (&pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_compatible_with_channel_map"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_get_balance + *(void **) (&pa_cvolume_get_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_balance"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_set_balance + *(void **) (&pa_cvolume_set_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_balance"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_get_fade + *(void **) (&pa_cvolume_get_fade_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_fade"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_set_fade + *(void **) (&pa_cvolume_set_fade_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_fade"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_get_lfe_balance + *(void **) (&pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_lfe_balance"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_set_lfe_balance + *(void **) (&pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_lfe_balance"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_scale + *(void **) (&pa_cvolume_scale_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_scale"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_scale_mask + *(void **) (&pa_cvolume_scale_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_scale_mask"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_set_position + *(void **) (&pa_cvolume_set_position_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_position"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_get_position + *(void **) (&pa_cvolume_get_position_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_position"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_merge + *(void **) (&pa_cvolume_merge_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_merge"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_inc_clamp + *(void **) (&pa_cvolume_inc_clamp_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_inc_clamp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_inc + *(void **) (&pa_cvolume_inc_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_inc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_cvolume_dec + *(void **) (&pa_cvolume_dec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_dec"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_new + *(void **) (&pa_stream_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_new_with_proplist + *(void **) (&pa_stream_new_with_proplist_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_new_with_proplist"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_new_extended + *(void **) (&pa_stream_new_extended_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_new_extended"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_unref + *(void **) (&pa_stream_unref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_ref + *(void **) (&pa_stream_ref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_state + *(void **) (&pa_stream_get_state_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_state"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_context + *(void **) (&pa_stream_get_context_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_context"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_index + *(void **) (&pa_stream_get_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_device_index + *(void **) (&pa_stream_get_device_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_device_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_device_name + *(void **) (&pa_stream_get_device_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_device_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_is_suspended + *(void **) (&pa_stream_is_suspended_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_is_suspended"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_is_corked + *(void **) (&pa_stream_is_corked_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_is_corked"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_connect_playback + *(void **) (&pa_stream_connect_playback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_connect_playback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_connect_record + *(void **) (&pa_stream_connect_record_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_connect_record"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_disconnect + *(void **) (&pa_stream_disconnect_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_disconnect"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_begin_write + *(void **) (&pa_stream_begin_write_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_begin_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_cancel_write + *(void **) (&pa_stream_cancel_write_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_cancel_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_write + *(void **) (&pa_stream_write_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_write"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_write_ext_free + *(void **) (&pa_stream_write_ext_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_write_ext_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_peek + *(void **) (&pa_stream_peek_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_peek"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_drop + *(void **) (&pa_stream_drop_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_drop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_writable_size + *(void **) (&pa_stream_writable_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_writable_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_readable_size + *(void **) (&pa_stream_readable_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_readable_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_drain + *(void **) (&pa_stream_drain_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_drain"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_update_timing_info + *(void **) (&pa_stream_update_timing_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_update_timing_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_state_callback + *(void **) (&pa_stream_set_state_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_state_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_write_callback + *(void **) (&pa_stream_set_write_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_write_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_read_callback + *(void **) (&pa_stream_set_read_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_read_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_overflow_callback + *(void **) (&pa_stream_set_overflow_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_overflow_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_underflow_index + *(void **) (&pa_stream_get_underflow_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_underflow_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_underflow_callback + *(void **) (&pa_stream_set_underflow_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_underflow_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_started_callback + *(void **) (&pa_stream_set_started_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_started_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_latency_update_callback + *(void **) (&pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_latency_update_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_moved_callback + *(void **) (&pa_stream_set_moved_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_moved_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_suspended_callback + *(void **) (&pa_stream_set_suspended_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_suspended_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_event_callback + *(void **) (&pa_stream_set_event_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_event_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_buffer_attr_callback + *(void **) (&pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_buffer_attr_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_cork + *(void **) (&pa_stream_cork_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_cork"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_flush + *(void **) (&pa_stream_flush_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_flush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_prebuf + *(void **) (&pa_stream_prebuf_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_prebuf"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_trigger + *(void **) (&pa_stream_trigger_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_trigger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_name + *(void **) (&pa_stream_set_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_time + *(void **) (&pa_stream_get_time_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_time"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_latency + *(void **) (&pa_stream_get_latency_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_latency"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_timing_info + *(void **) (&pa_stream_get_timing_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_timing_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_sample_spec + *(void **) (&pa_stream_get_sample_spec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_sample_spec"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_channel_map + *(void **) (&pa_stream_get_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_channel_map"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_format_info + *(void **) (&pa_stream_get_format_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_format_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_buffer_attr + *(void **) (&pa_stream_get_buffer_attr_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_buffer_attr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_buffer_attr + *(void **) (&pa_stream_set_buffer_attr_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_buffer_attr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_update_sample_rate + *(void **) (&pa_stream_update_sample_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_update_sample_rate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_proplist_update + *(void **) (&pa_stream_proplist_update_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_proplist_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_proplist_remove + *(void **) (&pa_stream_proplist_remove_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_proplist_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_set_monitor_stream + *(void **) (&pa_stream_set_monitor_stream_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_monitor_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_get_monitor_stream + *(void **) (&pa_stream_get_monitor_stream_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_monitor_stream"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sink_info_by_name + *(void **) (&pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_info_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sink_info_by_index + *(void **) (&pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_info_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sink_info_list + *(void **) (&pa_context_get_sink_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_volume_by_index + *(void **) (&pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_volume_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_volume_by_name + *(void **) (&pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_volume_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_mute_by_index + *(void **) (&pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_mute_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_mute_by_name + *(void **) (&pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_mute_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_suspend_sink_by_name + *(void **) (&pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_sink_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_suspend_sink_by_index + *(void **) (&pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_sink_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_port_by_index + *(void **) (&pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_port_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_port_by_name + *(void **) (&pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_port_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_source_info_by_name + *(void **) (&pa_context_get_source_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_info_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_source_info_by_index + *(void **) (&pa_context_get_source_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_info_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_source_info_list + *(void **) (&pa_context_get_source_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_volume_by_index + *(void **) (&pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_volume_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_volume_by_name + *(void **) (&pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_volume_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_mute_by_index + *(void **) (&pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_mute_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_mute_by_name + *(void **) (&pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_mute_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_suspend_source_by_name + *(void **) (&pa_context_suspend_source_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_source_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_suspend_source_by_index + *(void **) (&pa_context_suspend_source_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_source_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_port_by_index + *(void **) (&pa_context_set_source_port_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_port_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_port_by_name + *(void **) (&pa_context_set_source_port_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_port_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_server_info + *(void **) (&pa_context_get_server_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_server_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_module_info + *(void **) (&pa_context_get_module_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_module_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_module_info_list + *(void **) (&pa_context_get_module_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_module_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_load_module + *(void **) (&pa_context_load_module_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_load_module"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_unload_module + *(void **) (&pa_context_unload_module_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_unload_module"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_client_info + *(void **) (&pa_context_get_client_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_client_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_client_info_list + *(void **) (&pa_context_get_client_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_client_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_kill_client + *(void **) (&pa_context_kill_client_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_kill_client"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_card_info_by_index + *(void **) (&pa_context_get_card_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_card_info_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_card_info_by_name + *(void **) (&pa_context_get_card_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_card_info_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_card_info_list + *(void **) (&pa_context_get_card_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_card_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_card_profile_by_index + *(void **) (&pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_card_profile_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_card_profile_by_name + *(void **) (&pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_card_profile_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_port_latency_offset + *(void **) (&pa_context_set_port_latency_offset_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_port_latency_offset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sink_input_info + *(void **) (&pa_context_get_sink_input_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_input_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sink_input_info_list + *(void **) (&pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_input_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_move_sink_input_by_name + *(void **) (&pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_sink_input_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_move_sink_input_by_index + *(void **) (&pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_sink_input_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_input_volume + *(void **) (&pa_context_set_sink_input_volume_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_input_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_sink_input_mute + *(void **) (&pa_context_set_sink_input_mute_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_input_mute"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_kill_sink_input + *(void **) (&pa_context_kill_sink_input_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_kill_sink_input"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_source_output_info + *(void **) (&pa_context_get_source_output_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_output_info"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_source_output_info_list + *(void **) (&pa_context_get_source_output_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_output_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_move_source_output_by_name + *(void **) (&pa_context_move_source_output_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_source_output_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_move_source_output_by_index + *(void **) (&pa_context_move_source_output_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_source_output_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_output_volume + *(void **) (&pa_context_set_source_output_volume_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_output_volume"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_source_output_mute + *(void **) (&pa_context_set_source_output_mute_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_output_mute"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_kill_source_output + *(void **) (&pa_context_kill_source_output_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_kill_source_output"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_stat + *(void **) (&pa_context_stat_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_stat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sample_info_by_name + *(void **) (&pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sample_info_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sample_info_by_index + *(void **) (&pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sample_info_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_sample_info_list + *(void **) (&pa_context_get_sample_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sample_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_autoload_info_by_name + *(void **) (&pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_autoload_info_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_autoload_info_by_index + *(void **) (&pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_autoload_info_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_get_autoload_info_list + *(void **) (&pa_context_get_autoload_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_autoload_info_list"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_add_autoload + *(void **) (&pa_context_add_autoload_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_add_autoload"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_remove_autoload_by_name + *(void **) (&pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_remove_autoload_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_remove_autoload_by_index + *(void **) (&pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_remove_autoload_by_index"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_subscribe + *(void **) (&pa_context_subscribe_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_subscribe"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_set_subscribe_callback + *(void **) (&pa_context_set_subscribe_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_subscribe_callback"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_connect_upload + *(void **) (&pa_stream_connect_upload_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_connect_upload"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_stream_finish_upload + *(void **) (&pa_stream_finish_upload_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_finish_upload"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_remove_sample + *(void **) (&pa_context_remove_sample_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_remove_sample"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_play_sample + *(void **) (&pa_context_play_sample_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_play_sample"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_context_play_sample_with_proplist + *(void **) (&pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_play_sample_with_proplist"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_strerror + *(void **) (&pa_strerror_dylibloader_wrapper_pulse) = dlsym(handle, "pa_strerror"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xmalloc + *(void **) (&pa_xmalloc_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xmalloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xmalloc0 + *(void **) (&pa_xmalloc0_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xmalloc0"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xrealloc + *(void **) (&pa_xrealloc_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xrealloc"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xfree + *(void **) (&pa_xfree_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xfree"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xstrdup + *(void **) (&pa_xstrdup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xstrdup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xstrndup + *(void **) (&pa_xstrndup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xstrndup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_xmemdup + *(void **) (&pa_xmemdup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xmemdup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_utf8_valid + *(void **) (&pa_utf8_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_utf8_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_ascii_valid + *(void **) (&pa_ascii_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_ascii_valid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_utf8_filter + *(void **) (&pa_utf8_filter_dylibloader_wrapper_pulse) = dlsym(handle, "pa_utf8_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_ascii_filter + *(void **) (&pa_ascii_filter_dylibloader_wrapper_pulse) = dlsym(handle, "pa_ascii_filter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_utf8_to_locale + *(void **) (&pa_utf8_to_locale_dylibloader_wrapper_pulse) = dlsym(handle, "pa_utf8_to_locale"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_locale_to_utf8 + *(void **) (&pa_locale_to_utf8_dylibloader_wrapper_pulse) = dlsym(handle, "pa_locale_to_utf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_new + *(void **) (&pa_threaded_mainloop_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_free + *(void **) (&pa_threaded_mainloop_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_start + *(void **) (&pa_threaded_mainloop_start_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_start"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_stop + *(void **) (&pa_threaded_mainloop_stop_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_stop"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_lock + *(void **) (&pa_threaded_mainloop_lock_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_lock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_unlock + *(void **) (&pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_unlock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_wait + *(void **) (&pa_threaded_mainloop_wait_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_wait"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_signal + *(void **) (&pa_threaded_mainloop_signal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_signal"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_accept + *(void **) (&pa_threaded_mainloop_accept_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_accept"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_get_retval + *(void **) (&pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_get_retval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_get_api + *(void **) (&pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_get_api"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_in_thread + *(void **) (&pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_in_thread"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_set_name + *(void **) (&pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_set_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_threaded_mainloop_once_unlocked + *(void **) (&pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_once_unlocked"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_new + *(void **) (&pa_mainloop_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_free + *(void **) (&pa_mainloop_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_prepare + *(void **) (&pa_mainloop_prepare_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_prepare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_poll + *(void **) (&pa_mainloop_poll_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_poll"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_dispatch + *(void **) (&pa_mainloop_dispatch_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_dispatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_get_retval + *(void **) (&pa_mainloop_get_retval_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_get_retval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_iterate + *(void **) (&pa_mainloop_iterate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_iterate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_run + *(void **) (&pa_mainloop_run_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_run"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_get_api + *(void **) (&pa_mainloop_get_api_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_get_api"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_quit + *(void **) (&pa_mainloop_quit_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_quit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_wakeup + *(void **) (&pa_mainloop_wakeup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_wakeup"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_mainloop_set_poll_func + *(void **) (&pa_mainloop_set_poll_func_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_set_poll_func"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_signal_init + *(void **) (&pa_signal_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_init"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_signal_done + *(void **) (&pa_signal_done_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_done"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_signal_new + *(void **) (&pa_signal_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_signal_free + *(void **) (&pa_signal_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_free"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_signal_set_destroy + *(void **) (&pa_signal_set_destroy_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_set_destroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_get_user_name + *(void **) (&pa_get_user_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_user_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_get_host_name + *(void **) (&pa_get_host_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_host_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_get_fqdn + *(void **) (&pa_get_fqdn_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_fqdn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_get_home_dir + *(void **) (&pa_get_home_dir_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_home_dir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_get_binary_name + *(void **) (&pa_get_binary_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_binary_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_path_get_filename + *(void **) (&pa_path_get_filename_dylibloader_wrapper_pulse) = dlsym(handle, "pa_path_get_filename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_msleep + *(void **) (&pa_msleep_dylibloader_wrapper_pulse) = dlsym(handle, "pa_msleep"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_thread_make_realtime + *(void **) (&pa_thread_make_realtime_dylibloader_wrapper_pulse) = dlsym(handle, "pa_thread_make_realtime"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_gettimeofday + *(void **) (&pa_gettimeofday_dylibloader_wrapper_pulse) = dlsym(handle, "pa_gettimeofday"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_diff + *(void **) (&pa_timeval_diff_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_diff"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_cmp + *(void **) (&pa_timeval_cmp_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_cmp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_age + *(void **) (&pa_timeval_age_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_age"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_add + *(void **) (&pa_timeval_add_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_add"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_sub + *(void **) (&pa_timeval_sub_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_sub"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_store + *(void **) (&pa_timeval_store_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_store"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_timeval_load + *(void **) (&pa_timeval_load_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_load"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// pa_rtclock_now + *(void **) (&pa_rtclock_now_dylibloader_wrapper_pulse) = dlsym(handle, "pa_rtclock_now"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/drivers/pulseaudio/pulse-so_wrap.h b/drivers/pulseaudio/pulse-so_wrap.h new file mode 100644 index 0000000000..7f9a70fae1 --- /dev/null +++ b/drivers/pulseaudio/pulse-so_wrap.h @@ -0,0 +1,1446 @@ +#ifndef DYLIBLOAD_WRAPPER_PULSE +#define DYLIBLOAD_WRAPPER_PULSE +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:31 +// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include <pulse/pulseaudio.h> --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-so_wrap.h --output-implementation pulse-so_wrap.c +// +#include <stdint.h> + +#define pa_get_library_version pa_get_library_version_dylibloader_orig_pulse +#define pa_bytes_per_second pa_bytes_per_second_dylibloader_orig_pulse +#define pa_frame_size pa_frame_size_dylibloader_orig_pulse +#define pa_sample_size pa_sample_size_dylibloader_orig_pulse +#define pa_sample_size_of_format pa_sample_size_of_format_dylibloader_orig_pulse +#define pa_bytes_to_usec pa_bytes_to_usec_dylibloader_orig_pulse +#define pa_usec_to_bytes pa_usec_to_bytes_dylibloader_orig_pulse +#define pa_sample_spec_init pa_sample_spec_init_dylibloader_orig_pulse +#define pa_sample_format_valid pa_sample_format_valid_dylibloader_orig_pulse +#define pa_sample_rate_valid pa_sample_rate_valid_dylibloader_orig_pulse +#define pa_channels_valid pa_channels_valid_dylibloader_orig_pulse +#define pa_sample_spec_valid pa_sample_spec_valid_dylibloader_orig_pulse +#define pa_sample_spec_equal pa_sample_spec_equal_dylibloader_orig_pulse +#define pa_sample_format_to_string pa_sample_format_to_string_dylibloader_orig_pulse +#define pa_parse_sample_format pa_parse_sample_format_dylibloader_orig_pulse +#define pa_sample_spec_snprint pa_sample_spec_snprint_dylibloader_orig_pulse +#define pa_bytes_snprint pa_bytes_snprint_dylibloader_orig_pulse +#define pa_sample_format_is_le pa_sample_format_is_le_dylibloader_orig_pulse +#define pa_sample_format_is_be pa_sample_format_is_be_dylibloader_orig_pulse +#define pa_direction_valid pa_direction_valid_dylibloader_orig_pulse +#define pa_direction_to_string pa_direction_to_string_dylibloader_orig_pulse +#define pa_mainloop_api_once pa_mainloop_api_once_dylibloader_orig_pulse +#define pa_proplist_new pa_proplist_new_dylibloader_orig_pulse +#define pa_proplist_free pa_proplist_free_dylibloader_orig_pulse +#define pa_proplist_key_valid pa_proplist_key_valid_dylibloader_orig_pulse +#define pa_proplist_sets pa_proplist_sets_dylibloader_orig_pulse +#define pa_proplist_setp pa_proplist_setp_dylibloader_orig_pulse +#define pa_proplist_setf pa_proplist_setf_dylibloader_orig_pulse +#define pa_proplist_set pa_proplist_set_dylibloader_orig_pulse +#define pa_proplist_gets pa_proplist_gets_dylibloader_orig_pulse +#define pa_proplist_get pa_proplist_get_dylibloader_orig_pulse +#define pa_proplist_update pa_proplist_update_dylibloader_orig_pulse +#define pa_proplist_unset pa_proplist_unset_dylibloader_orig_pulse +#define pa_proplist_unset_many pa_proplist_unset_many_dylibloader_orig_pulse +#define pa_proplist_iterate pa_proplist_iterate_dylibloader_orig_pulse +#define pa_proplist_to_string pa_proplist_to_string_dylibloader_orig_pulse +#define pa_proplist_to_string_sep pa_proplist_to_string_sep_dylibloader_orig_pulse +#define pa_proplist_from_string pa_proplist_from_string_dylibloader_orig_pulse +#define pa_proplist_contains pa_proplist_contains_dylibloader_orig_pulse +#define pa_proplist_clear pa_proplist_clear_dylibloader_orig_pulse +#define pa_proplist_copy pa_proplist_copy_dylibloader_orig_pulse +#define pa_proplist_size pa_proplist_size_dylibloader_orig_pulse +#define pa_proplist_isempty pa_proplist_isempty_dylibloader_orig_pulse +#define pa_proplist_equal pa_proplist_equal_dylibloader_orig_pulse +#define pa_channel_map_init pa_channel_map_init_dylibloader_orig_pulse +#define pa_channel_map_init_mono pa_channel_map_init_mono_dylibloader_orig_pulse +#define pa_channel_map_init_stereo pa_channel_map_init_stereo_dylibloader_orig_pulse +#define pa_channel_map_init_auto pa_channel_map_init_auto_dylibloader_orig_pulse +#define pa_channel_map_init_extend pa_channel_map_init_extend_dylibloader_orig_pulse +#define pa_channel_position_to_string pa_channel_position_to_string_dylibloader_orig_pulse +#define pa_channel_position_from_string pa_channel_position_from_string_dylibloader_orig_pulse +#define pa_channel_position_to_pretty_string pa_channel_position_to_pretty_string_dylibloader_orig_pulse +#define pa_channel_map_snprint pa_channel_map_snprint_dylibloader_orig_pulse +#define pa_channel_map_parse pa_channel_map_parse_dylibloader_orig_pulse +#define pa_channel_map_equal pa_channel_map_equal_dylibloader_orig_pulse +#define pa_channel_map_valid pa_channel_map_valid_dylibloader_orig_pulse +#define pa_channel_map_compatible pa_channel_map_compatible_dylibloader_orig_pulse +#define pa_channel_map_superset pa_channel_map_superset_dylibloader_orig_pulse +#define pa_channel_map_can_balance pa_channel_map_can_balance_dylibloader_orig_pulse +#define pa_channel_map_can_fade pa_channel_map_can_fade_dylibloader_orig_pulse +#define pa_channel_map_can_lfe_balance pa_channel_map_can_lfe_balance_dylibloader_orig_pulse +#define pa_channel_map_to_name pa_channel_map_to_name_dylibloader_orig_pulse +#define pa_channel_map_to_pretty_name pa_channel_map_to_pretty_name_dylibloader_orig_pulse +#define pa_channel_map_has_position pa_channel_map_has_position_dylibloader_orig_pulse +#define pa_channel_map_mask pa_channel_map_mask_dylibloader_orig_pulse +#define pa_encoding_to_string pa_encoding_to_string_dylibloader_orig_pulse +#define pa_encoding_from_string pa_encoding_from_string_dylibloader_orig_pulse +#define pa_format_info_new pa_format_info_new_dylibloader_orig_pulse +#define pa_format_info_copy pa_format_info_copy_dylibloader_orig_pulse +#define pa_format_info_free pa_format_info_free_dylibloader_orig_pulse +#define pa_format_info_valid pa_format_info_valid_dylibloader_orig_pulse +#define pa_format_info_is_pcm pa_format_info_is_pcm_dylibloader_orig_pulse +#define pa_format_info_is_compatible pa_format_info_is_compatible_dylibloader_orig_pulse +#define pa_format_info_snprint pa_format_info_snprint_dylibloader_orig_pulse +#define pa_format_info_from_string pa_format_info_from_string_dylibloader_orig_pulse +#define pa_format_info_from_sample_spec pa_format_info_from_sample_spec_dylibloader_orig_pulse +#define pa_format_info_to_sample_spec pa_format_info_to_sample_spec_dylibloader_orig_pulse +#define pa_format_info_get_prop_type pa_format_info_get_prop_type_dylibloader_orig_pulse +#define pa_format_info_get_prop_int pa_format_info_get_prop_int_dylibloader_orig_pulse +#define pa_format_info_get_prop_int_range pa_format_info_get_prop_int_range_dylibloader_orig_pulse +#define pa_format_info_get_prop_int_array pa_format_info_get_prop_int_array_dylibloader_orig_pulse +#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_orig_pulse +#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_orig_pulse +#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_orig_pulse +#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_orig_pulse +#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_orig_pulse +#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_orig_pulse +#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_orig_pulse +#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_orig_pulse +#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_orig_pulse +#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_orig_pulse +#define pa_format_info_set_prop_string pa_format_info_set_prop_string_dylibloader_orig_pulse +#define pa_format_info_set_prop_string_array pa_format_info_set_prop_string_array_dylibloader_orig_pulse +#define pa_format_info_set_sample_format pa_format_info_set_sample_format_dylibloader_orig_pulse +#define pa_format_info_set_rate pa_format_info_set_rate_dylibloader_orig_pulse +#define pa_format_info_set_channels pa_format_info_set_channels_dylibloader_orig_pulse +#define pa_format_info_set_channel_map pa_format_info_set_channel_map_dylibloader_orig_pulse +#define pa_operation_ref pa_operation_ref_dylibloader_orig_pulse +#define pa_operation_unref pa_operation_unref_dylibloader_orig_pulse +#define pa_operation_cancel pa_operation_cancel_dylibloader_orig_pulse +#define pa_operation_get_state pa_operation_get_state_dylibloader_orig_pulse +#define pa_operation_set_state_callback pa_operation_set_state_callback_dylibloader_orig_pulse +#define pa_context_new pa_context_new_dylibloader_orig_pulse +#define pa_context_new_with_proplist pa_context_new_with_proplist_dylibloader_orig_pulse +#define pa_context_unref pa_context_unref_dylibloader_orig_pulse +#define pa_context_ref pa_context_ref_dylibloader_orig_pulse +#define pa_context_set_state_callback pa_context_set_state_callback_dylibloader_orig_pulse +#define pa_context_set_event_callback pa_context_set_event_callback_dylibloader_orig_pulse +#define pa_context_errno pa_context_errno_dylibloader_orig_pulse +#define pa_context_is_pending pa_context_is_pending_dylibloader_orig_pulse +#define pa_context_get_state pa_context_get_state_dylibloader_orig_pulse +#define pa_context_connect pa_context_connect_dylibloader_orig_pulse +#define pa_context_disconnect pa_context_disconnect_dylibloader_orig_pulse +#define pa_context_drain pa_context_drain_dylibloader_orig_pulse +#define pa_context_exit_daemon pa_context_exit_daemon_dylibloader_orig_pulse +#define pa_context_set_default_sink pa_context_set_default_sink_dylibloader_orig_pulse +#define pa_context_set_default_source pa_context_set_default_source_dylibloader_orig_pulse +#define pa_context_is_local pa_context_is_local_dylibloader_orig_pulse +#define pa_context_set_name pa_context_set_name_dylibloader_orig_pulse +#define pa_context_get_server pa_context_get_server_dylibloader_orig_pulse +#define pa_context_get_protocol_version pa_context_get_protocol_version_dylibloader_orig_pulse +#define pa_context_get_server_protocol_version pa_context_get_server_protocol_version_dylibloader_orig_pulse +#define pa_context_proplist_update pa_context_proplist_update_dylibloader_orig_pulse +#define pa_context_proplist_remove pa_context_proplist_remove_dylibloader_orig_pulse +#define pa_context_get_index pa_context_get_index_dylibloader_orig_pulse +#define pa_context_rttime_new pa_context_rttime_new_dylibloader_orig_pulse +#define pa_context_rttime_restart pa_context_rttime_restart_dylibloader_orig_pulse +#define pa_context_get_tile_size pa_context_get_tile_size_dylibloader_orig_pulse +#define pa_context_load_cookie_from_file pa_context_load_cookie_from_file_dylibloader_orig_pulse +#define pa_cvolume_equal pa_cvolume_equal_dylibloader_orig_pulse +#define pa_cvolume_init pa_cvolume_init_dylibloader_orig_pulse +#define pa_cvolume_set pa_cvolume_set_dylibloader_orig_pulse +#define pa_cvolume_snprint pa_cvolume_snprint_dylibloader_orig_pulse +#define pa_sw_cvolume_snprint_dB pa_sw_cvolume_snprint_dB_dylibloader_orig_pulse +#define pa_cvolume_snprint_verbose pa_cvolume_snprint_verbose_dylibloader_orig_pulse +#define pa_volume_snprint pa_volume_snprint_dylibloader_orig_pulse +#define pa_sw_volume_snprint_dB pa_sw_volume_snprint_dB_dylibloader_orig_pulse +#define pa_volume_snprint_verbose pa_volume_snprint_verbose_dylibloader_orig_pulse +#define pa_cvolume_avg pa_cvolume_avg_dylibloader_orig_pulse +#define pa_cvolume_avg_mask pa_cvolume_avg_mask_dylibloader_orig_pulse +#define pa_cvolume_max pa_cvolume_max_dylibloader_orig_pulse +#define pa_cvolume_max_mask pa_cvolume_max_mask_dylibloader_orig_pulse +#define pa_cvolume_min pa_cvolume_min_dylibloader_orig_pulse +#define pa_cvolume_min_mask pa_cvolume_min_mask_dylibloader_orig_pulse +#define pa_cvolume_valid pa_cvolume_valid_dylibloader_orig_pulse +#define pa_cvolume_channels_equal_to pa_cvolume_channels_equal_to_dylibloader_orig_pulse +#define pa_sw_volume_multiply pa_sw_volume_multiply_dylibloader_orig_pulse +#define pa_sw_cvolume_multiply pa_sw_cvolume_multiply_dylibloader_orig_pulse +#define pa_sw_cvolume_multiply_scalar pa_sw_cvolume_multiply_scalar_dylibloader_orig_pulse +#define pa_sw_volume_divide pa_sw_volume_divide_dylibloader_orig_pulse +#define pa_sw_cvolume_divide pa_sw_cvolume_divide_dylibloader_orig_pulse +#define pa_sw_cvolume_divide_scalar pa_sw_cvolume_divide_scalar_dylibloader_orig_pulse +#define pa_sw_volume_from_dB pa_sw_volume_from_dB_dylibloader_orig_pulse +#define pa_sw_volume_to_dB pa_sw_volume_to_dB_dylibloader_orig_pulse +#define pa_sw_volume_from_linear pa_sw_volume_from_linear_dylibloader_orig_pulse +#define pa_sw_volume_to_linear pa_sw_volume_to_linear_dylibloader_orig_pulse +#define pa_cvolume_remap pa_cvolume_remap_dylibloader_orig_pulse +#define pa_cvolume_compatible pa_cvolume_compatible_dylibloader_orig_pulse +#define pa_cvolume_compatible_with_channel_map pa_cvolume_compatible_with_channel_map_dylibloader_orig_pulse +#define pa_cvolume_get_balance pa_cvolume_get_balance_dylibloader_orig_pulse +#define pa_cvolume_set_balance pa_cvolume_set_balance_dylibloader_orig_pulse +#define pa_cvolume_get_fade pa_cvolume_get_fade_dylibloader_orig_pulse +#define pa_cvolume_set_fade pa_cvolume_set_fade_dylibloader_orig_pulse +#define pa_cvolume_get_lfe_balance pa_cvolume_get_lfe_balance_dylibloader_orig_pulse +#define pa_cvolume_set_lfe_balance pa_cvolume_set_lfe_balance_dylibloader_orig_pulse +#define pa_cvolume_scale pa_cvolume_scale_dylibloader_orig_pulse +#define pa_cvolume_scale_mask pa_cvolume_scale_mask_dylibloader_orig_pulse +#define pa_cvolume_set_position pa_cvolume_set_position_dylibloader_orig_pulse +#define pa_cvolume_get_position pa_cvolume_get_position_dylibloader_orig_pulse +#define pa_cvolume_merge pa_cvolume_merge_dylibloader_orig_pulse +#define pa_cvolume_inc_clamp pa_cvolume_inc_clamp_dylibloader_orig_pulse +#define pa_cvolume_inc pa_cvolume_inc_dylibloader_orig_pulse +#define pa_cvolume_dec pa_cvolume_dec_dylibloader_orig_pulse +#define pa_stream_new pa_stream_new_dylibloader_orig_pulse +#define pa_stream_new_with_proplist pa_stream_new_with_proplist_dylibloader_orig_pulse +#define pa_stream_new_extended pa_stream_new_extended_dylibloader_orig_pulse +#define pa_stream_unref pa_stream_unref_dylibloader_orig_pulse +#define pa_stream_ref pa_stream_ref_dylibloader_orig_pulse +#define pa_stream_get_state pa_stream_get_state_dylibloader_orig_pulse +#define pa_stream_get_context pa_stream_get_context_dylibloader_orig_pulse +#define pa_stream_get_index pa_stream_get_index_dylibloader_orig_pulse +#define pa_stream_get_device_index pa_stream_get_device_index_dylibloader_orig_pulse +#define pa_stream_get_device_name pa_stream_get_device_name_dylibloader_orig_pulse +#define pa_stream_is_suspended pa_stream_is_suspended_dylibloader_orig_pulse +#define pa_stream_is_corked pa_stream_is_corked_dylibloader_orig_pulse +#define pa_stream_connect_playback pa_stream_connect_playback_dylibloader_orig_pulse +#define pa_stream_connect_record pa_stream_connect_record_dylibloader_orig_pulse +#define pa_stream_disconnect pa_stream_disconnect_dylibloader_orig_pulse +#define pa_stream_begin_write pa_stream_begin_write_dylibloader_orig_pulse +#define pa_stream_cancel_write pa_stream_cancel_write_dylibloader_orig_pulse +#define pa_stream_write pa_stream_write_dylibloader_orig_pulse +#define pa_stream_write_ext_free pa_stream_write_ext_free_dylibloader_orig_pulse +#define pa_stream_peek pa_stream_peek_dylibloader_orig_pulse +#define pa_stream_drop pa_stream_drop_dylibloader_orig_pulse +#define pa_stream_writable_size pa_stream_writable_size_dylibloader_orig_pulse +#define pa_stream_readable_size pa_stream_readable_size_dylibloader_orig_pulse +#define pa_stream_drain pa_stream_drain_dylibloader_orig_pulse +#define pa_stream_update_timing_info pa_stream_update_timing_info_dylibloader_orig_pulse +#define pa_stream_set_state_callback pa_stream_set_state_callback_dylibloader_orig_pulse +#define pa_stream_set_write_callback pa_stream_set_write_callback_dylibloader_orig_pulse +#define pa_stream_set_read_callback pa_stream_set_read_callback_dylibloader_orig_pulse +#define pa_stream_set_overflow_callback pa_stream_set_overflow_callback_dylibloader_orig_pulse +#define pa_stream_get_underflow_index pa_stream_get_underflow_index_dylibloader_orig_pulse +#define pa_stream_set_underflow_callback pa_stream_set_underflow_callback_dylibloader_orig_pulse +#define pa_stream_set_started_callback pa_stream_set_started_callback_dylibloader_orig_pulse +#define pa_stream_set_latency_update_callback pa_stream_set_latency_update_callback_dylibloader_orig_pulse +#define pa_stream_set_moved_callback pa_stream_set_moved_callback_dylibloader_orig_pulse +#define pa_stream_set_suspended_callback pa_stream_set_suspended_callback_dylibloader_orig_pulse +#define pa_stream_set_event_callback pa_stream_set_event_callback_dylibloader_orig_pulse +#define pa_stream_set_buffer_attr_callback pa_stream_set_buffer_attr_callback_dylibloader_orig_pulse +#define pa_stream_cork pa_stream_cork_dylibloader_orig_pulse +#define pa_stream_flush pa_stream_flush_dylibloader_orig_pulse +#define pa_stream_prebuf pa_stream_prebuf_dylibloader_orig_pulse +#define pa_stream_trigger pa_stream_trigger_dylibloader_orig_pulse +#define pa_stream_set_name pa_stream_set_name_dylibloader_orig_pulse +#define pa_stream_get_time pa_stream_get_time_dylibloader_orig_pulse +#define pa_stream_get_latency pa_stream_get_latency_dylibloader_orig_pulse +#define pa_stream_get_timing_info pa_stream_get_timing_info_dylibloader_orig_pulse +#define pa_stream_get_sample_spec pa_stream_get_sample_spec_dylibloader_orig_pulse +#define pa_stream_get_channel_map pa_stream_get_channel_map_dylibloader_orig_pulse +#define pa_stream_get_format_info pa_stream_get_format_info_dylibloader_orig_pulse +#define pa_stream_get_buffer_attr pa_stream_get_buffer_attr_dylibloader_orig_pulse +#define pa_stream_set_buffer_attr pa_stream_set_buffer_attr_dylibloader_orig_pulse +#define pa_stream_update_sample_rate pa_stream_update_sample_rate_dylibloader_orig_pulse +#define pa_stream_proplist_update pa_stream_proplist_update_dylibloader_orig_pulse +#define pa_stream_proplist_remove pa_stream_proplist_remove_dylibloader_orig_pulse +#define pa_stream_set_monitor_stream pa_stream_set_monitor_stream_dylibloader_orig_pulse +#define pa_stream_get_monitor_stream pa_stream_get_monitor_stream_dylibloader_orig_pulse +#define pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name_dylibloader_orig_pulse +#define pa_context_get_sink_info_by_index pa_context_get_sink_info_by_index_dylibloader_orig_pulse +#define pa_context_get_sink_info_list pa_context_get_sink_info_list_dylibloader_orig_pulse +#define pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name_dylibloader_orig_pulse +#define pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_mute_by_name pa_context_set_sink_mute_by_name_dylibloader_orig_pulse +#define pa_context_suspend_sink_by_name pa_context_suspend_sink_by_name_dylibloader_orig_pulse +#define pa_context_suspend_sink_by_index pa_context_suspend_sink_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_port_by_index pa_context_set_sink_port_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_port_by_name pa_context_set_sink_port_by_name_dylibloader_orig_pulse +#define pa_context_get_source_info_by_name pa_context_get_source_info_by_name_dylibloader_orig_pulse +#define pa_context_get_source_info_by_index pa_context_get_source_info_by_index_dylibloader_orig_pulse +#define pa_context_get_source_info_list pa_context_get_source_info_list_dylibloader_orig_pulse +#define pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index_dylibloader_orig_pulse +#define pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name_dylibloader_orig_pulse +#define pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index_dylibloader_orig_pulse +#define pa_context_set_source_mute_by_name pa_context_set_source_mute_by_name_dylibloader_orig_pulse +#define pa_context_suspend_source_by_name pa_context_suspend_source_by_name_dylibloader_orig_pulse +#define pa_context_suspend_source_by_index pa_context_suspend_source_by_index_dylibloader_orig_pulse +#define pa_context_set_source_port_by_index pa_context_set_source_port_by_index_dylibloader_orig_pulse +#define pa_context_set_source_port_by_name pa_context_set_source_port_by_name_dylibloader_orig_pulse +#define pa_context_get_server_info pa_context_get_server_info_dylibloader_orig_pulse +#define pa_context_get_module_info pa_context_get_module_info_dylibloader_orig_pulse +#define pa_context_get_module_info_list pa_context_get_module_info_list_dylibloader_orig_pulse +#define pa_context_load_module pa_context_load_module_dylibloader_orig_pulse +#define pa_context_unload_module pa_context_unload_module_dylibloader_orig_pulse +#define pa_context_get_client_info pa_context_get_client_info_dylibloader_orig_pulse +#define pa_context_get_client_info_list pa_context_get_client_info_list_dylibloader_orig_pulse +#define pa_context_kill_client pa_context_kill_client_dylibloader_orig_pulse +#define pa_context_get_card_info_by_index pa_context_get_card_info_by_index_dylibloader_orig_pulse +#define pa_context_get_card_info_by_name pa_context_get_card_info_by_name_dylibloader_orig_pulse +#define pa_context_get_card_info_list pa_context_get_card_info_list_dylibloader_orig_pulse +#define pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index_dylibloader_orig_pulse +#define pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name_dylibloader_orig_pulse +#define pa_context_set_port_latency_offset pa_context_set_port_latency_offset_dylibloader_orig_pulse +#define pa_context_get_sink_input_info pa_context_get_sink_input_info_dylibloader_orig_pulse +#define pa_context_get_sink_input_info_list pa_context_get_sink_input_info_list_dylibloader_orig_pulse +#define pa_context_move_sink_input_by_name pa_context_move_sink_input_by_name_dylibloader_orig_pulse +#define pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index_dylibloader_orig_pulse +#define pa_context_set_sink_input_volume pa_context_set_sink_input_volume_dylibloader_orig_pulse +#define pa_context_set_sink_input_mute pa_context_set_sink_input_mute_dylibloader_orig_pulse +#define pa_context_kill_sink_input pa_context_kill_sink_input_dylibloader_orig_pulse +#define pa_context_get_source_output_info pa_context_get_source_output_info_dylibloader_orig_pulse +#define pa_context_get_source_output_info_list pa_context_get_source_output_info_list_dylibloader_orig_pulse +#define pa_context_move_source_output_by_name pa_context_move_source_output_by_name_dylibloader_orig_pulse +#define pa_context_move_source_output_by_index pa_context_move_source_output_by_index_dylibloader_orig_pulse +#define pa_context_set_source_output_volume pa_context_set_source_output_volume_dylibloader_orig_pulse +#define pa_context_set_source_output_mute pa_context_set_source_output_mute_dylibloader_orig_pulse +#define pa_context_kill_source_output pa_context_kill_source_output_dylibloader_orig_pulse +#define pa_context_stat pa_context_stat_dylibloader_orig_pulse +#define pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name_dylibloader_orig_pulse +#define pa_context_get_sample_info_by_index pa_context_get_sample_info_by_index_dylibloader_orig_pulse +#define pa_context_get_sample_info_list pa_context_get_sample_info_list_dylibloader_orig_pulse +#define pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name_dylibloader_orig_pulse +#define pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index_dylibloader_orig_pulse +#define pa_context_get_autoload_info_list pa_context_get_autoload_info_list_dylibloader_orig_pulse +#define pa_context_add_autoload pa_context_add_autoload_dylibloader_orig_pulse +#define pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name_dylibloader_orig_pulse +#define pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index_dylibloader_orig_pulse +#define pa_context_subscribe pa_context_subscribe_dylibloader_orig_pulse +#define pa_context_set_subscribe_callback pa_context_set_subscribe_callback_dylibloader_orig_pulse +#define pa_stream_connect_upload pa_stream_connect_upload_dylibloader_orig_pulse +#define pa_stream_finish_upload pa_stream_finish_upload_dylibloader_orig_pulse +#define pa_context_remove_sample pa_context_remove_sample_dylibloader_orig_pulse +#define pa_context_play_sample pa_context_play_sample_dylibloader_orig_pulse +#define pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist_dylibloader_orig_pulse +#define pa_strerror pa_strerror_dylibloader_orig_pulse +#define pa_xmalloc pa_xmalloc_dylibloader_orig_pulse +#define pa_xmalloc0 pa_xmalloc0_dylibloader_orig_pulse +#define pa_xrealloc pa_xrealloc_dylibloader_orig_pulse +#define pa_xfree pa_xfree_dylibloader_orig_pulse +#define pa_xstrdup pa_xstrdup_dylibloader_orig_pulse +#define pa_xstrndup pa_xstrndup_dylibloader_orig_pulse +#define pa_xmemdup pa_xmemdup_dylibloader_orig_pulse +#define pa_utf8_valid pa_utf8_valid_dylibloader_orig_pulse +#define pa_ascii_valid pa_ascii_valid_dylibloader_orig_pulse +#define pa_utf8_filter pa_utf8_filter_dylibloader_orig_pulse +#define pa_ascii_filter pa_ascii_filter_dylibloader_orig_pulse +#define pa_utf8_to_locale pa_utf8_to_locale_dylibloader_orig_pulse +#define pa_locale_to_utf8 pa_locale_to_utf8_dylibloader_orig_pulse +#define pa_threaded_mainloop_new pa_threaded_mainloop_new_dylibloader_orig_pulse +#define pa_threaded_mainloop_free pa_threaded_mainloop_free_dylibloader_orig_pulse +#define pa_threaded_mainloop_start pa_threaded_mainloop_start_dylibloader_orig_pulse +#define pa_threaded_mainloop_stop pa_threaded_mainloop_stop_dylibloader_orig_pulse +#define pa_threaded_mainloop_lock pa_threaded_mainloop_lock_dylibloader_orig_pulse +#define pa_threaded_mainloop_unlock pa_threaded_mainloop_unlock_dylibloader_orig_pulse +#define pa_threaded_mainloop_wait pa_threaded_mainloop_wait_dylibloader_orig_pulse +#define pa_threaded_mainloop_signal pa_threaded_mainloop_signal_dylibloader_orig_pulse +#define pa_threaded_mainloop_accept pa_threaded_mainloop_accept_dylibloader_orig_pulse +#define pa_threaded_mainloop_get_retval pa_threaded_mainloop_get_retval_dylibloader_orig_pulse +#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_orig_pulse +#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_orig_pulse +#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_orig_pulse +#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_orig_pulse +#define pa_mainloop_new pa_mainloop_new_dylibloader_orig_pulse +#define pa_mainloop_free pa_mainloop_free_dylibloader_orig_pulse +#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_orig_pulse +#define pa_mainloop_poll pa_mainloop_poll_dylibloader_orig_pulse +#define pa_mainloop_dispatch pa_mainloop_dispatch_dylibloader_orig_pulse +#define pa_mainloop_get_retval pa_mainloop_get_retval_dylibloader_orig_pulse +#define pa_mainloop_iterate pa_mainloop_iterate_dylibloader_orig_pulse +#define pa_mainloop_run pa_mainloop_run_dylibloader_orig_pulse +#define pa_mainloop_get_api pa_mainloop_get_api_dylibloader_orig_pulse +#define pa_mainloop_quit pa_mainloop_quit_dylibloader_orig_pulse +#define pa_mainloop_wakeup pa_mainloop_wakeup_dylibloader_orig_pulse +#define pa_mainloop_set_poll_func pa_mainloop_set_poll_func_dylibloader_orig_pulse +#define pa_signal_init pa_signal_init_dylibloader_orig_pulse +#define pa_signal_done pa_signal_done_dylibloader_orig_pulse +#define pa_signal_new pa_signal_new_dylibloader_orig_pulse +#define pa_signal_free pa_signal_free_dylibloader_orig_pulse +#define pa_signal_set_destroy pa_signal_set_destroy_dylibloader_orig_pulse +#define pa_get_user_name pa_get_user_name_dylibloader_orig_pulse +#define pa_get_host_name pa_get_host_name_dylibloader_orig_pulse +#define pa_get_fqdn pa_get_fqdn_dylibloader_orig_pulse +#define pa_get_home_dir pa_get_home_dir_dylibloader_orig_pulse +#define pa_get_binary_name pa_get_binary_name_dylibloader_orig_pulse +#define pa_path_get_filename pa_path_get_filename_dylibloader_orig_pulse +#define pa_msleep pa_msleep_dylibloader_orig_pulse +#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_orig_pulse +#define pa_gettimeofday pa_gettimeofday_dylibloader_orig_pulse +#define pa_timeval_diff pa_timeval_diff_dylibloader_orig_pulse +#define pa_timeval_cmp pa_timeval_cmp_dylibloader_orig_pulse +#define pa_timeval_age pa_timeval_age_dylibloader_orig_pulse +#define pa_timeval_add pa_timeval_add_dylibloader_orig_pulse +#define pa_timeval_sub pa_timeval_sub_dylibloader_orig_pulse +#define pa_timeval_store pa_timeval_store_dylibloader_orig_pulse +#define pa_timeval_load pa_timeval_load_dylibloader_orig_pulse +#define pa_rtclock_now pa_rtclock_now_dylibloader_orig_pulse +#include <pulse/pulseaudio.h> +#undef pa_get_library_version +#undef pa_bytes_per_second +#undef pa_frame_size +#undef pa_sample_size +#undef pa_sample_size_of_format +#undef pa_bytes_to_usec +#undef pa_usec_to_bytes +#undef pa_sample_spec_init +#undef pa_sample_format_valid +#undef pa_sample_rate_valid +#undef pa_channels_valid +#undef pa_sample_spec_valid +#undef pa_sample_spec_equal +#undef pa_sample_format_to_string +#undef pa_parse_sample_format +#undef pa_sample_spec_snprint +#undef pa_bytes_snprint +#undef pa_sample_format_is_le +#undef pa_sample_format_is_be +#undef pa_direction_valid +#undef pa_direction_to_string +#undef pa_mainloop_api_once +#undef pa_proplist_new +#undef pa_proplist_free +#undef pa_proplist_key_valid +#undef pa_proplist_sets +#undef pa_proplist_setp +#undef pa_proplist_setf +#undef pa_proplist_set +#undef pa_proplist_gets +#undef pa_proplist_get +#undef pa_proplist_update +#undef pa_proplist_unset +#undef pa_proplist_unset_many +#undef pa_proplist_iterate +#undef pa_proplist_to_string +#undef pa_proplist_to_string_sep +#undef pa_proplist_from_string +#undef pa_proplist_contains +#undef pa_proplist_clear +#undef pa_proplist_copy +#undef pa_proplist_size +#undef pa_proplist_isempty +#undef pa_proplist_equal +#undef pa_channel_map_init +#undef pa_channel_map_init_mono +#undef pa_channel_map_init_stereo +#undef pa_channel_map_init_auto +#undef pa_channel_map_init_extend +#undef pa_channel_position_to_string +#undef pa_channel_position_from_string +#undef pa_channel_position_to_pretty_string +#undef pa_channel_map_snprint +#undef pa_channel_map_parse +#undef pa_channel_map_equal +#undef pa_channel_map_valid +#undef pa_channel_map_compatible +#undef pa_channel_map_superset +#undef pa_channel_map_can_balance +#undef pa_channel_map_can_fade +#undef pa_channel_map_can_lfe_balance +#undef pa_channel_map_to_name +#undef pa_channel_map_to_pretty_name +#undef pa_channel_map_has_position +#undef pa_channel_map_mask +#undef pa_encoding_to_string +#undef pa_encoding_from_string +#undef pa_format_info_new +#undef pa_format_info_copy +#undef pa_format_info_free +#undef pa_format_info_valid +#undef pa_format_info_is_pcm +#undef pa_format_info_is_compatible +#undef pa_format_info_snprint +#undef pa_format_info_from_string +#undef pa_format_info_from_sample_spec +#undef pa_format_info_to_sample_spec +#undef pa_format_info_get_prop_type +#undef pa_format_info_get_prop_int +#undef pa_format_info_get_prop_int_range +#undef pa_format_info_get_prop_int_array +#undef pa_format_info_get_prop_string +#undef pa_format_info_get_prop_string_array +#undef pa_format_info_free_string_array +#undef pa_format_info_get_sample_format +#undef pa_format_info_get_rate +#undef pa_format_info_get_channels +#undef pa_format_info_get_channel_map +#undef pa_format_info_set_prop_int +#undef pa_format_info_set_prop_int_array +#undef pa_format_info_set_prop_int_range +#undef pa_format_info_set_prop_string +#undef pa_format_info_set_prop_string_array +#undef pa_format_info_set_sample_format +#undef pa_format_info_set_rate +#undef pa_format_info_set_channels +#undef pa_format_info_set_channel_map +#undef pa_operation_ref +#undef pa_operation_unref +#undef pa_operation_cancel +#undef pa_operation_get_state +#undef pa_operation_set_state_callback +#undef pa_context_new +#undef pa_context_new_with_proplist +#undef pa_context_unref +#undef pa_context_ref +#undef pa_context_set_state_callback +#undef pa_context_set_event_callback +#undef pa_context_errno +#undef pa_context_is_pending +#undef pa_context_get_state +#undef pa_context_connect +#undef pa_context_disconnect +#undef pa_context_drain +#undef pa_context_exit_daemon +#undef pa_context_set_default_sink +#undef pa_context_set_default_source +#undef pa_context_is_local +#undef pa_context_set_name +#undef pa_context_get_server +#undef pa_context_get_protocol_version +#undef pa_context_get_server_protocol_version +#undef pa_context_proplist_update +#undef pa_context_proplist_remove +#undef pa_context_get_index +#undef pa_context_rttime_new +#undef pa_context_rttime_restart +#undef pa_context_get_tile_size +#undef pa_context_load_cookie_from_file +#undef pa_cvolume_equal +#undef pa_cvolume_init +#undef pa_cvolume_set +#undef pa_cvolume_snprint +#undef pa_sw_cvolume_snprint_dB +#undef pa_cvolume_snprint_verbose +#undef pa_volume_snprint +#undef pa_sw_volume_snprint_dB +#undef pa_volume_snprint_verbose +#undef pa_cvolume_avg +#undef pa_cvolume_avg_mask +#undef pa_cvolume_max +#undef pa_cvolume_max_mask +#undef pa_cvolume_min +#undef pa_cvolume_min_mask +#undef pa_cvolume_valid +#undef pa_cvolume_channels_equal_to +#undef pa_sw_volume_multiply +#undef pa_sw_cvolume_multiply +#undef pa_sw_cvolume_multiply_scalar +#undef pa_sw_volume_divide +#undef pa_sw_cvolume_divide +#undef pa_sw_cvolume_divide_scalar +#undef pa_sw_volume_from_dB +#undef pa_sw_volume_to_dB +#undef pa_sw_volume_from_linear +#undef pa_sw_volume_to_linear +#undef pa_cvolume_remap +#undef pa_cvolume_compatible +#undef pa_cvolume_compatible_with_channel_map +#undef pa_cvolume_get_balance +#undef pa_cvolume_set_balance +#undef pa_cvolume_get_fade +#undef pa_cvolume_set_fade +#undef pa_cvolume_get_lfe_balance +#undef pa_cvolume_set_lfe_balance +#undef pa_cvolume_scale +#undef pa_cvolume_scale_mask +#undef pa_cvolume_set_position +#undef pa_cvolume_get_position +#undef pa_cvolume_merge +#undef pa_cvolume_inc_clamp +#undef pa_cvolume_inc +#undef pa_cvolume_dec +#undef pa_stream_new +#undef pa_stream_new_with_proplist +#undef pa_stream_new_extended +#undef pa_stream_unref +#undef pa_stream_ref +#undef pa_stream_get_state +#undef pa_stream_get_context +#undef pa_stream_get_index +#undef pa_stream_get_device_index +#undef pa_stream_get_device_name +#undef pa_stream_is_suspended +#undef pa_stream_is_corked +#undef pa_stream_connect_playback +#undef pa_stream_connect_record +#undef pa_stream_disconnect +#undef pa_stream_begin_write +#undef pa_stream_cancel_write +#undef pa_stream_write +#undef pa_stream_write_ext_free +#undef pa_stream_peek +#undef pa_stream_drop +#undef pa_stream_writable_size +#undef pa_stream_readable_size +#undef pa_stream_drain +#undef pa_stream_update_timing_info +#undef pa_stream_set_state_callback +#undef pa_stream_set_write_callback +#undef pa_stream_set_read_callback +#undef pa_stream_set_overflow_callback +#undef pa_stream_get_underflow_index +#undef pa_stream_set_underflow_callback +#undef pa_stream_set_started_callback +#undef pa_stream_set_latency_update_callback +#undef pa_stream_set_moved_callback +#undef pa_stream_set_suspended_callback +#undef pa_stream_set_event_callback +#undef pa_stream_set_buffer_attr_callback +#undef pa_stream_cork +#undef pa_stream_flush +#undef pa_stream_prebuf +#undef pa_stream_trigger +#undef pa_stream_set_name +#undef pa_stream_get_time +#undef pa_stream_get_latency +#undef pa_stream_get_timing_info +#undef pa_stream_get_sample_spec +#undef pa_stream_get_channel_map +#undef pa_stream_get_format_info +#undef pa_stream_get_buffer_attr +#undef pa_stream_set_buffer_attr +#undef pa_stream_update_sample_rate +#undef pa_stream_proplist_update +#undef pa_stream_proplist_remove +#undef pa_stream_set_monitor_stream +#undef pa_stream_get_monitor_stream +#undef pa_context_get_sink_info_by_name +#undef pa_context_get_sink_info_by_index +#undef pa_context_get_sink_info_list +#undef pa_context_set_sink_volume_by_index +#undef pa_context_set_sink_volume_by_name +#undef pa_context_set_sink_mute_by_index +#undef pa_context_set_sink_mute_by_name +#undef pa_context_suspend_sink_by_name +#undef pa_context_suspend_sink_by_index +#undef pa_context_set_sink_port_by_index +#undef pa_context_set_sink_port_by_name +#undef pa_context_get_source_info_by_name +#undef pa_context_get_source_info_by_index +#undef pa_context_get_source_info_list +#undef pa_context_set_source_volume_by_index +#undef pa_context_set_source_volume_by_name +#undef pa_context_set_source_mute_by_index +#undef pa_context_set_source_mute_by_name +#undef pa_context_suspend_source_by_name +#undef pa_context_suspend_source_by_index +#undef pa_context_set_source_port_by_index +#undef pa_context_set_source_port_by_name +#undef pa_context_get_server_info +#undef pa_context_get_module_info +#undef pa_context_get_module_info_list +#undef pa_context_load_module +#undef pa_context_unload_module +#undef pa_context_get_client_info +#undef pa_context_get_client_info_list +#undef pa_context_kill_client +#undef pa_context_get_card_info_by_index +#undef pa_context_get_card_info_by_name +#undef pa_context_get_card_info_list +#undef pa_context_set_card_profile_by_index +#undef pa_context_set_card_profile_by_name +#undef pa_context_set_port_latency_offset +#undef pa_context_get_sink_input_info +#undef pa_context_get_sink_input_info_list +#undef pa_context_move_sink_input_by_name +#undef pa_context_move_sink_input_by_index +#undef pa_context_set_sink_input_volume +#undef pa_context_set_sink_input_mute +#undef pa_context_kill_sink_input +#undef pa_context_get_source_output_info +#undef pa_context_get_source_output_info_list +#undef pa_context_move_source_output_by_name +#undef pa_context_move_source_output_by_index +#undef pa_context_set_source_output_volume +#undef pa_context_set_source_output_mute +#undef pa_context_kill_source_output +#undef pa_context_stat +#undef pa_context_get_sample_info_by_name +#undef pa_context_get_sample_info_by_index +#undef pa_context_get_sample_info_list +#undef pa_context_get_autoload_info_by_name +#undef pa_context_get_autoload_info_by_index +#undef pa_context_get_autoload_info_list +#undef pa_context_add_autoload +#undef pa_context_remove_autoload_by_name +#undef pa_context_remove_autoload_by_index +#undef pa_context_subscribe +#undef pa_context_set_subscribe_callback +#undef pa_stream_connect_upload +#undef pa_stream_finish_upload +#undef pa_context_remove_sample +#undef pa_context_play_sample +#undef pa_context_play_sample_with_proplist +#undef pa_strerror +#undef pa_xmalloc +#undef pa_xmalloc0 +#undef pa_xrealloc +#undef pa_xfree +#undef pa_xstrdup +#undef pa_xstrndup +#undef pa_xmemdup +#undef pa_utf8_valid +#undef pa_ascii_valid +#undef pa_utf8_filter +#undef pa_ascii_filter +#undef pa_utf8_to_locale +#undef pa_locale_to_utf8 +#undef pa_threaded_mainloop_new +#undef pa_threaded_mainloop_free +#undef pa_threaded_mainloop_start +#undef pa_threaded_mainloop_stop +#undef pa_threaded_mainloop_lock +#undef pa_threaded_mainloop_unlock +#undef pa_threaded_mainloop_wait +#undef pa_threaded_mainloop_signal +#undef pa_threaded_mainloop_accept +#undef pa_threaded_mainloop_get_retval +#undef pa_threaded_mainloop_get_api +#undef pa_threaded_mainloop_in_thread +#undef pa_threaded_mainloop_set_name +#undef pa_threaded_mainloop_once_unlocked +#undef pa_mainloop_new +#undef pa_mainloop_free +#undef pa_mainloop_prepare +#undef pa_mainloop_poll +#undef pa_mainloop_dispatch +#undef pa_mainloop_get_retval +#undef pa_mainloop_iterate +#undef pa_mainloop_run +#undef pa_mainloop_get_api +#undef pa_mainloop_quit +#undef pa_mainloop_wakeup +#undef pa_mainloop_set_poll_func +#undef pa_signal_init +#undef pa_signal_done +#undef pa_signal_new +#undef pa_signal_free +#undef pa_signal_set_destroy +#undef pa_get_user_name +#undef pa_get_host_name +#undef pa_get_fqdn +#undef pa_get_home_dir +#undef pa_get_binary_name +#undef pa_path_get_filename +#undef pa_msleep +#undef pa_thread_make_realtime +#undef pa_gettimeofday +#undef pa_timeval_diff +#undef pa_timeval_cmp +#undef pa_timeval_age +#undef pa_timeval_add +#undef pa_timeval_sub +#undef pa_timeval_store +#undef pa_timeval_load +#undef pa_rtclock_now +#ifdef __cplusplus +extern "C" { +#endif +#define pa_get_library_version pa_get_library_version_dylibloader_wrapper_pulse +#define pa_bytes_per_second pa_bytes_per_second_dylibloader_wrapper_pulse +#define pa_frame_size pa_frame_size_dylibloader_wrapper_pulse +#define pa_sample_size pa_sample_size_dylibloader_wrapper_pulse +#define pa_sample_size_of_format pa_sample_size_of_format_dylibloader_wrapper_pulse +#define pa_bytes_to_usec pa_bytes_to_usec_dylibloader_wrapper_pulse +#define pa_usec_to_bytes pa_usec_to_bytes_dylibloader_wrapper_pulse +#define pa_sample_spec_init pa_sample_spec_init_dylibloader_wrapper_pulse +#define pa_sample_format_valid pa_sample_format_valid_dylibloader_wrapper_pulse +#define pa_sample_rate_valid pa_sample_rate_valid_dylibloader_wrapper_pulse +#define pa_channels_valid pa_channels_valid_dylibloader_wrapper_pulse +#define pa_sample_spec_valid pa_sample_spec_valid_dylibloader_wrapper_pulse +#define pa_sample_spec_equal pa_sample_spec_equal_dylibloader_wrapper_pulse +#define pa_sample_format_to_string pa_sample_format_to_string_dylibloader_wrapper_pulse +#define pa_parse_sample_format pa_parse_sample_format_dylibloader_wrapper_pulse +#define pa_sample_spec_snprint pa_sample_spec_snprint_dylibloader_wrapper_pulse +#define pa_bytes_snprint pa_bytes_snprint_dylibloader_wrapper_pulse +#define pa_sample_format_is_le pa_sample_format_is_le_dylibloader_wrapper_pulse +#define pa_sample_format_is_be pa_sample_format_is_be_dylibloader_wrapper_pulse +#define pa_direction_valid pa_direction_valid_dylibloader_wrapper_pulse +#define pa_direction_to_string pa_direction_to_string_dylibloader_wrapper_pulse +#define pa_mainloop_api_once pa_mainloop_api_once_dylibloader_wrapper_pulse +#define pa_proplist_new pa_proplist_new_dylibloader_wrapper_pulse +#define pa_proplist_free pa_proplist_free_dylibloader_wrapper_pulse +#define pa_proplist_key_valid pa_proplist_key_valid_dylibloader_wrapper_pulse +#define pa_proplist_sets pa_proplist_sets_dylibloader_wrapper_pulse +#define pa_proplist_setp pa_proplist_setp_dylibloader_wrapper_pulse +#define pa_proplist_setf pa_proplist_setf_dylibloader_wrapper_pulse +#define pa_proplist_set pa_proplist_set_dylibloader_wrapper_pulse +#define pa_proplist_gets pa_proplist_gets_dylibloader_wrapper_pulse +#define pa_proplist_get pa_proplist_get_dylibloader_wrapper_pulse +#define pa_proplist_update pa_proplist_update_dylibloader_wrapper_pulse +#define pa_proplist_unset pa_proplist_unset_dylibloader_wrapper_pulse +#define pa_proplist_unset_many pa_proplist_unset_many_dylibloader_wrapper_pulse +#define pa_proplist_iterate pa_proplist_iterate_dylibloader_wrapper_pulse +#define pa_proplist_to_string pa_proplist_to_string_dylibloader_wrapper_pulse +#define pa_proplist_to_string_sep pa_proplist_to_string_sep_dylibloader_wrapper_pulse +#define pa_proplist_from_string pa_proplist_from_string_dylibloader_wrapper_pulse +#define pa_proplist_contains pa_proplist_contains_dylibloader_wrapper_pulse +#define pa_proplist_clear pa_proplist_clear_dylibloader_wrapper_pulse +#define pa_proplist_copy pa_proplist_copy_dylibloader_wrapper_pulse +#define pa_proplist_size pa_proplist_size_dylibloader_wrapper_pulse +#define pa_proplist_isempty pa_proplist_isempty_dylibloader_wrapper_pulse +#define pa_proplist_equal pa_proplist_equal_dylibloader_wrapper_pulse +#define pa_channel_map_init pa_channel_map_init_dylibloader_wrapper_pulse +#define pa_channel_map_init_mono pa_channel_map_init_mono_dylibloader_wrapper_pulse +#define pa_channel_map_init_stereo pa_channel_map_init_stereo_dylibloader_wrapper_pulse +#define pa_channel_map_init_auto pa_channel_map_init_auto_dylibloader_wrapper_pulse +#define pa_channel_map_init_extend pa_channel_map_init_extend_dylibloader_wrapper_pulse +#define pa_channel_position_to_string pa_channel_position_to_string_dylibloader_wrapper_pulse +#define pa_channel_position_from_string pa_channel_position_from_string_dylibloader_wrapper_pulse +#define pa_channel_position_to_pretty_string pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse +#define pa_channel_map_snprint pa_channel_map_snprint_dylibloader_wrapper_pulse +#define pa_channel_map_parse pa_channel_map_parse_dylibloader_wrapper_pulse +#define pa_channel_map_equal pa_channel_map_equal_dylibloader_wrapper_pulse +#define pa_channel_map_valid pa_channel_map_valid_dylibloader_wrapper_pulse +#define pa_channel_map_compatible pa_channel_map_compatible_dylibloader_wrapper_pulse +#define pa_channel_map_superset pa_channel_map_superset_dylibloader_wrapper_pulse +#define pa_channel_map_can_balance pa_channel_map_can_balance_dylibloader_wrapper_pulse +#define pa_channel_map_can_fade pa_channel_map_can_fade_dylibloader_wrapper_pulse +#define pa_channel_map_can_lfe_balance pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse +#define pa_channel_map_to_name pa_channel_map_to_name_dylibloader_wrapper_pulse +#define pa_channel_map_to_pretty_name pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse +#define pa_channel_map_has_position pa_channel_map_has_position_dylibloader_wrapper_pulse +#define pa_channel_map_mask pa_channel_map_mask_dylibloader_wrapper_pulse +#define pa_encoding_to_string pa_encoding_to_string_dylibloader_wrapper_pulse +#define pa_encoding_from_string pa_encoding_from_string_dylibloader_wrapper_pulse +#define pa_format_info_new pa_format_info_new_dylibloader_wrapper_pulse +#define pa_format_info_copy pa_format_info_copy_dylibloader_wrapper_pulse +#define pa_format_info_free pa_format_info_free_dylibloader_wrapper_pulse +#define pa_format_info_valid pa_format_info_valid_dylibloader_wrapper_pulse +#define pa_format_info_is_pcm pa_format_info_is_pcm_dylibloader_wrapper_pulse +#define pa_format_info_is_compatible pa_format_info_is_compatible_dylibloader_wrapper_pulse +#define pa_format_info_snprint pa_format_info_snprint_dylibloader_wrapper_pulse +#define pa_format_info_from_string pa_format_info_from_string_dylibloader_wrapper_pulse +#define pa_format_info_from_sample_spec pa_format_info_from_sample_spec_dylibloader_wrapper_pulse +#define pa_format_info_to_sample_spec pa_format_info_to_sample_spec_dylibloader_wrapper_pulse +#define pa_format_info_get_prop_type pa_format_info_get_prop_type_dylibloader_wrapper_pulse +#define pa_format_info_get_prop_int pa_format_info_get_prop_int_dylibloader_wrapper_pulse +#define pa_format_info_get_prop_int_range pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse +#define pa_format_info_get_prop_int_array pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse +#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_wrapper_pulse +#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse +#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_wrapper_pulse +#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_wrapper_pulse +#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_wrapper_pulse +#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_wrapper_pulse +#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_wrapper_pulse +#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_wrapper_pulse +#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse +#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse +#define pa_format_info_set_prop_string pa_format_info_set_prop_string_dylibloader_wrapper_pulse +#define pa_format_info_set_prop_string_array pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse +#define pa_format_info_set_sample_format pa_format_info_set_sample_format_dylibloader_wrapper_pulse +#define pa_format_info_set_rate pa_format_info_set_rate_dylibloader_wrapper_pulse +#define pa_format_info_set_channels pa_format_info_set_channels_dylibloader_wrapper_pulse +#define pa_format_info_set_channel_map pa_format_info_set_channel_map_dylibloader_wrapper_pulse +#define pa_operation_ref pa_operation_ref_dylibloader_wrapper_pulse +#define pa_operation_unref pa_operation_unref_dylibloader_wrapper_pulse +#define pa_operation_cancel pa_operation_cancel_dylibloader_wrapper_pulse +#define pa_operation_get_state pa_operation_get_state_dylibloader_wrapper_pulse +#define pa_operation_set_state_callback pa_operation_set_state_callback_dylibloader_wrapper_pulse +#define pa_context_new pa_context_new_dylibloader_wrapper_pulse +#define pa_context_new_with_proplist pa_context_new_with_proplist_dylibloader_wrapper_pulse +#define pa_context_unref pa_context_unref_dylibloader_wrapper_pulse +#define pa_context_ref pa_context_ref_dylibloader_wrapper_pulse +#define pa_context_set_state_callback pa_context_set_state_callback_dylibloader_wrapper_pulse +#define pa_context_set_event_callback pa_context_set_event_callback_dylibloader_wrapper_pulse +#define pa_context_errno pa_context_errno_dylibloader_wrapper_pulse +#define pa_context_is_pending pa_context_is_pending_dylibloader_wrapper_pulse +#define pa_context_get_state pa_context_get_state_dylibloader_wrapper_pulse +#define pa_context_connect pa_context_connect_dylibloader_wrapper_pulse +#define pa_context_disconnect pa_context_disconnect_dylibloader_wrapper_pulse +#define pa_context_drain pa_context_drain_dylibloader_wrapper_pulse +#define pa_context_exit_daemon pa_context_exit_daemon_dylibloader_wrapper_pulse +#define pa_context_set_default_sink pa_context_set_default_sink_dylibloader_wrapper_pulse +#define pa_context_set_default_source pa_context_set_default_source_dylibloader_wrapper_pulse +#define pa_context_is_local pa_context_is_local_dylibloader_wrapper_pulse +#define pa_context_set_name pa_context_set_name_dylibloader_wrapper_pulse +#define pa_context_get_server pa_context_get_server_dylibloader_wrapper_pulse +#define pa_context_get_protocol_version pa_context_get_protocol_version_dylibloader_wrapper_pulse +#define pa_context_get_server_protocol_version pa_context_get_server_protocol_version_dylibloader_wrapper_pulse +#define pa_context_proplist_update pa_context_proplist_update_dylibloader_wrapper_pulse +#define pa_context_proplist_remove pa_context_proplist_remove_dylibloader_wrapper_pulse +#define pa_context_get_index pa_context_get_index_dylibloader_wrapper_pulse +#define pa_context_rttime_new pa_context_rttime_new_dylibloader_wrapper_pulse +#define pa_context_rttime_restart pa_context_rttime_restart_dylibloader_wrapper_pulse +#define pa_context_get_tile_size pa_context_get_tile_size_dylibloader_wrapper_pulse +#define pa_context_load_cookie_from_file pa_context_load_cookie_from_file_dylibloader_wrapper_pulse +#define pa_cvolume_equal pa_cvolume_equal_dylibloader_wrapper_pulse +#define pa_cvolume_init pa_cvolume_init_dylibloader_wrapper_pulse +#define pa_cvolume_set pa_cvolume_set_dylibloader_wrapper_pulse +#define pa_cvolume_snprint pa_cvolume_snprint_dylibloader_wrapper_pulse +#define pa_sw_cvolume_snprint_dB pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse +#define pa_cvolume_snprint_verbose pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse +#define pa_volume_snprint pa_volume_snprint_dylibloader_wrapper_pulse +#define pa_sw_volume_snprint_dB pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse +#define pa_volume_snprint_verbose pa_volume_snprint_verbose_dylibloader_wrapper_pulse +#define pa_cvolume_avg pa_cvolume_avg_dylibloader_wrapper_pulse +#define pa_cvolume_avg_mask pa_cvolume_avg_mask_dylibloader_wrapper_pulse +#define pa_cvolume_max pa_cvolume_max_dylibloader_wrapper_pulse +#define pa_cvolume_max_mask pa_cvolume_max_mask_dylibloader_wrapper_pulse +#define pa_cvolume_min pa_cvolume_min_dylibloader_wrapper_pulse +#define pa_cvolume_min_mask pa_cvolume_min_mask_dylibloader_wrapper_pulse +#define pa_cvolume_valid pa_cvolume_valid_dylibloader_wrapper_pulse +#define pa_cvolume_channels_equal_to pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse +#define pa_sw_volume_multiply pa_sw_volume_multiply_dylibloader_wrapper_pulse +#define pa_sw_cvolume_multiply pa_sw_cvolume_multiply_dylibloader_wrapper_pulse +#define pa_sw_cvolume_multiply_scalar pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse +#define pa_sw_volume_divide pa_sw_volume_divide_dylibloader_wrapper_pulse +#define pa_sw_cvolume_divide pa_sw_cvolume_divide_dylibloader_wrapper_pulse +#define pa_sw_cvolume_divide_scalar pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse +#define pa_sw_volume_from_dB pa_sw_volume_from_dB_dylibloader_wrapper_pulse +#define pa_sw_volume_to_dB pa_sw_volume_to_dB_dylibloader_wrapper_pulse +#define pa_sw_volume_from_linear pa_sw_volume_from_linear_dylibloader_wrapper_pulse +#define pa_sw_volume_to_linear pa_sw_volume_to_linear_dylibloader_wrapper_pulse +#define pa_cvolume_remap pa_cvolume_remap_dylibloader_wrapper_pulse +#define pa_cvolume_compatible pa_cvolume_compatible_dylibloader_wrapper_pulse +#define pa_cvolume_compatible_with_channel_map pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse +#define pa_cvolume_get_balance pa_cvolume_get_balance_dylibloader_wrapper_pulse +#define pa_cvolume_set_balance pa_cvolume_set_balance_dylibloader_wrapper_pulse +#define pa_cvolume_get_fade pa_cvolume_get_fade_dylibloader_wrapper_pulse +#define pa_cvolume_set_fade pa_cvolume_set_fade_dylibloader_wrapper_pulse +#define pa_cvolume_get_lfe_balance pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse +#define pa_cvolume_set_lfe_balance pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse +#define pa_cvolume_scale pa_cvolume_scale_dylibloader_wrapper_pulse +#define pa_cvolume_scale_mask pa_cvolume_scale_mask_dylibloader_wrapper_pulse +#define pa_cvolume_set_position pa_cvolume_set_position_dylibloader_wrapper_pulse +#define pa_cvolume_get_position pa_cvolume_get_position_dylibloader_wrapper_pulse +#define pa_cvolume_merge pa_cvolume_merge_dylibloader_wrapper_pulse +#define pa_cvolume_inc_clamp pa_cvolume_inc_clamp_dylibloader_wrapper_pulse +#define pa_cvolume_inc pa_cvolume_inc_dylibloader_wrapper_pulse +#define pa_cvolume_dec pa_cvolume_dec_dylibloader_wrapper_pulse +#define pa_stream_new pa_stream_new_dylibloader_wrapper_pulse +#define pa_stream_new_with_proplist pa_stream_new_with_proplist_dylibloader_wrapper_pulse +#define pa_stream_new_extended pa_stream_new_extended_dylibloader_wrapper_pulse +#define pa_stream_unref pa_stream_unref_dylibloader_wrapper_pulse +#define pa_stream_ref pa_stream_ref_dylibloader_wrapper_pulse +#define pa_stream_get_state pa_stream_get_state_dylibloader_wrapper_pulse +#define pa_stream_get_context pa_stream_get_context_dylibloader_wrapper_pulse +#define pa_stream_get_index pa_stream_get_index_dylibloader_wrapper_pulse +#define pa_stream_get_device_index pa_stream_get_device_index_dylibloader_wrapper_pulse +#define pa_stream_get_device_name pa_stream_get_device_name_dylibloader_wrapper_pulse +#define pa_stream_is_suspended pa_stream_is_suspended_dylibloader_wrapper_pulse +#define pa_stream_is_corked pa_stream_is_corked_dylibloader_wrapper_pulse +#define pa_stream_connect_playback pa_stream_connect_playback_dylibloader_wrapper_pulse +#define pa_stream_connect_record pa_stream_connect_record_dylibloader_wrapper_pulse +#define pa_stream_disconnect pa_stream_disconnect_dylibloader_wrapper_pulse +#define pa_stream_begin_write pa_stream_begin_write_dylibloader_wrapper_pulse +#define pa_stream_cancel_write pa_stream_cancel_write_dylibloader_wrapper_pulse +#define pa_stream_write pa_stream_write_dylibloader_wrapper_pulse +#define pa_stream_write_ext_free pa_stream_write_ext_free_dylibloader_wrapper_pulse +#define pa_stream_peek pa_stream_peek_dylibloader_wrapper_pulse +#define pa_stream_drop pa_stream_drop_dylibloader_wrapper_pulse +#define pa_stream_writable_size pa_stream_writable_size_dylibloader_wrapper_pulse +#define pa_stream_readable_size pa_stream_readable_size_dylibloader_wrapper_pulse +#define pa_stream_drain pa_stream_drain_dylibloader_wrapper_pulse +#define pa_stream_update_timing_info pa_stream_update_timing_info_dylibloader_wrapper_pulse +#define pa_stream_set_state_callback pa_stream_set_state_callback_dylibloader_wrapper_pulse +#define pa_stream_set_write_callback pa_stream_set_write_callback_dylibloader_wrapper_pulse +#define pa_stream_set_read_callback pa_stream_set_read_callback_dylibloader_wrapper_pulse +#define pa_stream_set_overflow_callback pa_stream_set_overflow_callback_dylibloader_wrapper_pulse +#define pa_stream_get_underflow_index pa_stream_get_underflow_index_dylibloader_wrapper_pulse +#define pa_stream_set_underflow_callback pa_stream_set_underflow_callback_dylibloader_wrapper_pulse +#define pa_stream_set_started_callback pa_stream_set_started_callback_dylibloader_wrapper_pulse +#define pa_stream_set_latency_update_callback pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse +#define pa_stream_set_moved_callback pa_stream_set_moved_callback_dylibloader_wrapper_pulse +#define pa_stream_set_suspended_callback pa_stream_set_suspended_callback_dylibloader_wrapper_pulse +#define pa_stream_set_event_callback pa_stream_set_event_callback_dylibloader_wrapper_pulse +#define pa_stream_set_buffer_attr_callback pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse +#define pa_stream_cork pa_stream_cork_dylibloader_wrapper_pulse +#define pa_stream_flush pa_stream_flush_dylibloader_wrapper_pulse +#define pa_stream_prebuf pa_stream_prebuf_dylibloader_wrapper_pulse +#define pa_stream_trigger pa_stream_trigger_dylibloader_wrapper_pulse +#define pa_stream_set_name pa_stream_set_name_dylibloader_wrapper_pulse +#define pa_stream_get_time pa_stream_get_time_dylibloader_wrapper_pulse +#define pa_stream_get_latency pa_stream_get_latency_dylibloader_wrapper_pulse +#define pa_stream_get_timing_info pa_stream_get_timing_info_dylibloader_wrapper_pulse +#define pa_stream_get_sample_spec pa_stream_get_sample_spec_dylibloader_wrapper_pulse +#define pa_stream_get_channel_map pa_stream_get_channel_map_dylibloader_wrapper_pulse +#define pa_stream_get_format_info pa_stream_get_format_info_dylibloader_wrapper_pulse +#define pa_stream_get_buffer_attr pa_stream_get_buffer_attr_dylibloader_wrapper_pulse +#define pa_stream_set_buffer_attr pa_stream_set_buffer_attr_dylibloader_wrapper_pulse +#define pa_stream_update_sample_rate pa_stream_update_sample_rate_dylibloader_wrapper_pulse +#define pa_stream_proplist_update pa_stream_proplist_update_dylibloader_wrapper_pulse +#define pa_stream_proplist_remove pa_stream_proplist_remove_dylibloader_wrapper_pulse +#define pa_stream_set_monitor_stream pa_stream_set_monitor_stream_dylibloader_wrapper_pulse +#define pa_stream_get_monitor_stream pa_stream_get_monitor_stream_dylibloader_wrapper_pulse +#define pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse +#define pa_context_get_sink_info_by_index pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse +#define pa_context_get_sink_info_list pa_context_get_sink_info_list_dylibloader_wrapper_pulse +#define pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse +#define pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse +#define pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse +#define pa_context_set_sink_mute_by_name pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse +#define pa_context_suspend_sink_by_name pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse +#define pa_context_suspend_sink_by_index pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse +#define pa_context_set_sink_port_by_index pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse +#define pa_context_set_sink_port_by_name pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse +#define pa_context_get_source_info_by_name pa_context_get_source_info_by_name_dylibloader_wrapper_pulse +#define pa_context_get_source_info_by_index pa_context_get_source_info_by_index_dylibloader_wrapper_pulse +#define pa_context_get_source_info_list pa_context_get_source_info_list_dylibloader_wrapper_pulse +#define pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse +#define pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse +#define pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse +#define pa_context_set_source_mute_by_name pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse +#define pa_context_suspend_source_by_name pa_context_suspend_source_by_name_dylibloader_wrapper_pulse +#define pa_context_suspend_source_by_index pa_context_suspend_source_by_index_dylibloader_wrapper_pulse +#define pa_context_set_source_port_by_index pa_context_set_source_port_by_index_dylibloader_wrapper_pulse +#define pa_context_set_source_port_by_name pa_context_set_source_port_by_name_dylibloader_wrapper_pulse +#define pa_context_get_server_info pa_context_get_server_info_dylibloader_wrapper_pulse +#define pa_context_get_module_info pa_context_get_module_info_dylibloader_wrapper_pulse +#define pa_context_get_module_info_list pa_context_get_module_info_list_dylibloader_wrapper_pulse +#define pa_context_load_module pa_context_load_module_dylibloader_wrapper_pulse +#define pa_context_unload_module pa_context_unload_module_dylibloader_wrapper_pulse +#define pa_context_get_client_info pa_context_get_client_info_dylibloader_wrapper_pulse +#define pa_context_get_client_info_list pa_context_get_client_info_list_dylibloader_wrapper_pulse +#define pa_context_kill_client pa_context_kill_client_dylibloader_wrapper_pulse +#define pa_context_get_card_info_by_index pa_context_get_card_info_by_index_dylibloader_wrapper_pulse +#define pa_context_get_card_info_by_name pa_context_get_card_info_by_name_dylibloader_wrapper_pulse +#define pa_context_get_card_info_list pa_context_get_card_info_list_dylibloader_wrapper_pulse +#define pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse +#define pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse +#define pa_context_set_port_latency_offset pa_context_set_port_latency_offset_dylibloader_wrapper_pulse +#define pa_context_get_sink_input_info pa_context_get_sink_input_info_dylibloader_wrapper_pulse +#define pa_context_get_sink_input_info_list pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse +#define pa_context_move_sink_input_by_name pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse +#define pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse +#define pa_context_set_sink_input_volume pa_context_set_sink_input_volume_dylibloader_wrapper_pulse +#define pa_context_set_sink_input_mute pa_context_set_sink_input_mute_dylibloader_wrapper_pulse +#define pa_context_kill_sink_input pa_context_kill_sink_input_dylibloader_wrapper_pulse +#define pa_context_get_source_output_info pa_context_get_source_output_info_dylibloader_wrapper_pulse +#define pa_context_get_source_output_info_list pa_context_get_source_output_info_list_dylibloader_wrapper_pulse +#define pa_context_move_source_output_by_name pa_context_move_source_output_by_name_dylibloader_wrapper_pulse +#define pa_context_move_source_output_by_index pa_context_move_source_output_by_index_dylibloader_wrapper_pulse +#define pa_context_set_source_output_volume pa_context_set_source_output_volume_dylibloader_wrapper_pulse +#define pa_context_set_source_output_mute pa_context_set_source_output_mute_dylibloader_wrapper_pulse +#define pa_context_kill_source_output pa_context_kill_source_output_dylibloader_wrapper_pulse +#define pa_context_stat pa_context_stat_dylibloader_wrapper_pulse +#define pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse +#define pa_context_get_sample_info_by_index pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse +#define pa_context_get_sample_info_list pa_context_get_sample_info_list_dylibloader_wrapper_pulse +#define pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse +#define pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse +#define pa_context_get_autoload_info_list pa_context_get_autoload_info_list_dylibloader_wrapper_pulse +#define pa_context_add_autoload pa_context_add_autoload_dylibloader_wrapper_pulse +#define pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse +#define pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse +#define pa_context_subscribe pa_context_subscribe_dylibloader_wrapper_pulse +#define pa_context_set_subscribe_callback pa_context_set_subscribe_callback_dylibloader_wrapper_pulse +#define pa_stream_connect_upload pa_stream_connect_upload_dylibloader_wrapper_pulse +#define pa_stream_finish_upload pa_stream_finish_upload_dylibloader_wrapper_pulse +#define pa_context_remove_sample pa_context_remove_sample_dylibloader_wrapper_pulse +#define pa_context_play_sample pa_context_play_sample_dylibloader_wrapper_pulse +#define pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse +#define pa_strerror pa_strerror_dylibloader_wrapper_pulse +#define pa_xmalloc pa_xmalloc_dylibloader_wrapper_pulse +#define pa_xmalloc0 pa_xmalloc0_dylibloader_wrapper_pulse +#define pa_xrealloc pa_xrealloc_dylibloader_wrapper_pulse +#define pa_xfree pa_xfree_dylibloader_wrapper_pulse +#define pa_xstrdup pa_xstrdup_dylibloader_wrapper_pulse +#define pa_xstrndup pa_xstrndup_dylibloader_wrapper_pulse +#define pa_xmemdup pa_xmemdup_dylibloader_wrapper_pulse +#define pa_utf8_valid pa_utf8_valid_dylibloader_wrapper_pulse +#define pa_ascii_valid pa_ascii_valid_dylibloader_wrapper_pulse +#define pa_utf8_filter pa_utf8_filter_dylibloader_wrapper_pulse +#define pa_ascii_filter pa_ascii_filter_dylibloader_wrapper_pulse +#define pa_utf8_to_locale pa_utf8_to_locale_dylibloader_wrapper_pulse +#define pa_locale_to_utf8 pa_locale_to_utf8_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_new pa_threaded_mainloop_new_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_free pa_threaded_mainloop_free_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_start pa_threaded_mainloop_start_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_stop pa_threaded_mainloop_stop_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_lock pa_threaded_mainloop_lock_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_unlock pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_wait pa_threaded_mainloop_wait_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_signal pa_threaded_mainloop_signal_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_accept pa_threaded_mainloop_accept_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_get_retval pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse +#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse +#define pa_mainloop_new pa_mainloop_new_dylibloader_wrapper_pulse +#define pa_mainloop_free pa_mainloop_free_dylibloader_wrapper_pulse +#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_wrapper_pulse +#define pa_mainloop_poll pa_mainloop_poll_dylibloader_wrapper_pulse +#define pa_mainloop_dispatch pa_mainloop_dispatch_dylibloader_wrapper_pulse +#define pa_mainloop_get_retval pa_mainloop_get_retval_dylibloader_wrapper_pulse +#define pa_mainloop_iterate pa_mainloop_iterate_dylibloader_wrapper_pulse +#define pa_mainloop_run pa_mainloop_run_dylibloader_wrapper_pulse +#define pa_mainloop_get_api pa_mainloop_get_api_dylibloader_wrapper_pulse +#define pa_mainloop_quit pa_mainloop_quit_dylibloader_wrapper_pulse +#define pa_mainloop_wakeup pa_mainloop_wakeup_dylibloader_wrapper_pulse +#define pa_mainloop_set_poll_func pa_mainloop_set_poll_func_dylibloader_wrapper_pulse +#define pa_signal_init pa_signal_init_dylibloader_wrapper_pulse +#define pa_signal_done pa_signal_done_dylibloader_wrapper_pulse +#define pa_signal_new pa_signal_new_dylibloader_wrapper_pulse +#define pa_signal_free pa_signal_free_dylibloader_wrapper_pulse +#define pa_signal_set_destroy pa_signal_set_destroy_dylibloader_wrapper_pulse +#define pa_get_user_name pa_get_user_name_dylibloader_wrapper_pulse +#define pa_get_host_name pa_get_host_name_dylibloader_wrapper_pulse +#define pa_get_fqdn pa_get_fqdn_dylibloader_wrapper_pulse +#define pa_get_home_dir pa_get_home_dir_dylibloader_wrapper_pulse +#define pa_get_binary_name pa_get_binary_name_dylibloader_wrapper_pulse +#define pa_path_get_filename pa_path_get_filename_dylibloader_wrapper_pulse +#define pa_msleep pa_msleep_dylibloader_wrapper_pulse +#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_wrapper_pulse +#define pa_gettimeofday pa_gettimeofday_dylibloader_wrapper_pulse +#define pa_timeval_diff pa_timeval_diff_dylibloader_wrapper_pulse +#define pa_timeval_cmp pa_timeval_cmp_dylibloader_wrapper_pulse +#define pa_timeval_age pa_timeval_age_dylibloader_wrapper_pulse +#define pa_timeval_add pa_timeval_add_dylibloader_wrapper_pulse +#define pa_timeval_sub pa_timeval_sub_dylibloader_wrapper_pulse +#define pa_timeval_store pa_timeval_store_dylibloader_wrapper_pulse +#define pa_timeval_load pa_timeval_load_dylibloader_wrapper_pulse +#define pa_rtclock_now pa_rtclock_now_dylibloader_wrapper_pulse +extern const char* (*pa_get_library_version_dylibloader_wrapper_pulse)( void); +extern size_t (*pa_bytes_per_second_dylibloader_wrapper_pulse)(const pa_sample_spec*); +extern size_t (*pa_frame_size_dylibloader_wrapper_pulse)(const pa_sample_spec*); +extern size_t (*pa_sample_size_dylibloader_wrapper_pulse)(const pa_sample_spec*); +extern size_t (*pa_sample_size_of_format_dylibloader_wrapper_pulse)( pa_sample_format_t); +extern pa_usec_t (*pa_bytes_to_usec_dylibloader_wrapper_pulse)( uint64_t,const pa_sample_spec*); +extern size_t (*pa_usec_to_bytes_dylibloader_wrapper_pulse)( pa_usec_t,const pa_sample_spec*); +extern pa_sample_spec* (*pa_sample_spec_init_dylibloader_wrapper_pulse)( pa_sample_spec*); +extern int (*pa_sample_format_valid_dylibloader_wrapper_pulse)( unsigned); +extern int (*pa_sample_rate_valid_dylibloader_wrapper_pulse)( uint32_t); +extern int (*pa_channels_valid_dylibloader_wrapper_pulse)( uint8_t); +extern int (*pa_sample_spec_valid_dylibloader_wrapper_pulse)(const pa_sample_spec*); +extern int (*pa_sample_spec_equal_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_sample_spec*); +extern const char* (*pa_sample_format_to_string_dylibloader_wrapper_pulse)( pa_sample_format_t); +extern pa_sample_format_t (*pa_parse_sample_format_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_sample_spec_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_sample_spec*); +extern char* (*pa_bytes_snprint_dylibloader_wrapper_pulse)( char*, size_t, unsigned); +extern int (*pa_sample_format_is_le_dylibloader_wrapper_pulse)( pa_sample_format_t); +extern int (*pa_sample_format_is_be_dylibloader_wrapper_pulse)( pa_sample_format_t); +extern int (*pa_direction_valid_dylibloader_wrapper_pulse)( pa_direction_t); +extern const char* (*pa_direction_to_string_dylibloader_wrapper_pulse)( pa_direction_t); +extern void (*pa_mainloop_api_once_dylibloader_wrapper_pulse)( pa_mainloop_api*, void*, void*); +extern pa_proplist* (*pa_proplist_new_dylibloader_wrapper_pulse)( void); +extern void (*pa_proplist_free_dylibloader_wrapper_pulse)( pa_proplist*); +extern int (*pa_proplist_key_valid_dylibloader_wrapper_pulse)(const char*); +extern int (*pa_proplist_sets_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*); +extern int (*pa_proplist_setp_dylibloader_wrapper_pulse)( pa_proplist*,const char*); +extern int (*pa_proplist_setf_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*,...); +extern int (*pa_proplist_set_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void*, size_t); +extern const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)(const pa_proplist*,const char*); +extern int (*pa_proplist_get_dylibloader_wrapper_pulse)(const pa_proplist*,const char*,const void**, size_t*); +extern void (*pa_proplist_update_dylibloader_wrapper_pulse)( pa_proplist*, pa_update_mode_t,const pa_proplist*); +extern int (*pa_proplist_unset_dylibloader_wrapper_pulse)( pa_proplist*,const char*); +extern int (*pa_proplist_unset_many_dylibloader_wrapper_pulse)( pa_proplist*,const char* []); +extern const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)(const pa_proplist*, void**); +extern char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)(const pa_proplist*); +extern char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)(const pa_proplist*,const char*); +extern pa_proplist* (*pa_proplist_from_string_dylibloader_wrapper_pulse)(const char*); +extern int (*pa_proplist_contains_dylibloader_wrapper_pulse)(const pa_proplist*,const char*); +extern void (*pa_proplist_clear_dylibloader_wrapper_pulse)( pa_proplist*); +extern pa_proplist* (*pa_proplist_copy_dylibloader_wrapper_pulse)(const pa_proplist*); +extern unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)(const pa_proplist*); +extern int (*pa_proplist_isempty_dylibloader_wrapper_pulse)(const pa_proplist*); +extern int (*pa_proplist_equal_dylibloader_wrapper_pulse)(const pa_proplist*,const pa_proplist*); +extern pa_channel_map* (*pa_channel_map_init_dylibloader_wrapper_pulse)( pa_channel_map*); +extern pa_channel_map* (*pa_channel_map_init_mono_dylibloader_wrapper_pulse)( pa_channel_map*); +extern pa_channel_map* (*pa_channel_map_init_stereo_dylibloader_wrapper_pulse)( pa_channel_map*); +extern pa_channel_map* (*pa_channel_map_init_auto_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t); +extern pa_channel_map* (*pa_channel_map_init_extend_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t); +extern const char* (*pa_channel_position_to_string_dylibloader_wrapper_pulse)( pa_channel_position_t); +extern pa_channel_position_t (*pa_channel_position_from_string_dylibloader_wrapper_pulse)(const char*); +extern const char* (*pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse)( pa_channel_position_t); +extern char* (*pa_channel_map_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_channel_map*); +extern pa_channel_map* (*pa_channel_map_parse_dylibloader_wrapper_pulse)( pa_channel_map*,const char*); +extern int (*pa_channel_map_equal_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*); +extern int (*pa_channel_map_valid_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern int (*pa_channel_map_compatible_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_sample_spec*); +extern int (*pa_channel_map_superset_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*); +extern int (*pa_channel_map_can_balance_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern int (*pa_channel_map_can_fade_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern int (*pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern const char* (*pa_channel_map_to_name_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern const char* (*pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern int (*pa_channel_map_has_position_dylibloader_wrapper_pulse)(const pa_channel_map*, pa_channel_position_t); +extern pa_channel_position_mask_t (*pa_channel_map_mask_dylibloader_wrapper_pulse)(const pa_channel_map*); +extern const char* (*pa_encoding_to_string_dylibloader_wrapper_pulse)( pa_encoding_t); +extern pa_encoding_t (*pa_encoding_from_string_dylibloader_wrapper_pulse)(const char*); +extern pa_format_info* (*pa_format_info_new_dylibloader_wrapper_pulse)( void); +extern pa_format_info* (*pa_format_info_copy_dylibloader_wrapper_pulse)(const pa_format_info*); +extern void (*pa_format_info_free_dylibloader_wrapper_pulse)( pa_format_info*); +extern int (*pa_format_info_valid_dylibloader_wrapper_pulse)(const pa_format_info*); +extern int (*pa_format_info_is_pcm_dylibloader_wrapper_pulse)(const pa_format_info*); +extern int (*pa_format_info_is_compatible_dylibloader_wrapper_pulse)(const pa_format_info*,const pa_format_info*); +extern char* (*pa_format_info_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_format_info*); +extern pa_format_info* (*pa_format_info_from_string_dylibloader_wrapper_pulse)(const char*); +extern pa_format_info* (*pa_format_info_from_sample_spec_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_channel_map*); +extern int (*pa_format_info_to_sample_spec_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_spec*, pa_channel_map*); +extern pa_prop_type_t (*pa_format_info_get_prop_type_dylibloader_wrapper_pulse)(const pa_format_info*,const char*); +extern int (*pa_format_info_get_prop_int_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*); +extern int (*pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*, int*); +extern int (*pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int**, int*); +extern int (*pa_format_info_get_prop_string_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char**); +extern int (*pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char***, int*); +extern void (*pa_format_info_free_string_array_dylibloader_wrapper_pulse)( char**, int); +extern int (*pa_format_info_get_sample_format_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_format_t*); +extern int (*pa_format_info_get_rate_dylibloader_wrapper_pulse)(const pa_format_info*, uint32_t*); +extern int (*pa_format_info_get_channels_dylibloader_wrapper_pulse)(const pa_format_info*, uint8_t*); +extern int (*pa_format_info_get_channel_map_dylibloader_wrapper_pulse)(const pa_format_info*, pa_channel_map*); +extern void (*pa_format_info_set_prop_int_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int); +extern void (*pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const int*, int); +extern void (*pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int, int); +extern void (*pa_format_info_set_prop_string_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char*); +extern void (*pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char**, int); +extern void (*pa_format_info_set_sample_format_dylibloader_wrapper_pulse)( pa_format_info*, pa_sample_format_t); +extern void (*pa_format_info_set_rate_dylibloader_wrapper_pulse)( pa_format_info*, int); +extern void (*pa_format_info_set_channels_dylibloader_wrapper_pulse)( pa_format_info*, int); +extern void (*pa_format_info_set_channel_map_dylibloader_wrapper_pulse)( pa_format_info*,const pa_channel_map*); +extern pa_operation* (*pa_operation_ref_dylibloader_wrapper_pulse)( pa_operation*); +extern void (*pa_operation_unref_dylibloader_wrapper_pulse)( pa_operation*); +extern void (*pa_operation_cancel_dylibloader_wrapper_pulse)( pa_operation*); +extern pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)(const pa_operation*); +extern void (*pa_operation_set_state_callback_dylibloader_wrapper_pulse)( pa_operation*, pa_operation_notify_cb_t, void*); +extern pa_context* (*pa_context_new_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*); +extern pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*,const pa_proplist*); +extern void (*pa_context_unref_dylibloader_wrapper_pulse)( pa_context*); +extern pa_context* (*pa_context_ref_dylibloader_wrapper_pulse)( pa_context*); +extern void (*pa_context_set_state_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*); +extern void (*pa_context_set_event_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_event_cb_t, void*); +extern int (*pa_context_errno_dylibloader_wrapper_pulse)(const pa_context*); +extern int (*pa_context_is_pending_dylibloader_wrapper_pulse)(const pa_context*); +extern pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)(const pa_context*); +extern int (*pa_context_connect_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_flags_t,const pa_spawn_api*); +extern void (*pa_context_disconnect_dylibloader_wrapper_pulse)( pa_context*); +extern pa_operation* (*pa_context_drain_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*); +extern pa_operation* (*pa_context_exit_daemon_dylibloader_wrapper_pulse)( pa_context*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_default_sink_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_default_source_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +extern int (*pa_context_is_local_dylibloader_wrapper_pulse)(const pa_context*); +extern pa_operation* (*pa_context_set_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +extern const char* (*pa_context_get_server_dylibloader_wrapper_pulse)(const pa_context*); +extern uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)(const pa_context*); +extern uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)(const pa_context*); +extern pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t,const pa_proplist*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_proplist_remove_dylibloader_wrapper_pulse)( pa_context*,const char* [], pa_context_success_cb_t, void*); +extern uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)(const pa_context*); +extern pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)(const pa_context*, pa_usec_t, pa_time_event_cb_t, void*); +extern void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)(const pa_context*, pa_time_event*, pa_usec_t); +extern size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)(const pa_context*,const pa_sample_spec*); +extern int (*pa_context_load_cookie_from_file_dylibloader_wrapper_pulse)( pa_context*,const char*); +extern int (*pa_cvolume_equal_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_cvolume*); +extern pa_cvolume* (*pa_cvolume_init_dylibloader_wrapper_pulse)( pa_cvolume*); +extern pa_cvolume* (*pa_cvolume_set_dylibloader_wrapper_pulse)( pa_cvolume*, unsigned, pa_volume_t); +extern char* (*pa_cvolume_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*); +extern char* (*pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*); +extern char* (*pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*,const pa_channel_map*, int); +extern char* (*pa_volume_snprint_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t); +extern char* (*pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t); +extern char* (*pa_volume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t, int); +extern pa_volume_t (*pa_cvolume_avg_dylibloader_wrapper_pulse)(const pa_cvolume*); +extern pa_volume_t (*pa_cvolume_avg_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t); +extern pa_volume_t (*pa_cvolume_max_dylibloader_wrapper_pulse)(const pa_cvolume*); +extern pa_volume_t (*pa_cvolume_max_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t); +extern pa_volume_t (*pa_cvolume_min_dylibloader_wrapper_pulse)(const pa_cvolume*); +extern pa_volume_t (*pa_cvolume_min_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t); +extern int (*pa_cvolume_valid_dylibloader_wrapper_pulse)(const pa_cvolume*); +extern int (*pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse)(const pa_cvolume*, pa_volume_t); +extern pa_volume_t (*pa_sw_volume_multiply_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t); +extern pa_cvolume* (*pa_sw_cvolume_multiply_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*); +extern pa_cvolume* (*pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t); +extern pa_volume_t (*pa_sw_volume_divide_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t); +extern pa_cvolume* (*pa_sw_cvolume_divide_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*); +extern pa_cvolume* (*pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t); +extern pa_volume_t (*pa_sw_volume_from_dB_dylibloader_wrapper_pulse)( double); +extern double (*pa_sw_volume_to_dB_dylibloader_wrapper_pulse)( pa_volume_t); +extern pa_volume_t (*pa_sw_volume_from_linear_dylibloader_wrapper_pulse)( double); +extern double (*pa_sw_volume_to_linear_dylibloader_wrapper_pulse)( pa_volume_t); +extern pa_cvolume* (*pa_cvolume_remap_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*,const pa_channel_map*); +extern int (*pa_cvolume_compatible_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_sample_spec*); +extern int (*pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +extern float (*pa_cvolume_get_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +extern pa_cvolume* (*pa_cvolume_set_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float); +extern float (*pa_cvolume_get_fade_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +extern pa_cvolume* (*pa_cvolume_set_fade_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float); +extern float (*pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*); +extern pa_cvolume* (*pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float); +extern pa_cvolume* (*pa_cvolume_scale_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t); +extern pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t,const pa_channel_map*, pa_channel_position_mask_t); +extern pa_cvolume* (*pa_cvolume_set_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t, pa_volume_t); +extern pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_t); +extern pa_cvolume* (*pa_cvolume_merge_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*); +extern pa_cvolume* (*pa_cvolume_inc_clamp_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_volume_t); +extern pa_cvolume* (*pa_cvolume_inc_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t); +extern pa_cvolume* (*pa_cvolume_dec_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t); +extern pa_stream* (*pa_stream_new_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*); +extern pa_stream* (*pa_stream_new_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*, pa_proplist*); +extern pa_stream* (*pa_stream_new_extended_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_format_info**, unsigned int, pa_proplist*); +extern void (*pa_stream_unref_dylibloader_wrapper_pulse)( pa_stream*); +extern pa_stream* (*pa_stream_ref_dylibloader_wrapper_pulse)( pa_stream*); +extern pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)(const pa_stream*); +extern pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)(const pa_stream*); +extern uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)(const pa_stream*); +extern uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)(const pa_stream*); +extern const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)(const pa_stream*); +extern int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)(const pa_stream*); +extern int (*pa_stream_is_corked_dylibloader_wrapper_pulse)(const pa_stream*); +extern int (*pa_stream_connect_playback_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t,const pa_cvolume*, pa_stream*); +extern int (*pa_stream_connect_record_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t); +extern int (*pa_stream_disconnect_dylibloader_wrapper_pulse)( pa_stream*); +extern int (*pa_stream_begin_write_dylibloader_wrapper_pulse)( pa_stream*, void**, size_t*); +extern int (*pa_stream_cancel_write_dylibloader_wrapper_pulse)( pa_stream*); +extern int (*pa_stream_write_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t); +extern int (*pa_stream_write_ext_free_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, void*, int64_t, pa_seek_mode_t); +extern int (*pa_stream_peek_dylibloader_wrapper_pulse)( pa_stream*,const void**, size_t*); +extern int (*pa_stream_drop_dylibloader_wrapper_pulse)( pa_stream*); +extern size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)(const pa_stream*); +extern size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)(const pa_stream*); +extern pa_operation* (*pa_stream_drain_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_update_timing_info_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +extern void (*pa_stream_set_state_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern void (*pa_stream_set_write_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*); +extern void (*pa_stream_set_read_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*); +extern void (*pa_stream_set_overflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)(const pa_stream*); +extern void (*pa_stream_set_underflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern void (*pa_stream_set_started_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern void (*pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern void (*pa_stream_set_moved_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern void (*pa_stream_set_suspended_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern void (*pa_stream_set_event_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_event_cb_t, void*); +extern void (*pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*); +extern pa_operation* (*pa_stream_cork_dylibloader_wrapper_pulse)( pa_stream*, int, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_flush_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_prebuf_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_trigger_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_set_name_dylibloader_wrapper_pulse)( pa_stream*,const char*, pa_stream_success_cb_t, void*); +extern int (*pa_stream_get_time_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*); +extern int (*pa_stream_get_latency_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*, int*); +extern const pa_timing_info* (*pa_stream_get_timing_info_dylibloader_wrapper_pulse)( pa_stream*); +extern const pa_sample_spec* (*pa_stream_get_sample_spec_dylibloader_wrapper_pulse)( pa_stream*); +extern const pa_channel_map* (*pa_stream_get_channel_map_dylibloader_wrapper_pulse)( pa_stream*); +extern const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)(const pa_stream*); +extern const pa_buffer_attr* (*pa_stream_get_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*); +extern pa_operation* (*pa_stream_set_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*,const pa_buffer_attr*, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_update_sample_rate_dylibloader_wrapper_pulse)( pa_stream*, uint32_t, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_proplist_update_dylibloader_wrapper_pulse)( pa_stream*, pa_update_mode_t, pa_proplist*, pa_stream_success_cb_t, void*); +extern pa_operation* (*pa_stream_proplist_remove_dylibloader_wrapper_pulse)( pa_stream*,const char* [], pa_stream_success_cb_t, void*); +extern int (*pa_stream_set_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*, uint32_t); +extern uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)(const pa_stream*); +extern pa_operation* (*pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sink_info_cb_t, void*); +extern pa_operation* (*pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_info_cb_t, void*); +extern pa_operation* (*pa_context_get_sink_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_info_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_get_source_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_source_info_cb_t, void*); +extern pa_operation* (*pa_context_get_source_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_info_cb_t, void*); +extern pa_operation* (*pa_context_get_source_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_info_cb_t, void*); +extern pa_operation* (*pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_suspend_source_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_suspend_source_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_get_server_info_dylibloader_wrapper_pulse)( pa_context*, pa_server_info_cb_t, void*); +extern pa_operation* (*pa_context_get_module_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_module_info_cb_t, void*); +extern pa_operation* (*pa_context_get_module_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_module_info_cb_t, void*); +extern pa_operation* (*pa_context_load_module_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_index_cb_t, void*); +extern pa_operation* (*pa_context_unload_module_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_get_client_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_client_info_cb_t, void*); +extern pa_operation* (*pa_context_get_client_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_client_info_cb_t, void*); +extern pa_operation* (*pa_context_kill_client_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_get_card_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_card_info_cb_t, void*); +extern pa_operation* (*pa_context_get_card_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_card_info_cb_t, void*); +extern pa_operation* (*pa_context_get_card_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_card_info_cb_t, void*); +extern pa_operation* (*pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_port_latency_offset_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, int64_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_get_sink_input_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_input_info_cb_t, void*); +extern pa_operation* (*pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_input_info_cb_t, void*); +extern pa_operation* (*pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_input_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_sink_input_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_kill_sink_input_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_get_source_output_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_output_info_cb_t, void*); +extern pa_operation* (*pa_context_get_source_output_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_output_info_cb_t, void*); +extern pa_operation* (*pa_context_move_source_output_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_move_source_output_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_output_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_set_source_output_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_kill_source_output_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_stat_dylibloader_wrapper_pulse)( pa_context*, pa_stat_info_cb_t, void*); +extern pa_operation* (*pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sample_info_cb_t, void*); +extern pa_operation* (*pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sample_info_cb_t, void*); +extern pa_operation* (*pa_context_get_sample_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sample_info_cb_t, void*); +extern pa_operation* (*pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_autoload_info_cb_t, void*); +extern pa_operation* (*pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_autoload_info_cb_t, void*); +extern pa_operation* (*pa_context_get_autoload_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_autoload_info_cb_t, void*); +extern pa_operation* (*pa_context_add_autoload_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t,const char*,const char*, pa_context_index_cb_t, void*); +extern pa_operation* (*pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_subscribe_dylibloader_wrapper_pulse)( pa_context*, pa_subscription_mask_t, pa_context_success_cb_t, void*); +extern void (*pa_context_set_subscribe_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_subscribe_cb_t, void*); +extern int (*pa_stream_connect_upload_dylibloader_wrapper_pulse)( pa_stream*, size_t); +extern int (*pa_stream_finish_upload_dylibloader_wrapper_pulse)( pa_stream*); +extern pa_operation* (*pa_context_remove_sample_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_play_sample_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_context_success_cb_t, void*); +extern pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t,const pa_proplist*, pa_context_play_sample_cb_t, void*); +extern const char* (*pa_strerror_dylibloader_wrapper_pulse)( int); +extern void* (*pa_xmalloc_dylibloader_wrapper_pulse)( size_t); +extern void* (*pa_xmalloc0_dylibloader_wrapper_pulse)( size_t); +extern void* (*pa_xrealloc_dylibloader_wrapper_pulse)( void*, size_t); +extern void (*pa_xfree_dylibloader_wrapper_pulse)( void*); +extern char* (*pa_xstrdup_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_xstrndup_dylibloader_wrapper_pulse)(const char*, size_t); +extern void* (*pa_xmemdup_dylibloader_wrapper_pulse)(const void*, size_t); +extern char* (*pa_utf8_valid_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_ascii_valid_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_utf8_filter_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_ascii_filter_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_utf8_to_locale_dylibloader_wrapper_pulse)(const char*); +extern char* (*pa_locale_to_utf8_dylibloader_wrapper_pulse)(const char*); +extern pa_threaded_mainloop* (*pa_threaded_mainloop_new_dylibloader_wrapper_pulse)( void); +extern void (*pa_threaded_mainloop_free_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern int (*pa_threaded_mainloop_start_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern void (*pa_threaded_mainloop_stop_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern void (*pa_threaded_mainloop_lock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern void (*pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern void (*pa_threaded_mainloop_wait_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern void (*pa_threaded_mainloop_signal_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, int); +extern void (*pa_threaded_mainloop_accept_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_threaded_mainloop*); +extern pa_mainloop_api* (*pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern int (*pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse)( pa_threaded_mainloop*); +extern void (*pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse)( pa_threaded_mainloop*,const char*); +extern void (*pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, void*, void*); +extern pa_mainloop* (*pa_mainloop_new_dylibloader_wrapper_pulse)( void); +extern void (*pa_mainloop_free_dylibloader_wrapper_pulse)( pa_mainloop*); +extern int (*pa_mainloop_prepare_dylibloader_wrapper_pulse)( pa_mainloop*, int); +extern int (*pa_mainloop_poll_dylibloader_wrapper_pulse)( pa_mainloop*); +extern int (*pa_mainloop_dispatch_dylibloader_wrapper_pulse)( pa_mainloop*); +extern int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_mainloop*); +extern int (*pa_mainloop_iterate_dylibloader_wrapper_pulse)( pa_mainloop*, int, int*); +extern int (*pa_mainloop_run_dylibloader_wrapper_pulse)( pa_mainloop*, int*); +extern pa_mainloop_api* (*pa_mainloop_get_api_dylibloader_wrapper_pulse)( pa_mainloop*); +extern void (*pa_mainloop_quit_dylibloader_wrapper_pulse)( pa_mainloop*, int); +extern void (*pa_mainloop_wakeup_dylibloader_wrapper_pulse)( pa_mainloop*); +extern void (*pa_mainloop_set_poll_func_dylibloader_wrapper_pulse)( pa_mainloop*, pa_poll_func, void*); +extern int (*pa_signal_init_dylibloader_wrapper_pulse)( pa_mainloop_api*); +extern void (*pa_signal_done_dylibloader_wrapper_pulse)( void); +extern pa_signal_event* (*pa_signal_new_dylibloader_wrapper_pulse)( int, pa_signal_cb_t, void*); +extern void (*pa_signal_free_dylibloader_wrapper_pulse)( pa_signal_event*); +extern void (*pa_signal_set_destroy_dylibloader_wrapper_pulse)( pa_signal_event*, pa_signal_destroy_cb_t); +extern char* (*pa_get_user_name_dylibloader_wrapper_pulse)( char*, size_t); +extern char* (*pa_get_host_name_dylibloader_wrapper_pulse)( char*, size_t); +extern char* (*pa_get_fqdn_dylibloader_wrapper_pulse)( char*, size_t); +extern char* (*pa_get_home_dir_dylibloader_wrapper_pulse)( char*, size_t); +extern char* (*pa_get_binary_name_dylibloader_wrapper_pulse)( char*, size_t); +extern char* (*pa_path_get_filename_dylibloader_wrapper_pulse)(const char*); +extern int (*pa_msleep_dylibloader_wrapper_pulse)( unsigned long); +extern int (*pa_thread_make_realtime_dylibloader_wrapper_pulse)( int); +extern struct timeval* (*pa_gettimeofday_dylibloader_wrapper_pulse)(struct timeval*); +extern pa_usec_t (*pa_timeval_diff_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*); +extern int (*pa_timeval_cmp_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*); +extern pa_usec_t (*pa_timeval_age_dylibloader_wrapper_pulse)(struct timeval*); +extern struct timeval* (*pa_timeval_add_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t); +extern struct timeval* (*pa_timeval_sub_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t); +extern struct timeval* (*pa_timeval_store_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t); +extern pa_usec_t (*pa_timeval_load_dylibloader_wrapper_pulse)(struct timeval*); +extern pa_usec_t (*pa_rtclock_now_dylibloader_wrapper_pulse)( void); +int initialize_pulse(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 5dc039afd9..eda929850c 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -232,7 +232,7 @@ static void _get_drives(List<String> *list) { // Parse only file:// links if (strncmp(string, "file://", 7) == 0) { // Strip any unwanted edges on the strings and push_back if it's not a duplicate - String fpath = String(string + 7).strip_edges().split_spaces()[0].percent_decode(); + String fpath = String(string + 7).strip_edges().split_spaces()[0].uri_decode(); if (!list->find(fpath)) { list->push_back(fpath); } diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index d9c2a754d6..b9bd773c2e 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -35,11 +35,9 @@ #include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" -#include "core/os/thread_dummy.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "drivers/unix/net_socket_posix.h" -#include "drivers/unix/rw_lock_posix.h" #include "drivers/unix/thread_posix.h" #include "servers/rendering_server.h" @@ -64,6 +62,7 @@ #include <string.h> #include <sys/time.h> #include <sys/wait.h> +#include <time.h> #include <unistd.h> /// Clock Setup function (used by get_ticks_usec) @@ -117,13 +116,10 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) { } void OS_Unix::initialize_core() { -#ifdef NO_THREADS - ThreadDummy::make_default(); - RWLockDummy::make_default(); -#else - ThreadPosix::make_default(); - RWLockPosix::make_default(); +#if !defined(NO_THREADS) + init_thread_posix(); #endif + FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA); FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM); @@ -234,8 +230,11 @@ OS::TimeZoneInfo OS_Unix::get_time_zone_info() const { } void OS_Unix::delay_usec(uint32_t p_usec) const { - struct timespec rem = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 }; - while (nanosleep(&rem, &rem) == EINTR) { + struct timespec requested = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 }; + struct timespec remaining; + while (nanosleep(&requested, &remaining) == -1 && errno == EINTR) { + requested.tv_sec = remaining.tv_sec; + requested.tv_nsec = remaining.tv_nsec; } } @@ -254,31 +253,26 @@ uint64_t OS_Unix::get_ticks_usec() const { return longtime; } -Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { +Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { #ifdef __EMSCRIPTEN__ // Don't compile this code at all to avoid undefined references. // Actual virtual call goes to OS_JavaScript. ERR_FAIL_V(ERR_BUG); #else - if (p_blocking && r_pipe) { - String argss; - argss = "\"" + p_path + "\""; - + if (r_pipe) { + String command = "\"" + p_path + "\""; for (int i = 0; i < p_arguments.size(); i++) { - argss += String(" \"") + p_arguments[i] + "\""; + command += String(" \"") + p_arguments[i] + "\""; } - if (read_stderr) { - argss += " 2>&1"; // Read stderr too + command += " 2>&1"; // Include stderr } else { - argss += " 2>/dev/null"; //silence stderr + command += " 2>/dev/null"; // Silence stderr } - FILE *f = popen(argss.utf8().get_data(), "r"); - - ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot pipe stream from process running with following arguments '" + argss + "'."); + FILE *f = popen(command.utf8().get_data(), "r"); + ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot create pipe from command: " + command); char buf[65535]; - while (fgets(buf, 65535, f)) { if (p_pipe_mutex) { p_pipe_mutex->lock(); @@ -289,10 +283,10 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo } } int rv = pclose(f); + if (r_exitcode) { *r_exitcode = WEXITSTATUS(rv); } - return OK; } @@ -300,14 +294,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo ERR_FAIL_COND_V(pid < 0, ERR_CANT_FORK); if (pid == 0) { - // is child - - if (!p_blocking) { - // For non blocking calls, create a new session-ID so parent won't wait for it. - // This ensures the process won't go zombie at end. - setsid(); - } - + // The child process Vector<CharString> cs; cs.push_back(p_path.utf8()); for (int i = 0; i < p_arguments.size(); i++) { @@ -321,24 +308,56 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo args.push_back(0); execvp(p_path.utf8().get_data(), &args[0]); - // still alive? something failed.. - fprintf(stderr, "**ERROR** OS_Unix::execute - Could not create child process while executing: %s\n", p_path.utf8().get_data()); + // The execvp() function only returns if an error occurs. + ERR_PRINT("Could not create child process: " + p_path); raise(SIGKILL); } - if (p_blocking) { - int status; - waitpid(pid, &status, 0); - if (r_exitcode) { - *r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status; + int status; + waitpid(pid, &status, 0); + if (r_exitcode) { + *r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status; + } + return OK; +#endif +} + +Error OS_Unix::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { +#ifdef __EMSCRIPTEN__ + // Don't compile this code at all to avoid undefined references. + // Actual virtual call goes to OS_JavaScript. + ERR_FAIL_V(ERR_BUG); +#else + pid_t pid = fork(); + ERR_FAIL_COND_V(pid < 0, ERR_CANT_FORK); + + if (pid == 0) { + // The new process + // Create a new session-ID so parent won't wait for it. + // This ensures the process won't go zombie at the end. + setsid(); + + Vector<CharString> cs; + cs.push_back(p_path.utf8()); + for (int i = 0; i < p_arguments.size(); i++) { + cs.push_back(p_arguments[i].utf8()); } - } else { - if (r_child_id) { - *r_child_id = pid; + Vector<char *> args; + for (int i = 0; i < cs.size(); i++) { + args.push_back((char *)cs[i].get_data()); } + args.push_back(0); + + execvp(p_path.utf8().get_data(), &args[0]); + // The execvp() function only returns if an error occurs. + ERR_PRINT("Could not create child process: " + p_path); + raise(SIGKILL); } + if (r_child_id) { + *r_child_id = pid; + } return OK; #endif } diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 7d1f1c82c2..6c79d984e9 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -82,7 +82,8 @@ public: virtual void delay_usec(uint32_t p_usec) const override; virtual uint64_t get_ticks_usec() const override; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; + virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; + virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; virtual Error kill(const ProcessID &p_pid) override; virtual int get_process_id() const override; diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp deleted file mode 100644 index af3ca3a597..0000000000 --- a/drivers/unix/rw_lock_posix.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************/ -/* rw_lock_posix.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) - -#include "rw_lock_posix.h" - -#include "core/error/error_macros.h" -#include "core/os/memory.h" -#include <stdio.h> - -void RWLockPosix::read_lock() { - int err = pthread_rwlock_rdlock(&rwlock); - if (err != 0) { - perror("Acquiring lock failed"); - } - ERR_FAIL_COND(err != 0); -} - -void RWLockPosix::read_unlock() { - pthread_rwlock_unlock(&rwlock); -} - -Error RWLockPosix::read_try_lock() { - if (pthread_rwlock_tryrdlock(&rwlock) != 0) { - return ERR_BUSY; - } else { - return OK; - } -} - -void RWLockPosix::write_lock() { - int err = pthread_rwlock_wrlock(&rwlock); - ERR_FAIL_COND(err != 0); -} - -void RWLockPosix::write_unlock() { - pthread_rwlock_unlock(&rwlock); -} - -Error RWLockPosix::write_try_lock() { - if (pthread_rwlock_trywrlock(&rwlock) != 0) { - return ERR_BUSY; - } else { - return OK; - } -} - -RWLock *RWLockPosix::create_func_posix() { - return memnew(RWLockPosix); -} - -void RWLockPosix::make_default() { - create_func = create_func_posix; -} - -RWLockPosix::RWLockPosix() { - //rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX - pthread_rwlock_init(&rwlock, nullptr); -} - -RWLockPosix::~RWLockPosix() { - pthread_rwlock_destroy(&rwlock); -} - -#endif diff --git a/drivers/unix/rw_lock_posix.h b/drivers/unix/rw_lock_posix.h deleted file mode 100644 index aecb2e18ab..0000000000 --- a/drivers/unix/rw_lock_posix.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* rw_lock_posix.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RWLOCKPOSIX_H -#define RWLOCKPOSIX_H - -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) - -#include "core/os/rw_lock.h" -#include <pthread.h> - -class RWLockPosix : public RWLock { - pthread_rwlock_t rwlock; - - static RWLock *create_func_posix(); - -public: - virtual void read_lock(); - virtual void read_unlock(); - virtual Error read_try_lock(); - - virtual void write_lock(); - virtual void write_unlock(); - virtual Error write_try_lock(); - - static void make_default(); - - RWLockPosix(); - - ~RWLockPosix(); -}; - -#endif - -#endif // RWLOCKPOSIX_H diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index 5c7a546b29..19fab1d475 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -28,88 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "thread_posix.h" - #if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS) -#include "core/object/script_language.h" -#include "core/os/memory.h" -#include "core/templates/safe_refcount.h" - -#ifdef PTHREAD_BSD_SET_NAME -#include <pthread_np.h> -#endif - -static void _thread_id_key_destr_callback(void *p_value) { - memdelete(static_cast<Thread::ID *>(p_value)); -} - -static pthread_key_t _create_thread_id_key() { - pthread_key_t key; - pthread_key_create(&key, &_thread_id_key_destr_callback); - return key; -} - -pthread_key_t ThreadPosix::thread_id_key = _create_thread_id_key(); -Thread::ID ThreadPosix::next_thread_id = 0; - -Thread::ID ThreadPosix::get_id() const { - return id; -} - -Thread *ThreadPosix::create_thread_posix() { - return memnew(ThreadPosix); -} - -void *ThreadPosix::thread_callback(void *userdata) { - ThreadPosix *t = reinterpret_cast<ThreadPosix *>(userdata); - t->id = atomic_increment(&next_thread_id); - pthread_setspecific(thread_id_key, (void *)memnew(ID(t->id))); - - ScriptServer::thread_enter(); //scripts may need to attach a stack - - t->callback(t->user); - - ScriptServer::thread_exit(); - - return nullptr; -} - -Thread *ThreadPosix::create_func_posix(ThreadCreateCallback p_callback, void *p_user, const Settings &) { - ThreadPosix *tr = memnew(ThreadPosix); - tr->callback = p_callback; - tr->user = p_user; - pthread_attr_init(&tr->pthread_attr); - pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setstacksize(&tr->pthread_attr, 256 * 1024); - - pthread_create(&tr->pthread, &tr->pthread_attr, thread_callback, tr); - - return tr; -} - -Thread::ID ThreadPosix::get_thread_id_func_posix() { - void *value = pthread_getspecific(thread_id_key); - - if (value) { - return *static_cast<ID *>(value); - } - - ID new_id = atomic_increment(&next_thread_id); - pthread_setspecific(thread_id_key, (void *)memnew(ID(new_id))); - return new_id; -} - -void ThreadPosix::wait_to_finish_func_posix(Thread *p_thread) { - ThreadPosix *tp = static_cast<ThreadPosix *>(p_thread); - ERR_FAIL_COND(!tp); - ERR_FAIL_COND(tp->pthread == 0); +#include "thread_posix.h" - pthread_join(tp->pthread, nullptr); - tp->pthread = 0; -} +#include "core/os/thread.h" +#include "core/string/ustring.h" -Error ThreadPosix::set_name_func_posix(const String &p_name) { +static Error set_name(const String &p_name) { #ifdef PTHREAD_NO_RENAME return ERR_UNAVAILABLE; @@ -137,20 +63,10 @@ Error ThreadPosix::set_name_func_posix(const String &p_name) { return err == 0 ? OK : ERR_INVALID_PARAMETER; #endif // PTHREAD_NO_RENAME -}; - -void ThreadPosix::make_default() { - create_func = create_func_posix; - get_thread_id_func = get_thread_id_func_posix; - wait_to_finish_func = wait_to_finish_func_posix; - set_name_func = set_name_func_posix; -} - -ThreadPosix::ThreadPosix() { - pthread = 0; } -ThreadPosix::~ThreadPosix() { +void init_thread_posix() { + Thread::_set_platform_funcs(&set_name, nullptr); } #endif diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h index fa2037e1a2..8b8a736bf0 100644 --- a/drivers/unix/thread_posix.h +++ b/drivers/unix/thread_posix.h @@ -31,42 +31,8 @@ #ifndef THREAD_POSIX_H #define THREAD_POSIX_H -#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS) - -#include "core/os/thread.h" -#include <pthread.h> -#include <sys/types.h> - -class ThreadPosix : public Thread { - static pthread_key_t thread_id_key; - static ID next_thread_id; - - pthread_t pthread; - pthread_attr_t pthread_attr; - ThreadCreateCallback callback; - void *user; - ID id; - - static Thread *create_thread_posix(); - - static void *thread_callback(void *userdata); - - static Thread *create_func_posix(ThreadCreateCallback p_callback, void *, const Settings &); - static ID get_thread_id_func_posix(); - static void wait_to_finish_func_posix(Thread *p_thread); - - static Error set_name_func_posix(const String &p_name); - - ThreadPosix(); - -public: - virtual ID get_id() const; - - static void make_default(); - - ~ThreadPosix(); -}; - +#if !defined(NO_THREADS) +void init_thread_posix(); #endif #endif diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 6eadec4cce..9584dd3f67 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -41,28 +41,62 @@ //#define FORCE_FULL_BARRIER // Get the Vulkan object information and possible stage access types (bitwise OR'd with incoming values) -RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &stage_mask, VkAccessFlags &access_mask) { +RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &r_stage_mask, VkAccessFlags &r_access_mask, uint32_t p_post_barrier) { Buffer *buffer = nullptr; if (vertex_buffer_owner.owns(p_buffer)) { - stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - access_mask |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; buffer = vertex_buffer_owner.getornull(p_buffer); + + r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + r_access_mask |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; + if (buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) { + if (p_post_barrier & BARRIER_MASK_RASTER) { + r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + } + } } else if (index_buffer_owner.owns(p_buffer)) { - stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - access_mask |= VK_ACCESS_INDEX_READ_BIT; + r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + r_access_mask |= VK_ACCESS_INDEX_READ_BIT; buffer = index_buffer_owner.getornull(p_buffer); } else if (uniform_buffer_owner.owns(p_buffer)) { - stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - access_mask |= VK_ACCESS_UNIFORM_READ_BIT; + if (p_post_barrier & BARRIER_MASK_RASTER) { + r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + } + r_access_mask |= VK_ACCESS_UNIFORM_READ_BIT; buffer = uniform_buffer_owner.getornull(p_buffer); } else if (texture_buffer_owner.owns(p_buffer)) { - stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - access_mask |= VK_ACCESS_SHADER_READ_BIT; + if (p_post_barrier & BARRIER_MASK_RASTER) { + r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + r_access_mask |= VK_ACCESS_SHADER_READ_BIT; + } + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + r_access_mask |= VK_ACCESS_SHADER_READ_BIT; + } + buffer = &texture_buffer_owner.getornull(p_buffer)->buffer; } else if (storage_buffer_owner.owns(p_buffer)) { - stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; buffer = storage_buffer_owner.getornull(p_buffer); + if (p_post_barrier & BARRIER_MASK_RASTER) { + r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + + if (buffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) { + r_stage_mask |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + r_access_mask |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + } } return buffer; } @@ -1595,6 +1629,9 @@ void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mas mem_barrier.srcAccessMask = p_src_access; mem_barrier.dstAccessMask = p_dst_sccess; + if (p_src_stage_mask == 0 || p_dst_stage_mask == 0) { + return; //no barrier, since this is invalid + } vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, p_src_stage_mask, p_dst_stage_mask, 0, 1, &mem_barrier, 0, nullptr, 0, nullptr); } @@ -2067,6 +2104,48 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; } + VkImageViewUsageCreateInfo usage_info; + usage_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; + usage_info.pNext = nullptr; + if (p_view.format_override != DATA_FORMAT_MAX) { + //need to validate usage with vulkan + + usage_info.usage = 0; + + if (texture.usage_flags & TEXTURE_USAGE_SAMPLING_BIT) { + usage_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT; + } + + if (texture.usage_flags & TEXTURE_USAGE_STORAGE_BIT) { + if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_STORAGE_BIT)) { + usage_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT; + } + } + + if (texture.usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) { + usage_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + } + + if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { + usage_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + + if (texture.usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT) { + usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + } + if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT) { + usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } + + if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT) { + usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + } + + image_view_create_info.pNext = &usage_info; + } + VkResult err = vkCreateImageView(device, &image_view_create_info, nullptr, &texture.view); ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateImageView failed with error " + itos(err) + "."); @@ -2196,11 +2275,11 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p return id; } -Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { +Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ - ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER, - "Updating textures in 'sync to draw' mode is forbidden during creation of a draw list"); + ERR_FAIL_COND_V_MSG(draw_list || compute_list, ERR_INVALID_PARAMETER, + "Updating textures in is forbidden during creation of a draw or compute list"); Texture *texture = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!texture, ERR_INVALID_PARAMETER); @@ -2241,7 +2320,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con const uint8_t *r = p_data.ptr(); - VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; + VkCommandBuffer command_buffer = p_post_barrier ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; //barrier to transfer { @@ -2266,6 +2345,10 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con } uint32_t mipmap_offset = 0; + + uint32_t logic_width = texture->width; + uint32_t logic_height = texture->height; + for (uint32_t mm_i = 0; mm_i < texture->mipmaps; mm_i++) { uint32_t depth; uint32_t image_total = get_image_format_required_size(texture->format, texture->width, texture->height, texture->depth, mm_i + 1, &width, &height, &depth); @@ -2282,12 +2365,15 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con uint32_t region_w = MIN(region_size, width - x); uint32_t region_h = MIN(region_size, height - y); + uint32_t region_logic_w = MIN(region_size, logic_width - x); + uint32_t region_logic_h = MIN(region_size, logic_height - y); + uint32_t pixel_size = get_image_format_pixel_size(texture->format); uint32_t to_allocate = region_w * region_h * pixel_size; to_allocate >>= get_compressed_image_format_pixel_rshift(texture->format); uint32_t alloc_offset, alloc_size; - Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, p_sync_with_draw); + Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, p_post_barrier); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); uint8_t *write_ptr; @@ -2363,8 +2449,8 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con buffer_image_copy.imageOffset.y = y; buffer_image_copy.imageOffset.z = z; - buffer_image_copy.imageExtent.width = region_w; - buffer_image_copy.imageExtent.height = region_h; + buffer_image_copy.imageExtent.width = region_logic_w; + buffer_image_copy.imageExtent.height = region_logic_h; buffer_image_copy.imageExtent.depth = 1; vkCmdCopyBufferToImage(command_buffer, staging_buffer_blocks[staging_buffer_current].buffer, texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &buffer_image_copy); @@ -2375,15 +2461,36 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con } mipmap_offset = image_total; + logic_width = MAX(1, logic_width >> 1); + logic_height = MAX(1, logic_height >> 1); } //barrier to restore layout { + uint32_t barrier_flags = 0; + uint32_t access_flags = 0; + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT; + } + if (p_post_barrier & BARRIER_MASK_RASTER) { + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT; + } + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; + } + + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; image_memory_barrier.newLayout = texture->layout; image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -2395,8 +2502,15 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con image_memory_barrier.subresourceRange.baseArrayLayer = p_layer; image_memory_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + } + + if (texture->used_in_frame != frames_drawn) { + texture->used_in_raster = false; + texture->used_in_compute = false; + texture->used_in_frame = frames_drawn; } + texture->used_in_transfer = true; return OK; } @@ -2608,13 +2722,13 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) { return texture_owner.owns(p_texture); } -Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw) { +Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ Texture *src_tex = texture_owner.getornull(p_from_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER, + ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, "Source texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER, "Source texture requires the TEXTURE_USAGE_CAN_COPY_FROM_BIT in order to be retrieved."); @@ -2635,7 +2749,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, Texture *dst_tex = texture_owner.getornull(p_to_texture); ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V_MSG(p_sync_with_draw && dst_tex->bound, ERR_INVALID_PARAMETER, + ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER, "Destination texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER, "Destination texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be retrieved."); @@ -2656,7 +2770,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER, "Source and destination texture must be of the same type (color or depth)."); - VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; + VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; { //PRE Copy the image @@ -2731,12 +2845,31 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, // RESTORE LAYOUT for SRC and DST + uint32_t barrier_flags = 0; + uint32_t access_flags = 0; + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_RASTER) { + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; + } + + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + { //restore src VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; image_memory_barrier.newLayout = src_tex->layout; image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -2748,7 +2881,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer; image_memory_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } { //make dst readable @@ -2757,7 +2890,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; image_memory_barrier.newLayout = dst_tex->layout; @@ -2770,20 +2903,20 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer; image_memory_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } } return OK; } -Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw) { +Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ Texture *src_tex = texture_owner.getornull(p_from_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER, + ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, "Source texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER, "Source texture requires the TEXTURE_USAGE_CAN_COPY_FROM_BIT in order to be retrieved."); @@ -2794,7 +2927,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID Texture *dst_tex = texture_owner.getornull(p_to_texture); ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V_MSG(p_sync_with_draw && dst_tex->bound, ERR_INVALID_PARAMETER, + ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER, "Destination texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER, "Destination texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be retrieved."); @@ -2808,7 +2941,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER, "Source and destination texture must be of the same type (color or depth)."); - VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; + VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; { //PRE Copy the image @@ -2883,12 +3016,31 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID // RESTORE LAYOUT for SRC and DST + uint32_t barrier_flags = 0; + uint32_t access_flags = 0; + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_RASTER) { + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; + } + + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + { //restore src VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; image_memory_barrier.newLayout = src_tex->layout; image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -2900,7 +3052,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer; image_memory_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } { //make dst readable @@ -2909,7 +3061,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; image_memory_barrier.newLayout = dst_tex->layout; @@ -2922,20 +3074,20 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer; image_memory_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } } return OK; } -Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) { +Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ Texture *src_tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER, + ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, "Source texture can't be cleared while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); ERR_FAIL_COND_V(p_layers == 0, ERR_INVALID_PARAMETER); @@ -2952,7 +3104,7 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, ERR_FAIL_COND_V(p_base_mipmap + p_mipmaps > src_tex->mipmaps, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_base_layer + p_layers > src_layer_count, ERR_INVALID_PARAMETER); - VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; + VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; VkImageLayout clear_layout = (src_tex->layout == VK_IMAGE_LAYOUT_GENERAL) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; @@ -2999,11 +3151,31 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, vkCmdClearColorImage(command_buffer, src_tex->image, clear_layout, &clear_color, 1, &range); { // Barrier to post clear accesses (changing back the layout if needed) + + uint32_t barrier_flags = 0; + uint32_t access_flags = 0; + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_RASTER) { + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; + } + + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_memory_barrier.dstAccessMask = valid_texture_access; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = clear_layout; image_memory_barrier.newLayout = src_tex->layout; @@ -3016,9 +3188,16 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer; image_memory_barrier.subresourceRange.layerCount = p_layers; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, valid_texture_stages, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } + if (src_tex->used_in_frame != frames_drawn) { + src_tex->used_in_raster = false; + src_tex->used_in_compute = false; + src_tex->used_in_frame = frames_drawn; + } + src_tex->used_in_transfer = true; + return OK; } @@ -3104,6 +3283,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF // the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that // stage switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) { + case INITIAL_ACTION_CLEAR_REGION: case INITIAL_ACTION_CLEAR: { description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; @@ -3116,9 +3296,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; dependency_from_external.srcStageMask |= reading_stages; } else { description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -3144,6 +3324,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF dependency_from_external.srcStageMask |= reading_stages; } } break; + case INITIAL_ACTION_CLEAR_REGION_CONTINUE: case INITIAL_ACTION_CONTINUE: { if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; @@ -3151,7 +3332,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; //don't care what is there + description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; } else { description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -3280,8 +3461,13 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF render_pass_create_info.pAttachments = attachments.ptr(); render_pass_create_info.subpassCount = 1; render_pass_create_info.pSubpasses = &subpass; - render_pass_create_info.dependencyCount = 2; - render_pass_create_info.pDependencies = dependencies; + // Commenting this because it seems it just avoids raster and compute to work at the same time. + // Other barriers seem to be protecting the render pass fine. + // render_pass_create_info.dependencyCount = 2; + // render_pass_create_info.pDependencies = dependencies; + + render_pass_create_info.dependencyCount = 0; + render_pass_create_info.pDependencies = nullptr; VkRenderPass render_pass; VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass); @@ -3323,11 +3509,8 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c return id; } -RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_empty(const Size2i &p_size) { - ERR_FAIL_COND_V(p_size.width <= 0 || p_size.height <= 0, INVALID_FORMAT_ID); - +RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_empty(TextureSamples p_samples) { FramebufferFormatKey key; - key.empty_size = p_size; const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E = framebuffer_format_cache.find(key); if (E) { @@ -3375,7 +3558,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c fb_format.E = E; fb_format.color_attachments = 0; fb_format.render_pass = render_pass; - fb_format.samples = TEXTURE_SAMPLES_1; + fb_format.samples = p_samples; framebuffer_formats[id] = fb_format; return id; } @@ -3391,10 +3574,10 @@ RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_te /**** RENDER TARGET ****/ /***********************/ -RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check) { +RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples, FramebufferFormatID p_format_check) { _THREAD_SAFE_METHOD_ Framebuffer framebuffer; - framebuffer.format_id = framebuffer_format_create_empty(p_size); + framebuffer.format_id = framebuffer_format_create_empty(p_samples); ERR_FAIL_COND_V(p_format_check != INVALID_FORMAT_ID && framebuffer.format_id != p_format_check, RID()); framebuffer.size = p_size; @@ -3966,6 +4149,8 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages bool is_compute = false; + uint32_t compute_local_size[3] = { 0, 0, 0 }; + for (int i = 0; i < p_stages.size(); i++) { if (p_stages[i].shader_stage == SHADER_STAGE_COMPUTE) { is_compute = true; @@ -3982,6 +4167,11 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_stages[i].shader_stage]) + "' failed parsing shader."); + if (is_compute) { + compute_local_size[0] = module.entry_points->local_size.x; + compute_local_size[1] = module.entry_points->local_size.y; + compute_local_size[2] = module.entry_points->local_size.z; + } uint32_t binding_count = 0; result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), @@ -4061,6 +4251,10 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; info.type = UNIFORM_TYPE_INPUT_ATTACHMENT; } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { + ERR_PRINT("Acceleration structure not supported."); + continue; + } break; } if (need_array_dimensions) { @@ -4182,6 +4376,7 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages } } } + uint32_t pc_count = 0; result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), @@ -4230,6 +4425,9 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages shader.fragment_outputs = fragment_outputs; shader.push_constant = push_constant; shader.is_compute = is_compute; + shader.compute_local_size[0] = compute_local_size[0]; + shader.compute_local_size[1] = compute_local_size[1]; + shader.compute_local_size[2] = compute_local_size[2]; String error_text; @@ -5036,19 +5234,22 @@ bool RenderingDeviceVulkan::uniform_set_is_valid(RID p_uniform_set) { return uniform_set_owner.owns(p_uniform_set); } -Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw) { +Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ - ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER, - "Updating buffers in 'sync to draw' mode is forbidden during creation of a draw list"); - ERR_FAIL_COND_V_MSG(compute_list && p_sync_with_draw, ERR_INVALID_PARAMETER, - "Updating buffers in 'sync to draw' mode is forbidden during creation of a compute list"); + ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER, + "Updating buffers is forbidden during creation of a draw list"); + ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER, + "Updating buffers is forbidden during creation of a compute list"); - // Protect subsequent updates... - VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; - VkAccessFlags dst_access = VK_ACCESS_TRANSFER_WRITE_BIT; - - Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access); + VkPipelineStageFlags dst_stage_mask = 0; + VkAccessFlags dst_access = 0; + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + // Protect subsequent updates... + dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; + dst_access = VK_ACCESS_TRANSFER_WRITE_BIT; + } + Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access, p_post_barrier); if (!buffer) { ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type."); } @@ -5056,20 +5257,73 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER, "Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end."); - _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, p_sync_with_draw); - Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, p_sync_with_draw); + // no barrier should be needed here + // _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, true); + + Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, p_post_barrier); if (err) { return err; } #ifdef FORCE_FULL_BARRIER - _full_barrier(p_sync_with_draw); + _full_barrier(true); #else - _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw); + if (dst_stage_mask == 0) { + dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + if (p_post_barrier != RD::BARRIER_MASK_NO_BARRIER) { + _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, true); + } + #endif return err; } +Error RenderingDeviceVulkan::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier) { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V_MSG((p_size % 4) != 0, ERR_INVALID_PARAMETER, + "Size must be a multiple of four"); + ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER, + "Updating buffers in is forbidden during creation of a draw list"); + ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER, + "Updating buffers is forbidden during creation of a compute list"); + + VkPipelineStageFlags dst_stage_mask = 0; + VkAccessFlags dst_access = 0; + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + // Protect subsequent updates... + dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; + dst_access = VK_ACCESS_TRANSFER_WRITE_BIT; + } + + Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access, p_post_barrier); + if (!buffer) { + ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type."); + } + + ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER, + "Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end."); + + // should not be needed + // _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, p_post_barrier); + + vkCmdFillBuffer(frames[frame].draw_command_buffer, buffer->buffer, p_offset, p_size, 0); + +#ifdef FORCE_FULL_BARRIER + _full_barrier(true); +#else + if (dst_stage_mask == 0) { + dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, dst_stage_mask); + +#endif + return OK; +} + Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { _THREAD_SAFE_METHOD_ @@ -5077,7 +5331,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { VkPipelineShaderStageCreateFlags src_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT; VkAccessFlags src_access_mask = VK_ACCESS_TRANSFER_WRITE_BIT; // Get the vulkan buffer and the potential stage/access possible - Buffer *buffer = _get_buffer_from_owner(p_buffer, src_stage_mask, src_access_mask); + Buffer *buffer = _get_buffer_from_owner(p_buffer, src_stage_mask, src_access_mask, BARRIER_MASK_ALL); if (!buffer) { ERR_FAIL_V_MSG(Vector<uint8_t>(), "Buffer is either invalid or this type of buffer can't be retrieved. Only Index and Vertex buffers allow retrieving."); } @@ -5520,6 +5774,9 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) { pipeline.pipeline_layout = shader->pipeline_layout; pipeline.shader = p_shader; pipeline.push_constant_size = shader->push_constant.push_constant_size; + pipeline.local_group_size[0] = shader->compute_local_size[0]; + pipeline.local_group_size[1] = shader->compute_local_size[1]; + pipeline.local_group_size[2] = shader->compute_local_size[2]; //create ID to associate with this pipeline RID id = compute_pipeline_owner.make_rid(pipeline); @@ -5691,11 +5948,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff render_pass_begin.pNext = nullptr; render_pass_begin.renderPass = render_pass; render_pass_begin.framebuffer = vkframebuffer; - + /* + * Given how API works, it makes sense to always fully operate on the whole framebuffer. + * This allows better continue operations for operations like shadowmapping. render_pass_begin.renderArea.extent.width = viewport_size.width; render_pass_begin.renderArea.extent.height = viewport_size.height; render_pass_begin.renderArea.offset.x = viewport_offset.x; render_pass_begin.renderArea.offset.y = viewport_offset.y; + */ + render_pass_begin.renderArea.extent.width = framebuffer->size.width; + render_pass_begin.renderArea.extent.height = framebuffer->size.height; + render_pass_begin.renderArea.offset.x = 0; + render_pass_begin.renderArea.offset.y = 0; Vector<VkClearValue> clear_values; clear_values.resize(framebuffer->texture_ids.size()); @@ -5822,7 +6086,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); - ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); + ERR_FAIL_COND_V_MSG(compute_list != nullptr && !compute_list->state.allow_draw_overlap, INVALID_ID, "Only one draw/compute list can be active at the same time."); Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer); ERR_FAIL_COND_V(!framebuffer, INVALID_ID); @@ -5843,12 +6107,19 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu viewport_offset = regioni.position; viewport_size = regioni.size; - - if (p_initial_color_action == INITIAL_ACTION_CLEAR) { + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_color = true; p_initial_color_action = INITIAL_ACTION_KEEP; } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR) { + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_depth = true; p_initial_depth_action = INITIAL_ACTION_KEEP; } @@ -5934,11 +6205,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_color_action == INITIAL_ACTION_CLEAR) { + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_color = true; p_initial_color_action = INITIAL_ACTION_KEEP; } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR) { + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_depth = true; p_initial_depth_action = INITIAL_ACTION_KEEP; } @@ -6191,6 +6462,19 @@ void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_ dl->state.sets[p_index].uniform_set_format = uniform_set->format; dl->state.sets[p_index].uniform_set = p_uniform_set; + uint32_t mst_count = uniform_set->mutable_storage_textures.size(); + if (mst_count) { + Texture **mst_textures = const_cast<UniformSet *>(uniform_set)->mutable_storage_textures.ptrw(); + for (uint32_t i = 0; i < mst_count; i++) { + if (mst_textures[i]->used_in_frame != frames_drawn) { + mst_textures[i]->used_in_frame = frames_drawn; + mst_textures[i]->used_in_transfer = false; + mst_textures[i]->used_in_compute = false; + } + mst_textures[i]->used_in_raster = true; + } + } + #ifdef DEBUG_ENABLED { //validate that textures bound are not attached as framebuffer bindings uint32_t attachable_count = uniform_set->attachable_textures.size(); @@ -6433,7 +6717,7 @@ void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) { vkCmdSetScissor(dl->command_buffer, 0, 1, &scissor); } -void RenderingDeviceVulkan::draw_list_end() { +void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_MSG(!draw_list, "Immediate draw list is already inactive."); @@ -6469,16 +6753,51 @@ void RenderingDeviceVulkan::draw_list_end() { } } + uint32_t barrier_flags = 0; + uint32_t access_flags = 0; + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_RASTER) { + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT /*| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT*/; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT /*| VK_ACCESS_INDIRECT_COMMAND_READ_BIT*/; + } + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; + } + + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + draw_list_bound_textures.clear(); - for (int i = 0; i < draw_list_storage_textures.size(); i++) { + VkImageMemoryBarrier *image_barriers = nullptr; + + uint32_t image_barrier_count = draw_list_storage_textures.size(); + + if (image_barrier_count) { + image_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * draw_list_storage_textures.size()); + } + + uint32_t src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + uint32_t src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + if (image_barrier_count) { + src_stage |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + src_access |= VK_ACCESS_SHADER_WRITE_BIT; + } + + for (uint32_t i = 0; i < image_barrier_count; i++) { Texture *texture = texture_owner.getornull(draw_list_storage_textures[i]); - VkImageMemoryBarrier image_memory_barrier; + VkImageMemoryBarrier &image_memory_barrier = image_barriers[i]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; - image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + image_memory_barrier.srcAccessMask = src_access; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = texture->layout; image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -6491,8 +6810,6 @@ void RenderingDeviceVulkan::draw_list_end() { image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer; image_memory_barrier.subresourceRange.layerCount = texture->layers; - vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } @@ -6505,7 +6822,17 @@ void RenderingDeviceVulkan::draw_list_end() { #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, true); + + VkMemoryBarrier mem_barrier; + mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + mem_barrier.pNext = nullptr; + mem_barrier.srcAccessMask = src_access; + mem_barrier.dstAccessMask = access_flags; + + if (image_barrier_count > 0 || p_post_barrier != BARRIER_MASK_NO_BARRIER) { + vkCmdPipelineBarrier(frames[frame].draw_command_buffer, src_stage, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers); + } + #endif } @@ -6513,12 +6840,13 @@ void RenderingDeviceVulkan::draw_list_end() { /**** COMPUTE LISTS ****/ /***********************/ -RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin() { - ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); +RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin(bool p_allow_draw_overlap) { + ERR_FAIL_COND_V_MSG(!p_allow_draw_overlap && draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); compute_list = memnew(ComputeList); compute_list->command_buffer = frames[frame].draw_command_buffer; + compute_list->state.allow_draw_overlap = p_allow_draw_overlap; return ID_TYPE_COMPUTE_LIST; } @@ -6575,6 +6903,9 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l } cl->state.pipeline_shader = pipeline->shader; + cl->state.local_group_size[0] = pipeline->local_group_size[0]; + cl->state.local_group_size[1] = pipeline->local_group_size[1]; + cl->state.local_group_size[2] = pipeline->local_group_size[2]; } #ifdef DEBUG_ENABLED @@ -6612,11 +6943,24 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, cl->state.sets[p_index].uniform_set = p_uniform_set; uint32_t textures_to_sampled_count = uniform_set->mutable_sampled_textures.size(); + uint32_t textures_to_storage_count = uniform_set->mutable_storage_textures.size(); + Texture **textures_to_sampled = uniform_set->mutable_sampled_textures.ptrw(); + VkImageMemoryBarrier *texture_barriers = nullptr; + + if (textures_to_sampled_count + textures_to_storage_count) { + texture_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * (textures_to_sampled_count + textures_to_storage_count)); + } + uint32_t texture_barrier_count = 0; + + uint32_t src_stage_flags = 0; + for (uint32_t i = 0; i < textures_to_sampled_count; i++) { if (textures_to_sampled[i]->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - VkImageMemoryBarrier image_memory_barrier; + src_stage_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + + VkImageMemoryBarrier &image_memory_barrier = texture_barriers[texture_barrier_count++]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; @@ -6633,23 +6977,55 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_sampled[i]->base_layer; image_memory_barrier.subresourceRange.layerCount = textures_to_sampled[i]->layers; - vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - textures_to_sampled[i]->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; cl->state.textures_to_sampled_layout.erase(textures_to_sampled[i]); } + + if (textures_to_sampled[i]->used_in_frame != frames_drawn) { + textures_to_sampled[i]->used_in_frame = frames_drawn; + textures_to_sampled[i]->used_in_transfer = false; + textures_to_sampled[i]->used_in_raster = false; + } + textures_to_sampled[i]->used_in_compute = true; } - uint32_t textures_to_storage_count = uniform_set->mutable_storage_textures.size(); Texture **textures_to_storage = uniform_set->mutable_storage_textures.ptrw(); for (uint32_t i = 0; i < textures_to_storage_count; i++) { if (textures_to_storage[i]->layout != VK_IMAGE_LAYOUT_GENERAL) { - VkImageMemoryBarrier image_memory_barrier; + uint32_t src_access_flags = 0; + + if (textures_to_storage[i]->used_in_frame == frames_drawn) { + if (textures_to_storage[i]->used_in_compute) { + src_stage_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + src_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (textures_to_storage[i]->used_in_raster) { + src_stage_flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; + src_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (textures_to_storage[i]->used_in_transfer) { + src_stage_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + src_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; + } + + textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_raster = false; + textures_to_storage[i]->used_in_compute = false; + + } else { + src_access_flags = 0; + textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_raster = false; + textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_frame = frames_drawn; + } + + VkImageMemoryBarrier &image_memory_barrier = texture_barriers[texture_barrier_count++]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; - image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.srcAccessMask = src_access_flags; image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; image_memory_barrier.oldLayout = textures_to_storage[i]->layout; image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -6663,14 +7039,20 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_storage[i]->base_layer; image_memory_barrier.subresourceRange.layerCount = textures_to_storage[i]->layers; - vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - textures_to_storage[i]->layout = VK_IMAGE_LAYOUT_GENERAL; cl->state.textures_to_sampled_layout.insert(textures_to_storage[i]); //needs to go back to sampled layout afterwards } } + if (texture_barrier_count) { + if (src_stage_flags == 0) { + src_stage_flags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + } + + vkCmdPipelineBarrier(cl->command_buffer, src_stage_flags, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, texture_barrier_count, texture_barriers); + } + #if 0 { //validate that textures bound are not attached as framebuffer bindings uint32_t attachable_count = uniform_set->attachable_textures.size(); @@ -6764,6 +7146,27 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t vkCmdDispatch(cl->command_buffer, p_x_groups, p_y_groups, p_z_groups); } +void RenderingDeviceVulkan::compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads) { + ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); + ERR_FAIL_COND(!compute_list); + + ComputeList *cl = compute_list; + +#ifdef DEBUG_ENABLED + + ERR_FAIL_COND_MSG(!cl->validation.pipeline_active, "No compute pipeline was set before attempting to draw."); + + if (cl->validation.pipeline_push_constant_size > 0) { + //using push constants, check that they were supplied + ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied, + "The shader in this pipeline requires a push constant to be set before drawing, but it's not present."); + } + +#endif + + compute_list_dispatch(p_list, (p_x_threads - 1) / cl->state.local_group_size[0] + 1, (p_y_threads - 1) / cl->state.local_group_size[1] + 1, (p_z_threads - 1) / cl->state.local_group_size[2] + 1); +} + void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -6828,14 +7231,44 @@ void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) { #endif } -void RenderingDeviceVulkan::compute_list_end() { +void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) { ERR_FAIL_COND(!compute_list); + + uint32_t barrier_flags = 0; + uint32_t access_flags = 0; + if (p_post_barrier & BARRIER_MASK_COMPUTE) { + barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_post_barrier & BARRIER_MASK_RASTER) { + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + } + if (p_post_barrier & BARRIER_MASK_TRANSFER) { + barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; + } + + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + VkImageMemoryBarrier *image_barriers = nullptr; + + uint32_t image_barrier_count = compute_list->state.textures_to_sampled_layout.size(); + + if (image_barrier_count) { + image_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * image_barrier_count); + } + + uint32_t barrier_idx = 0; + for (Set<Texture *>::Element *E = compute_list->state.textures_to_sampled_layout.front(); E; E = E->next()) { - VkImageMemoryBarrier image_memory_barrier; + VkImageMemoryBarrier &image_memory_barrier = image_barriers[barrier_idx++]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT; + image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = E->get()->layout; image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -6848,19 +7281,75 @@ void RenderingDeviceVulkan::compute_list_end() { image_memory_barrier.subresourceRange.baseArrayLayer = E->get()->base_layer; image_memory_barrier.subresourceRange.layerCount = E->get()->layers; - // TODO: Look at the usages in the compute list and determine tighter dst stage and access masks based on some "final" usage equivalent - vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - E->get()->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + if (E->get()->used_in_frame != frames_drawn) { + E->get()->used_in_transfer = false; + E->get()->used_in_raster = false; + E->get()->used_in_compute = false; + E->get()->used_in_frame = frames_drawn; + } } - memdelete(compute_list); - compute_list = nullptr; #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT, true); + VkMemoryBarrier mem_barrier; + mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + mem_barrier.pNext = nullptr; + mem_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + mem_barrier.dstAccessMask = access_flags; + + if (image_barrier_count > 0 || p_post_barrier != BARRIER_MASK_NO_BARRIER) { + vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers); + } + #endif + + memdelete(compute_list); + compute_list = nullptr; +} + +void RenderingDeviceVulkan::barrier(uint32_t p_from, uint32_t p_to) { + uint32_t src_barrier_flags = 0; + uint32_t src_access_flags = 0; + if (p_from & BARRIER_MASK_COMPUTE) { + src_barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + src_access_flags |= VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_from & BARRIER_MASK_RASTER) { + src_barrier_flags |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + src_access_flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } + if (p_from & BARRIER_MASK_TRANSFER) { + src_barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + src_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; + } + + if (p_from == 0) { + src_barrier_flags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + } + + uint32_t dst_barrier_flags = 0; + uint32_t dst_access_flags = 0; + if (p_to & BARRIER_MASK_COMPUTE) { + dst_barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + dst_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (p_to & BARRIER_MASK_RASTER) { + dst_barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + dst_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + } + if (p_to & BARRIER_MASK_TRANSFER) { + dst_barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + dst_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; + } + + if (p_to == 0) { + dst_barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + _memory_barrier(src_barrier_flags, dst_barrier_flags, src_access_flags, dst_access_flags, true); } void RenderingDeviceVulkan::full_barrier() { @@ -6997,6 +7486,82 @@ void RenderingDeviceVulkan::free(RID p_id) { _free_internal(p_id); } +// The full list of resources that can be named is in the VkObjectType enum +// We just expose the resources that are owned and can be accessed easily. +void RenderingDeviceVulkan::set_resource_name(RID p_id, const String p_name) { + if (texture_owner.owns(p_id)) { + Texture *texture = texture_owner.getornull(p_id); + if (texture->owner.is_null()) { + // Don't set the source texture's name when calling on a texture view + context->set_object_name(VK_OBJECT_TYPE_IMAGE, uint64_t(texture->image), p_name); + } + context->set_object_name(VK_OBJECT_TYPE_IMAGE_VIEW, uint64_t(texture->view), p_name + " View"); + } else if (framebuffer_owner.owns(p_id)) { + //Framebuffer *framebuffer = framebuffer_owner.getornull(p_id); + // Not implemented for now as the relationship between Framebuffer and RenderPass is very complex + } else if (sampler_owner.owns(p_id)) { + VkSampler *sampler = sampler_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_SAMPLER, uint64_t(*sampler), p_name); + } else if (vertex_buffer_owner.owns(p_id)) { + Buffer *vertex_buffer = vertex_buffer_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(vertex_buffer->buffer), p_name); + } else if (index_buffer_owner.owns(p_id)) { + IndexBuffer *index_buffer = index_buffer_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(index_buffer->buffer), p_name); + } else if (shader_owner.owns(p_id)) { + Shader *shader = shader_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(shader->pipeline_layout), p_name + " Pipeline Layout"); + for (int i = 0; i < shader->sets.size(); i++) { + context->set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, uint64_t(shader->sets[i].descriptor_set_layout), p_name); + } + } else if (uniform_buffer_owner.owns(p_id)) { + Buffer *uniform_buffer = uniform_buffer_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(uniform_buffer->buffer), p_name); + } else if (texture_buffer_owner.owns(p_id)) { + TextureBuffer *texture_buffer = texture_buffer_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(texture_buffer->buffer.buffer), p_name); + context->set_object_name(VK_OBJECT_TYPE_BUFFER_VIEW, uint64_t(texture_buffer->view), p_name + " View"); + } else if (storage_buffer_owner.owns(p_id)) { + Buffer *storage_buffer = storage_buffer_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(storage_buffer->buffer), p_name); + } else if (uniform_set_owner.owns(p_id)) { + UniformSet *uniform_set = uniform_set_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET, uint64_t(uniform_set->descriptor_set), p_name); + } else if (render_pipeline_owner.owns(p_id)) { + RenderPipeline *pipeline = render_pipeline_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_PIPELINE, uint64_t(pipeline->pipeline), p_name); + context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(pipeline->pipeline_layout), p_name + " Layout"); + } else if (compute_pipeline_owner.owns(p_id)) { + ComputePipeline *pipeline = compute_pipeline_owner.getornull(p_id); + context->set_object_name(VK_OBJECT_TYPE_PIPELINE, uint64_t(pipeline->pipeline), p_name); + context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(pipeline->pipeline_layout), p_name + " Layout"); + } else { + ERR_PRINT("Attempted to name invalid ID: " + itos(p_id.get_id())); + } +} + +void RenderingDeviceVulkan::draw_command_begin_label(String p_label_name, const Color p_color) { + context->command_begin_label(frames[frame].draw_command_buffer, p_label_name, p_color); +} + +void RenderingDeviceVulkan::draw_command_insert_label(String p_label_name, const Color p_color) { + context->command_insert_label(frames[frame].draw_command_buffer, p_label_name, p_color); +} + +void RenderingDeviceVulkan::draw_command_end_label() { + context->command_end_label(frames[frame].draw_command_buffer); +} + +String RenderingDeviceVulkan::get_device_vendor_name() const { + return context->get_device_vendor_name(); +} +String RenderingDeviceVulkan::get_device_name() const { + return context->get_device_name(); +} +String RenderingDeviceVulkan::get_device_pipeline_cache_uuid() const { + return context->get_device_pipeline_cache_uuid(); +} + void RenderingDeviceVulkan::_finalize_command_bufers() { if (draw_list) { ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); @@ -7049,6 +7614,7 @@ void RenderingDeviceVulkan::_begin_frame() { if (frames[frame].timestamp_count) { vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); + vkCmdResetQueryPool(frames[frame].setup_command_buffer, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count); SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); } @@ -7415,9 +7981,10 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) { } } -void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_to_draw) { +void RenderingDeviceVulkan::capture_timestamp(const String &p_name) { ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements); + //this should be optional for profiling, else it will slow things down { VkMemoryBarrier memoryBarrier; @@ -7454,9 +8021,10 @@ void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_ VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT; - vkCmdPipelineBarrier(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr); + vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr); } - vkCmdWriteTimestamp(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frames[frame].timestamp_pool, frames[frame].timestamp_count); + + vkCmdWriteTimestamp(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frames[frame].timestamp_pool, frames[frame].timestamp_count); frames[frame].timestamp_names[frames[frame].timestamp_count] = p_name; frames[frame].timestamp_cpu_values[frames[frame].timestamp_count] = OS::get_singleton()->get_ticks_usec(); frames[frame].timestamp_count++; diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index a786eca70d..a2527d5c33 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -141,6 +141,11 @@ class RenderingDeviceVulkan : public RenderingDevice { VkImageLayout layout; + uint64_t used_in_frame = 0; + bool used_in_transfer = false; + bool used_in_raster = false; + bool used_in_compute = false; + uint32_t read_aspect_mask = 0; uint32_t barrier_aspect_mask = 0; bool bound = false; //bound to framebffer @@ -228,13 +233,8 @@ class RenderingDeviceVulkan : public RenderingDevice { // used for the render pipelines. struct FramebufferFormatKey { - Size2i empty_size; Vector<AttachmentFormat> attachments; bool operator<(const FramebufferFormatKey &p_key) const { - if (empty_size != p_key.empty_size) { - return empty_size < p_key.empty_size; - } - int as = attachments.size(); int bs = p_key.attachments.size(); if (as != bs) { @@ -533,6 +533,8 @@ class RenderingDeviceVulkan : public RenderingDevice { PushConstant push_constant; + uint32_t compute_local_size[3] = { 0, 0, 0 }; + bool is_compute = false; int max_output = 0; Vector<Set> sets; @@ -691,6 +693,7 @@ class RenderingDeviceVulkan : public RenderingDevice { VkPipeline pipeline = VK_NULL_HANDLE; uint32_t push_constant_size = 0; uint32_t push_constant_stages = 0; + uint32_t local_group_size[3] = { 0, 0, 0 }; }; RID_Owner<ComputePipeline, true> compute_pipeline_owner; @@ -790,7 +793,7 @@ class RenderingDeviceVulkan : public RenderingDevice { Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass); Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector<RID> &p_storage_textures); _FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id); - Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access); + Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access, uint32_t p_post_barrier); /**********************/ /**** COMPUTE LIST ****/ @@ -813,8 +816,10 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t set_count = 0; RID pipeline; RID pipeline_shader; + uint32_t local_group_size[3] = { 0, 0, 0 }; VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; uint32_t pipeline_push_constant_stages = 0; + bool allow_draw_overlap; } state; #ifdef DEBUG_ENABLED @@ -918,27 +923,27 @@ public: virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture); virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); - virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false); + virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer); virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const; virtual bool texture_is_shared(RID p_texture); virtual bool texture_is_valid(RID p_texture); - virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false); - virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false); - virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false); + virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL); + virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL); + virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier = BARRIER_MASK_ALL); /*********************/ /**** FRAMEBUFFER ****/ /*********************/ virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format); - virtual FramebufferFormatID framebuffer_format_create_empty(const Size2i &p_size); + virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1); virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format); virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID); - virtual RID framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check = INVALID_ID); + virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID); virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer); @@ -980,7 +985,8 @@ public: virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set); virtual bool uniform_set_is_valid(RID p_uniform_set); - virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false); //works for any buffer + virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); //works for any buffer + virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL); virtual Vector<uint8_t> buffer_get_data(RID p_buffer); /*************************/ @@ -1026,22 +1032,24 @@ public: virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect); virtual void draw_list_disable_scissor(DrawListID p_list); - virtual void draw_list_end(); + virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL); /***********************/ /**** COMPUTE LISTS ****/ /***********************/ - virtual ComputeListID compute_list_begin(); + virtual ComputeListID compute_list_begin(bool p_allow_draw_overlap = false); virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline); virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index); virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size); virtual void compute_list_add_barrier(ComputeListID p_list); virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups); + virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads); virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset); - virtual void compute_list_end(); + virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL); + virtual void barrier(uint32_t p_from = BARRIER_MASK_ALL, uint32_t p_to = BARRIER_MASK_ALL); virtual void full_barrier(); /**************/ @@ -1054,7 +1062,7 @@ public: /**** Timing ****/ /****************/ - virtual void capture_timestamp(const String &p_name, bool p_sync_to_draw); + virtual void capture_timestamp(const String &p_name); virtual uint32_t get_captured_timestamps_count() const; virtual uint64_t get_captured_timestamps_frame() const; virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const; @@ -1082,6 +1090,16 @@ public: virtual uint64_t get_memory_usage() const; + virtual void set_resource_name(RID p_id, const String p_name); + + virtual void draw_command_begin_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)); + virtual void draw_command_insert_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)); + virtual void draw_command_end_label(); + + virtual String get_device_vendor_name() const; + virtual String get_device_name() const; + virtual String get_device_pipeline_cache_uuid() const; + RenderingDeviceVulkan(); ~RenderingDeviceVulkan(); }; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 4d2bc406e4..c564cee757 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -55,10 +55,29 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback( return VK_FALSE; } // This needs to be ignored because Validator is wrong here. + if (strstr(pCallbackData->pMessage, "Invalid SPIR-V binary version 1.3") != nullptr) { + return VK_FALSE; + } + // This needs to be ignored because Validator is wrong here. + if (strstr(pCallbackData->pMessage, "Shader requires flag") != nullptr) { + return VK_FALSE; + } + + // This needs to be ignored because Validator is wrong here. if (strstr(pCallbackData->pMessage, "SPIR-V module not valid: Pointer operand") != nullptr && strstr(pCallbackData->pMessage, "must be a memory object") != nullptr) { return VK_FALSE; } + /* + // This is a valid warning because its illegal in Vulkan, but in practice it should work according to VK_KHR_maintenance2 + if (strstr(pCallbackData->pMessage, "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT") != nullptr) { + return VK_FALSE; + } + + if (strstr(pCallbackData->pMessage, "VK_FORMAT_R4G4B4A4_UNORM_PACK16 with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT") != nullptr) { + return VK_FALSE; + } +*/ // Workaround for Vulkan-Loader usability bug: https://github.com/KhronosGroup/Vulkan-Loader/issues/262. if (strstr(pCallbackData->pMessage, "wrong ELF class: ELFCLASS32") != nullptr) { return VK_FALSE; @@ -220,6 +239,7 @@ Error VulkanContext::_initialize_extensions() { enabled_extension_count = 0; enabled_layer_count = 0; + enabled_debug_utils = false; /* Look for instance extensions */ VkBool32 surfaceExtFound = 0; VkBool32 platformSurfaceExtFound = 0; @@ -251,9 +271,8 @@ Error VulkanContext::_initialize_extensions() { } } if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) { - if (use_validation_layers) { - extension_names[enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; - } + extension_names[enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; + enabled_debug_utils = true; } if (enabled_extension_count >= MAX_EXTENSIONS) { free(instance_extensions); @@ -312,7 +331,7 @@ Error VulkanContext::_create_physical_device() { * function to register the final callback. */ VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info; - if (use_validation_layers) { + if (enabled_debug_utils) { // VK_EXT_debug_utils style dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; dbg_messenger_create_info.pNext = nullptr; @@ -361,7 +380,8 @@ Error VulkanContext::_create_physical_device() { ERR_FAIL_V(ERR_CANT_CREATE); } /* for now, just grab the first physical device */ - gpu = physical_devices[0]; + uint32_t device_index = 0; + gpu = physical_devices[device_index]; free(physical_devices); /* Look for device extensions */ @@ -370,6 +390,40 @@ Error VulkanContext::_create_physical_device() { enabled_extension_count = 0; memset(extension_names, 0, sizeof(extension_names)); + /* Get identifier properties */ + vkGetPhysicalDeviceProperties(gpu, &gpu_props); + + static const struct { + uint32_t id; + const char *name; + } vendor_names[] = { + { 0x1002, "AMD" }, + { 0x1010, "ImgTec" }, + { 0x10DE, "NVIDIA" }, + { 0x13B5, "ARM" }, + { 0x5143, "Qualcomm" }, + { 0x8086, "INTEL" }, + { 0, nullptr }, + }; + device_name = gpu_props.deviceName; + pipeline_cache_id = String::hex_encode_buffer(gpu_props.pipelineCacheUUID, VK_UUID_SIZE); + pipeline_cache_id += "-driver-" + itos(gpu_props.driverVersion); + { + device_vendor = "Unknown"; + uint32_t vendor_idx = 0; + while (vendor_names[vendor_idx].name != nullptr) { + if (gpu_props.vendorID == vendor_names[vendor_idx].id) { + device_vendor = vendor_names[vendor_idx].name; + break; + } + vendor_idx++; + } + } +#ifdef DEBUG_ENABLED + print_line("Using Vulkan Device #" + itos(device_index) + ": " + device_vendor + " - " + device_name); +#endif + device_api_version = gpu_props.apiVersion; + err = vkEnumerateDeviceExtensionProperties(gpu, nullptr, &device_extension_count, nullptr); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); @@ -436,7 +490,7 @@ Error VulkanContext::_create_physical_device() { " extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n" "vkCreateInstance Failure"); - if (use_validation_layers) { + if (enabled_debug_utils) { // Setup VK_EXT_debug_utils function pointers always (we use them for // debug labels and names). CreateDebugUtilsMessengerEXT = @@ -479,7 +533,6 @@ Error VulkanContext::_create_physical_device() { break; } } - vkGetPhysicalDeviceProperties(gpu, &gpu_props); /* Call with NULL data to get count */ vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr); @@ -546,6 +599,7 @@ Error VulkanContext::_create_device() { } err = vkCreateDevice(gpu, &sdevice, nullptr, &device); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); + return OK; } @@ -1567,6 +1621,70 @@ void VulkanContext::local_device_free(RID p_local_device) { local_device_owner.free(p_local_device); } +void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color) { + if (!enabled_debug_utils) { + return; + } + + CharString cs = p_label_name.utf8().get_data(); + VkDebugUtilsLabelEXT label; + label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + label.pNext = nullptr; + label.pLabelName = cs.get_data(); + label.color[0] = p_color[0]; + label.color[1] = p_color[1]; + label.color[2] = p_color[2]; + label.color[3] = p_color[3]; + CmdBeginDebugUtilsLabelEXT(p_command_buffer, &label); +} + +void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color) { + if (!enabled_debug_utils) { + return; + } + CharString cs = p_label_name.utf8().get_data(); + VkDebugUtilsLabelEXT label; + label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + label.pNext = nullptr; + label.pLabelName = cs.get_data(); + label.color[0] = p_color[0]; + label.color[1] = p_color[1]; + label.color[2] = p_color[2]; + label.color[3] = p_color[3]; + CmdInsertDebugUtilsLabelEXT(p_command_buffer, &label); +} + +void VulkanContext::command_end_label(VkCommandBuffer p_command_buffer) { + if (!enabled_debug_utils) { + return; + } + CmdEndDebugUtilsLabelEXT(p_command_buffer); +} + +void VulkanContext::set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name) { + if (!enabled_debug_utils) { + return; + } + CharString obj_data = p_object_name.utf8(); + VkDebugUtilsObjectNameInfoEXT name_info; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.pNext = nullptr; + name_info.objectType = p_object_type; + name_info.objectHandle = p_object_handle; + name_info.pObjectName = obj_data.get_data(); + SetDebugUtilsObjectNameEXT(device, &name_info); +} + +String VulkanContext::get_device_vendor_name() const { + return device_vendor; +} +String VulkanContext::get_device_name() const { + return device_name; +} +String VulkanContext::get_device_pipeline_cache_uuid() const { + return pipeline_cache_id; +} + VulkanContext::VulkanContext() { use_validation_layers = Engine::get_singleton()->is_validation_layers_enabled(); diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 2be9903483..dc6b0410bc 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -57,6 +57,11 @@ class VulkanContext { bool device_initialized = false; bool inst_initialized = false; + String device_vendor; + String device_name; + String pipeline_cache_id; + uint32_t device_api_version = 0; + bool buffers_prepared = false; // Present queue. @@ -119,6 +124,7 @@ class VulkanContext { bool VK_GOOGLE_display_timing_enabled = true; uint32_t enabled_extension_count = 0; const char *extension_names[MAX_EXTENSIONS]; + bool enabled_debug_utils = false; uint32_t enabled_layer_count = 0; const char *enabled_layers[MAX_LAYERS]; @@ -209,6 +215,15 @@ public: Error swap_buffers(); Error initialize(); + void command_begin_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color); + void command_insert_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color); + void command_end_label(VkCommandBuffer p_command_buffer); + void set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name); + + String get_device_vendor_name() const; + String get_device_name() const; + String get_device_pipeline_cache_uuid() const; + VulkanContext(); virtual ~VulkanContext(); }; diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 7d5082d276..43c8722b06 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -387,7 +387,7 @@ Error AudioDriverWASAPI::finish_capture_device() { } Error AudioDriverWASAPI::init() { - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); Error err = init_render_device(); if (err != OK) { @@ -397,7 +397,7 @@ Error AudioDriverWASAPI::init() { exit_thread = false; thread_exited = false; - thread = Thread::create(thread_func, this); + thread.start(thread_func, this); return OK; } @@ -767,13 +767,8 @@ void AudioDriverWASAPI::unlock() { } void AudioDriverWASAPI::finish() { - if (thread) { - exit_thread = true; - Thread::wait_to_finish(thread); - - memdelete(thread); - thread = nullptr; - } + exit_thread = true; + thread.wait_to_finish(); finish_capture_device(); finish_render_device(); diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index 2df07d16f7..b9b325f0fb 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -64,7 +64,7 @@ class AudioDriverWASAPI : public AudioDriver { AudioDeviceWASAPI audio_output; Mutex mutex; - Thread *thread = nullptr; + Thread thread; Vector<int32_t> samples_in; diff --git a/drivers/windows/rw_lock_windows.h b/drivers/windows/rw_lock_windows.h deleted file mode 100644 index a9d55bdef9..0000000000 --- a/drivers/windows/rw_lock_windows.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* rw_lock_windows.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RWLOCKWINDOWS_H -#define RWLOCKWINDOWS_H - -#if defined(WINDOWS_ENABLED) - -#include "core/os/rw_lock.h" - -#include <windows.h> - -class RWLockWindows : public RWLock { - SRWLOCK lock; - - static RWLock *create_func_windows(); - -public: - virtual void read_lock(); - virtual void read_unlock(); - virtual Error read_try_lock(); - - virtual void write_lock(); - virtual void write_unlock(); - virtual Error write_try_lock(); - - static void make_default(); - - RWLockWindows(); - - ~RWLockWindows(); -}; - -#endif - -#endif // RWLOCKWINDOWS_H diff --git a/drivers/windows/thread_windows.cpp b/drivers/windows/thread_windows.cpp deleted file mode 100644 index ec95c9523d..0000000000 --- a/drivers/windows/thread_windows.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************/ -/* thread_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "thread_windows.h" - -#if defined(WINDOWS_ENABLED) && !defined(UWP_ENABLED) - -#include "core/os/memory.h" - -Thread::ID ThreadWindows::get_id() const { - return id; -} - -Thread *ThreadWindows::create_thread_windows() { - return memnew(ThreadWindows); -} - -DWORD ThreadWindows::thread_callback(LPVOID userdata) { - ThreadWindows *t = reinterpret_cast<ThreadWindows *>(userdata); - - ScriptServer::thread_enter(); //scripts may need to attach a stack - - t->id = (ID)GetCurrentThreadId(); // must implement - t->callback(t->user); - SetEvent(t->handle); - - ScriptServer::thread_exit(); - - return 0; -} - -Thread *ThreadWindows::create_func_windows(ThreadCreateCallback p_callback, void *p_user, const Settings &) { - ThreadWindows *tr = memnew(ThreadWindows); - tr->callback = p_callback; - tr->user = p_user; - tr->handle = CreateEvent(nullptr, TRUE, FALSE, nullptr); - - QueueUserWorkItem(thread_callback, tr, WT_EXECUTELONGFUNCTION); - - return tr; -} - -Thread::ID ThreadWindows::get_thread_id_func_windows() { - return (ID)GetCurrentThreadId(); //must implement -} - -void ThreadWindows::wait_to_finish_func_windows(Thread *p_thread) { - ThreadWindows *tp = static_cast<ThreadWindows *>(p_thread); - ERR_FAIL_COND(!tp); - WaitForSingleObject(tp->handle, INFINITE); - CloseHandle(tp->handle); - //`memdelete(tp); -} - -void ThreadWindows::make_default() { - create_func = create_func_windows; - get_thread_id_func = get_thread_id_func_windows; - wait_to_finish_func = wait_to_finish_func_windows; -} - -#endif diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h deleted file mode 100644 index 3801bddc2c..0000000000 --- a/drivers/windows/thread_windows.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* thread_windows.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef THREAD_WINDOWS_H -#define THREAD_WINDOWS_H - -#ifdef WINDOWS_ENABLED - -#include "core/object/script_language.h" -#include "core/os/thread.h" - -#include <windows.h> - -class ThreadWindows : public Thread { - ThreadCreateCallback callback; - void *user; - ID id; - HANDLE handle = nullptr; - - static Thread *create_thread_windows(); - - static DWORD WINAPI thread_callback(LPVOID userdata); - - static Thread *create_func_windows(ThreadCreateCallback p_callback, void *, const Settings &); - static ID get_thread_id_func_windows(); - static void wait_to_finish_func_windows(Thread *p_thread); - - ThreadWindows() {} - -public: - virtual ID get_id() const; - - static void make_default(); - - ~ThreadWindows() {} -}; - -#endif - -#endif diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 3b3c3481b6..1c7bf5d6c6 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -44,12 +44,12 @@ Error AudioDriverXAudio2::init() { pcm_open = false; samples_in = nullptr; - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); // FIXME: speaker_mode seems unused in the Xaudio2 driver so far speaker_mode = SPEAKER_MODE_STEREO; channels = 2; - int latency = GLOBAL_GET("audio/output_latency"); + int latency = GLOBAL_GET("audio/driver/output_latency"); buffer_size = closest_power_of_2(latency * mix_rate / 1000); samples_in = memnew_arr(int32_t, buffer_size * channels); @@ -78,7 +78,7 @@ Error AudioDriverXAudio2::init() { hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback); ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 source voice. Error code: " + itos(hr) + "."); - thread = Thread::create(AudioDriverXAudio2::thread_func, this); + thread.start(AudioDriverXAudio2::thread_func, this); return OK; } @@ -146,23 +146,16 @@ float AudioDriverXAudio2::get_latency() { } void AudioDriverXAudio2::lock() { - if (!thread) - return; mutex.lock(); } void AudioDriverXAudio2::unlock() { - if (!thread) - return; mutex.unlock(); } void AudioDriverXAudio2::finish() { - if (!thread) - return; - exit_thread = true; - Thread::wait_to_finish(thread); + thread.wait_to_finish(); if (source_voice) { source_voice->Stop(0); @@ -179,9 +172,6 @@ void AudioDriverXAudio2::finish() { } mastering_voice->DestroyVoice(); - - memdelete(thread); - thread = nullptr; } AudioDriverXAudio2::AudioDriverXAudio2() { diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h index e3c2d3a326..d3938a19d0 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.h +++ b/drivers/xaudio2/audio_driver_xaudio2.h @@ -62,7 +62,7 @@ class AudioDriverXAudio2 : public AudioDriver { void STDMETHODCALLTYPE OnVoiceError(void *pBufferContext, HRESULT Error) {} }; - Thread *thread = nullptr; + Thread thread; Mutex mutex; int32_t *samples_in = nullptr; diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp new file mode 100644 index 0000000000..55640ca590 --- /dev/null +++ b/editor/action_map_editor.cpp @@ -0,0 +1,1167 @@ +/*************************************************************************/ +/* action_map_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "action_map_editor.h" +#include "core/input/input_map.h" +#include "core/os/keyboard.h" +#include "editor/editor_scale.h" +#include "scene/gui/center_container.h" + +///////////////////////////////////////// + +// Maps to 2*axis if value is neg, or + 1 if value is pos. +static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = { + TTRC("Left Stick Left, Joystick 0 Left"), + TTRC("Left Stick Right, Joystick 0 Right"), + TTRC("Left Stick Up, Joystick 0 Up"), + TTRC("Left Stick Down, Joystick 0 Down"), + TTRC("Right Stick Left, Joystick 1 Left"), + TTRC("Right Stick Right, Joystick 1 Right"), + TTRC("Right Stick Up, Joystick 1 Up"), + TTRC("Right Stick Down, Joystick 1 Down"), + TTRC("Joystick 2 Left"), + TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"), + TTRC("Joystick 2 Up"), + TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"), + TTRC("Joystick 3 Left"), + TTRC("Joystick 3 Right"), + TTRC("Joystick 3 Up"), + TTRC("Joystick 3 Down"), + TTRC("Joystick 4 Left"), + TTRC("Joystick 4 Right"), + TTRC("Joystick 4 Up"), + TTRC("Joystick 4 Down"), +}; + +String InputEventConfigurationDialog::get_event_text(const Ref<InputEvent> &p_event) { + ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEvent"); + + // Joypad motion events will display slighlty differently than what the event->as_text() provides. See #43660. + Ref<InputEventJoypadMotion> jpmotion = p_event; + if (jpmotion.is_valid()) { + String desc = TTR("Unknown Joypad Axis"); + if (jpmotion->get_axis() < JOY_AXIS_MAX) { + desc = RTR(_joy_axis_descriptions[2 * jpmotion->get_axis() + (jpmotion->get_axis_value() < 0 ? 0 : 1)]); + } + + return vformat("Joypad Axis %s %s (%s)", itos(jpmotion->get_axis()), jpmotion->get_axis_value() < 0 ? "-" : "+", desc); + } else { + return p_event->as_text(); + } +} + +void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) { + if (p_event.is_valid()) { + event = p_event; + + // Update Label + event_as_text->set_text(get_event_text(event)); + + Ref<InputEventKey> k = p_event; + Ref<InputEventMouseButton> mb = p_event; + Ref<InputEventJoypadButton> joyb = p_event; + Ref<InputEventJoypadMotion> joym = p_event; + Ref<InputEventWithModifiers> mod = p_event; + + // Update option values and visibility + bool show_mods = false; + bool show_device = false; + bool show_phys_key = false; + + if (mod.is_valid()) { + show_mods = true; + mod_checkboxes[MOD_ALT]->set_pressed(mod->get_alt()); + mod_checkboxes[MOD_SHIFT]->set_pressed(mod->get_shift()); + mod_checkboxes[MOD_COMMAND]->set_pressed(mod->get_command()); + mod_checkboxes[MOD_CONTROL]->set_pressed(mod->get_control()); + mod_checkboxes[MOD_META]->set_pressed(mod->get_metakey()); + + store_command_checkbox->set_pressed(mod->is_storing_command()); + } + + if (k.is_valid()) { + show_phys_key = true; + physical_key_checkbox->set_pressed(k->get_physical_keycode() != 0 && k->get_keycode() == 0); + + } else if (joyb.is_valid() || joym.is_valid() || mb.is_valid()) { + show_device = true; + _set_current_device(event->get_device()); + } + + mod_container->set_visible(show_mods); + device_container->set_visible(show_device); + physical_key_checkbox->set_visible(show_phys_key); + additional_options_container->show(); + + // Update selected item in input list for keys, joybuttons and joyaxis only (since the mouse cannot be "listened" for). + if (k.is_valid() || joyb.is_valid() || joym.is_valid()) { + TreeItem *category = input_list_tree->get_root()->get_children(); + while (category) { + TreeItem *input_item = category->get_children(); + + // has_type this should be always true, unless the tree structure has been misconfigured. + bool has_type = input_item->get_parent()->has_meta("__type"); + int input_type = input_item->get_parent()->get_meta("__type"); + if (!has_type) { + return; + } + + // If event type matches input types of this category. + if ((k.is_valid() && input_type == INPUT_KEY) || (joyb.is_valid() && input_type == INPUT_JOY_BUTTON) || (joym.is_valid() && input_type == INPUT_JOY_MOTION)) { + // Loop through all items of this category until one matches. + while (input_item) { + bool key_match = k.is_valid() && (Variant(k->get_keycode()) == input_item->get_meta("__keycode") || Variant(k->get_physical_keycode()) == input_item->get_meta("__keycode")); + bool joyb_match = joyb.is_valid() && Variant(joyb->get_button_index()) == input_item->get_meta("__index"); + bool joym_match = joym.is_valid() && Variant(joym->get_axis()) == input_item->get_meta("__axis") && joym->get_axis_value() == (float)input_item->get_meta("__value"); + if (key_match || joyb_match || joym_match) { + category->set_collapsed(false); + input_item->select(0); + input_list_tree->ensure_cursor_is_visible(); + return; + } + input_item = input_item->get_next(); + } + } + + category->set_collapsed(true); // Event not in this category, so collapse; + category = category->get_next(); + } + } + } else { + // Event is not valid, reset dialog + event = p_event; + Vector<String> strings; + + // Reset message, promp for input according to which input types are allowed. + String text = TTR("Perform an Input (%s)."); + + if (allowed_input_types & INPUT_KEY) { + strings.append(TTR("Key")); + } + // We don't check for INPUT_MOUSE_BUTTON since it is ignored in the "Listen Window Input" method. + + if (allowed_input_types & INPUT_JOY_BUTTON) { + strings.append(TTR("Joypad Button")); + } + if (allowed_input_types & INPUT_JOY_MOTION) { + strings.append(TTR("Joypad Axis")); + } + + if (strings.size() == 0) { + text = TTR("Input Event dialog has been misconfigured: No input types are allowed."); + event_as_text->set_text(text); + } else { + String insert_text = String(", ").join(strings); + event_as_text->set_text(vformat(text, insert_text)); + } + + additional_options_container->hide(); + input_list_tree->deselect_all(); + _update_input_list(); + } +} + +void InputEventConfigurationDialog::_tab_selected(int p_tab) { + Callable signal_method = callable_mp(this, &InputEventConfigurationDialog::_listen_window_input); + if (p_tab == 0) { + // Start Listening. + if (!is_connected("window_input", signal_method)) { + connect("window_input", signal_method); + } + } else { + // Stop Listening. + if (is_connected("window_input", signal_method)) { + disconnect("window_input", signal_method); + } + input_list_tree->call_deferred("ensure_cursor_is_visible"); + if (input_list_tree->get_selected() == nullptr) { + // If nothing selected, scroll to top. + input_list_tree->scroll_to_item(input_list_tree->get_root()); + } + } +} + +void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &p_event) { + // Ignore if echo or not pressed + if (p_event->is_echo() || !p_event->is_pressed()) { + return; + } + + // Ignore mouse + Ref<InputEventMouse> m = p_event; + if (m.is_valid()) { + return; + } + + // Check what the type is and if it is allowed. + Ref<InputEventKey> k = p_event; + Ref<InputEventJoypadButton> joyb = p_event; + Ref<InputEventJoypadMotion> joym = p_event; + + int type = k.is_valid() ? INPUT_KEY : joyb.is_valid() ? INPUT_JOY_BUTTON : + joym.is_valid() ? INPUT_JOY_MOTION : + 0; + + if (!(allowed_input_types & type)) { + return; + } + + if (joym.is_valid()) { + float axis_value = joym->get_axis_value(); + if (ABS(axis_value) < 0.9) { + // Ignore motion below 0.9 magnitude to avoid accidental touches + return; + } else { + // Always make the value 1 or -1 for display consistency + joym->set_axis_value(SGN(axis_value)); + } + } + + if (k.is_valid()) { + k->set_pressed(false); // to avoid serialisation of 'pressed' property - doesn't matter for actions anyway. + // Maintain physical keycode option state + if (physical_key_checkbox->is_pressed()) { + k->set_physical_keycode(k->get_keycode()); + k->set_keycode(0); + } else { + k->set_keycode(k->get_physical_keycode()); + k->set_physical_keycode(0); + } + } + + Ref<InputEventWithModifiers> mod = p_event; + if (mod.is_valid()) { + // Maintain store command option state + mod->set_store_command(store_command_checkbox->is_pressed()); + + mod->set_window_id(0); + } + + _set_event(p_event); + set_input_as_handled(); +} + +void InputEventConfigurationDialog::_search_term_updated(const String &) { + _update_input_list(); +} + +void InputEventConfigurationDialog::_update_input_list() { + input_list_tree->clear(); + + TreeItem *root = input_list_tree->create_item(); + String search_term = input_list_search->get_text(); + + bool collapse = input_list_search->get_text().is_empty(); + + if (allowed_input_types & INPUT_KEY) { + TreeItem *kb_root = input_list_tree->create_item(root); + kb_root->set_text(0, TTR("Keyboard Keys")); + kb_root->set_icon(0, icon_cache.keyboard); + kb_root->set_collapsed(collapse); + kb_root->set_meta("__type", INPUT_KEY); + + for (int i = 0; i < keycode_get_count(); i++) { + String name = keycode_get_name_by_index(i); + + if (!search_term.is_empty() && name.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(kb_root); + item->set_text(0, name); + item->set_meta("__keycode", keycode_get_value_by_index(i)); + } + } + + if (allowed_input_types & INPUT_MOUSE_BUTTON) { + TreeItem *mouse_root = input_list_tree->create_item(root); + mouse_root->set_text(0, TTR("Mouse Buttons")); + mouse_root->set_icon(0, icon_cache.mouse); + mouse_root->set_collapsed(collapse); + mouse_root->set_meta("__type", INPUT_MOUSE_BUTTON); + + int mouse_buttons[9] = { BUTTON_LEFT, BUTTON_RIGHT, BUTTON_MIDDLE, BUTTON_WHEEL_UP, BUTTON_WHEEL_DOWN, BUTTON_WHEEL_LEFT, BUTTON_WHEEL_RIGHT, BUTTON_XBUTTON1, BUTTON_XBUTTON2 }; + for (int i = 0; i < 9; i++) { + Ref<InputEventMouseButton> mb; + mb.instance(); + mb->set_button_index(mouse_buttons[i]); + String desc = get_event_text(mb); + + if (!search_term.is_empty() && desc.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(mouse_root); + item->set_text(0, desc); + item->set_meta("__index", mouse_buttons[i]); + } + } + + if (allowed_input_types & INPUT_JOY_BUTTON) { + TreeItem *joyb_root = input_list_tree->create_item(root); + joyb_root->set_text(0, TTR("Joypad Buttons")); + joyb_root->set_icon(0, icon_cache.joypad_button); + joyb_root->set_collapsed(collapse); + joyb_root->set_meta("__type", INPUT_JOY_BUTTON); + + for (int i = 0; i < JOY_BUTTON_MAX; i++) { + Ref<InputEventJoypadButton> joyb; + joyb.instance(); + joyb->set_button_index(i); + String desc = get_event_text(joyb); + + if (!search_term.is_empty() && desc.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(joyb_root); + item->set_text(0, desc); + item->set_meta("__index", i); + } + } + + if (allowed_input_types & INPUT_JOY_MOTION) { + TreeItem *joya_root = input_list_tree->create_item(root); + joya_root->set_text(0, TTR("Joypad Axes")); + joya_root->set_icon(0, icon_cache.joypad_axis); + joya_root->set_collapsed(collapse); + joya_root->set_meta("__type", INPUT_JOY_MOTION); + + for (int i = 0; i < JOY_AXIS_MAX * 2; i++) { + int axis = i / 2; + int direction = (i & 1) ? 1 : -1; + Ref<InputEventJoypadMotion> joym; + joym.instance(); + joym->set_axis(axis); + joym->set_axis_value(direction); + String desc = get_event_text(joym); + + if (!search_term.is_empty() && desc.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(joya_root); + item->set_text(0, desc); + item->set_meta("__axis", i >> 1); + item->set_meta("__value", (i & 1) ? 1 : -1); + } + } +} + +void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) { + Ref<InputEventWithModifiers> ie = event; + + // Not event with modifiers + if (ie.is_null()) { + return; + } + + if (p_index == 0) { + ie->set_alt(p_checked); + } else if (p_index == 1) { + ie->set_shift(p_checked); + } else if (p_index == 2) { + ie->set_command(p_checked); + } else if (p_index == 3) { + ie->set_control(p_checked); + } else if (p_index == 4) { + ie->set_metakey(p_checked); + } + + _set_event(ie); +} + +void InputEventConfigurationDialog::_store_command_toggled(bool p_checked) { + Ref<InputEventWithModifiers> ie = event; + if (ie.is_valid()) { + ie->set_store_command(p_checked); + _set_event(ie); + } + + if (p_checked) { + // If storing Command, show it's checkbox and hide Control (Win/Lin) or Meta (Mac) +#ifdef APPLE_STYLE_KEYS + mod_checkboxes[MOD_META]->hide(); + + mod_checkboxes[MOD_COMMAND]->show(); + mod_checkboxes[MOD_COMMAND]->set_text("Meta (Command)"); +#else + mod_checkboxes[MOD_CONTROL]->hide(); + + mod_checkboxes[MOD_COMMAND]->show(); + mod_checkboxes[MOD_COMMAND]->set_text("Control (Command)"); +#endif + } else { + // If not, hide Command, show Control and Meta. + mod_checkboxes[MOD_COMMAND]->hide(); + mod_checkboxes[MOD_CONTROL]->show(); + mod_checkboxes[MOD_META]->show(); + } +} + +void InputEventConfigurationDialog::_physical_keycode_toggled(bool p_checked) { + Ref<InputEventKey> k = event; + + if (k.is_null()) { + return; + } + + if (p_checked) { + k->set_physical_keycode(k->get_keycode()); + k->set_keycode(0); + } else { + k->set_keycode(k->get_physical_keycode()); + k->set_physical_keycode(0); + } + + _set_event(k); +} + +void InputEventConfigurationDialog::_input_list_item_selected() { + TreeItem *selected = input_list_tree->get_selected(); + + // Invalid tree selection - type only exists on the "category" items, which are not a valid selection. + if (selected->has_meta("__type")) { + return; + } + + int input_type = selected->get_parent()->get_meta("__type"); + + switch (input_type) { + case InputEventConfigurationDialog::INPUT_KEY: { + int kc = selected->get_meta("__keycode"); + Ref<InputEventKey> k; + k.instance(); + + if (physical_key_checkbox->is_pressed()) { + k->set_physical_keycode(kc); + k->set_keycode(0); + } else { + k->set_physical_keycode(0); + k->set_keycode(kc); + } + + // Maintain modifier state from checkboxes + k->set_alt(mod_checkboxes[MOD_ALT]->is_pressed()); + k->set_shift(mod_checkboxes[MOD_SHIFT]->is_pressed()); + k->set_command(mod_checkboxes[MOD_COMMAND]->is_pressed()); + k->set_control(mod_checkboxes[MOD_CONTROL]->is_pressed()); + k->set_metakey(mod_checkboxes[MOD_META]->is_pressed()); + k->set_store_command(store_command_checkbox->is_pressed()); + + _set_event(k); + } break; + case InputEventConfigurationDialog::INPUT_MOUSE_BUTTON: { + int idx = selected->get_meta("__index"); + Ref<InputEventMouseButton> mb; + mb.instance(); + mb->set_button_index(idx); + // Maintain modifier state from checkboxes + mb->set_alt(mod_checkboxes[MOD_ALT]->is_pressed()); + mb->set_shift(mod_checkboxes[MOD_SHIFT]->is_pressed()); + mb->set_command(mod_checkboxes[MOD_COMMAND]->is_pressed()); + mb->set_control(mod_checkboxes[MOD_CONTROL]->is_pressed()); + mb->set_metakey(mod_checkboxes[MOD_META]->is_pressed()); + mb->set_store_command(store_command_checkbox->is_pressed()); + + _set_event(mb); + } break; + case InputEventConfigurationDialog::INPUT_JOY_BUTTON: { + int idx = selected->get_meta("__index"); + Ref<InputEventJoypadButton> jb = InputEventJoypadButton::create_reference(idx); + _set_event(jb); + } break; + case InputEventConfigurationDialog::INPUT_JOY_MOTION: { + int axis = selected->get_meta("__axis"); + int value = selected->get_meta("__value"); + + Ref<InputEventJoypadMotion> jm; + jm.instance(); + jm->set_axis(axis); + jm->set_axis_value(value); + _set_event(jm); + } break; + default: + break; + } +} + +void InputEventConfigurationDialog::_set_current_device(int i_device) { + device_id_option->select(i_device + 1); +} + +int InputEventConfigurationDialog::_get_current_device() const { + return device_id_option->get_selected() - 1; +} + +String InputEventConfigurationDialog::_get_device_string(int i_device) const { + if (i_device == InputMap::ALL_DEVICES) { + return TTR("All Devices"); + } + return TTR("Device") + " " + itos(i_device); +} + +void InputEventConfigurationDialog::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + input_list_search->set_right_icon(input_list_search->get_theme_icon("Search", "EditorIcons")); + + physical_key_checkbox->set_icon(get_theme_icon("KeyboardPhysical", "EditorIcons")); + + icon_cache.keyboard = get_theme_icon("Keyboard", "EditorIcons"); + icon_cache.mouse = get_theme_icon("Mouse", "EditorIcons"); + icon_cache.joypad_button = get_theme_icon("JoyButton", "EditorIcons"); + icon_cache.joypad_axis = get_theme_icon("JoyAxis", "EditorIcons"); + + _update_input_list(); + } break; + default: + break; + } +} + +void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p_event) { + if (p_event.is_valid()) { + _set_event(p_event); + } else { + // Clear Event + _set_event(p_event); + + // Clear Checkbox Values + for (int i = 0; i < MOD_MAX; i++) { + mod_checkboxes[i]->set_pressed(false); + } + physical_key_checkbox->set_pressed(false); + store_command_checkbox->set_pressed(true); + _set_current_device(0); + + // Switch to "Listen" tab + tab_container->set_current_tab(0); + } + + popup_centered(); +} + +Ref<InputEvent> InputEventConfigurationDialog::get_event() const { + return event; +} + +void InputEventConfigurationDialog::set_allowed_input_types(int p_type_masks) { + allowed_input_types = p_type_masks; +} + +InputEventConfigurationDialog::InputEventConfigurationDialog() { + allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION; + + set_title("Event Configuration"); + set_min_size(Size2i(550 * EDSCALE, 0)); // Min width + + VBoxContainer *main_vbox = memnew(VBoxContainer); + add_child(main_vbox); + + tab_container = memnew(TabContainer); + tab_container->set_tab_align(TabContainer::TabAlign::ALIGN_LEFT); + tab_container->set_use_hidden_tabs_for_min_size(true); + tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL); + tab_container->connect("tab_selected", callable_mp(this, &InputEventConfigurationDialog::_tab_selected)); + main_vbox->add_child(tab_container); + + CenterContainer *cc = memnew(CenterContainer); + cc->set_name("Listen for Input"); + event_as_text = memnew(Label); + event_as_text->set_align(Label::ALIGN_CENTER); + cc->add_child(event_as_text); + tab_container->add_child(cc); + + // List of all input options to manually select from. + + VBoxContainer *manual_vbox = memnew(VBoxContainer); + manual_vbox->set_name("Manual Selection"); + manual_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL); + tab_container->add_child(manual_vbox); + + input_list_search = memnew(LineEdit); + input_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL); + input_list_search->set_placeholder(TTR("Filter Inputs")); + input_list_search->set_clear_button_enabled(true); + input_list_search->connect("text_changed", callable_mp(this, &InputEventConfigurationDialog::_search_term_updated)); + manual_vbox->add_child(input_list_search); + + input_list_tree = memnew(Tree); + input_list_tree->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); // Min height for tree + input_list_tree->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_input_list_item_selected)); + input_list_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); + manual_vbox->add_child(input_list_tree); + + input_list_tree->set_hide_root(true); + input_list_tree->set_columns(1); + + _update_input_list(); + + // Additional Options + additional_options_container = memnew(VBoxContainer); + additional_options_container->hide(); + + Label *opts_label = memnew(Label); + opts_label->set_text("Additional Options"); + additional_options_container->add_child(opts_label); + + // Device Selection + device_container = memnew(HBoxContainer); + device_container->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + Label *device_label = memnew(Label); + device_label->set_text("Device:"); + device_container->add_child(device_label); + + device_id_option = memnew(OptionButton); + device_id_option->set_h_size_flags(Control::SIZE_EXPAND_FILL); + device_container->add_child(device_id_option); + + for (int i = -1; i < 8; i++) { + device_id_option->add_item(_get_device_string(i)); + } + _set_current_device(0); + device_container->hide(); + additional_options_container->add_child(device_container); + + // Modifier Selection + mod_container = memnew(HBoxContainer); + for (int i = 0; i < MOD_MAX; i++) { + String name = mods[i]; + mod_checkboxes[i] = memnew(CheckBox); + mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled), varray(i)); + mod_checkboxes[i]->set_text(name); + mod_container->add_child(mod_checkboxes[i]); + } + + mod_container->add_child(memnew(VSeparator)); + + store_command_checkbox = memnew(CheckBox); + store_command_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_store_command_toggled)); + store_command_checkbox->set_pressed(true); + store_command_checkbox->set_text(TTR("Store Command")); +#ifdef APPLE_STYLE_KEYS + store_command_checkbox->set_tooltip(TTR("Toggles between serializing 'command' and 'meta'. Used for compatibility with Windows/Linux style keyboard.")); +#else + store_command_checkbox->set_tooltip(TTR("Toggles between serializing 'command' and 'control'. Used for compatibility with Apple Style keyboards.")); +#endif + mod_container->add_child(store_command_checkbox); + + mod_container->hide(); + additional_options_container->add_child(mod_container); + + // Physical Key Checkbox + + physical_key_checkbox = memnew(CheckBox); + physical_key_checkbox->set_text(TTR("Use Physical Keycode")); + physical_key_checkbox->set_tooltip(TTR("Stores the physical position of the key on the keyboard rather than the keys value. Used for compatibility with non-latin layouts.")); + physical_key_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_physical_keycode_toggled)); + physical_key_checkbox->hide(); + additional_options_container->add_child(physical_key_checkbox); + + main_vbox->add_child(additional_options_container); + + // Default to first tab + tab_container->set_current_tab(0); +} + +///////////////////////////////////////// + +static bool _is_action_name_valid(const String &p_name) { + const char32_t *cstr = p_name.get_data(); + for (int i = 0; cstr[i]; i++) { + if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' || + cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) { + return false; + } + } + return true; +} + +void ActionMapEditor::_event_config_confirmed() { + Ref<InputEvent> ev = event_config_dialog->get_event(); + + Dictionary new_action = current_action.duplicate(); + Array events = new_action["events"]; + + if (current_action_event_index == -1) { + // Add new event + events.push_back(ev); + } else { + // Edit existing event + events[current_action_event_index] = ev; + } + + new_action["events"] = events; + emit_signal("action_edited", current_action_name, new_action); +} + +void ActionMapEditor::_add_action_pressed() { + _add_action(add_edit->get_text()); +} + +void ActionMapEditor::_add_action(const String &p_name) { + if (!allow_editing_actions) { + return; + } + + if (p_name == "" || !_is_action_name_valid(p_name)) { + show_message(TTR("Invalid action name. it cannot be.is_empty()() nor contain '/', ':', '=', '\\' or '\"'")); + return; + } + + add_edit->clear(); + emit_signal("action_added", p_name); +} + +void ActionMapEditor::_action_edited() { + if (!allow_editing_actions) { + return; + } + + TreeItem *ti = action_tree->get_edited(); + if (!ti) { + return; + } + + if (action_tree->get_selected_column() == 0) { + // Name Edited + String new_name = ti->get_text(0); + String old_name = ti->get_meta("__name"); + + if (new_name == old_name) { + return; + } + + if (new_name == "" || !_is_action_name_valid(new_name)) { + ti->set_text(0, old_name); + show_message(TTR("Invalid action name. it cannot be.is_empty()() nor contain '/', ':', '=', '\\' or '\"'")); + return; + } + + emit_signal("action_renamed", old_name, new_name); + } else if (action_tree->get_selected_column() == 1) { + // Deadzone Edited + String name = ti->get_meta("__name"); + Dictionary old_action = ti->get_meta("__action"); + Dictionary new_action = old_action.duplicate(); + new_action["deadzone"] = ti->get_range(1); + + // Call deferred so that input can finish propagating through tree, allowing re-making of tree to occur. + call_deferred("emit_signal", "action_edited", name, new_action); + } +} + +void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_id) { + ItemButton option = (ItemButton)p_id; + + TreeItem *item = Object::cast_to<TreeItem>(p_item); + if (!item) { + return; + } + + switch (option) { + case ActionMapEditor::BUTTON_ADD_EVENT: { + current_action = item->get_meta("__action"); + current_action_name = item->get_meta("__name"); + current_action_event_index = -1; + + event_config_dialog->popup_and_configure(); + + } break; + case ActionMapEditor::BUTTON_EDIT_EVENT: { + // Action and Action name is located on the parent of the event. + current_action = item->get_parent()->get_meta("__action"); + current_action_name = item->get_parent()->get_meta("__name"); + + current_action_event_index = item->get_meta("__index"); + + Ref<InputEvent> ie = item->get_meta("__event"); + if (ie.is_valid()) { + event_config_dialog->popup_and_configure(ie); + } + + } break; + case ActionMapEditor::BUTTON_REMOVE_ACTION: { + if (!allow_editing_actions) { + break; + } + + // Send removed action name + String name = item->get_meta("__name"); + emit_signal("action_removed", name); + } break; + case ActionMapEditor::BUTTON_REMOVE_EVENT: { + // Remove event and send updated action + Dictionary action = item->get_parent()->get_meta("__action"); + String action_name = item->get_parent()->get_meta("__name"); + + int event_index = item->get_meta("__index"); + + Array events = action["events"]; + events.remove(event_index); + action["events"] = events; + + emit_signal("action_edited", action_name, action); + } break; + default: + break; + } +} + +void ActionMapEditor::_tree_item_activated() { + TreeItem *item = action_tree->get_selected(); + + if (!item || !item->has_meta("__event")) { + return; + } + + _tree_button_pressed(item, 2, BUTTON_EDIT_EVENT); +} + +void ActionMapEditor::set_show_uneditable(bool p_show) { + show_uneditable = p_show; + show_uneditable_actions_checkbox->set_pressed(p_show); + + // Prevent unnecessary updates of action list when cache is.is_empty()(). + if (!actions_cache.is_empty()) { + update_action_list(); + } +} + +void ActionMapEditor::_search_term_updated(const String &) { + update_action_list(); +} + +Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + TreeItem *selected = action_tree->get_selected(); + if (!selected) { + return Variant(); + } + + String name = selected->get_text(0); + Label *label = memnew(Label(name)); + label->set_modulate(Color(1, 1, 1, 1.0f)); + action_tree->set_drag_preview(label); + + Dictionary drag_data; + + if (selected->has_meta("__action")) { + drag_data["input_type"] = "action"; + } + + if (selected->has_meta("__event")) { + drag_data["input_type"] = "event"; + } + + action_tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); + + return drag_data; +} + +bool ActionMapEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + Dictionary d = p_data; + if (!d.has("input_type")) { + return false; + } + + TreeItem *selected = action_tree->get_selected(); + TreeItem *item = action_tree->get_item_at_position(p_point); + if (!selected || !item || item == selected) { + return false; + } + + // Don't allow moving an action in-between events. + if (d["input_type"] == "action" && item->has_meta("__event")) { + return false; + } + + // Don't allow moving an event to a different action. + if (d["input_type"] == "event" && item->get_parent() != selected->get_parent()) { + return false; + } + + return true; +} + +void ActionMapEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + if (!can_drop_data_fw(p_point, p_data, p_from)) { + return; + } + + TreeItem *selected = action_tree->get_selected(); + TreeItem *target = action_tree->get_item_at_position(p_point); + bool drop_above = action_tree->get_drop_section_at_position(p_point) == -1; + + if (!target) { + return; + } + + Dictionary d = p_data; + if (d["input_type"] == "action") { + // Change action order. + String relative_to = target->get_meta("__name"); + String action_name = selected->get_meta("__name"); + emit_signal("action_reordered", action_name, relative_to, drop_above); + + } else if (d["input_type"] == "event") { + // Change event order + int current_index = selected->get_meta("__index"); + int target_index = target->get_meta("__index"); + + // Construct new events array. + Dictionary new_action = selected->get_parent()->get_meta("__action"); + + Array events = new_action["events"]; + Array new_events; + + // The following method was used to perform the array changes since `remove` followed by `insert` was not working properly at time of writing. + // Loop thought existing events + for (int i = 0; i < events.size(); i++) { + // If you come across the current index, just skip it, as it has been moved. + if (i == current_index) { + continue; + } else if (i == target_index) { + // We are at the target index. If drop above, add selected event there first, then target, so moved event goes on top. + if (drop_above) { + new_events.push_back(events[current_index]); + new_events.push_back(events[target_index]); + } else { + new_events.push_back(events[target_index]); + new_events.push_back(events[current_index]); + } + } else { + new_events.push_back(events[i]); + } + } + + new_action["events"] = new_events; + emit_signal("action_edited", selected->get_parent()->get_meta("__name"), new_action); + } +} + +void ActionMapEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + action_list_search->set_right_icon(get_theme_icon("Search", "EditorIcons")); + } break; + default: + break; + } +} + +void ActionMapEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ActionMapEditor::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ActionMapEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &ActionMapEditor::drop_data_fw); + + ADD_SIGNAL(MethodInfo("action_added", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("action_edited", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::DICTIONARY, "new_action"))); + ADD_SIGNAL(MethodInfo("action_removed", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("action_renamed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name"))); + ADD_SIGNAL(MethodInfo("action_reordered", PropertyInfo(Variant::STRING, "action_name"), PropertyInfo(Variant::STRING, "relative_to"), PropertyInfo(Variant::BOOL, "before"))); +} + +LineEdit *ActionMapEditor::get_search_box() const { + return action_list_search; +} + +InputEventConfigurationDialog *ActionMapEditor::get_configuration_dialog() { + return event_config_dialog; +} + +void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_infos) { + if (!p_action_infos.is_empty()) { + actions_cache = p_action_infos; + } + + action_tree->clear(); + TreeItem *root = action_tree->create_item(); + + int uneditable_count = 0; + + for (int i = 0; i < actions_cache.size(); i++) { + ActionInfo action_info = actions_cache[i]; + + if (!action_info.editable) { + uneditable_count++; + } + + String search_term = action_list_search->get_text(); + if (!search_term.is_empty() && action_info.name.findn(search_term) == -1) { + continue; + } + + if (!action_info.editable && !show_uneditable) { + continue; + } + + const Array events = action_info.action["events"]; + const Variant deadzone = action_info.action["deadzone"]; + + // Update Tree... + + TreeItem *action_item = action_tree->create_item(root); + action_item->set_meta("__action", action_info.action); + action_item->set_meta("__name", action_info.name); + + // First Column - Action Name + action_item->set_text(0, action_info.name); + action_item->set_editable(0, action_info.editable); + action_item->set_icon(0, action_info.icon); + + // Second Column - Deadzone + action_item->set_editable(1, true); + action_item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE); + action_item->set_range_config(1, 0.0, 1.0, 0.01); + action_item->set_range(1, deadzone); + + // Third column - buttons + action_item->add_button(2, action_tree->get_theme_icon("Add", "EditorIcons"), BUTTON_ADD_EVENT, false, TTR("Add Event")); + action_item->add_button(2, action_tree->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? "Remove Action" : "Cannot Remove Action"); + + action_item->set_custom_bg_color(0, action_tree->get_theme_color("prop_subsection", "Editor")); + action_item->set_custom_bg_color(1, action_tree->get_theme_color("prop_subsection", "Editor")); + + for (int evnt_idx = 0; evnt_idx < events.size(); evnt_idx++) { + Ref<InputEvent> event = events[evnt_idx]; + if (event.is_null()) { + continue; + } + + TreeItem *event_item = action_tree->create_item(action_item); + + // First Column - Text + event_item->set_text(0, event_config_dialog->get_event_text(event)); // Need to us the special description for JoypadMotion here, so don't use as_text() directly. + event_item->set_meta("__event", event); + event_item->set_meta("__index", evnt_idx); + + // Third Column - Buttons + event_item->add_button(2, action_tree->get_theme_icon("Edit", "EditorIcons"), BUTTON_EDIT_EVENT, false, TTR("Edit Event")); + event_item->add_button(2, action_tree->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_EVENT, false, TTR("Remove Event")); + event_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); + event_item->set_button_color(2, 1, Color(1, 1, 1, 0.75)); + } + } +} + +void ActionMapEditor::show_message(const String &p_message) { + message->set_text(p_message); + message->popup_centered(Size2(300, 100) * EDSCALE); +} + +void ActionMapEditor::set_allow_editing_actions(bool p_allow) { + allow_editing_actions = p_allow; + add_hbox->set_visible(p_allow); +} + +void ActionMapEditor::set_toggle_editable_label(const String &p_label) { + show_uneditable_actions_checkbox->set_text(p_label); +} + +void ActionMapEditor::use_external_search_box(LineEdit *p_searchbox) { + memdelete(action_list_search); + action_list_search = p_searchbox; + action_list_search->connect("text_changed", callable_mp(this, &ActionMapEditor::_search_term_updated)); +} + +ActionMapEditor::ActionMapEditor() { + allow_editing_actions = true; + show_uneditable = true; + + // Main Vbox Container + VBoxContainer *main_vbox = memnew(VBoxContainer); + main_vbox->set_anchors_and_offsets_preset(PRESET_WIDE); + add_child(main_vbox); + + HBoxContainer *top_hbox = memnew(HBoxContainer); + main_vbox->add_child(top_hbox); + + action_list_search = memnew(LineEdit); + action_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL); + action_list_search->set_placeholder(TTR("Filter Actions")); + action_list_search->set_clear_button_enabled(true); + action_list_search->connect("text_changed", callable_mp(this, &ActionMapEditor::_search_term_updated)); + top_hbox->add_child(action_list_search); + + show_uneditable_actions_checkbox = memnew(CheckBox); + show_uneditable_actions_checkbox->set_pressed(false); + show_uneditable_actions_checkbox->set_text(TTR("Show Uneditable Actions")); + show_uneditable_actions_checkbox->connect("toggled", callable_mp(this, &ActionMapEditor::set_show_uneditable)); + top_hbox->add_child(show_uneditable_actions_checkbox); + + // Adding Action line edit + button + add_hbox = memnew(HBoxContainer); + add_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + add_edit = memnew(LineEdit); + add_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL); + add_edit->set_placeholder(TTR("Add New Action")); + add_edit->set_clear_button_enabled(true); + add_edit->connect("text_entered", callable_mp(this, &ActionMapEditor::_add_action)); + add_hbox->add_child(add_edit); + + Button *add_button = memnew(Button); + add_button->set_text("Add"); + add_button->connect("pressed", callable_mp(this, &ActionMapEditor::_add_action_pressed)); + add_hbox->add_child(add_button); + + main_vbox->add_child(add_hbox); + + // Action Editor Tree + action_tree = memnew(Tree); + action_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); + action_tree->set_columns(3); + action_tree->set_hide_root(true); + action_tree->set_column_titles_visible(true); + action_tree->set_column_title(0, TTR("Action")); + action_tree->set_column_title(1, TTR("Deadzone")); + action_tree->set_column_expand(1, false); + action_tree->set_column_min_width(1, 80 * EDSCALE); + action_tree->set_column_expand(2, false); + action_tree->set_column_min_width(2, 50 * EDSCALE); + action_tree->connect("item_edited", callable_mp(this, &ActionMapEditor::_action_edited)); + action_tree->connect("item_activated", callable_mp(this, &ActionMapEditor::_tree_item_activated)); + action_tree->connect("button_pressed", callable_mp(this, &ActionMapEditor::_tree_button_pressed)); + main_vbox->add_child(action_tree); + + action_tree->set_drag_forwarding(this); + + // Adding event dialog + event_config_dialog = memnew(InputEventConfigurationDialog); + event_config_dialog->connect("confirmed", callable_mp(this, &ActionMapEditor::_event_config_confirmed)); + add_child(event_config_dialog); + + message = memnew(AcceptDialog); + add_child(message); +} diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h new file mode 100644 index 0000000000..f1f7bffef4 --- /dev/null +++ b/editor/action_map_editor.h @@ -0,0 +1,203 @@ +/*************************************************************************/ +/* action_map_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef ACTION_MAP_EDITOR_H +#define ACTION_MAP_EDITOR_H + +#include "editor/editor_data.h" + +// Confirmation Dialog used when configuring an input event. +// Separate from ActionMapEditor for code cleanliness and separation of responsibilities. +class InputEventConfigurationDialog : public ConfirmationDialog { + GDCLASS(InputEventConfigurationDialog, ConfirmationDialog); + +public: + enum InputType { + INPUT_KEY = 1, + INPUT_MOUSE_BUTTON = 2, + INPUT_JOY_BUTTON = 4, + INPUT_JOY_MOTION = 8 + }; + +private: + struct IconCache { + Ref<Texture2D> keyboard; + Ref<Texture2D> mouse; + Ref<Texture2D> joypad_button; + Ref<Texture2D> joypad_axis; + } icon_cache; + + Ref<InputEvent> event = Ref<InputEvent>(); + + TabContainer *tab_container; + + // Listening for input + Label *event_as_text; + + // List of All Key/Mouse/Joypad input options. + int allowed_input_types; + Tree *input_list_tree; + LineEdit *input_list_search; + + // Additional Options, shown depending on event selected + VBoxContainer *additional_options_container; + + HBoxContainer *device_container; + OptionButton *device_id_option; + + HBoxContainer *mod_container; // Contains the subcontainer and the store command checkbox. + + enum ModCheckbox { + MOD_ALT, + MOD_SHIFT, + MOD_COMMAND, + MOD_CONTROL, + MOD_META, + MOD_MAX + }; + String mods[MOD_MAX] = { "Alt", "Shift", "Command", "Control", "Meta" }; + + CheckBox *mod_checkboxes[MOD_MAX]; + CheckBox *store_command_checkbox; + + CheckBox *physical_key_checkbox; + + void _set_event(const Ref<InputEvent> &p_event); + + void _tab_selected(int p_tab); + void _listen_window_input(const Ref<InputEvent> &p_event); + + void _search_term_updated(const String &p_term); + void _update_input_list(); + void _input_list_item_selected(); + + void _mod_toggled(bool p_checked, int p_index); + void _store_command_toggled(bool p_checked); + void _physical_keycode_toggled(bool p_checked); + + void _set_current_device(int i_device); + int _get_current_device() const; + String _get_device_string(int i_device) const; + +protected: + void _notification(int p_what); + +public: + // Pass an existing event to configure it. Alternatively, pass no event to start with a blank configuration. + void popup_and_configure(const Ref<InputEvent> &p_event = Ref<InputEvent>()); + Ref<InputEvent> get_event() const; + String get_event_text(const Ref<InputEvent> &p_event); + + void set_allowed_input_types(int p_type_masks); + + InputEventConfigurationDialog(); +}; + +class ActionMapEditor : public Control { + GDCLASS(ActionMapEditor, Control); + +public: + struct ActionInfo { + String name = String(); + Dictionary action = Dictionary(); + + Ref<Texture2D> icon = Ref<Texture2D>(); + bool editable = true; + }; + +private: + enum ItemButton { + BUTTON_ADD_EVENT, + BUTTON_EDIT_EVENT, + BUTTON_REMOVE_ACTION, + BUTTON_REMOVE_EVENT, + }; + + Vector<ActionInfo> actions_cache; + Tree *action_tree; + + // Storing which action/event is currently being edited in the InputEventConfigurationDialog. + + Dictionary current_action = Dictionary(); + String current_action_name = String(); + int current_action_event_index = -1; + + // Popups + + InputEventConfigurationDialog *event_config_dialog; + AcceptDialog *message; + + // Filtering and Adding actions + + bool show_uneditable; + CheckBox *show_uneditable_actions_checkbox; + LineEdit *action_list_search; + + bool allow_editing_actions; + HBoxContainer *add_hbox; + LineEdit *add_edit; + + void _event_config_confirmed(); + + void _add_action_pressed(); + void _add_action(const String &p_name); + void _action_edited(); + + void _tree_button_pressed(Object *p_item, int p_column, int p_id); + void _tree_item_activated(); + void _search_term_updated(const String &p_search_term); + + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + LineEdit *get_search_box() const; + InputEventConfigurationDialog *get_configuration_dialog(); + + // Dictionary represents an Action with "events" (Array) and "deadzone" (float) items. Pass with no param to update list from cached action map. + void update_action_list(const Vector<ActionInfo> &p_action_infos = Vector<ActionInfo>()); + void show_message(const String &p_message); + + void set_show_uneditable(bool p_show); + void set_allow_editing_actions(bool p_allow); + + void set_toggle_editable_label(const String &p_label); + + void use_external_search_box(LineEdit *p_searchbox); + + ActionMapEditor(); +}; + +#endif diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 5d49290612..934c6b95a4 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -634,7 +634,7 @@ public: bool use_fps = false; void notify_change() { - _change_notify(); + notify_property_list_changed(); } Node *get_root_path() { @@ -643,7 +643,7 @@ public: void set_use_fps(bool p_enable) { use_fps = p_enable; - _change_notify(); + notify_property_list_changed(); } }; @@ -1276,7 +1276,7 @@ public: UndoRedo *undo_redo = nullptr; void notify_change() { - _change_notify(); + notify_property_list_changed(); } Node *get_root_path() { @@ -1285,7 +1285,7 @@ public: void set_use_fps(bool p_enable) { use_fps = p_enable; - _change_notify(); + notify_property_list_changed(); } }; @@ -4283,7 +4283,6 @@ void AnimationTrackEditor::_animation_update() { _update_step_spinbox(); emit_signal("animation_step_changed", animation->get_step()); emit_signal("animation_len_changed", animation->get_length()); - EditorNode::get_singleton()->get_inspector()->refresh(); animation_changing_awaiting_update = false; } diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp index 3daee4587c..09defac354 100644 --- a/editor/array_property_edit.cpp +++ b/editor/array_property_edit.cpp @@ -49,11 +49,7 @@ Variant ArrayPropertyEdit::get_array() const { } void ArrayPropertyEdit::_notif_change() { - _change_notify(); -} - -void ArrayPropertyEdit::_notif_changev(const String &p_v) { - _change_notify(p_v.utf8().get_data()); + notify_property_list_changed(); } void ArrayPropertyEdit::_set_size(int p_size) { @@ -120,7 +116,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { } if (pn == "array/page") { page = p_value; - _change_notify(); + notify_property_list_changed(); return true; } @@ -159,8 +155,6 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { ur->create_action(TTR("Change Array Value")); ur->add_do_method(this, "_set_value", idx, p_value); ur->add_undo_method(this, "_set_value", idx, value); - ur->add_do_method(this, "_notif_changev", p_name); - ur->add_undo_method(this, "_notif_changev", p_name); ur->commit_action(); return true; } @@ -288,7 +282,6 @@ void ArrayPropertyEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_size"), &ArrayPropertyEdit::_set_size); ClassDB::bind_method(D_METHOD("_set_value"), &ArrayPropertyEdit::_set_value); ClassDB::bind_method(D_METHOD("_notif_change"), &ArrayPropertyEdit::_notif_change); - ClassDB::bind_method(D_METHOD("_notif_changev"), &ArrayPropertyEdit::_notif_changev); ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &ArrayPropertyEdit::_dont_undo_redo); } diff --git a/editor/array_property_edit.h b/editor/array_property_edit.h index dd495b57f4..fa3dcbe038 100644 --- a/editor/array_property_edit.h +++ b/editor/array_property_edit.h @@ -47,7 +47,6 @@ class ArrayPropertyEdit : public Reference { Variant::Type default_type; void _notif_change(); - void _notif_changev(const String &p_v); void _set_size(int p_size); void _set_value(int p_idx, const Variant &p_value); diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index 2e0c3491f7..539657afd7 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -155,7 +155,7 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) { preview->playback->stop(); - preview->generating = false; + preview->generating.clear(); } Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref<AudioStream> &p_stream) { @@ -172,7 +172,7 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref< Preview *preview = &previews[p_stream->get_instance_id()]; preview->base_stream = p_stream; preview->playback = preview->base_stream->instance_playback(); - preview->generating = true; + preview->generating.set(); preview->id = p_stream->get_instance_id(); float len_s = preview->base_stream->get_length(); @@ -197,7 +197,8 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref< preview->preview->length = len_s; if (preview->playback.is_valid()) { - preview->thread = Thread::create(_preview_thread, preview); + preview->thread = memnew(Thread); + preview->thread->start(_preview_thread, preview); } return preview->preview; @@ -216,9 +217,10 @@ void AudioStreamPreviewGenerator::_notification(int p_what) { if (p_what == NOTIFICATION_PROCESS) { List<ObjectID> to_erase; for (Map<ObjectID, Preview>::Element *E = previews.front(); E; E = E->next()) { - if (!E->get().generating) { + if (!E->get().generating.is_set()) { if (E->get().thread) { - Thread::wait_to_finish(E->get().thread); + E->get().thread->wait_to_finish(); + memdelete(E->get().thread); E->get().thread = nullptr; } if (!ObjectDB::get_instance(E->key())) { //no longer in use, get rid of preview diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h index 21c9ea203e..accc7275c0 100644 --- a/editor/audio_stream_preview.h +++ b/editor/audio_stream_preview.h @@ -32,6 +32,7 @@ #define AUDIO_STREAM_PREVIEW_H #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "scene/main/node.h" #include "servers/audio/audio_stream.h" @@ -60,9 +61,20 @@ class AudioStreamPreviewGenerator : public Node { Ref<AudioStreamPreview> preview; Ref<AudioStream> base_stream; Ref<AudioStreamPlayback> playback; - volatile bool generating = false; + SafeFlag generating; ObjectID id; Thread *thread = nullptr; + + // Needed for the bookkeeping of the Map + Preview &operator=(const Preview &p_rhs) { + preview = p_rhs.preview; + base_stream = p_rhs.base_stream; + playback = p_rhs.playback; + generating.set_to(generating.is_set()); + id = p_rhs.id; + thread = p_rhs.thread; + return *this; + } }; Map<ObjectID, Preview> previews; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 01fa094d38..0c1fb6fe4d 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -98,7 +98,7 @@ public: } void notify_changed() { - _change_notify(); + notify_property_list_changed(); } ConnectDialogBinds() { diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 9e23ca08ec..711072f4b2 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -237,7 +237,10 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String bool can_instance = (p_cpp_type && ClassDB::can_instance(p_type)) || !p_cpp_type; if (!can_instance) { r_item->set_custom_color(0, search_options->get_theme_color("disabled_font_color", "Editor")); + r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled")); r_item->set_selectable(0, false); + } else { + r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback)); } if (search_box->get_text() != "") { @@ -254,7 +257,6 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description); r_item->set_tooltip(0, description); - r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback)); if (!p_cpp_type && !script_type) { Ref<Texture2D> icon = EditorNode::get_editor_data().get_custom_types()[custom_type_parents[p_type]][custom_type_indices[p_type]].icon; diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h index cf2d81cbf1..6648c99c03 100644 --- a/editor/debugger/editor_debugger_inspector.h +++ b/editor/debugger/editor_debugger_inspector.h @@ -58,7 +58,7 @@ public: prop_values.clear(); } - void update() { _change_notify(); } + void update() { notify_property_list_changed(); } EditorDebuggerRemoteObject() {} }; diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 6db3b94aee..ec92edc795 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -129,6 +129,8 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int updating_scene_tree = true; const String last_path = get_selected_path(); const String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter(); + bool filter_changed = filter != last_filter; + TreeItem *scroll_item = nullptr; // Nodes are in a flatten list, depth first. Use a stack of parents, avoid recursion. List<Pair<TreeItem *, int>> parents; @@ -162,11 +164,17 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int if (debugger_id == p_debugger) { // Can use remote id. if (node.id == inspected_object_id) { item->select(0); + if (filter_changed) { + scroll_item = item; + } } } else { // Must use path if (last_path == _get_path(item)) { updating_scene_tree = false; // Force emission of new selection item->select(0); + if (filter_changed) { + scroll_item = item; + } updating_scene_tree = true; } } @@ -183,6 +191,9 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } parent->remove_child(item); memdelete(item); + if (scroll_item == item) { + scroll_item = nullptr; + } if (had_siblings) { break; // Parent must survive. } @@ -199,6 +210,10 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } } debugger_id = p_debugger; // Needed by hook, could be avoided if every debugger had its own tree + if (scroll_item) { + call_deferred("scroll_to_item", scroll_item); + } + last_filter = filter; updating_scene_tree = false; } diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 8c966dffd5..13193344f1 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -51,6 +51,7 @@ private: Set<ObjectID> unfold_cache; PopupMenu *item_menu = nullptr; EditorFileDialog *file_dialog = nullptr; + String last_filter; String _get_path(TreeItem *p_item); void _scene_tree_folded(Object *p_obj); diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp index d541fdd249..2d57dff69d 100644 --- a/editor/debugger/editor_network_profiler.cpp +++ b/editor/debugger/editor_network_profiler.cpp @@ -46,8 +46,8 @@ void EditorNetworkProfiler::_notification(int p_what) { outgoing_bandwidth_text->set_right_icon(get_theme_icon("ArrowUp", "EditorIcons")); // This needs to be done here to set the faded color when the profiler is first opened - incoming_bandwidth_text->add_theme_color_override("font_color_uneditable", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5)); - outgoing_bandwidth_text->add_theme_color_override("font_color_uneditable", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5)); + incoming_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5)); + outgoing_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5)); } } @@ -113,10 +113,10 @@ void EditorNetworkProfiler::set_bandwidth(int p_incoming, int p_outgoing) { // Make labels more prominent when the bandwidth is greater than 0 to attract user attention incoming_bandwidth_text->add_theme_color_override( - "font_color_uneditable", + "font_uneditable_color", get_theme_color("font_color", "Editor") * Color(1, 1, 1, p_incoming > 0 ? 1 : 0.5)); outgoing_bandwidth_text->add_theme_color_override( - "font_color_uneditable", + "font_uneditable_color", get_theme_color("font_color", "Editor") * Color(1, 1, 1, p_outgoing > 0 ? 1 : 0.5)); } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 2780b74469..25e155aafe 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -480,8 +480,8 @@ void DependencyRemoveDialog::ok_pressed() { if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/boot_splash/image"))) { ProjectSettings::get_singleton()->set("application/boot_splash/image", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("rendering/environment/default_environment"))) { - ProjectSettings::get_singleton()->set("rendering/environment/default_environment", ""); + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("rendering/environment/defaults/default_environment"))) { + ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", ""); } if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"))) { ProjectSettings::get_singleton()->set("display/mouse_cursor/custom_image", ""); @@ -492,8 +492,8 @@ void DependencyRemoveDialog::ok_pressed() { if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("gui/theme/custom_font"))) { ProjectSettings::get_singleton()->set("gui/theme/custom_font", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("audio/default_bus_layout"))) { - ProjectSettings::get_singleton()->set("audio/default_bus_layout", ""); + if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"))) { + ProjectSettings::get_singleton()->set("audio/buses/default_bus_layout", ""); } String path = OS::get_singleton()->get_resource_dir() + files_to_delete[i].replace_first("res://", "/"); diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp index 9683003d89..408177e523 100644 --- a/editor/dictionary_property_edit.cpp +++ b/editor/dictionary_property_edit.cpp @@ -32,11 +32,7 @@ #include "editor_node.h" void DictionaryPropertyEdit::_notif_change() { - _change_notify(); -} - -void DictionaryPropertyEdit::_notif_changev(const String &p_v) { - _change_notify(p_v.utf8().get_data()); + notify_property_list_changed(); } void DictionaryPropertyEdit::_set_key(const Variant &p_old_key, const Variant &p_new_key) { @@ -107,7 +103,6 @@ void DictionaryPropertyEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_key"), &DictionaryPropertyEdit::_set_key); ClassDB::bind_method(D_METHOD("_set_value"), &DictionaryPropertyEdit::_set_value); ClassDB::bind_method(D_METHOD("_notif_change"), &DictionaryPropertyEdit::_notif_change); - ClassDB::bind_method(D_METHOD("_notif_changev"), &DictionaryPropertyEdit::_notif_changev); ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &DictionaryPropertyEdit::_dont_undo_redo); } @@ -128,8 +123,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val ur->create_action(TTR("Change Dictionary Key")); ur->add_do_method(this, "_set_key", key, p_value); ur->add_undo_method(this, "_set_key", p_value, key); - ur->add_do_method(this, "_notif_changev", p_name); - ur->add_undo_method(this, "_notif_changev", p_name); ur->commit_action(); return true; @@ -142,8 +135,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val ur->create_action(TTR("Change Dictionary Value")); ur->add_do_method(this, "_set_value", key, p_value); ur->add_undo_method(this, "_set_value", key, value); - ur->add_do_method(this, "_notif_changev", p_name); - ur->add_undo_method(this, "_notif_changev", p_name); ur->commit_action(); return true; diff --git a/editor/dictionary_property_edit.h b/editor/dictionary_property_edit.h index 564bbf205b..e0fd945491 100644 --- a/editor/dictionary_property_edit.h +++ b/editor/dictionary_property_edit.h @@ -40,7 +40,6 @@ class DictionaryPropertyEdit : public Reference { StringName property; void _notif_change(); - void _notif_changev(const String &p_v); void _set_key(const Variant &p_old_key, const Variant &p_new_key); void _set_value(const Variant &p_key, const Variant &p_value); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 7569800a7e..9a826ab106 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -78,11 +78,11 @@ void EditorAudioBus::_notification(int p_what) { Color bypass_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(0.44, 0.87, 1.0); solo->set_icon(get_theme_icon("AudioBusSolo", "EditorIcons")); - solo->add_theme_color_override("icon_color_pressed", solo_color); + solo->add_theme_color_override("icon_pressed_color", solo_color); mute->set_icon(get_theme_icon("AudioBusMute", "EditorIcons")); - mute->add_theme_color_override("icon_color_pressed", mute_color); + mute->add_theme_color_override("icon_pressed_color", mute_color); bypass->set_icon(get_theme_icon("AudioBusBypass", "EditorIcons")); - bypass->add_theme_color_override("icon_color_pressed", bypass_color); + bypass->add_theme_color_override("icon_pressed_color", bypass_color); bus_options->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons")); @@ -1191,9 +1191,9 @@ void EditorAudioBuses::_load_layout() { } void EditorAudioBuses::_load_default_layout() { - String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); + String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); - Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", true); + Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { EditorNode::get_singleton()->show_warning(vformat(TTR("There is no '%s' file."), layout_path)); return; @@ -1209,7 +1209,7 @@ void EditorAudioBuses::_load_default_layout() { void EditorAudioBuses::_file_dialog_callback(const String &p_string) { if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_OPEN_FILE) { - Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", true); + Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { EditorNode::get_singleton()->show_warning(TTR("Invalid file, not an audio bus layout.")); return; @@ -1257,7 +1257,7 @@ EditorAudioBuses::EditorAudioBuses() { add_child(top_hb); file = memnew(Label); - String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); + String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); file->set_text(String(TTR("Layout")) + ": " + layout_path.get_file()); file->set_clip_text(true); file->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1313,7 +1313,7 @@ EditorAudioBuses::EditorAudioBuses() { set_v_size_flags(SIZE_EXPAND_FILL); - edited_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); + edited_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); file_dialog = memnew(EditorFileDialog); List<String> ext; @@ -1330,7 +1330,7 @@ EditorAudioBuses::EditorAudioBuses() { void EditorAudioBuses::open_layout(const String &p_path) { EditorNode::get_singleton()->make_bottom_panel_item_visible(this); - Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", true); + Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { EditorNode::get_singleton()->show_warning(TTR("Invalid file, not an audio bus layout.")); return; diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 1d3bd55ed3..213c3f5631 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -273,16 +273,6 @@ EditorPlugin *EditorData::get_editor(Object *p_object) { return nullptr; } -EditorPlugin *EditorData::get_subeditor(Object *p_object) { - for (int i = editor_plugins.size() - 1; i > -1; i--) { - if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) { - return editor_plugins[i]; - } - } - - return nullptr; -} - Vector<EditorPlugin *> EditorData::get_subeditors(Object *p_object) { Vector<EditorPlugin *> sub_plugins; for (int i = editor_plugins.size() - 1; i > -1; i--) { @@ -510,6 +500,7 @@ int EditorData::add_edited_scene(int p_at_pos) { EditedScene es; es.root = nullptr; es.path = String(); + es.file_modified_time = 0; es.history_current = -1; es.version = 0; es.live_edit_root = NodePath(String("/root")); @@ -666,6 +657,10 @@ void EditorData::set_edited_scene_root(Node *p_root) { p_root->set_filename(edited_scene[current_edited_scene].path); } } + + if (edited_scene[current_edited_scene].path != "") { + edited_scene.write[current_edited_scene].file_modified_time = FileAccess::get_modified_time(edited_scene[current_edited_scene].path); + } } int EditorData::get_edited_scene_count() const { @@ -697,6 +692,21 @@ uint64_t EditorData::get_scene_version(int p_idx) const { return edited_scene[p_idx].version; } +void EditorData::set_scene_modified_time(int p_idx, uint64_t p_time) { + if (p_idx == -1) { + p_idx = current_edited_scene; + } + + ERR_FAIL_INDEX(p_idx, edited_scene.size()); + + edited_scene.write[p_idx].file_modified_time = p_time; +} + +uint64_t EditorData::get_scene_modified_time(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0); + return edited_scene[p_idx].file_modified_time; +} + String EditorData::get_scene_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String()); if (!edited_scene[p_idx].root) { @@ -932,6 +942,14 @@ void EditorData::script_class_save_icon_paths() { } } + Dictionary old; + if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) { + old = ProjectSettings::get_singleton()->get("_global_script_class_icons"); + } + if ((!old.is_empty() || d.is_empty()) && d.hash() == old.hash()) { + return; + } + if (d.is_empty()) { if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) { ProjectSettings::get_singleton()->clear("_global_script_class_icons"); diff --git a/editor/editor_data.h b/editor/editor_data.h index d5c8c2a713..18b4137162 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -111,6 +111,7 @@ public: struct EditedScene { Node *root = nullptr; String path; + uint64_t file_modified_time = 0; Dictionary editor_states; List<Node *> selection; Vector<EditorHistory::History> history_stored; @@ -144,7 +145,6 @@ private: public: EditorPlugin *get_editor(Object *p_object); - EditorPlugin *get_subeditor(Object *p_object); Vector<EditorPlugin *> get_subeditors(Object *p_object); EditorPlugin *get_editor(String p_name); @@ -191,6 +191,8 @@ public: Ref<Script> get_scene_root_script(int p_idx) const; void set_edited_scene_version(uint64_t version, int p_scene_idx = -1); uint64_t get_scene_version(int p_idx) const; + void set_scene_modified_time(int p_idx, uint64_t p_time); + uint64_t get_scene_modified_time(int p_idx) const; void clear_edited_scenes(); void set_edited_scene_live_edit_root(const NodePath &p_root); NodePath get_edited_scene_live_edit_root(); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index fd4423646f..4f60258d95 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -507,6 +507,11 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S if (dir.begins_with(".")) { continue; } + + if (EditorFileSystem::_should_skip_directory(cur_dir + dir)) { + continue; + } + da->change_dir(dir); _edit_files_with_filter(da, p_filters, r_list, exclude); da->change_dir(".."); @@ -732,6 +737,26 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & _export_find_dependencies(files[i], paths); } + + // Add autoload resources and their dependencies + List<PropertyInfo> props; + ProjectSettings::get_singleton()->get_property_list(&props); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + const PropertyInfo &pi = E->get(); + + if (!pi.name.begins_with("autoload/")) { + continue; + } + + String autoload_path = ProjectSettings::get_singleton()->get(pi.name); + + if (autoload_path.begins_with("*")) { + autoload_path = autoload_path.substr(1); + } + + _export_find_dependencies(autoload_path, paths); + } } //add native icons to non-resource include list @@ -1008,6 +1033,10 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) { EditorProgress ep("savepack", TTR("Packing"), 102, true); + // Create the temporary export directory if it doesn't exist. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->make_dir_recursive(EditorSettings::get_singleton()->get_cache_dir()); + String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp"); FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE); ERR_FAIL_COND_V_MSG(!ftmp, ERR_CANT_CREATE, "Cannot create file '" + tmppath + "'."); @@ -1379,9 +1408,9 @@ void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, in } String EditorExportPlatform::test_etc2() const { - String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); - bool etc_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc"); - bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2"); + String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); + bool etc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc"); + bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); if (driver == "GLES2" && !etc_supported) { return TTR("Target platform requires 'ETC' texture compression for GLES2. Enable 'Import Etc' in Project Settings."); @@ -1393,9 +1422,9 @@ String EditorExportPlatform::test_etc2() const { } String EditorExportPlatform::test_etc2_or_pvrtc() const { - String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); - bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2"); - bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc"); + String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); + bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); + bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc"); if (driver == "GLES2" && !pvrtc_supported) { return TTR("Target platform requires 'PVRTC' texture compression for GLES2. Enable 'Import Pvrtc' in Project Settings."); @@ -1878,7 +1907,7 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con return; } - bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export"); + bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); if (!convert) { return; } @@ -1898,5 +1927,5 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con } EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { - GLOBAL_DEF("editor/convert_text_resources_to_binary_on_export", false); + GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false); } diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index af02fcaf3c..bd00d86ec8 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -277,11 +277,7 @@ void EditorFeatureProfile::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_MAX); } -EditorFeatureProfile::EditorFeatureProfile() { - for (int i = 0; i < FEATURE_MAX; i++) { - features_disabled[i] = false; - } -} +EditorFeatureProfile::EditorFeatureProfile() {} ////////////////////////// diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 01aad0c41b..6d694358bf 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -1150,7 +1150,6 @@ void EditorFileDialog::_update_drives() { void EditorFileDialog::_favorite_selected(int p_idx) { dir_access->change_dir(favorites->get_item_metadata(p_idx)); - file->set_text(""); update_dir(); invalidate(); _push_history(); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 208f678947..dce022e86e 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -595,7 +595,7 @@ void EditorFileSystem::scan() { return; } - if (scanning || scanning_changes || thread) { + if (scanning || scanning_changes || thread.is_started()) { return; } @@ -619,13 +619,13 @@ void EditorFileSystem::scan() { _queue_update_script_classes(); first_scan = false; } else { - ERR_FAIL_COND(thread); + ERR_FAIL_COND(thread.is_started()); set_process(true); Thread::Settings s; scanning = true; scan_total = 0; s.priority = Thread::PRIORITY_LOW; - thread = Thread::create(_thread_func, this, s); + thread.start(_thread_func, this, s); //tree->hide(); //progress->show(); } @@ -669,10 +669,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess continue; } - if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) { // skip if another project inside this - continue; - } - if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) { // skip if another project inside this + if (_should_skip_directory(cd.plus_file(f))) { continue; } @@ -874,10 +871,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const int idx = p_dir->find_dir_index(f); if (idx == -1) { - if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) { // skip if another project inside this - continue; - } - if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) { // skip if another project inside this + if (_should_skip_directory(cd.plus_file(f))) { continue; } @@ -1046,7 +1040,7 @@ void EditorFileSystem::_thread_func_sources(void *_userdata) { void EditorFileSystem::scan_changes() { if (first_scan || // Prevent a premature changes scan from inhibiting the first full scan - scanning || scanning_changes || thread) { + scanning || scanning_changes || thread.is_started()) { scan_changes_pending = true; set_process(true); return; @@ -1076,12 +1070,12 @@ void EditorFileSystem::scan_changes() { scanning_changes_done = true; emit_signal("sources_changed", sources_changed.size() > 0); } else { - ERR_FAIL_COND(thread_sources); + ERR_FAIL_COND(thread_sources.is_started()); set_process(true); scan_total = 0; Thread::Settings s; s.priority = Thread::PRIORITY_LOW; - thread_sources = Thread::create(_thread_func_sources, this, s); + thread_sources.start(_thread_func_sources, this, s); } } @@ -1092,17 +1086,14 @@ void EditorFileSystem::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - Thread *active_thread = thread ? thread : thread_sources; - if (use_threads && active_thread) { + Thread &active_thread = thread.is_started() ? thread : thread_sources; + if (use_threads && active_thread.is_started()) { //abort thread if in progress abort_scan = true; while (scanning) { OS::get_singleton()->delay_usec(1000); } - Thread::wait_to_finish(active_thread); - memdelete(active_thread); - thread = nullptr; - thread_sources = nullptr; + active_thread.wait_to_finish(); WARN_PRINT("Scan thread aborted..."); set_process(false); } @@ -1125,9 +1116,7 @@ void EditorFileSystem::_notification(int p_what) { set_process(false); - Thread::wait_to_finish(thread_sources); - memdelete(thread_sources); - thread_sources = nullptr; + thread_sources.wait_to_finish(); if (_update_scan_actions()) { emit_signal("filesystem_changed"); } @@ -1135,7 +1124,7 @@ void EditorFileSystem::_notification(int p_what) { _queue_update_script_classes(); first_scan = false; } - } else if (!scanning && thread) { + } else if (!scanning && thread.is_started()) { set_process(false); if (filesystem) { @@ -1143,9 +1132,7 @@ void EditorFileSystem::_notification(int p_what) { } filesystem = new_filesystem; new_filesystem = nullptr; - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread.wait_to_finish(); _update_scan_actions(); emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); @@ -1420,11 +1407,11 @@ void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) { } void EditorFileSystem::update_script_classes() { - if (!update_script_classes_queued) { + if (!update_script_classes_queued.is_set()) { return; } - update_script_classes_queued = false; + update_script_classes_queued.clear(); ScriptServer::global_classes_clear(); if (get_filesystem()) { _scan_script_classes(get_filesystem()); @@ -1443,11 +1430,11 @@ void EditorFileSystem::update_script_classes() { } void EditorFileSystem::_queue_update_script_classes() { - if (update_script_classes_queued) { + if (update_script_classes_queued.is_set()) { return; } - update_script_classes_queued = true; + update_script_classes_queued.set(); call_deferred("update_script_classes"); } @@ -1477,20 +1464,21 @@ void EditorFileSystem::update_file(const String &p_file) { String type = ResourceLoader::get_resource_type(p_file); if (cpos == -1) { - //the file did not exist, it was added + // The file did not exist, it was added. - late_added_files.insert(p_file); //remember that it was added. This mean it will be scanned and imported on editor restart + late_added_files.insert(p_file); // Remember that it was added. This mean it will be scanned and imported on editor restart. int idx = 0; + String file_name = p_file.get_file(); for (int i = 0; i < fs->files.size(); i++) { - if (p_file < fs->files[i]->file) { + if (file_name < fs->files[i]->file) { break; } idx++; } EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); - fi->file = p_file.get_file(); + fi->file = file_name; fi->import_modified_time = 0; fi->import_valid = ResourceLoader::is_import_valid(p_file); @@ -1985,6 +1973,20 @@ Error EditorFileSystem::_resource_import(const String &p_path) { return OK; } +bool EditorFileSystem::_should_skip_directory(const String &p_path) { + if (FileAccess::exists(p_path.plus_file("project.godot"))) { + // skip if another project inside this + return true; + } + + if (FileAccess::exists(p_path.plus_file(".gdignore"))) { + // skip if a `.gdignore` file is inside this + return true; + } + + return false; +} + bool EditorFileSystem::is_group_file(const String &p_path) const { return group_file_cache.has(p_path); } @@ -2073,17 +2075,15 @@ void EditorFileSystem::_update_extensions() { EditorFileSystem::EditorFileSystem() { ResourceLoader::import = _resource_import; - reimport_on_missing_imported_files = GLOBAL_DEF("editor/reimport_missing_imported_files", true); + reimport_on_missing_imported_files = GLOBAL_DEF("editor/import/reimport_missing_imported_files", true); singleton = this; filesystem = memnew(EditorFileSystemDirectory); //like, empty filesystem->parent = nullptr; - thread = nullptr; scanning = false; importing = false; use_threads = true; - thread_sources = nullptr; new_filesystem = nullptr; abort_scan = false; @@ -2099,7 +2099,7 @@ EditorFileSystem::EditorFileSystem() { memdelete(da); scan_total = 0; - update_script_classes_queued = false; + update_script_classes_queued.clear(); first_scan = true; scan_changes_pending = false; revalidate_import_files = false; diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index c0e11a0402..59bde238a8 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -34,6 +34,7 @@ #include "core/os/dir_access.h" #include "core/os/thread.h" #include "core/os/thread_safe.h" +#include "core/templates/safe_refcount.h" #include "core/templates/set.h" #include "scene/main/node.h" class FileAccess; @@ -127,7 +128,7 @@ class EditorFileSystem : public Node { }; bool use_threads; - Thread *thread; + Thread thread; static void _thread_func(void *_userdata); EditorFileSystemDirectory *new_filesystem; @@ -189,7 +190,7 @@ class EditorFileSystem : public Node { void _scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess *da, const ScanProgress &p_progress); - Thread *thread_sources; + Thread thread_sources; bool scanning_changes; bool scanning_changes_done; @@ -220,7 +221,7 @@ class EditorFileSystem : public Node { }; void _scan_script_classes(EditorFileSystemDirectory *p_dir); - volatile bool update_script_classes_queued; + SafeFlag update_script_classes_queued; void _queue_update_script_classes(); String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const; @@ -261,6 +262,8 @@ public: bool is_group_file(const String &p_path) const; void move_group_file(const String &p_path, const String &p_new_path); + static bool _should_skip_directory(const String &p_path); + EditorFileSystem(); ~EditorFileSystem(); }; diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 9f98795e16..97a2c67c26 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -259,13 +259,17 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { } } } - } - if (E->get().type == Variant::OBJECT) { - RES res = p_object->get(E->get().name); - if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { - resources.insert(res); - _do_object_unfolds(res.ptr(), resources); + if (E->get().type == Variant::OBJECT) { + RES res = p_object->get(E->get().name); + print_line("res: " + String(E->get().name) + " valid " + itos(res.is_valid())); + if (res.is_valid()) { + print_line("path " + res->get_path()); + } + if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { + resources.insert(res); + _do_object_unfolds(res.ptr(), resources); + } } } } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 718f2e748d..283713cd3c 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1331,11 +1331,11 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { Ref<Font> doc_code_font = p_rt->get_theme_font("doc_source", "EditorFonts"); Ref<Font> doc_kbd_font = p_rt->get_theme_font("doc_keyboard", "EditorFonts"); - Color font_color_hl = p_rt->get_theme_color("headline_color", "EditorHelp"); + Color headline_color = p_rt->get_theme_color("headline_color", "EditorHelp"); Color accent_color = p_rt->get_theme_color("accent_color", "Editor"); Color property_color = p_rt->get_theme_color("property_color", "Editor"); - Color link_color = accent_color.lerp(font_color_hl, 0.8); - Color code_color = accent_color.lerp(font_color_hl, 0.6); + Color link_color = accent_color.lerp(headline_color, 0.8); + Color code_color = accent_color.lerp(headline_color, 0.6); Color kbd_color = accent_color.lerp(property_color, 0.6); String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges(); @@ -1481,7 +1481,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { tag_stack.push_front(tag); } else if (tag == "i") { //use italics font - p_rt->push_color(font_color_hl); + p_rt->push_color(headline_color); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code" || tag == "codeblock") { @@ -1549,46 +1549,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { tag_stack.push_front(tag); } else if (tag.begins_with("color=")) { String col = tag.substr(6, tag.length()); - Color color; - - if (col.begins_with("#")) { - color = Color::html(col); - } else if (col == "aqua") { - color = Color(0, 1, 1); - } else if (col == "black") { - color = Color(0, 0, 0); - } else if (col == "blue") { - color = Color(0, 0, 1); - } else if (col == "fuchsia") { - color = Color(1, 0, 1); - } else if (col == "gray" || col == "grey") { - color = Color(0.5, 0.5, 0.5); - } else if (col == "green") { - color = Color(0, 0.5, 0); - } else if (col == "lime") { - color = Color(0, 1, 0); - } else if (col == "maroon") { - color = Color(0.5, 0, 0); - } else if (col == "navy") { - color = Color(0, 0, 0.5); - } else if (col == "olive") { - color = Color(0.5, 0.5, 0); - } else if (col == "purple") { - color = Color(0.5, 0, 0.5); - } else if (col == "red") { - color = Color(1, 0, 0); - } else if (col == "silver") { - color = Color(0.75, 0.75, 0.75); - } else if (col == "teal") { - color = Color(0, 0.5, 0.5); - } else if (col == "white") { - color = Color(1, 1, 1); - } else if (col == "yellow") { - color = Color(1, 1, 0); - } else { - color = Color(0, 0, 0); //base_color; - } - + Color color = Color::from_string(col, Color()); p_rt->push_color(color); pos = brk_end + 1; tag_stack.push_front("color"); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index df330d8685..74b874b54e 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -81,7 +81,7 @@ Size2 EditorProperty::get_minimum_size() const { } if (bottom_editor != nullptr && bottom_editor->is_visible()) { - ms.height += get_theme_constant("vseparation", "Tree"); + ms.height += get_theme_constant("vseparation"); Size2 bems = bottom_editor->get_combined_minimum_size(); //bems.width += get_constant("item_margin", "Tree"); ms.height += bems.height; @@ -95,6 +95,7 @@ void EditorProperty::emit_changed(const StringName &p_property, const Variant &p Variant args[4] = { p_property, p_value, p_field, p_changing }; const Variant *argptrs[4] = { &args[0], &args[1], &args[2], &args[3] }; + cache[p_property] = p_value; emit_signal("property_changed", (const Variant **)argptrs, 4); } @@ -148,7 +149,7 @@ void EditorProperty::_notification(int p_what) { if (bottom_editor) { int m = 0; //get_constant("item_margin", "Tree"); - bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation", "Tree"), size.width - m, bottom_editor->get_combined_minimum_size().height); + bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation"), size.width - m, bottom_editor->get_combined_minimum_size().height); } if (keying) { @@ -225,11 +226,15 @@ void EditorProperty::_notification(int p_what) { size.height = label_reference->get_size().height; } + Ref<StyleBox> sb; if (selected) { - Ref<StyleBox> sb = get_theme_stylebox("selected", "Tree"); - draw_style_box(sb, Rect2(Vector2(), size)); + sb = get_theme_stylebox("bg_selected"); + } else { + sb = get_theme_stylebox("bg"); } + draw_style_box(sb, Rect2(Vector2(), size)); + if (draw_top_bg && right_child_rect != Rect2()) { draw_rect(right_child_rect, dark_color); } @@ -239,15 +244,15 @@ void EditorProperty::_notification(int p_what) { Color color; if (draw_red) { - color = get_theme_color("error_color", "Editor"); + color = get_theme_color("error_color"); } else { - color = get_theme_color("property_color", "Editor"); + color = get_theme_color("property_color"); } if (label.find(".") != -1) { color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides } - int ofs = 0; + int ofs = get_theme_constant("font_offset"); int text_limit = text_size; if (checkable) { @@ -805,6 +810,28 @@ void EditorProperty::set_bottom_editor(Control *p_control) { bottom_editor = p_control; } +bool EditorProperty::is_cache_valid() const { + if (object) { + for (Map<StringName, Variant>::Element *E = cache.front(); E; E = E->next()) { + bool valid; + Variant value = object->get(E->key(), &valid); + if (!valid || value != E->get()) { + return false; + } + } + } + return true; +} +void EditorProperty::update_cache() { + cache.clear(); + if (object && property != StringName()) { + bool valid; + Variant value = object->get(property, &valid); + if (valid) { + cache[property] = value; + } + } +} Variant EditorProperty::get_drag_data(const Point2 &p_point) { if (property == StringName()) { return Variant(); @@ -1524,6 +1551,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->update_property(); ep->update_reload_status(); ep->set_deletable(deletable_properties); + ep->update_cache(); } } ped->added_editors.clear(); @@ -1661,7 +1689,7 @@ void EditorInspector::update_tree() { bool valid = true; //if no properties in category, skip while (N) { - if (N->get().usage & PROPERTY_USAGE_EDITOR) { + if (N->get().usage & PROPERTY_USAGE_EDITOR && (!restrict_to_basic || (N->get().usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { break; } if (N->get().usage & PROPERTY_USAGE_CATEGORY) { @@ -1729,10 +1757,14 @@ void EditorInspector::update_tree() { continue; - } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name)) { + } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name) || (restrict_to_basic && !(p.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { continue; } + if (p.name == "script") { + category_vbox = nullptr; // script should go into its own category + } + if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && RS::get_singleton()->is_low_end()) { continue; //do not show this property in low end gfx } @@ -1982,6 +2014,7 @@ void EditorInspector::update_tree() { } ep->update_property(); ep->update_reload_status(); + ep->update_cache(); if (current_selected && ep->property == current_selected) { ep->select(current_focusable); @@ -2012,6 +2045,7 @@ void EditorInspector::update_property(const String &p_prop) { for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); + E->get()->update_cache(); } } @@ -2027,13 +2061,6 @@ void EditorInspector::_clear() { restart_request_props.clear(); } -void EditorInspector::refresh() { - if (refresh_countdown > 0 || changing) { - return; - } - refresh_countdown = EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval"); -} - Object *EditorInspector::get_edited_object() { return object; } @@ -2044,7 +2071,7 @@ void EditorInspector::edit(Object *p_object) { } if (object) { _clear(); - object->remove_change_receptor(this); + object->disconnect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback)); } object = p_object; @@ -2054,7 +2081,7 @@ void EditorInspector::edit(Object *p_object) { if (scroll_cache.has(object->get_instance_id())) { //if exists, set something else update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accommodated } - object->add_change_receptor(this); + object->connect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback)); update_tree(); } } @@ -2161,17 +2188,30 @@ void EditorInspector::set_use_wide_editors(bool p_enable) { wide_editors = p_enable; } +void EditorInspector::_update_inspector_bg() { + if (sub_inspector) { + int count_subinspectors = 0; + Node *n = get_parent(); + while (n) { + EditorInspector *ei = Object::cast_to<EditorInspector>(n); + if (ei && ei->sub_inspector) { + count_subinspectors++; + } + n = n->get_parent(); + } + count_subinspectors = MIN(15, count_subinspectors); + add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), "Editor")); + } else { + add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); + } +} void EditorInspector::set_sub_inspector(bool p_enable) { sub_inspector = p_enable; if (!is_inside_tree()) { return; } - if (sub_inspector) { - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor")); - } else { - add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); - } + _update_inspector_bg(); } void EditorInspector::set_use_deletable_properties(bool p_enabled) { @@ -2351,6 +2391,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); + E->get()->update_cache(); } } @@ -2394,13 +2435,12 @@ void EditorInspector::_node_removed(Node *p_node) { void EditorInspector::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &EditorInspector::_feature_profile_changed)); + set_process(is_visible_in_tree()); } if (p_what == NOTIFICATION_ENTER_TREE) { - if (sub_inspector) { - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor")); - } else { - add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); + _update_inspector_bg(); + if (!sub_inspector) { get_tree()->connect("node_removed", callable_mp(this, &EditorInspector::_node_removed)); } } @@ -2414,6 +2454,10 @@ void EditorInspector::_notification(int p_what) { edit(nullptr); } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + set_process(is_visible_in_tree()); + } + if (p_what == NOTIFICATION_PROCESS) { if (update_scroll_request >= 0) { get_v_scrollbar()->call_deferred("set_value", update_scroll_request); @@ -2424,10 +2468,14 @@ void EditorInspector::_notification(int p_what) { if (refresh_countdown <= 0) { for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { - E->get()->update_property(); - E->get()->update_reload_status(); + if (!E->get()->is_cache_valid()) { + E->get()->update_property(); + E->get()->update_reload_status(); + E->get()->update_cache(); + } } } + refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); } } @@ -2445,6 +2493,7 @@ void EditorInspector::_notification(int p_what) { for (List<EditorProperty *>::Element *E = editor_property_map[prop].front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); + E->get()->update_cache(); } } pending.erase(pending.front()); @@ -2455,19 +2504,17 @@ void EditorInspector::_notification(int p_what) { } if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - if (sub_inspector) { - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor")); - } else if (is_inside_tree()) { - add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); - } + _update_inspector_bg(); update_tree(); } } -void EditorInspector::_changed_callback(Object *p_changed, const char *p_prop) { - //this is called when property change is notified via _change_notify() - _edit_request_change(p_changed, p_prop); +void EditorInspector::_changed_callback() { + //this is called when property change is notified via notify_property_list_changed() + if (object != nullptr) { + _edit_request_change(object, String()); + } } void EditorInspector::_vscroll_changed(double p_offset) { @@ -2506,22 +2553,11 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li return; } - List<StringName> classes; - Map<StringName, String> paths; + List<Ref<Script>> classes; // NodeC -> NodeB -> NodeA while (script.is_valid()) { - String n = EditorNode::get_editor_data().script_class_get_name(script->get_path()); - if (n.length()) { - classes.push_front(n); - } else if (script->get_path() != String() && script->get_path().find("::") == -1) { - n = script->get_path().get_file(); - classes.push_front(n); - } else { - n = TTR("Built-in script"); - classes.push_front(n); - } - paths[n] = script->get_path(); + classes.push_front(script); script = script->get_base_script(); } @@ -2545,17 +2581,18 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li } Set<StringName> added; - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - StringName name = E->get(); - String path = paths[name]; - Ref<Script> s; - if (path == String()) { - // Built-in script. It can't be inherited, so must be the script attached to the object. - s = p_object.get_script(); - } else { - s = ResourceLoader::load(path, "Script"); + for (List<Ref<Script>>::Element *E = classes.front(); E; E = E->next()) { + Ref<Script> s = E->get(); + String path = s->get_path(); + String name = EditorNode::get_editor_data().script_class_get_name(path); + if (name.is_empty()) { + if (!path.is_empty() && path.find("::") == -1) { + name = path.get_file(); + } else { + name = TTR("Built-in script"); + } } - ERR_FAIL_COND(!s->is_valid()); + List<PropertyInfo> props; s->get_script_property_list(&props); @@ -2587,11 +2624,14 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li r_list.erase(bottom); } +void EditorInspector::set_restrict_to_basic_settings(bool p_restrict) { + restrict_to_basic = p_restrict; + update_tree(); +} + void EditorInspector::_bind_methods() { ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change); - ClassDB::bind_method("refresh", &EditorInspector::refresh); - ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property"))); @@ -2623,16 +2663,21 @@ EditorInspector::EditorInspector() { use_folding = false; update_all_pending = false; update_tree_pending = false; - refresh_countdown = 0; read_only = false; search_box = nullptr; keying = false; _prop_edited = "property_edited"; - set_process(true); + set_process(false); property_focusable = -1; sub_inspector = false; deletable_properties = false; get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed)); update_scroll_request = -1; + if (EditorSettings::get_singleton()) { + refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); + } else { + //used when class is created by the docgen to dump default values of everything bindable, editorsettings may not be created + refresh_countdown = 0.33; + } } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 81a22d4ff1..18250780be 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -98,6 +98,8 @@ private: mutable String tooltip_text; + Map<StringName, Variant> cache; + protected: void _notification(int p_what); static void _bind_methods(); @@ -152,6 +154,8 @@ public: virtual void collapse_all_folding(); virtual Variant get_drag_data(const Point2 &p_point) override; + virtual void update_cache(); + virtual bool is_cache_valid() const; void set_selectable(bool p_selectable); bool is_selectable() const; @@ -309,6 +313,8 @@ class EditorInspector : public ScrollContainer { String property_prefix; //used for sectioned inspector String object_class; + bool restrict_to_basic = false; + void _edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field); void _property_changed(const String &p_path, const Variant &p_value, const String &p_name = "", bool p_changing = false); @@ -326,7 +332,7 @@ class EditorInspector : public ScrollContainer { void _node_removed(Node *p_node); - void _changed_callback(Object *p_changed, const char *p_prop) override; + void _changed_callback(); void _edit_request_change(Object *p_object, const String &p_prop); void _filter_changed(const String &p_text); @@ -339,6 +345,8 @@ class EditorInspector : public ScrollContainer { bool _is_property_disabled_by_feature_profile(const StringName &p_property); + void _update_inspector_bg(); + protected: static void _bind_methods(); void _notification(int p_what); @@ -356,9 +364,6 @@ public: void update_tree(); void update_property(const String &p_prop); - - void refresh(); - void edit(Object *p_object); Object *get_edited_object(); @@ -393,9 +398,12 @@ public: void set_use_wide_editors(bool p_enable); void set_sub_inspector(bool p_enable); + bool is_sub_inspector() const { return sub_inspector; } void set_use_deletable_properties(bool p_enabled); + void set_restrict_to_basic_settings(bool p_restrict); + EditorInspector(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6f03518029..f0e53e7ef5 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -430,6 +430,74 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) { } } +void EditorNode::_update_from_settings() { + int current_filter = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_filter"); + if (current_filter != scene_root->get_default_canvas_item_texture_filter()) { + Viewport::DefaultCanvasItemTextureFilter tf = (Viewport::DefaultCanvasItemTextureFilter)current_filter; + scene_root->set_default_canvas_item_texture_filter(tf); + } + int current_repeat = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_repeat"); + if (current_repeat != scene_root->get_default_canvas_item_texture_repeat()) { + Viewport::DefaultCanvasItemTextureRepeat tr = (Viewport::DefaultCanvasItemTextureRepeat)current_repeat; + scene_root->set_default_canvas_item_texture_repeat(tr); + } + + RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape"))); + RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape); + RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality"))); + bool dof_jitter = GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_use_jitter"); + RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter); + RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/environment/ssao/quality"))), GLOBAL_GET("rendering/environment/ssao/half_size"), GLOBAL_GET("rendering/environment/ssao/adaptive_target"), GLOBAL_GET("rendering/environment/ssao/blur_passes"), GLOBAL_GET("rendering/environment/ssao/fadeout_from"), GLOBAL_GET("rendering/environment/ssao/fadeout_to")); + RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/enabled"), GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount"), GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit")); + bool glow_bicubic = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0; + RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic); + bool glow_high_quality = GLOBAL_GET("rendering/environment/glow/use_high_quality"); + RS::get_singleton()->environment_glow_set_use_high_quality(glow_high_quality); + RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/environment/screen_space_reflection/roughness_quality"))); + RS::get_singleton()->environment_set_ssr_roughness_quality(ssr_roughness_quality); + RS::SubSurfaceScatteringQuality sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_quality"))); + RS::get_singleton()->sub_surface_scattering_set_quality(sss_quality); + float sss_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_scale"); + float sss_depth_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale"); + RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale); + + uint32_t directional_shadow_size = GLOBAL_GET("rendering/shadows/directional_shadow/size"); + uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits"); + RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits); + + RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/shadows/soft_shadow_quality"))); + RS::get_singleton()->shadows_quality_set(shadows_quality); + RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_quality"))); + RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality); + float probe_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed"); + RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed); + RS::EnvironmentSDFGIFramesToConverge frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(int(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge"))); + RS::get_singleton()->environment_set_sdfgi_frames_to_converge(frames_to_converge); + RS::EnvironmentSDFGIRayCount ray_count = RS::EnvironmentSDFGIRayCount(int(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count"))); + RS::get_singleton()->environment_set_sdfgi_ray_count(ray_count); + RS::GIProbeQuality gi_probe_quality = RS::GIProbeQuality(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality"))); + RS::get_singleton()->gi_probe_set_quality(gi_probe_quality); + RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size"), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth")); + RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"))); + RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/2d/shadow_atlas/size")); + + bool use_half_res_gi = GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); + RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi); + + bool snap_2d_transforms = GLOBAL_GET("rendering/2d/snap/snap_2d_transforms_to_pixel"); + scene_root->set_snap_2d_transforms_to_pixel(snap_2d_transforms); + bool snap_2d_vertices = GLOBAL_GET("rendering/2d/snap/snap_2d_vertices_to_pixel"); + scene_root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); + + Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_GET("rendering/2d/sdf/oversize"))); + scene_root->set_sdf_oversize(sdf_oversize); + Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_GET("rendering/2d/sdf/scale"))); + scene_root->set_sdf_scale(sdf_scale); + + float lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels"); + scene_root->set_lod_threshold(lod_threshold); +} + void EditorNode::_notification(int p_what) { switch (p_what) { case NOTIFICATION_PROCESS: { @@ -468,69 +536,13 @@ void EditorNode::_notification(int p_what) { editor_selection->update(); - { //TODO should only happen on settings changed - int current_filter = GLOBAL_GET("rendering/canvas_textures/default_texture_filter"); - if (current_filter != scene_root->get_default_canvas_item_texture_filter()) { - Viewport::DefaultCanvasItemTextureFilter tf = (Viewport::DefaultCanvasItemTextureFilter)current_filter; - scene_root->set_default_canvas_item_texture_filter(tf); - } - int current_repeat = GLOBAL_GET("rendering/canvas_textures/default_texture_repeat"); - if (current_repeat != scene_root->get_default_canvas_item_texture_repeat()) { - Viewport::DefaultCanvasItemTextureRepeat tr = (Viewport::DefaultCanvasItemTextureRepeat)current_repeat; - scene_root->set_default_canvas_item_texture_repeat(tr); - } + ResourceImporterTexture::get_singleton()->update_imports(); - RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape"))); - RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape); - RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))); - bool dof_jitter = GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter"); - RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter); - RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"), GLOBAL_GET("rendering/quality/ssao/adaptive_target"), GLOBAL_GET("rendering/quality/ssao/blur_passes"), GLOBAL_GET("rendering/quality/ssao/fadeout_from"), GLOBAL_GET("rendering/quality/ssao/fadeout_to")); - RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit")); - bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0; - RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic); - bool glow_high_quality = GLOBAL_GET("rendering/quality/glow/use_high_quality"); - RS::get_singleton()->environment_glow_set_use_high_quality(glow_high_quality); - RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality"))); - RS::get_singleton()->environment_set_ssr_roughness_quality(ssr_roughness_quality); - RS::SubSurfaceScatteringQuality sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality"))); - RS::get_singleton()->sub_surface_scattering_set_quality(sss_quality); - float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale"); - float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale"); - RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale); - RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality"))); - RS::get_singleton()->shadows_quality_set(shadows_quality); - RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality"))); - RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality); - float probe_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed"); - RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed); - RS::EnvironmentSDFGIFramesToConverge frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(int(GLOBAL_GET("rendering/sdfgi/frames_to_converge"))); - RS::get_singleton()->environment_set_sdfgi_frames_to_converge(frames_to_converge); - RS::EnvironmentSDFGIRayCount ray_count = RS::EnvironmentSDFGIRayCount(int(GLOBAL_GET("rendering/sdfgi/probe_ray_count"))); - RS::get_singleton()->environment_set_sdfgi_ray_count(ray_count); - RS::GIProbeQuality gi_probe_quality = RS::GIProbeQuality(int(GLOBAL_GET("rendering/quality/gi_probes/quality"))); - RS::get_singleton()->gi_probe_set_quality(gi_probe_quality); - RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth")); - RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/volumetric_fog/use_filter"))); - RS::get_singleton()->environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink")); - RS::get_singleton()->environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); - RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size")); - - bool snap_2d_transforms = GLOBAL_GET("rendering/quality/2d/snap_2d_transforms_to_pixel"); - scene_root->set_snap_2d_transforms_to_pixel(snap_2d_transforms); - bool snap_2d_vertices = GLOBAL_GET("rendering/quality/2d/snap_2d_vertices_to_pixel"); - scene_root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); - - Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_GET("rendering/quality/2d_sdf/oversize"))); - scene_root->set_sdf_oversize(sdf_oversize); - Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_GET("rendering/quality/2d_sdf/scale"))); - scene_root->set_sdf_scale(sdf_scale); - - float lod_threshold = GLOBAL_GET("rendering/quality/mesh_lod/threshold_pixels"); - scene_root->set_lod_threshold(lod_threshold); + if (settings_changed) { + _update_from_settings(); + settings_changed = false; + emit_signal("project_settings_changed"); } - - ResourceImporterTexture::get_singleton()->update_imports(); } break; case NOTIFICATION_ENTER_TREE: { @@ -588,6 +600,7 @@ void EditorNode::_notification(int p_what) { OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); EditorFileSystem::get_singleton()->scan_changes(); + _scan_external_changes(); } break; case NOTIFICATION_APPLICATION_FOCUS_OUT: { @@ -613,8 +626,8 @@ void EditorNode::_notification(int p_what) { gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox("Background", "EditorStyles")); scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox("Content", "EditorStyles")); bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox("panel", "TabContainer")); - scene_tabs->add_theme_style_override("tab_fg", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles")); - scene_tabs->add_theme_style_override("tab_bg", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles")); + scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles")); + scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles")); file_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox("MenuHover", "EditorStyles")); project_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox("MenuHover", "EditorStyles")); @@ -880,6 +893,83 @@ void EditorNode::_sources_changed(bool p_exist) { } } +void EditorNode::_scan_external_changes() { + disk_changed_list->clear(); + TreeItem *r = disk_changed_list->create_item(); + disk_changed_list->set_hide_root(true); + bool need_reload = false; + + // Check if any edited scene has changed. + + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (editor_data.get_scene_path(i) == "" || !da->file_exists(editor_data.get_scene_path(i))) { + continue; + } + + uint64_t last_date = editor_data.get_scene_modified_time(i); + uint64_t date = FileAccess::get_modified_time(editor_data.get_scene_path(i)); + + if (date > last_date) { + TreeItem *ti = disk_changed_list->create_item(r); + ti->set_text(0, editor_data.get_scene_path(i).get_file()); + need_reload = true; + } + } + + String project_settings_path = ProjectSettings::get_singleton()->get_resource_path().plus_file("project.godot"); + if (FileAccess::get_modified_time(project_settings_path) > ProjectSettings::get_singleton()->get_last_saved_time()) { + TreeItem *ti = disk_changed_list->create_item(r); + ti->set_text(0, "project.godot"); + need_reload = true; + } + + if (need_reload) { + disk_changed->call_deferred("popup_centered_ratio", 0.5); + } +} + +void EditorNode::_resave_scenes(String p_str) { + save_all_scenes(); + ProjectSettings::get_singleton()->save(); + disk_changed->hide(); +} + +void EditorNode::_reload_modified_scenes() { + int current_idx = editor_data.get_edited_scene(); + + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + if (editor_data.get_scene_path(i) == "") { + continue; + } + + uint64_t last_date = editor_data.get_scene_modified_time(i); + uint64_t date = FileAccess::get_modified_time(editor_data.get_scene_path(i)); + + if (date > last_date) { + String filename = editor_data.get_scene_path(i); + editor_data.set_edited_scene(i); + _remove_edited_scene(false); + + Error err = load_scene(filename, false, false, true, false, true); + if (err != OK) { + ERR_PRINT(vformat("Failed to load scene: %s", filename)); + } + editor_data.move_edited_scene_to_index(i); + } + } + + get_undo_redo()->clear_history(false); + set_current_scene(current_idx); + _update_scene_tabs(); + disk_changed->hide(); +} + +void EditorNode::_reload_project_settings() { + ProjectSettings::get_singleton()->setup(ProjectSettings::get_singleton()->get_resource_path(), String(), true); + settings_changed = true; +} + void EditorNode::_vp_resized() { } @@ -921,7 +1011,7 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d dependency_errors.clear(); Error err; - RES res = ResourceLoader::load(p_resource, "", false, &err); + RES res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN); if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) { @@ -1505,6 +1595,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } else { editor_data.set_edited_scene_version(0, idx); } + editor_data.set_scene_modified_time(idx, FileAccess::get_modified_time(p_file)); editor_folding.save_scene_folding(scene, p_file); @@ -1708,7 +1799,7 @@ void EditorNode::_dialog_action(String p_file) { ObjectID current = editor_history.get_current(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; ERR_FAIL_COND(!current_obj); - current_obj->_change_notify(); + current_obj->notify_property_list_changed(); } break; case SETTINGS_LAYOUT_SAVE: { if (p_file.is_empty()) { @@ -1850,6 +1941,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in node_dock->set_node(nullptr); scene_tree_dock->set_selected(nullptr); inspector_dock->update(nullptr); + _display_top_editors(false); return; } @@ -2169,7 +2261,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { List<String> breakpoints; editor_data.get_editor_breakpoints(&breakpoints); - args = ProjectSettings::get_singleton()->get("editor/main_run_args"); + args = ProjectSettings::get_singleton()->get("editor/run/main_run_args"); skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints(); EditorDebuggerNode::get_singleton()->start(); @@ -2292,6 +2384,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case FILE_CLOSE: { if (!p_confirmed) { tab_closing = p_option == FILE_CLOSE ? editor_data.get_edited_scene() : _next_unsaved_scene(false); + _scene_tab_changed(tab_closing); if (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) { String scene_filename = editor_data.get_edited_scene_root(tab_closing)->get_filename(); @@ -2316,7 +2409,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing; Node *scene = editor_data.get_edited_scene_root(scene_idx); - if (scene && scene->get_filename() != "" && FileAccess::exists(scene->get_filename())) { + if (scene && scene->get_filename() != "") { if (scene_idx != editor_data.get_edited_scene()) { _save_scene_with_preview(scene->get_filename(), scene_idx); } else { @@ -2428,16 +2521,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; - case FILE_IMPORT_SUBSCENE: { - if (!editor_data.get_edited_scene_root()) { - show_accept(TTR("This operation can't be done without a selected node."), TTR("OK")); - break; - } - - scene_tree_dock->import_subscene(); - - } break; - case FILE_EXTERNAL_OPEN_SCENE: { if (unsaved_cache && !p_confirmed) { confirmation->get_ok_button()->set_text(TTR("Open")); @@ -2598,15 +2681,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { if (!p_confirmed) { bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit"); if (_next_unsaved_scene(!save_each) == -1) { - bool confirm = EDITOR_GET("interface/editor/quit_confirmation"); - if (confirm) { - confirmation->get_ok_button()->set_text(p_option == FILE_QUIT ? TTR("Quit") : TTR("Yes")); - confirmation->set_text(p_option == FILE_QUIT ? TTR("Exit the editor?") : TTR("Open Project Manager?")); - confirmation->popup_centered(); - } else { - _discard_changes(); - break; - } + _discard_changes(); + break; } else { if (save_each) { _menu_option_confirm(p_option == FILE_QUIT ? FILE_CLOSE_ALL_AND_QUIT : FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER, false); @@ -2714,7 +2790,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case SET_VIDEO_DRIVER_SAVE_AND_RESTART: { - ProjectSettings::get_singleton()->set("rendering/quality/driver/driver_name", video_driver_request); + ProjectSettings::get_singleton()->set("rendering/driver/driver_name", video_driver_request); ProjectSettings::get_singleton()->save(); save_all_scenes(); @@ -2820,6 +2896,10 @@ void EditorNode::_discard_changes(const String &p_str) { _update_scene_tabs(); if (current_option == FILE_CLOSE_ALL_AND_QUIT || current_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) { + // If restore tabs is enabled, reopen the scene that has just been closed, so it's remembered properly. + if (bool(EDITOR_GET("interface/scene_tabs/restore_scenes_on_load"))) { + _menu_option_confirm(FILE_OPEN_PREV, true); + } if (_next_unsaved_scene(false) == -1) { current_option = current_option == FILE_CLOSE_ALL_AND_QUIT ? FILE_QUIT : RUN_PROJECT_MANAGER; _discard_changes(); @@ -2855,8 +2935,7 @@ void EditorNode::_discard_changes(const String &p_str) { args.push_back(exec.get_base_dir()); args.push_back("--project-manager"); - OS::ProcessID pid = 0; - Error err = OS::get_singleton()->execute(exec, args, false, &pid); + Error err = OS::get_singleton()->create_process(exec, args); ERR_FAIL_COND(err); } break; } @@ -3034,8 +3113,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, Ref<ConfigFile> cf; cf.instance(); - String addon_path = String("res://addons").plus_file(p_addon).plus_file("plugin.cfg"); - if (!DirAccess::exists(addon_path.get_base_dir())) { + if (!DirAccess::exists(p_addon.get_base_dir())) { ProjectSettings *ps = ProjectSettings::get_singleton(); PackedStringArray enabled_plugins = ps->get("editor_plugins/enabled"); for (int i = 0; i < enabled_plugins.size(); ++i) { @@ -3049,14 +3127,14 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, WARN_PRINT("Addon '" + p_addon + "' failed to load. No directory found. Removing from enabled plugins."); return; } - Error err = cf->load(addon_path); + Error err = cf->load(p_addon); if (err != OK) { - show_warning(vformat(TTR("Unable to enable addon plugin at: '%s' parsing of config failed."), addon_path)); + show_warning(vformat(TTR("Unable to enable addon plugin at: '%s' parsing of config failed."), p_addon)); return; } if (!cf->has_section_key("plugin", "script")) { - show_warning(vformat(TTR("Unable to find script field for addon plugin at: 'res://addons/%s'."), p_addon)); + show_warning(vformat(TTR("Unable to find script field for addon plugin at: '%s'."), p_addon)); return; } @@ -3065,7 +3143,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, // Only try to load the script if it has a name. Else, the plugin has no init script. if (script_path.length() > 0) { - script_path = String("res://addons").plus_file(p_addon).plus_file(script_path); + script_path = p_addon.get_base_dir().plus_file(script_path); script = ResourceLoader::load(script_path); if (script.is_null()) { @@ -3323,7 +3401,7 @@ int EditorNode::new_scene() { return idx; } -Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) { +Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported, bool p_silent_change_tab) { if (!is_inside_tree()) { defer_load_scene = p_scene; return OK; @@ -3363,14 +3441,16 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count() == 2) { _remove_edited_scene(); - } else { + } else if (!p_silent_change_tab) { _scene_tab_changed(idx); + } else { + set_current_scene(idx); } dependency_errors.clear(); Error err; - Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err); + Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err); if (!sdata.is_valid()) { _dialog_display_load_error(lpath, err); opening_prev = false; @@ -4703,8 +4783,8 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) { } bool unsaved = (p_tab == editor_data.get_edited_scene()) ? - saved_version != editor_data.get_undo_redo().get_version() : - editor_data.get_scene_version(p_tab) != 0; + saved_version != editor_data.get_undo_redo().get_version() : + editor_data.get_scene_version(p_tab) != 0; if (unsaved) { save_confirmation->get_ok_button()->set_text(TTR("Save & Close")); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_filename() != "" ? scene->get_filename() : "unsaved scene")); @@ -5139,9 +5219,7 @@ void EditorNode::_global_menu_new_window(const Variant &p_tag) { List<String> args; args.push_back("-p"); String exec = OS::get_singleton()->get_executable_path(); - - OS::ProcessID pid = 0; - OS::get_singleton()->execute(exec, args, false, &pid); + OS::get_singleton()->create_process(exec, args); } } @@ -5194,6 +5272,8 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) { } void EditorNode::reload_scene(const String &p_path) { + /* + * No longer necesary since scenes now reset and reload their internal resource if needed. //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk List<Ref<Resource>> cached; @@ -5211,6 +5291,8 @@ void EditorNode::reload_scene(const String &p_path) { to_clear.pop_front(); } + */ + int scene_idx = -1; for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { if (editor_data.get_scene_path(i) == p_path) { @@ -5454,6 +5536,7 @@ void EditorNode::_bind_methods() { ADD_SIGNAL(MethodInfo("request_help_search")); ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "args"))); ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj"))); + ADD_SIGNAL(MethodInfo("project_settings_changed")); } static Node *_resource_get_edited_scene() { @@ -5467,13 +5550,14 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err static void _execute_thread(void *p_ud) { EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)p_ud; - Error err = OS::get_singleton()->execute(eta->path, eta->args, true, nullptr, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex); + Error err = OS::get_singleton()->execute(eta->path, eta->args, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex); print_verbose("Thread exit status: " + itos(eta->exitcode)); if (err != OK) { eta->exitcode = err; } - eta->done = true; + eta->done.set(); + ; } int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok, bool p_close_on_errors) { @@ -5487,15 +5571,12 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p eta.path = p_path; eta.args = p_arguments; eta.exitcode = 255; - eta.done = false; int prev_len = 0; - eta.execute_output_thread = Thread::create(_execute_thread, &eta); + eta.execute_output_thread.start(_execute_thread, &eta); - ERR_FAIL_COND_V(!eta.execute_output_thread, 0); - - while (!eta.done) { + while (!eta.done.is_set()) { { MutexLock lock(eta.execute_output_mutex); if (prev_len != eta.output.length()) { @@ -5508,8 +5589,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p OS::get_singleton()->delay_usec(1000); } - Thread::wait_to_finish(eta.execute_output_thread); - memdelete(eta.execute_output_thread); + eta.execute_output_thread.wait_to_finish(); execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode)); if (p_close_on_errors && eta.exitcode != 0) { @@ -5524,6 +5604,10 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p return eta.exitcode; } +void EditorNode::notify_settings_changed() { + settings_changed = true; +} + EditorNode::EditorNode() { Input::get_singleton()->set_use_accumulated_input(true); Resource::_get_local_scene_func = _resource_get_edited_scene; @@ -5584,6 +5668,8 @@ EditorNode::EditorNode() { switch (display_scale) { case 0: { // Try applying a suitable display scale automatically. + // The code below is adapted in `editor/editor_settings.cpp` and `editor/project_manager.cpp`. + // Make sure to update those when modifying the code below. #ifdef OSX_ENABLED editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale()); #else @@ -5592,6 +5678,10 @@ EditorNode::EditorNode() { if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) { // hiDPI display. scale = 2.0; + } else if (DisplayServer::get_singleton()->screen_get_size(screen).y >= 1700) { + // Likely a hiDPI display, but we aren't certain due to the returned DPI. + // Use an intermediate scale to handle this situation. + scale = 1.5; } else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) { // Small loDPI display. Use a smaller display scale so that editor elements fit more easily. // Icons won't look great, but this is better than having editor elements overflow from its window. @@ -5750,7 +5840,7 @@ EditorNode::EditorNode() { register_exporters(); - GLOBAL_DEF("editor/main_run_args", ""); + GLOBAL_DEF("editor/run/main_run_args", ""); ClassDB::set_class_enabled("RootMotionView", true); @@ -5763,7 +5853,6 @@ EditorNode::EditorNode() { EDITOR_DEF("run/output/always_close_output_on_stop", true); EDITOR_DEF("run/auto_save/save_before_running", true); EDITOR_DEF_RST("interface/editor/save_each_scene_on_quit", true); - EDITOR_DEF("interface/editor/quit_confirmation", true); EDITOR_DEF("interface/editor/show_update_spinner", false); EDITOR_DEF("interface/editor/update_continuously", false); EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false); @@ -5776,7 +5865,7 @@ EditorNode::EditorNode() { EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false); EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true); EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true); - EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "StandardMaterial3D,ORMMaterial3D,Script,MeshLibrary,TileSet"); + EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary,TileSet"); EDITOR_DEF("interface/inspector/default_color_picker_mode", 0); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); @@ -5972,8 +6061,8 @@ EditorNode::EditorNode() { tab_preview_panel->add_child(tab_preview); scene_tabs = memnew(Tabs); - scene_tabs->add_theme_style_override("tab_fg", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles")); - scene_tabs->add_theme_style_override("tab_bg", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles")); + scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles")); + scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles")); scene_tabs->set_select_with_rmb(true); scene_tabs->add_tab("unsaved"); scene_tabs->set_tab_align(Tabs::ALIGN_LEFT); @@ -6016,7 +6105,7 @@ EditorNode::EditorNode() { tabbar_container->add_child(distraction_free); scene_tab_add->set_tooltip(TTR("Add a new scene.")); scene_tab_add->set_icon(gui_base->get_theme_icon("Add", "EditorIcons")); - scene_tab_add->add_theme_color_override("icon_color_normal", Color(0.6f, 0.6f, 0.6f, 0.8f)); + scene_tab_add->add_theme_color_override("icon_normal_color", Color(0.6f, 0.6f, 0.6f, 0.8f)); scene_tab_add->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(FILE_NEW_SCENE)); scene_root_parent = memnew(PanelContainer); @@ -6127,8 +6216,8 @@ EditorNode::EditorNode() { pm_export->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option)); p->add_separator(); - p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true); - p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Z), EDIT_REDO, true); + p->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO, true); + p->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO, true); p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/reload_saved_scene", TTR("Reload Saved Scene")), EDIT_RELOAD_SAVED_SCENE); @@ -6264,7 +6353,11 @@ EditorNode::EditorNode() { p = help_menu->get_popup(); p->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option)); - p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search"), KEY_MASK_SHIFT | KEY_F1), HELP_SEARCH); +#ifdef OSX_ENABLED + p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE), HELP_SEARCH); +#else + p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1), HELP_SEARCH); +#endif p->add_separator(); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Docs")), HELP_DOCS); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/q&a", TTR("Q&A")), HELP_QA); @@ -6369,7 +6462,7 @@ EditorNode::EditorNode() { #warning needs to be reimplemented #endif #if 0 - String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/quality/driver/driver_name"].hint_string; + String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/driver/driver_name"].hint_string; String current_video_driver = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver()); video_driver_current = 0; for (int i = 0; i < video_drivers.get_slice_count(","); i++) { @@ -6602,6 +6695,30 @@ EditorNode::EditorNode() { //plugin stuff add_editor_plugin(memnew(DebuggerEditorPlugin(this, debug_menu))); + + disk_changed = memnew(ConfirmationDialog); + { + VBoxContainer *vbc = memnew(VBoxContainer); + disk_changed->add_child(vbc); + + Label *dl = memnew(Label); + dl->set_text(TTR("The following files are newer on disk.\nWhat action should be taken?")); + vbc->add_child(dl); + + disk_changed_list = memnew(Tree); + vbc->add_child(disk_changed_list); + disk_changed_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_modified_scenes)); + disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_project_settings)); + disk_changed->get_ok_button()->set_text(TTR("Reload")); + + disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); + disk_changed->connect("custom_action", callable_mp(this, &EditorNode::_resave_scenes)); + } + + gui_base->add_child(disk_changed); + add_editor_plugin(memnew(AnimationPlayerEditorPlugin(this))); add_editor_plugin(memnew(CanvasItemEditorPlugin(this))); add_editor_plugin(memnew(Node3DEditorPlugin(this))); @@ -6831,14 +6948,12 @@ EditorNode::EditorNode() { ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2); ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_ALT | KEY_3); ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_ALT | KEY_4); - ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE); #else // Use the Ctrl modifier so F2 can be used to rename nodes in the scene tree dock. ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_CTRL | KEY_F1); ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_CTRL | KEY_F2); ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_CTRL | KEY_F3); ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_CTRL | KEY_F4); - ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1); #endif ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor")); ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor")); diff --git a/editor/editor_node.h b/editor/editor_node.h index 1da162dc9c..91d873d16f 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -31,6 +31,7 @@ #ifndef EDITOR_NODE_H #define EDITOR_NODE_H +#include "core/templates/safe_refcount.h" #include "editor/editor_data.h" #include "editor/editor_export.h" #include "editor/editor_folding.h" @@ -108,10 +109,10 @@ public: String path; List<String> args; String output; - Thread *execute_output_thread = nullptr; + Thread execute_output_thread; Mutex execute_output_mutex; int exitcode = 0; - volatile bool done = false; + SafeFlag done; }; private: @@ -128,7 +129,6 @@ private: FILE_SAVE_ALL_SCENES, FILE_SAVE_AND_RUN, FILE_SHOW_IN_FILESYSTEM, - FILE_IMPORT_SUBSCENE, FILE_EXPORT_PROJECT, FILE_EXPORT_MESH_LIBRARY, FILE_INSTALL_ANDROID_SOURCE, @@ -312,6 +312,9 @@ private: EditorSettingsDialog *settings_config_dialog; ProjectSettingsEditor *project_settings; + bool settings_changed = true; //make it update settings on first frame + void _update_from_settings(); + PopupMenu *vcs_actions_menu; EditorFileDialog *file; ExportTemplateManager *export_template_manager; @@ -422,6 +425,9 @@ private: Label *version_label; Button *bottom_panel_raise; + Tree *disk_changed_list; + ConfirmationDialog *disk_changed; + void _bottom_panel_raise_toggled(bool); EditorInterface *editor_interface; @@ -641,6 +647,10 @@ private: static void _resource_loaded(RES p_resource, const String &p_path); void _resources_changed(const Vector<String> &p_resources); + void _scan_external_changes(); + void _reload_modified_scenes(); + void _reload_project_settings(); + void _resave_scenes(String p_str); void _feature_profile_changed(); bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class); @@ -709,8 +719,6 @@ public: void save_resource(const Ref<Resource> &p_resource); void save_resource_as(const Ref<Resource> &p_resource, const String &p_at_path = String()); - void merge_from_scene() { _menu_option_confirm(FILE_IMPORT_SUBSCENE, false); } - void show_about() { _menu_option_confirm(HELP_ABOUT, false); } static bool has_unsaved_changes() { return singleton->unsaved_cache; } @@ -741,7 +749,7 @@ public: void fix_dependencies(const String &p_for_file); void clear_scene() { _cleanup_scene(); } int new_scene(); - Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false); + Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false, bool p_silent_change_tab = false); Error load_resource(const String &p_resource, bool p_ignore_broken_deps = false); bool is_scene_open(const String &p_path); @@ -840,6 +848,8 @@ public: void save_scene_list(Vector<String> p_scene_filenames); void restart_editor(); + void notify_settings_changed(); + void dim_editor(bool p_dimming, bool p_force_dim = false); bool is_editor_dimmed() const; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 840bae35bf..c0cecbc651 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -756,7 +756,6 @@ int find(const PackedStringArray &a, const String &v) { void EditorPlugin::enable_plugin() { // Called when the plugin gets enabled in project settings, after it's added to the tree. // You can implement it to register autoloads. - if (get_script_instance() && get_script_instance()->has_method("enable_plugin")) { get_script_instance()->call("enable_plugin"); } @@ -819,6 +818,18 @@ void EditorPlugin::remove_debugger_plugin(const Ref<Script> &p_script) { EditorDebuggerNode::get_singleton()->remove_debugger_plugin(p_script); } +void EditorPlugin::_editor_project_settings_changed() { + emit_signal("project_settings_changed"); +} +void EditorPlugin::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE) { + EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &EditorPlugin::_editor_project_settings_changed)); + } + if (p_what == NOTIFICATION_EXIT_TREE) { + EditorNode::get_singleton()->disconnect("project_settings_changed", callable_mp(this, &EditorPlugin::_editor_project_settings_changed)); + } +} + void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("add_control_to_container", "container", "control"), &EditorPlugin::add_control_to_container); ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel", "control", "title"), &EditorPlugin::add_control_to_bottom_panel); @@ -890,6 +901,7 @@ void EditorPlugin::_bind_methods() { ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "filepath"))); ADD_SIGNAL(MethodInfo("main_screen_changed", PropertyInfo(Variant::STRING, "screen_name"))); ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); + ADD_SIGNAL(MethodInfo("project_settings_changed")); BIND_ENUM_CONSTANT(CONTAINER_TOOLBAR); BIND_ENUM_CONSTANT(CONTAINER_SPATIAL_EDITOR_MENU); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 3b741a2f22..ae9fcfb28a 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -130,7 +130,11 @@ class EditorPlugin : public Node { String last_main_screen_name; + void _editor_project_settings_changed(); + protected: + void _notification(int p_what); + static void _bind_methods(); UndoRedo &get_undo_redo() { return *undo_redo; } diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index aa3b75097e..e5b62513ff 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -49,44 +49,16 @@ void EditorPluginSettings::_notification(int p_what) { void EditorPluginSettings::update_plugins() { plugin_list->clear(); - - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - Error err = da->change_dir("res://addons"); - if (err != OK) { - memdelete(da); - return; - } - updating = true; - TreeItem *root = plugin_list->create_item(); - da->list_dir_begin(); - - String d = da->get_next(); - - Vector<String> plugins; - - while (d != String()) { - bool dir = da->current_is_dir(); - String path = "res://addons/" + d + "/plugin.cfg"; - - if (dir && FileAccess::exists(path)) { - plugins.push_back(d); - } - - d = da->get_next(); - } - - da->list_dir_end(); - memdelete(da); - + Vector<String> plugins = _get_plugins("res://addons"); plugins.sort(); for (int i = 0; i < plugins.size(); i++) { Ref<ConfigFile> cf; cf.instance(); - String path = "res://addons/" + plugins[i] + "/plugin.cfg"; + const String path = plugins[i]; Error err2 = cf->load(path); @@ -117,7 +89,6 @@ void EditorPluginSettings::update_plugins() { } if (!key_missing) { - String d2 = plugins[i]; String name = cf->get_value("plugin", "name"); String author = cf->get_value("plugin", "author"); String version = cf->get_value("plugin", "version"); @@ -127,14 +98,14 @@ void EditorPluginSettings::update_plugins() { TreeItem *item = plugin_list->create_item(root); item->set_text(0, name); item->set_tooltip(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description); - item->set_metadata(0, d2); + item->set_metadata(0, path); item->set_text(1, version); item->set_metadata(1, script); item->set_text(2, author); item->set_metadata(2, description); item->set_cell_mode(3, TreeItem::CELL_MODE_CHECK); item->set_text(3, TTR("Enable")); - bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(d2); + bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(path); item->set_checked(3, is_active); item->set_editable(3, true); item->add_button(4, get_theme_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin")); @@ -179,12 +150,39 @@ void EditorPluginSettings::_cell_button_pressed(Object *p_item, int p_column, in if (p_id == BUTTON_PLUGIN_EDIT) { if (p_column == 4) { String dir = item->get_metadata(0); - plugin_config_dialog->config("res://addons/" + dir + "/plugin.cfg"); + plugin_config_dialog->config(dir); plugin_config_dialog->popup_centered(); } } } +Vector<String> EditorPluginSettings::_get_plugins(const String &p_dir) { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Error err = da->change_dir(p_dir); + if (err != OK) { + return Vector<String>(); + } + + Vector<String> plugins; + da->list_dir_begin(); + for (String path = da->get_next(); path != String(); path = da->get_next()) { + if (path[0] == '.' || !da->current_is_dir()) { + continue; + } + + const String full_path = p_dir.plus_file(path); + const String plugin_config = full_path.plus_file("plugin.cfg"); + if (FileAccess::exists(plugin_config)) { + plugins.push_back(plugin_config); + } else { + plugins.append_array(_get_plugins(full_path)); + } + } + + da->list_dir_end(); + return plugins; +} + void EditorPluginSettings::_bind_methods() { } diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index 4f2b5293ec..34b26de90e 100644 --- a/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h @@ -54,6 +54,8 @@ class EditorPluginSettings : public VBoxContainer { void _create_clicked(); void _cell_button_pressed(Object *p_item, int p_column, int p_id); + static Vector<String> _get_plugins(const String &p_dir); + protected: void _notification(int p_what); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 3fa183e10c..6bfc16ccd7 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1267,16 +1267,20 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); - + bool grid = false; BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); add_child(bc); } else if (horizontal) { - bc = memnew(HBoxContainer); + bc = memnew(VBoxContainer); add_child(bc); set_bottom_editor(bc); + + bc->add_child(memnew(HBoxContainer)); + bc->add_child(memnew(HBoxContainer)); + grid = true; } else { bc = memnew(VBoxContainer); add_child(bc); @@ -1287,7 +1291,13 @@ EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); spin[i]->set_flat(true); - bc->add_child(spin[i]); + + if (grid) { + bc->get_child(i / 2)->add_child(spin[i]); + } else { + bc->add_child(spin[i]); + } + add_focusable(spin[i]); spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2::_value_changed), varray(desc[i])); if (horizontal) { @@ -1530,16 +1540,20 @@ void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) { EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); - + bool grid = false; BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); add_child(bc); } else if (horizontal) { - bc = memnew(HBoxContainer); + bc = memnew(VBoxContainer); add_child(bc); set_bottom_editor(bc); + + bc->add_child(memnew(HBoxContainer)); + bc->add_child(memnew(HBoxContainer)); + grid = true; } else { bc = memnew(VBoxContainer); add_child(bc); @@ -1550,7 +1564,13 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); spin[i]->set_flat(true); - bc->add_child(spin[i]); + + if (grid) { + bc->get_child(i / 2)->add_child(spin[i]); + } else { + bc->add_child(spin[i]); + } + add_focusable(spin[i]); spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i])); if (horizontal) { @@ -2148,6 +2168,12 @@ void EditorPropertyColor::_color_changed(const Color &p_color) { emit_changed(get_edited_property(), p_color, "", true); } +void EditorPropertyColor::_popup_closed() { + if (picker->get_pick_color() != last_color) { + emit_changed(get_edited_property(), picker->get_pick_color(), "", false); + } +} + void EditorPropertyColor::_picker_created() { // get default color picker mode from editor settings int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode"); @@ -2158,6 +2184,10 @@ void EditorPropertyColor::_picker_created() { } } +void EditorPropertyColor::_picker_opening() { + last_color = picker->get_pick_color(); +} + void EditorPropertyColor::_bind_methods() { } @@ -2191,7 +2221,9 @@ EditorPropertyColor::EditorPropertyColor() { add_child(picker); picker->set_flat(true); picker->connect("color_changed", callable_mp(this, &EditorPropertyColor::_color_changed)); + picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed)); picker->connect("picker_created", callable_mp(this, &EditorPropertyColor::_picker_created)); + picker->get_popup()->connect("about_to_popup", callable_mp(this, &EditorPropertyColor::_picker_opening)); } ////////////// NODE PATH ////////////////////// @@ -2827,6 +2859,41 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) { } } +void EditorPropertyResource::_update_property_bg() { + if (!is_inside_tree()) { + return; + } + + updating_theme = true; + if (sub_inspector != nullptr) { + int count_subinspectors = 0; + Node *n = get_parent(); + while (n) { + EditorInspector *ei = Object::cast_to<EditorInspector>(n); + if (ei && ei->is_sub_inspector()) { + count_subinspectors++; + } + n = n->get_parent(); + } + count_subinspectors = MIN(15, count_subinspectors); + + add_theme_color_override("property_color", get_theme_color("sub_inspector_property_color", "Editor")); + add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), "Editor")); + add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), "Editor")); + + add_theme_constant_override("font_offset", get_theme_constant("sub_inspector_font_offset", "Editor")); + add_theme_constant_override("vseparation", 0); + } else { + add_theme_color_override("property_color", get_theme_color("property_color", "EditorProperty")); + add_theme_style_override("bg_selected", get_theme_stylebox("bg_selected", "EditorProperty")); + add_theme_style_override("bg", get_theme_stylebox("bg", "EditorProperty")); + add_theme_constant_override("vseparation", get_theme_constant("vseparation", "EditorProperty")); + add_theme_constant_override("font_offset", get_theme_constant("font_offset", "EditorProperty")); + } + + updating_theme = false; + update(); +} void EditorPropertyResource::update_property() { RES res = get_edited_object()->get(get_edited_property()); @@ -2875,13 +2942,14 @@ void EditorPropertyResource::update_property() { } opened_editor = true; } + + _update_property_bg(); } if (res.ptr() != sub_inspector->get_edited_object()) { sub_inspector->edit(res.ptr()); } - sub_inspector->refresh(); } else { if (sub_inspector) { set_bottom_editor(nullptr); @@ -2892,6 +2960,7 @@ void EditorPropertyResource::update_property() { EditorNode::get_singleton()->hide_top_editors(); opened_editor = false; } + _update_property_bg(); } } } @@ -2945,8 +3014,12 @@ void EditorPropertyResource::setup(const String &p_base_type) { void EditorPropertyResource::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + if (updating_theme) { + return; + } Ref<Texture2D> t = get_theme_icon("select_arrow", "Tree"); edit->set_icon(t); + _update_property_bg(); } if (p_what == NOTIFICATION_DRAG_BEGIN) { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 856a406e62..6f097fb5df 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -547,7 +547,11 @@ class EditorPropertyColor : public EditorProperty { GDCLASS(EditorPropertyColor, EditorProperty); ColorPickerButton *picker; void _color_changed(const Color &p_color); + void _popup_closed(); void _picker_created(); + void _picker_opening(); + + Color last_color; protected: static void _bind_methods(); @@ -650,6 +654,9 @@ class EditorPropertyResource : public EditorProperty { bool opened_editor; + bool updating_theme = false; + void _update_property_bg(); + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index a798344973..de688f2709 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -573,8 +573,7 @@ void EditorPropertyArray::_bind_methods() { EditorPropertyArray::EditorPropertyArray() { object.instance(); - page_idx = 0; - page_len = 10; + page_len = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page")); edit = memnew(Button); edit->set_flat(true); edit->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1069,8 +1068,7 @@ void EditorPropertyDictionary::_bind_methods() { EditorPropertyDictionary::EditorPropertyDictionary() { object.instance(); - page_idx = 0; - page_len = 10; + page_len = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page")); edit = memnew(Button); edit->set_flat(true); edit->set_h_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 0359f3d9bc..fa5adc788d 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -84,8 +84,8 @@ class EditorPropertyArray : public EditorProperty { bool dropping; Ref<EditorPropertyArrayObject> object; - int page_len; - int page_idx; + int page_len = 20; + int page_idx = 0; int changing_type_idx; Button *edit; VBoxContainer *vbox; @@ -129,8 +129,8 @@ class EditorPropertyDictionary : public EditorProperty { bool updating; Ref<EditorPropertyDictionaryObject> object; - int page_len; - int page_idx; + int page_len = 20; + int page_idx = 0; int changing_type_idx; Button *edit; VBoxContainer *vbox; diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 29a929d179..77288be614 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -206,8 +206,8 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref< } void EditorResourcePreview::_thread() { - exited = false; - while (!exit) { + exited.clear(); + while (!exit.is_set()) { preview_sem.wait(); preview_mutex.lock(); @@ -326,7 +326,7 @@ void EditorResourcePreview::_thread() { preview_mutex.unlock(); } } - exited = true; + exited.set(); } void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p_res, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) { @@ -424,30 +424,25 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) { } void EditorResourcePreview::start() { - ERR_FAIL_COND_MSG(thread, "Thread already started."); - thread = Thread::create(_thread_func, this); + ERR_FAIL_COND_MSG(thread.is_started(), "Thread already started."); + thread.start(_thread_func, this); } void EditorResourcePreview::stop() { - if (thread) { - exit = true; + if (thread.is_started()) { + exit.set(); preview_sem.post(); - while (!exited) { + while (!exited.is_set()) { OS::get_singleton()->delay_usec(10000); RenderingServer::get_singleton()->sync(); //sync pending stuff, as thread may be blocked on visual server } - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread.wait_to_finish(); } } EditorResourcePreview::EditorResourcePreview() { - thread = nullptr; singleton = this; order = 0; - exit = false; - exited = false; } EditorResourcePreview::~EditorResourcePreview() { diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index c119ccd99f..c4e796dcf1 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -33,6 +33,7 @@ #include "core/os/semaphore.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "scene/main/node.h" #include "scene/resources/texture.h" @@ -70,9 +71,9 @@ class EditorResourcePreview : public Node { Mutex preview_mutex; Semaphore preview_sem; - Thread *thread; - volatile bool exit; - volatile bool exited; + Thread thread; + SafeFlag exit; + SafeFlag exited; struct Item { Ref<Texture2D> preview; diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 6fae56074d..e46f4eb65a 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -201,7 +201,7 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L int instances = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_instances", 1); for (int i = 0; i < instances; i++) { OS::ProcessID pid = 0; - Error err = OS::get_singleton()->execute(exec, args, false, &pid); + Error err = OS::get_singleton()->create_process(exec, args, &pid); ERR_FAIL_COND_V(err, err); pids.push_back(pid); } diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index a2627f51ac..f81c87be9e 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -116,12 +116,12 @@ public: void set_section(const String &p_section, bool p_allow_sub) { section = p_section; allow_sub = p_allow_sub; - _change_notify(); + notify_property_list_changed(); } void set_edited(Object *p_edited) { edited = p_edited; - _change_notify(); + notify_property_list_changed(); } }; @@ -226,7 +226,7 @@ void SectionedInspector::update_category_list() { if (pi.usage & PROPERTY_USAGE_CATEGORY) { continue; - } else if (!(pi.usage & PROPERTY_USAGE_EDITOR)) { + } else if (!(pi.usage & PROPERTY_USAGE_EDITOR) || (restrict_to_basic && !(pi.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { continue; } @@ -294,6 +294,12 @@ EditorInspector *SectionedInspector::get_inspector() { return inspector; } +void SectionedInspector::set_restrict_to_basic_settings(bool p_restrict) { + restrict_to_basic = p_restrict; + update_category_list(); + inspector->set_restrict_to_basic_settings(p_restrict); +} + SectionedInspector::SectionedInspector() : sections(memnew(Tree)), filter(memnew(SectionedInspectorFilter)), diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h index 55fb94fecc..1068a4f932 100644 --- a/editor/editor_sectioned_inspector.h +++ b/editor/editor_sectioned_inspector.h @@ -51,6 +51,8 @@ class SectionedInspector : public HSplitContainer { String selected_category; + bool restrict_to_basic = false; + static void _bind_methods(); void _section_selected(); @@ -65,6 +67,7 @@ public: void set_current_section(const String &p_section); String get_current_section() const; + void set_restrict_to_basic_settings(bool p_restrict); void update_category_list(); SectionedInspector(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 9b9b6bf628..ef1f8030fa 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -31,6 +31,7 @@ #include "editor_settings.h" #include "core/config/project_settings.h" +#include "core/input/input_map.h" #include "core/io/certs_compressed.gen.h" #include "core/io/compression.h" #include "core/io/config_file.h" @@ -70,7 +71,7 @@ bool EditorSettings::_set(const StringName &p_name, const Variant &p_value) { bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) { _THREAD_SAFE_METHOD_ - if (p_name.operator String() == "shortcuts") { + if (p_name == "shortcuts") { Array arr = p_value; ERR_FAIL_COND_V(arr.size() && arr.size() & 1, true); for (int i = 0; i < arr.size(); i += 2) { @@ -84,6 +85,24 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) } return false; + } else if (p_name == "builtin_action_overrides") { + Array actions_arr = p_value; + for (int i = 0; i < actions_arr.size(); i++) { + Dictionary action_dict = actions_arr[i]; + + String name = action_dict["name"]; + Array events = action_dict["events"]; + + InputMap *im = InputMap::get_singleton(); + im->action_erase_events(name); + + builtin_action_overrides[name].clear(); + for (int ev_idx = 0; ev_idx < events.size(); ev_idx++) { + im->action_add_event(name, events[ev_idx]); + builtin_action_overrides[name].push_back(events[ev_idx]); + } + } + return false; } bool changed = false; @@ -118,11 +137,16 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { _THREAD_SAFE_METHOD_ - if (p_name.operator String() == "shortcuts") { + if (p_name == "shortcuts") { Array arr; for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) { Ref<Shortcut> sc = E->get(); + if (builtin_action_overrides.has(E->key())) { + // This shortcut was auto-generated from built in actions: don't save. + continue; + } + if (optimize_save) { if (!sc->has_meta("original")) { continue; //this came from settings but is not any longer used @@ -139,6 +163,27 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { } r_ret = arr; return true; + } else if (p_name == "builtin_action_overrides") { + Array actions_arr; + for (Map<String, List<Ref<InputEvent>>>::Element *E = builtin_action_overrides.front(); E; E = E->next()) { + List<Ref<InputEvent>> events = E->get(); + + // TODO: skip actions which are the same as the builtin. + Dictionary action_dict; + action_dict["name"] = E->key(); + + Array events_arr; + for (List<Ref<InputEvent>>::Element *I = events.front(); I; I = I->next()) { + events_arr.push_back(I->get()); + } + + action_dict["events"] = events_arr; + + actions_arr.push_back(action_dict); + } + + r_ret = actions_arr; + return true; } const VariantContainer *v = props.getptr(p_name); @@ -220,6 +265,7 @@ void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const { } p_list->push_back(PropertyInfo(Variant::ARRAY, "shortcuts", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); //do not edit + p_list->push_back(PropertyInfo(Variant::ARRAY, "builtin_action_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } void EditorSettings::_add_property_info_bind(const Dictionary &p_info) { @@ -326,7 +372,30 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // Editor _initial_set("interface/editor/display_scale", 0); - hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, "Auto,75%,100%,125%,150%,175%,200%,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + // Display what the Auto display scale setting effectively corresponds to. + // The code below is adapted in `editor/editor_node.cpp` and `editor/project_manager.cpp`. + // Make sure to update those when modifying the code below. +#ifdef OSX_ENABLED + float scale = DisplayServer::get_singleton()->screen_get_max_scale(); +#else + const int screen = DisplayServer::get_singleton()->window_get_current_screen(); + float scale; + if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) { + // hiDPI display. + scale = 2.0; + } else if (DisplayServer::get_singleton()->screen_get_size(screen).y >= 1700) { + // Likely a hiDPI display, but we aren't certain due to the returned DPI. + // Use an intermediate scale to handle this situation. + scale = 1.5; + } else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) { + // Small loDPI display. Use a smaller display scale so that editor elements fit more easily. + // Icons won't look great, but this is better than having editor elements overflow from its window. + scale = 0.75; + } else { + scale = 1.0; + } +#endif + hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, vformat("Auto (%d%%),75%%,100%%,125%%,150%%,175%%,200%%,Custom", Math::round(scale * 100)), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/custom_display_scale", 1.0f); hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::FLOAT, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/main_font_size", 14); @@ -334,12 +403,16 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("interface/editor/code_font_size", 14); hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT); _initial_set("interface/editor/code_font_contextual_ligatures", 0); - hints["interface/editor/code_font_contextual_ligatures"] = PropertyInfo(Variant::INT, "interface/editor/code_font_contextual_ligatures", PROPERTY_HINT_ENUM, "Default,Disable contextual alternates (coding ligatures),Use custom OpenType feature set", PROPERTY_USAGE_DEFAULT); + hints["interface/editor/code_font_contextual_ligatures"] = PropertyInfo(Variant::INT, "interface/editor/code_font_contextual_ligatures", PROPERTY_HINT_ENUM, "Default,Disable Contextual Alternates (Coding Ligatures),Use Custom OpenType Feature Set", PROPERTY_USAGE_DEFAULT); _initial_set("interface/editor/code_font_custom_opentype_features", ""); _initial_set("interface/editor/code_font_custom_variations", ""); _initial_set("interface/editor/font_antialiased", true); _initial_set("interface/editor/font_hinting", 0); - hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto,None,Light,Normal", PROPERTY_USAGE_DEFAULT); +#ifdef OSX_ENABLED + hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto (None),None,Light,Normal", PROPERTY_USAGE_DEFAULT); +#else + hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto (Light),None,Light,Normal", PROPERTY_USAGE_DEFAULT); +#endif _initial_set("interface/editor/main_font", ""); hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT); _initial_set("interface/editor/main_font_bold", ""); @@ -357,7 +430,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/editor/single_window_mode"] = PropertyInfo(Variant::BOOL, "interface/editor/single_window_mode", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/hide_console_window", false); _initial_set("interface/editor/save_each_scene_on_quit", true); // Regression - _initial_set("interface/editor/quit_confirmation", true); + + // Inspector + _initial_set("interface/inspector/max_array_dictionary_items_per_page", 20); + hints["interface/inspector/max_array_dictionary_items_per_page"] = PropertyInfo(Variant::INT, "interface/inspector/max_array_dictionary_items_per_page", PROPERTY_HINT_RANGE, "10,100,1", PROPERTY_USAGE_DEFAULT); // Theme _initial_set("interface/theme/preset", "Default"); @@ -370,6 +446,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/theme/accent_color"] = PropertyInfo(Variant::COLOR, "interface/theme/accent_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); _initial_set("interface/theme/contrast", 0.25); hints["interface/theme/contrast"] = PropertyInfo(Variant::FLOAT, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01"); + _initial_set("interface/theme/icon_saturation", 1.0); + hints["interface/theme/icon_saturation"] = PropertyInfo(Variant::FLOAT, "interface/theme/icon_saturation", PROPERTY_HINT_RANGE, "0,2,0.01", PROPERTY_USAGE_DEFAULT); _initial_set("interface/theme/relationship_line_opacity", 0.1); hints["interface/theme/relationship_line_opacity"] = PropertyInfo(Variant::FLOAT, "interface/theme/relationship_line_opacity", PROPERTY_HINT_RANGE, "0.00, 1, 0.01"); _initial_set("interface/theme/highlight_tabs", false); @@ -419,7 +497,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("docks/filesystem/always_show_folders", true); // Property editor - _initial_set("docks/property_editor/auto_refresh_interval", 0.3); + _initial_set("docks/property_editor/auto_refresh_interval", 0.2); //update 5 times per second by default + _initial_set("docks/property_editor/subresource_hue_tint", 0.75); + hints["docks/property_editor/subresource_hue_tint"] = PropertyInfo(Variant::FLOAT, "docks/property_editor/subresource_hue_tint", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT); /* Text editor */ @@ -637,6 +717,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/animation/onion_layers_past_color", Color(1, 0, 0)); _initial_set("editors/animation/onion_layers_future_color", Color(0, 1, 0)); + // Visual editors + _initial_set("editors/visual_editors/minimap_opacity", 0.85); + hints["editors/visual_editors/minimap_opacity"] = PropertyInfo(Variant::FLOAT, "editors/visual_editors/minimap_opacity", PROPERTY_HINT_RANGE, "0.0,1.0,0.01", PROPERTY_USAGE_DEFAULT); + /* Run */ // Window placement @@ -933,27 +1017,16 @@ void EditorSettings::create() { _create_script_templates(dir->get_current_dir().plus_file("script_templates")); - if (dir->change_dir("projects") != OK) { - dir->make_dir("projects"); - } else { - dir->change_dir(".."); - } - - // Validate/create project-specific config dir - - dir->change_dir("projects"); - String project_config_dir = ProjectSettings::get_singleton()->get_resource_path(); - if (project_config_dir.ends_with("/")) { - project_config_dir = config_path.substr(0, project_config_dir.size() - 1); - } - project_config_dir = project_config_dir.get_file() + "-" + project_config_dir.md5_text(); - - if (dir->change_dir(project_config_dir) != OK) { - dir->make_dir(project_config_dir); - } else { - dir->change_dir(".."); + { + // Validate/create project-specific editor settings dir. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) { + Error err = da->make_dir_recursive(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH); + if (err || da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) { + ERR_FAIL_MSG("Failed to create '" + EditorSettings::PROJECT_EDITOR_SETTINGS_PATH + "' folder."); + } + } } - dir->change_dir(".."); // Validate editor config file @@ -975,7 +1048,6 @@ void EditorSettings::create() { singleton->save_changed_setting = true; singleton->config_file_path = config_file_path; - singleton->project_config_dir = project_config_dir; singleton->settings_dir = config_dir; singleton->data_dir = data_dir; singleton->cache_dir = cache_dir; @@ -1251,7 +1323,7 @@ String EditorSettings::get_settings_dir() const { } String EditorSettings::get_project_settings_dir() const { - return get_settings_dir().plus_file("projects").plus_file(project_config_dir); + return EditorSettings::PROJECT_EDITOR_SETTINGS_PATH; } String EditorSettings::get_text_editor_themes_dir() const { @@ -1263,7 +1335,7 @@ String EditorSettings::get_script_templates_dir() const { } String EditorSettings::get_project_script_templates_dir() const { - return ProjectSettings::get_singleton()->get("editor/script_templates_search_path"); + return ProjectSettings::get_singleton()->get("editor/script/templates_search_path"); } // Cache directory @@ -1517,12 +1589,39 @@ bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_ } Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const { - const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name); - if (!E) { - return Ref<Shortcut>(); + const Map<String, Ref<Shortcut>>::Element *SC = shortcuts.find(p_name); + if (SC) { + return SC->get(); } - return E->get(); + // If no shortcut with the provided name is found in the list, check the built-in shortcuts. + // Use the first item in the action list for the shortcut event, since a shortcut can only have 1 linked event. + + Ref<Shortcut> sc; + const Map<String, List<Ref<InputEvent>>>::Element *builtin_override = builtin_action_overrides.find(p_name); + if (builtin_override) { + sc.instance(); + sc->set_shortcut(builtin_override->get().front()->get()); + sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name)); + } + + // If there was no override, check the default builtins to see if it has an InputEvent for the provided name. + if (sc.is_null()) { + const OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins().find(p_name); + if (builtin_default) { + sc.instance(); + sc->set_shortcut(builtin_default.get().front()->get()); + sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name)); + } + } + + if (sc.is_valid()) { + // Add the shortcut to the list. + shortcuts[p_name] = sc; + return sc; + } + + return Ref<Shortcut>(); } void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) { @@ -1588,6 +1687,66 @@ Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p return sc; } +void EditorSettings::set_builtin_action_override(const String &p_name, const Array &p_events) { + List<Ref<InputEvent>> event_list; + + // Override the whole list, since events may have their order changed or be added, removed or edited. + InputMap::get_singleton()->action_erase_events(p_name); + for (int i = 0; i < p_events.size(); i++) { + event_list.push_back(p_events[i]); + InputMap::get_singleton()->action_add_event(p_name, p_events[i]); + } + + // Check if the provided event array is same as built-in. If it is, it does not need to be added to the overrides. + // Note that event order must also be the same. + bool same_as_builtin = true; + OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins().find(p_name); + if (builtin_default) { + List<Ref<InputEvent>> builtin_events = builtin_default.get(); + + if (p_events.size() == builtin_events.size()) { + int event_idx = 0; + + // Check equality of each event. + for (List<Ref<InputEvent>>::Element *E = builtin_events.front(); E; E = E->next()) { + if (!E->get()->shortcut_match(p_events[event_idx])) { + same_as_builtin = false; + break; + } + event_idx++; + } + } else { + same_as_builtin = false; + } + } + + if (same_as_builtin && builtin_action_overrides.has(p_name)) { + builtin_action_overrides.erase(p_name); + } else { + builtin_action_overrides[p_name] = event_list; + } + + // Update the shortcut (if it is used somewhere in the editor) to be the first event of the new list. + if (shortcuts.has(p_name)) { + shortcuts[p_name]->set_shortcut(event_list.front()->get()); + } +} + +const Array EditorSettings::get_builtin_action_overrides(const String &p_name) const { + const Map<String, List<Ref<InputEvent>>>::Element *AO = builtin_action_overrides.find(p_name); + if (AO) { + Array event_array; + + List<Ref<InputEvent>> events_list = AO->get(); + for (List<Ref<InputEvent>>::Element *E = events_list.front(); E; E = E->next()) { + event_array.push_back(E->get()); + } + return event_array; + } + + return Array(); +} + void EditorSettings::notify_changes() { _THREAD_SAFE_METHOD_ @@ -1626,6 +1785,8 @@ void EditorSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("set_recent_dirs", "dirs"), &EditorSettings::set_recent_dirs); ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs); + ClassDB::bind_method(D_METHOD("set_builtin_action_override", "name", "actions_list"), &EditorSettings::set_builtin_action_override); + ADD_SIGNAL(MethodInfo("settings_changed")); BIND_CONSTANT(NOTIFICATION_EDITOR_SETTINGS_CHANGED); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 61ec8546aa..e5f8527faf 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -46,6 +46,7 @@ class EditorSettings : public Resource { _THREAD_SAFE_CLASS_ public: + inline static const String PROJECT_EDITOR_SETTINGS_PATH = "res://.godot/editor"; struct Plugin { EditorPlugin *instance = nullptr; String path; @@ -83,7 +84,8 @@ private: int last_order; Ref<Resource> clipboard; - Map<String, Ref<Shortcut>> shortcuts; + mutable Map<String, Ref<Shortcut>> shortcuts; + Map<String, List<Ref<InputEvent>>> builtin_action_overrides; String resource_path; String settings_dir; @@ -185,6 +187,9 @@ public: Ref<Shortcut> get_shortcut(const String &p_name) const; void get_shortcut_list(List<String> *r_shortcuts); + void set_builtin_action_override(const String &p_name, const Array &p_events); + const Array get_builtin_action_overrides(const String &p_name) const; + void notify_changes(); EditorSettings(); diff --git a/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp deleted file mode 100644 index e319fbff52..0000000000 --- a/editor/editor_sub_scene.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************/ -/* editor_sub_scene.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "editor_sub_scene.h" - -#include "editor/editor_node.h" -#include "scene/gui/margin_container.h" -#include "scene/resources/packed_scene.h" - -void EditorSubScene::_path_selected(const String &p_path) { - path->set_text(p_path); - _path_changed(p_path); -} - -void EditorSubScene::_path_changed(const String &p_path) { - tree->clear(); - - if (scene) { - memdelete(scene); - scene = nullptr; - } - - if (p_path == "") { - return; - } - - Ref<PackedScene> ps = ResourceLoader::load(p_path, "PackedScene"); - - if (ps.is_null()) { - return; - } - - scene = ps->instance(); - if (!scene) { - return; - } - - _fill_tree(scene, nullptr); -} - -void EditorSubScene::_path_browse() { - file_dialog->popup_file_dialog(); -} - -void EditorSubScene::_notification(int p_what) { - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - if (is_visible() && scene == nullptr) { - _path_browse(); - } - } -} - -void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) { - TreeItem *it = tree->create_item(p_parent); - it->set_metadata(0, p_node); - it->set_text(0, p_node->get_name()); - it->set_editable(0, false); - it->set_selectable(0, true); - it->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_node, "Node")); - - for (int i = 0; i < p_node->get_child_count(); i++) { - Node *c = p_node->get_child(i); - if (c->get_owner() != scene) { - continue; - } - _fill_tree(c, it); - } -} - -void EditorSubScene::_selected_changed() { - TreeItem *item = tree->get_selected(); - ERR_FAIL_COND(!item); - Node *n = item->get_metadata(0); - - if (!n || !selection.find(n)) { - selection.clear(); - is_root = false; - } -} - -void EditorSubScene::_item_multi_selected(Object *p_object, int p_cell, bool p_selected) { - if (!is_root) { - TreeItem *item = Object::cast_to<TreeItem>(p_object); - ERR_FAIL_COND(!item); - - Node *n = item->get_metadata(0); - - if (!n) { - return; - } - if (p_selected) { - if (n == scene) { - is_root = true; - selection.clear(); - } - selection.push_back(n); - } else { - List<Node *>::Element *E = selection.find(n); - - if (E) { - selection.erase(E); - } - } - } -} - -void EditorSubScene::_item_activated() { - _ok_pressed(); // From AcceptDialog. -} - -void EditorSubScene::_remove_selection_child(Node *p_node) { - if (p_node->get_child_count() > 0) { - for (int i = 0; i < p_node->get_child_count(); i++) { - Node *c = p_node->get_child(i); - List<Node *>::Element *E = selection.find(c); - if (E) { - selection.move_to_back(E); - selection.pop_back(); - } - if (c->get_child_count() > 0) { - _remove_selection_child(c); - } - } - } -} - -void EditorSubScene::ok_pressed() { - if (selection.size() <= 0) { - return; - } - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node *c = E->get(); - _remove_selection_child(c); - } - emit_signal("subscene_selected"); - hide(); - clear(); -} - -void EditorSubScene::_reown(Node *p_node, List<Node *> *p_to_reown) { - if (p_node == scene) { - scene->set_filename(""); - p_to_reown->push_back(p_node); - } else if (p_node->get_owner() == scene) { - p_to_reown->push_back(p_node); - } - - for (int i = 0; i < p_node->get_child_count(); i++) { - Node *c = p_node->get_child(i); - _reown(c, p_to_reown); - } -} - -void EditorSubScene::move(Node *p_new_parent, Node *p_new_owner) { - if (!scene) { - return; - } - - if (selection.size() <= 0) { - return; - } - - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node *selnode = E->get(); - if (!selnode) { - return; - } - List<Node *> to_reown; - _reown(selnode, &to_reown); - if (selnode != scene) { - selnode->get_parent()->remove_child(selnode); - } - - p_new_parent->add_child(selnode); - for (List<Node *>::Element *F = to_reown.front(); F; F = F->next()) { - F->get()->set_owner(p_new_owner); - } - } - if (!is_root) { - memdelete(scene); - } - scene = nullptr; - //return selnode; -} - -void EditorSubScene::clear() { - path->set_text(""); - _path_changed(""); -} - -void EditorSubScene::_bind_methods() { - ADD_SIGNAL(MethodInfo("subscene_selected")); -} - -EditorSubScene::EditorSubScene() { - scene = nullptr; - is_root = false; - - set_title(TTR("Select Node(s) to Import")); - set_hide_on_ok(false); - - VBoxContainer *vb = memnew(VBoxContainer); - add_child(vb); - //set_child_rect(vb); - - HBoxContainer *hb = memnew(HBoxContainer); - path = memnew(LineEdit); - path->connect("text_entered", callable_mp(this, &EditorSubScene::_path_changed)); - hb->add_child(path); - path->set_h_size_flags(Control::SIZE_EXPAND_FILL); - Button *b = memnew(Button); - b->set_text(TTR("Browse")); - hb->add_child(b); - b->connect("pressed", callable_mp(this, &EditorSubScene::_path_browse)); - vb->add_margin_child(TTR("Scene Path:"), hb); - - tree = memnew(Tree); - tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); - vb->add_margin_child(TTR("Import From Node:"), tree, true); - tree->set_select_mode(Tree::SELECT_MULTI); - tree->connect("multi_selected", callable_mp(this, &EditorSubScene::_item_multi_selected)); - //tree->connect("nothing_selected", this, "_deselect_items"); - tree->connect("cell_selected", callable_mp(this, &EditorSubScene::_selected_changed)); - - tree->connect("item_activated", callable_mp(this, &EditorSubScene::_item_activated), make_binds(), CONNECT_DEFERRED); - - file_dialog = memnew(EditorFileDialog); - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions); - - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - file_dialog->add_filter("*." + E->get()); - } - - file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - add_child(file_dialog); - file_dialog->connect("file_selected", callable_mp(this, &EditorSubScene::_path_selected)); -} diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 0d24d5013d..3d40c145f2 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -41,16 +41,16 @@ #include "modules/svg/image_loader_svg.h" #endif -static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) { +static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) { Ref<StyleBoxTexture> style(memnew(StyleBoxTexture)); style->set_texture(p_texture); style->set_margin_size(SIDE_LEFT, p_left * EDSCALE); style->set_margin_size(SIDE_RIGHT, p_right * EDSCALE); - style->set_margin_size(SIDE_BOTTOM, p_botton * EDSCALE); + style->set_margin_size(SIDE_BOTTOM, p_bottom * EDSCALE); style->set_margin_size(SIDE_TOP, p_top * EDSCALE); style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); - style->set_default_margin(SIDE_BOTTOM, p_margin_botton * EDSCALE); + style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); style->set_draw_center(p_draw_center); return style; @@ -92,6 +92,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, Ref<ImageTexture> texture(memnew(ImageTexture)); Ref<Image> img = p_texture->get_data(); + img = img->duplicate(); if (p_flip_y) { img->flip_y(); @@ -105,7 +106,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, } #ifdef MODULE_SVG_ENABLED -static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, bool p_force_filter = false) { +static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0) { Ref<ImageTexture> icon = memnew(ImageTexture); Ref<Image> img = memnew(Image); @@ -115,6 +116,9 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale); ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color); + if (p_saturation != 1.0) { + img->adjust_bcs(1.0, 1.0, p_saturation); + } icon->create_from_image(img); // in this case filter really helps return icon; @@ -125,7 +129,7 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, #define ADD_CONVERT_COLOR(dictionary, old_color, new_color) dictionary[Color::html(old_color)] = Color::html(new_color) #endif -void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false) { +void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) { #ifdef MODULE_SVG_ENABLED // The default icon theme is designed to be used for a dark theme. // This dictionary stores color codes to convert to other colors @@ -238,14 +242,19 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = if (!p_only_thumbs) { for (int i = 0; i < editor_icons_count; i++) { float icon_scale = EDSCALE; + float saturation = p_icon_saturation; // Always keep the DefaultProjectIcon at the default size if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) { icon_scale = 1.0f; } + if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) { + saturation = 1.0; + } + const int is_exception = exceptions.has(editor_icons_names[i]); - const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale); + const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale, saturation); p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon); } @@ -289,6 +298,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color accent_color = EDITOR_GET("interface/theme/accent_color"); Color base_color = EDITOR_GET("interface/theme/base_color"); float contrast = EDITOR_GET("interface/theme/contrast"); + float icon_saturation = EDITOR_GET("interface/theme/icon_saturation"); float relationship_line_opacity = EDITOR_GET("interface/theme/relationship_line_opacity"); String preset = EDITOR_GET("interface/theme/preset"); @@ -375,23 +385,26 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color contrast_color_2 = base_color.lerp(mono_color, MAX(contrast * 1.5, default_contrast * 1.5)); const Color font_color = mono_color.lerp(base_color, 0.25); - const Color font_color_hl = mono_color.lerp(base_color, 0.15); - const Color font_color_disabled = Color(mono_color.r, mono_color.g, mono_color.b, 0.3); - const Color font_color_selection = accent_color * Color(1, 1, 1, 0.4); - const Color color_disabled = mono_color.inverted().lerp(base_color, 0.7); - const Color color_disabled_bg = mono_color.inverted().lerp(base_color, 0.9); - - Color icon_color_hover = Color(1, 1, 1) * (dark_theme ? 1.15 : 1.45); - icon_color_hover.a = 1.0; + const Color font_hover_color = mono_color.lerp(base_color, 0.15); + const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.3); + const Color selection_color = accent_color * Color(1, 1, 1, 0.4); + const Color disabled_color = mono_color.inverted().lerp(base_color, 0.7); + const Color disabled_bg_color = mono_color.inverted().lerp(base_color, 0.9); + + Color icon_hover_color = Color(1, 1, 1) * (dark_theme ? 1.15 : 1.45); + icon_hover_color.a = 1.0; // Make the pressed icon color overbright because icons are not completely white on a dark theme. // On a light theme, icons are dark, so we need to modulate them with an even brighter color. - Color icon_color_pressed = accent_color * (dark_theme ? 1.15 : 3.5); - icon_color_pressed.a = 1.0; + Color icon_pressed_color = accent_color * (dark_theme ? 1.15 : 3.5); + icon_pressed_color.a = 1.0; const Color separator_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.1); const Color highlight_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.2); + float prev_icon_saturation = theme->has_color("icon_saturation", "Editor") ? theme->get_color("icon_saturation", "Editor").r : 1.0; + + theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); //can't save single float in theme, so using color theme->set_color("accent_color", "Editor", accent_color); theme->set_color("highlight_color", "Editor", highlight_color); theme->set_color("base_color", "Editor", base_color); @@ -408,8 +421,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("axis_z_color", "Editor", Color(0.16, 0.55, 0.96)); theme->set_color("font_color", "Editor", font_color); - theme->set_color("highlighted_font_color", "Editor", font_color_hl); - theme->set_color("disabled_font_color", "Editor", font_color_disabled); + theme->set_color("highlighted_font_color", "Editor", font_hover_color); + theme->set_color("disabled_font_color", "Editor", font_disabled_color); theme->set_color("mono_color", "Editor", mono_color); @@ -443,13 +456,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { //Register icons + font // the resolution and the icon color (dark_theme bool) has not changed, so we do not regenerate the icons - if (p_theme != nullptr && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme) { + if (p_theme != nullptr && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme && prev_icon_saturation == icon_saturation) { // register already generated icons for (int i = 0; i < editor_icons_count; i++) { theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons")); } } else { - editor_register_and_generate_icons(theme, dark_theme, thumb_size); + editor_register_and_generate_icons(theme, dark_theme, thumb_size, false, icon_saturation); } // thumbnail size has changed, so we regenerate the medium sizes if (p_theme != nullptr && fabs((double)p_theme->get_constant("thumb_size", "Editor") - thumb_size) > 0.00001) { @@ -485,8 +498,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_widget->set_border_color(dark_color_2); Ref<StyleBoxFlat> style_widget_disabled = style_widget->duplicate(); - style_widget_disabled->set_border_color(color_disabled); - style_widget_disabled->set_bg_color(color_disabled_bg); + style_widget_disabled->set_border_color(disabled_color); + style_widget_disabled->set_bg_color(disabled_bg_color); Ref<StyleBoxFlat> style_widget_focus = style_widget->duplicate(); style_widget_focus->set_border_color(accent_color); @@ -550,8 +563,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tab_unselected->set_border_color(dark_color_2); Ref<StyleBoxFlat> style_tab_disabled = style_tab_selected->duplicate(); - style_tab_disabled->set_bg_color(color_disabled_bg); - style_tab_disabled->set_border_color(color_disabled); + style_tab_disabled->set_bg_color(disabled_bg_color); + style_tab_disabled->set_border_color(disabled_color); // Editor background theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(background_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size)); @@ -600,7 +613,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("disabled", "PopupMenu", style_menu); theme->set_color("font_color", "MenuButton", font_color); - theme->set_color("font_color_hover", "MenuButton", font_color_hl); + theme->set_color("font_hover_color", "MenuButton", font_hover_color); theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border); @@ -612,11 +625,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("disabled", "Button", style_widget_disabled); theme->set_color("font_color", "Button", font_color); - theme->set_color("font_color_hover", "Button", font_color_hl); - theme->set_color("font_color_pressed", "Button", accent_color); - theme->set_color("font_color_disabled", "Button", font_color_disabled); - theme->set_color("icon_color_hover", "Button", icon_color_hover); - theme->set_color("icon_color_pressed", "Button", icon_color_pressed); + theme->set_color("font_hover_color", "Button", font_hover_color); + theme->set_color("font_pressed_color", "Button", accent_color); + theme->set_color("font_disabled_color", "Button", font_disabled_color); + theme->set_color("icon_hover_color", "Button", icon_hover_color); + theme->set_color("icon_pressed_color", "Button", icon_pressed_color); // OptionButton theme->set_stylebox("focus", "OptionButton", style_widget_focus); @@ -632,10 +645,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("disabled_mirrored", "OptionButton", style_widget_disabled); theme->set_color("font_color", "OptionButton", font_color); - theme->set_color("font_color_hover", "OptionButton", font_color_hl); - theme->set_color("font_color_pressed", "OptionButton", accent_color); - theme->set_color("font_color_disabled", "OptionButton", font_color_disabled); - theme->set_color("icon_color_hover", "OptionButton", icon_color_hover); + theme->set_color("font_hover_color", "OptionButton", font_hover_color); + theme->set_color("font_pressed_color", "OptionButton", accent_color); + theme->set_color("font_disabled_color", "OptionButton", font_disabled_color); + theme->set_color("icon_hover_color", "OptionButton", icon_hover_color); theme->set_icon("arrow", "OptionButton", theme->get_icon("GuiOptionArrow", "EditorIcons")); theme->set_constant("arrow_margin", "OptionButton", default_margin_size * EDSCALE); theme->set_constant("modulate_arrow", "OptionButton", true); @@ -658,10 +671,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("off_disabled_mirrored", "CheckButton", theme->get_icon("GuiToggleOffDisabledMirrored", "EditorIcons")); theme->set_color("font_color", "CheckButton", font_color); - theme->set_color("font_color_hover", "CheckButton", font_color_hl); - theme->set_color("font_color_pressed", "CheckButton", accent_color); - theme->set_color("font_color_disabled", "CheckButton", font_color_disabled); - theme->set_color("icon_color_hover", "CheckButton", icon_color_hover); + theme->set_color("font_hover_color", "CheckButton", font_hover_color); + theme->set_color("font_pressed_color", "CheckButton", accent_color); + theme->set_color("font_disabled_color", "CheckButton", font_disabled_color); + theme->set_color("icon_hover_color", "CheckButton", icon_hover_color); theme->set_constant("hseparation", "CheckButton", 4 * EDSCALE); theme->set_constant("check_vadjust", "CheckButton", 0 * EDSCALE); @@ -683,10 +696,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon("GuiRadioUnchecked", "EditorIcons")); theme->set_color("font_color", "CheckBox", font_color); - theme->set_color("font_color_hover", "CheckBox", font_color_hl); - theme->set_color("font_color_pressed", "CheckBox", accent_color); - theme->set_color("font_color_disabled", "CheckBox", font_color_disabled); - theme->set_color("icon_color_hover", "CheckBox", icon_color_hover); + theme->set_color("font_hover_color", "CheckBox", font_hover_color); + theme->set_color("font_pressed_color", "CheckBox", accent_color); + theme->set_color("font_disabled_color", "CheckBox", font_disabled_color); + theme->set_color("icon_hover_color", "CheckBox", icon_hover_color); theme->set_constant("hseparation", "CheckBox", 4 * EDSCALE); theme->set_constant("check_vadjust", "CheckBox", 0 * EDSCALE); @@ -697,9 +710,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // PopupMenu const int popup_menu_margin_size = default_margin_size * 1.5 * EDSCALE; Ref<StyleBoxFlat> style_popup_menu = style_popup->duplicate(); - style_popup_menu->set_default_margin(SIDE_LEFT, popup_menu_margin_size); + // Use 1 pixel for the sides, since if 0 is used, the highlight of hovered items is drawn + // on top of the popup border. This causes a 'gap' in the panel border when an item is highlighted, + // and it looks weird. 1px solves this. + style_popup_menu->set_default_margin(SIDE_LEFT, 1 * EDSCALE); style_popup_menu->set_default_margin(SIDE_TOP, popup_menu_margin_size); - style_popup_menu->set_default_margin(SIDE_RIGHT, popup_menu_margin_size); + style_popup_menu->set_default_margin(SIDE_RIGHT, 1 * EDSCALE); style_popup_menu->set_default_margin(SIDE_BOTTOM, popup_menu_margin_size); theme->set_stylebox("panel", "PopupMenu", style_popup_menu); @@ -708,10 +724,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("labeled_separator_right", "PopupMenu", style_popup_labeled_separator_right); theme->set_color("font_color", "PopupMenu", font_color); - theme->set_color("font_color_hover", "PopupMenu", font_color_hl); - theme->set_color("font_color_accel", "PopupMenu", font_color_disabled); - theme->set_color("font_color_disabled", "PopupMenu", font_color_disabled); - theme->set_color("font_color_separator", "PopupMenu", font_color_disabled); + theme->set_color("font_hover_color", "PopupMenu", font_hover_color); + theme->set_color("font_accelerator_color", "PopupMenu", font_disabled_color); + theme->set_color("font_disabled_color", "PopupMenu", font_disabled_color); + theme->set_color("font_separator_color", "PopupMenu", font_disabled_color); theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons")); theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiRadioChecked", "EditorIcons")); @@ -721,16 +737,63 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons")); theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon("GuiVisibilityVisible", "EditorIcons")); theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons")); + theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size + 1) * EDSCALE); + theme->set_constant("item_start_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); + theme->set_constant("item_end_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); + + for (int i = 0; i < 16; i++) { + Color si_base_color = accent_color; + + float hue_rotate = (i * 2 % 16) / 16.0; + si_base_color.set_hsv(Math::fmod(float(si_base_color.get_h() + hue_rotate), float(1.0)), si_base_color.get_s(), si_base_color.get_v()); + si_base_color = accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint"))); + + Ref<StyleBoxFlat> sub_inspector_bg; + + sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(si_base_color, 0.08), 2, 0, 2, 2); + + sub_inspector_bg->set_border_width(SIDE_LEFT, 2); + sub_inspector_bg->set_border_width(SIDE_RIGHT, 2); + sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2); + sub_inspector_bg->set_border_width(SIDE_TOP, 2); + sub_inspector_bg->set_default_margin(SIDE_LEFT, 3); + sub_inspector_bg->set_default_margin(SIDE_RIGHT, 3); + sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 10); + sub_inspector_bg->set_default_margin(SIDE_TOP, 5); + sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); + sub_inspector_bg->set_draw_center(true); - Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(accent_color, 0.08), 2, 0, 2, 2); - sub_inspector_bg->set_border_width(SIDE_LEFT, 2); - sub_inspector_bg->set_border_width(SIDE_RIGHT, 2); - sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2); - sub_inspector_bg->set_border_color(accent_color * Color(1, 1, 1, 0.3)); - sub_inspector_bg->set_draw_center(true); + theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg); + + Ref<StyleBoxFlat> bg_color; + bg_color.instance(); + bg_color->set_bg_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); + bg_color->set_border_width_all(0); + + Ref<StyleBoxFlat> bg_color_selected; + bg_color_selected.instance(); + bg_color_selected->set_border_width_all(0); + bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8)); + + theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color); + theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected); + } + + theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); + theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE); + + Ref<StyleBoxFlat> style_property_bg = style_default->duplicate(); + style_property_bg->set_bg_color(highlight_color); + style_property_bg->set_border_width_all(0); + + theme->set_constant("font_offset", "EditorProperty", 1 * EDSCALE); + theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); + theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); + theme->set_color("error_color", "EditorProperty", error_color); + theme->set_color("property_color", "EditorProperty", property_color); - theme->set_stylebox("sub_inspector_bg", "Editor", sub_inspector_bg); theme->set_constant("inspector_margin", "Editor", 8 * EDSCALE); // Tree & ItemList background @@ -753,9 +816,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("custom_button", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_hover", "Tree", style_widget); - theme->set_color("custom_button_font_highlight", "Tree", font_color_hl); + theme->set_color("custom_button_font_highlight", "Tree", font_hover_color); theme->set_color("font_color", "Tree", font_color); - theme->set_color("font_color_selected", "Tree", mono_color); + theme->set_color("font_selected_color", "Tree", mono_color); theme->set_color("title_button_color", "Tree", font_color); theme->set_color("guide_color", "Tree", guide_color); theme->set_color("relationship_line_color", "Tree", relationship_line_color); @@ -826,7 +889,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("bg_focus", "ItemList", style_focus); theme->set_stylebox("bg", "ItemList", style_itemlist_bg); theme->set_color("font_color", "ItemList", font_color); - theme->set_color("font_color_selected", "ItemList", mono_color); + theme->set_color("font_selected_color", "ItemList", mono_color); theme->set_color("guide_color", "ItemList", guide_color); theme->set_constant("vseparation", "ItemList", 3 * EDSCALE); theme->set_constant("hseparation", "ItemList", 3 * EDSCALE); @@ -834,16 +897,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); // Tabs & TabContainer - theme->set_stylebox("tab_fg", "TabContainer", style_tab_selected); - theme->set_stylebox("tab_bg", "TabContainer", style_tab_unselected); + theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); + theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); - theme->set_stylebox("tab_fg", "Tabs", style_tab_selected); - theme->set_stylebox("tab_bg", "Tabs", style_tab_unselected); + theme->set_stylebox("tab_selected", "Tabs", style_tab_selected); + theme->set_stylebox("tab_unselected", "Tabs", style_tab_unselected); theme->set_stylebox("tab_disabled", "Tabs", style_tab_disabled); - theme->set_color("font_color_fg", "TabContainer", font_color); - theme->set_color("font_color_bg", "TabContainer", font_color_disabled); - theme->set_color("font_color_fg", "Tabs", font_color); - theme->set_color("font_color_bg", "Tabs", font_color_disabled); + theme->set_color("font_selected_color", "TabContainer", font_color); + theme->set_color("font_unselected_color", "TabContainer", font_disabled_color); + theme->set_color("font_selected_color", "Tabs", font_color); + theme->set_color("font_unselected_color", "Tabs", font_disabled_color); theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons")); theme->set_icon("menu_highlight", "TabContainer", theme->get_icon("GuiTabMenuHl", "EditorIcons")); theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected); @@ -891,7 +954,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger); Ref<StyleBoxFlat> style_panel_invisible_top = style_content_panel->duplicate(); - int stylebox_offset = theme->get_font("tab_fg", "TabContainer")->get_height(theme->get_font_size("tab_fg", "TabContainer")) + theme->get_stylebox("tab_fg", "TabContainer")->get_minimum_size().height + theme->get_stylebox("panel", "TabContainer")->get_default_margin(SIDE_TOP); + int stylebox_offset = theme->get_font("tab_selected", "TabContainer")->get_height(theme->get_font_size("tab_selected", "TabContainer")) + theme->get_stylebox("tab_selected", "TabContainer")->get_minimum_size().height + theme->get_stylebox("panel", "TabContainer")->get_default_margin(SIDE_TOP); style_panel_invisible_top->set_expand_margin_size(SIDE_TOP, -stylebox_offset); style_panel_invisible_top->set_default_margin(SIDE_TOP, 0); theme->set_stylebox("BottomPanelDebuggerOverride", "EditorStyles", style_panel_invisible_top); @@ -901,11 +964,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("focus", "LineEdit", style_widget_focus); theme->set_stylebox("read_only", "LineEdit", style_widget_disabled); theme->set_icon("clear", "LineEdit", theme->get_icon("GuiClose", "EditorIcons")); - theme->set_color("read_only", "LineEdit", font_color_disabled); + theme->set_color("read_only", "LineEdit", font_disabled_color); theme->set_color("font_color", "LineEdit", font_color); - theme->set_color("font_color_selected", "LineEdit", mono_color); + theme->set_color("font_selected_color", "LineEdit", mono_color); theme->set_color("cursor_color", "LineEdit", font_color); - theme->set_color("selection_color", "LineEdit", font_color_selection); + theme->set_color("selection_color", "LineEdit", selection_color); theme->set_color("clear_button_color", "LineEdit", font_color); theme->set_color("clear_button_color_pressed", "LineEdit", accent_color); @@ -918,7 +981,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("space", "TextEdit", theme->get_icon("GuiSpace", "EditorIcons")); theme->set_color("font_color", "TextEdit", font_color); theme->set_color("caret_color", "TextEdit", font_color); - theme->set_color("selection_color", "TextEdit", font_color_selection); + theme->set_color("selection_color", "TextEdit", selection_color); // CodeEdit theme->set_stylebox("normal", "CodeEdit", style_widget); @@ -932,7 +995,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("executing_line", "CodeEdit", theme->get_icon("MainPlay", "EditorIcons")); theme->set_color("font_color", "CodeEdit", font_color); theme->set_color("caret_color", "CodeEdit", font_color); - theme->set_color("selection_color", "CodeEdit", font_color_selection); + theme->set_color("selection_color", "CodeEdit", selection_color); // H/VSplitContainer theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("GuiVsplitBg", "EditorIcons"), 1, 1, 1, 1)); @@ -1023,7 +1086,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { //RichTextLabel theme->set_color("default_color", "RichTextLabel", font_color); - theme->set_color("font_color_shadow", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE); theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE); theme->set_constant("shadow_as_outline", "RichTextLabel", 0 * EDSCALE); @@ -1039,7 +1102,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Label theme->set_stylebox("normal", "Label", style_empty); theme->set_color("font_color", "Label", font_color); - theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0)); + theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE); theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE); theme->set_constant("shadow_as_outline", "Label", 0 * EDSCALE); @@ -1048,9 +1111,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // LinkButton theme->set_stylebox("focus", "LinkButton", style_empty); theme->set_color("font_color", "LinkButton", font_color); - theme->set_color("font_color_hover", "LinkButton", font_color_hl); - theme->set_color("font_color_pressed", "LinkButton", accent_color); - theme->set_color("font_color_disabled", "LinkButton", font_color_disabled); + theme->set_color("font_hover_color", "LinkButton", font_hover_color); + theme->set_color("font_pressed_color", "LinkButton", accent_color); + theme->set_color("font_disabled_color", "LinkButton", font_disabled_color); // TooltipPanel Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate(); @@ -1063,7 +1126,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tooltip->set_border_width_all(border_width); style_tooltip->set_border_color(mono_color); theme->set_color("font_color", "TooltipLabel", font_color.inverted()); - theme->set_color("font_color_shadow", "TooltipLabel", mono_color.inverted() * Color(1, 1, 1, 0.1)); + theme->set_color("font_shadow_color", "TooltipLabel", mono_color.inverted() * Color(1, 1, 1, 0.1)); theme->set_stylebox("panel", "TooltipPanel", style_tooltip); // PopupPanel @@ -1098,7 +1161,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("bezier_len_neg", "GraphEdit", 160 * EDSCALE); // GraphEditMinimap - theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(dark_color_1, 0, 0, 0, 0)); + Ref<StyleBoxFlat> style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); + style_minimap_bg->set_border_color(dark_color_3); + style_minimap_bg->set_border_width_all(1); + theme->set_stylebox("bg", "GraphEditMinimap", style_minimap_bg); + Ref<StyleBoxFlat> style_minimap_camera; Ref<StyleBoxFlat> style_minimap_node; if (dark_theme) { @@ -1115,9 +1182,15 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node); - Ref<Texture2D> resizer_icon = theme->get_icon("GuiResizer", "EditorIcons"); - theme->set_icon("resizer", "GraphEditMinimap", flip_icon(resizer_icon, true, true)); - theme->set_color("resizer_color", "GraphEditMinimap", Color(1, 1, 1, 0.65)); + Ref<Texture2D> minimap_resizer_icon = theme->get_icon("GuiResizer", "EditorIcons"); + Color minimap_resizer_color; + if (dark_theme) { + minimap_resizer_color = Color(1, 1, 1, 0.65); + } else { + minimap_resizer_color = Color(0, 0, 0, 0.65); + } + theme->set_icon("resizer", "GraphEditMinimap", flip_icon(minimap_resizer_icon, true, true)); + theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color); // GraphNode const float mv = dark_theme ? 0.0 : 1.0; @@ -1198,7 +1271,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Use a different color for folder icons to make them easier to distinguish from files. // On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color. theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7)); - theme->set_color("files_disabled", "FileDialog", font_color_disabled); + theme->set_color("files_disabled", "FileDialog", font_disabled_color); // color picker theme->set_constant("margin", "ColorPicker", popup_margin_size); @@ -1251,7 +1324,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color caret_color = mono_color; const Color caret_background_color = mono_color.inverted(); const Color text_selected_color = dark_color_3; - const Color selection_color = accent_color * Color(1, 1, 1, 0.35); const Color brace_mismatch_color = error_color; const Color current_line_color = alpha1; const Color line_length_guideline_color = dark_theme ? base_color : background_color; diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index 02bbeb57c7..07edae833d 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -43,7 +43,7 @@ void EditorFileServer::_close_client(ClientData *cd) { cd->connection->disconnect_from_host(); { MutexLock lock(cd->efs->wait_mutex); - cd->efs->to_wait.insert(cd->thread); + cd->efs->to_wait.insert(&cd->thread); } while (cd->files.size()) { memdelete(cd->files.front()->get()); @@ -278,7 +278,7 @@ void EditorFileServer::_thread_start(void *s) { cd->connection = self->server->take_connection(); cd->efs = self; cd->quit = false; - cd->thread = Thread::create(_subthread_start, cd); + cd->thread.start(_subthread_start, cd); } } @@ -287,8 +287,7 @@ void EditorFileServer::_thread_start(void *s) { Thread *w = self->to_wait.front()->get(); self->to_wait.erase(w); self->wait_mutex.unlock(); - Thread::wait_to_finish(w); - memdelete(w); + w->wait_to_finish(); self->wait_mutex.lock(); } self->wait_mutex.unlock(); @@ -317,7 +316,7 @@ EditorFileServer::EditorFileServer() { quit = false; active = false; cmd = CMD_NONE; - thread = Thread::create(_thread_start, this); + thread.start(_thread_start, this); EDITOR_DEF("filesystem/file_server/port", 6010); EDITOR_DEF("filesystem/file_server/password", ""); @@ -325,6 +324,5 @@ EditorFileServer::EditorFileServer() { EditorFileServer::~EditorFileServer() { quit = true; - Thread::wait_to_finish(thread); - memdelete(thread); + thread.wait_to_finish(); } diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index 267b129bda..e4c8327d76 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -47,7 +47,7 @@ class EditorFileServer : public Object { }; struct ClientData { - Thread *thread = nullptr; + Thread thread; Ref<StreamPeerTCP> connection; Map<int, FileAccess *> files; EditorFileServer *efs = nullptr; @@ -61,7 +61,7 @@ class EditorFileServer : public Object { static void _subthread_start(void *s); Mutex wait_mutex; - Thread *thread; + Thread thread; static void _thread_start(void *); bool quit; Command cmd; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index e8cf081320..ab5fd30998 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -76,6 +76,9 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory subdirectory_item->set_metadata(0, lpath); if (!p_select_in_favorites && (path == lpath || ((display_mode == DISPLAY_MODE_SPLIT) && path.get_base_dir() == lpath))) { subdirectory_item->select(0); + // Keep select an item when re-created a tree + // To prevent crashing when nothing is selected. + subdirectory_item->set_as_cursor(0); } if (p_unfold_path && path.begins_with(lpath) && path != lpath) { @@ -1407,10 +1410,28 @@ void FileSystemDock::_make_scene_confirm() { void FileSystemDock::_file_removed(String p_file) { emit_signal("file_removed", p_file); + + // Find the closest parent directory available, in case multiple items were deleted along the same path. + path = p_file.get_base_dir(); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (!da->dir_exists(path)) { + path = path.get_base_dir(); + } + + current_path->set_text(path); } void FileSystemDock::_folder_removed(String p_folder) { emit_signal("folder_removed", p_folder); + + // Find the closest parent directory available, in case multiple items were deleted along the same path. + path = p_folder.get_base_dir(); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (!da->dir_exists(path)) { + path = path.get_base_dir(); + } + + current_path->set_text(path); } void FileSystemDock::_rename_operation_confirm() { @@ -1465,6 +1486,9 @@ void FileSystemDock::_rename_operation_confirm() { print_verbose("FileSystem: saving moved scenes."); _save_scenes_after_move(file_renames); + + path = new_path; + current_path->set_text(path); } void FileSystemDock::_duplicate_operation_confirm() { @@ -1573,6 +1597,9 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_ove print_verbose("FileSystem: saving moved scenes."); _save_scenes_after_move(file_renames); + + path = p_to_path; + current_path->set_text(path); } } diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index c2f2254023..47079a92b7 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -463,7 +463,7 @@ void FindInFilesDialog::_notification(int p_what) { for (int i = 0; i < _filters_container->get_child_count(); i++) { _filters_container->get_child(i)->queue_delete(); } - Array exts = ProjectSettings::get_singleton()->get("editor/search_in_file_extensions"); + Array exts = ProjectSettings::get_singleton()->get("editor/script/search_in_file_extensions"); for (int i = 0; i < exts.size(); ++i) { CheckBox *cb = memnew(CheckBox); cb->set_text(exts[i]); @@ -687,6 +687,9 @@ void FindInFilesPanel::stop_search() { void FindInFilesPanel::_notification(int p_what) { if (p_what == NOTIFICATION_PROCESS) { _progress_bar->set_as_ratio(_finder->get_progress()); + } else if (p_what == NOTIFICATION_THEME_CHANGED) { + _search_text_label->add_theme_font_override("font", get_theme_font("source", "EditorFonts")); + _results_display->add_theme_font_override("font", get_theme_font("source", "EditorFonts")); } } diff --git a/editor/icons/GPUParticlesAttractorBox.svg b/editor/icons/GPUParticlesAttractorBox.svg new file mode 100644 index 0000000000..3c27b2d3cb --- /dev/null +++ b/editor/icons/GPUParticlesAttractorBox.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fc9c9c" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc9c9c" stroke-opacity=".996078"><ellipse cx="8" cy="-8" rx="2.339226" ry="4.949748" transform="rotate(90)"/><ellipse cx="8" cy="8" rx="2.339226" ry="4.949748"/><path d="m1.498906 1.498906h13.002189v13.002188h-13.002189z" stroke-width=".997813"/></g></svg> diff --git a/editor/icons/GPUParticlesAttractorSphere.svg b/editor/icons/GPUParticlesAttractorSphere.svg new file mode 100644 index 0000000000..5473a23854 --- /dev/null +++ b/editor/icons/GPUParticlesAttractorSphere.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-8" cy="-7.999999" fill="none" rx="6.499003" ry="6.499001" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.002" transform="scale(-1)"/><circle cx="8" cy="8" fill="#fc9c9c" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc9c9c" stroke-opacity=".996078"><ellipse cx="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 .70710678 -.70710678 .70710678 0 0)"/><ellipse cy="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 0)"/></g></svg> diff --git a/editor/icons/GPUParticlesAttractorVectorField.svg b/editor/icons/GPUParticlesAttractorVectorField.svg new file mode 100644 index 0000000000..93a29789e3 --- /dev/null +++ b/editor/icons/GPUParticlesAttractorVectorField.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="6.663637" cy="9.245457" fill="#fc9c9c" fill-opacity=".996078" rx="1.030661" ry=".998146"/><ellipse cx="-6.672815" cy="-9.387111" fill="none" rx="2.408711" ry="5.096776" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.99999945 .00104887 .00104887 -.99999945 0 0)"/><ellipse cx="9.387111" cy="-6.672815" fill="none" rx="2.408711" ry="5.096776" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.00104887 .99999945 -.99999945 .00104887 0 0)"/><g fill="#fc9c9c" fill-opacity=".996078"><path d="m11.8 15 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/><path d="m11 6 3-3 1 1v-3h-3l1 1-3 3z"/><path d="m1.8 5 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionBox.svg b/editor/icons/GPUParticlesCollisionBox.svg new file mode 100644 index 0000000000..f7296b34c3 --- /dev/null +++ b/editor/icons/GPUParticlesCollisionBox.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" fill-opacity=".996078"><path d="m7.5 2.8124998-5.5883107 2.7941554v5.7660988l5.5883107 2.794155 5.588311-2.794155v-5.7660988zm0 1.6886278 3.145021 1.5732692-3.145021 1.5717523-3.1450214-1.5717523zm-3.9916505 2.8362274 3.1933204 1.5966602v3.1465378l-3.1933204-1.598256zm7.9833015 0v3.145021l-3.1933209 1.598257v-3.146538z" stroke-width=".851579"/><circle cx="1.875" cy="3.75" r=".9375"/><circle cx="13.124999" cy="3.75" r=".9375"/><circle cx="9.374999" cy="1.875" r=".9375"/><circle cx="5.625" cy="1.875" r=".9375"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionHeightField.svg b/editor/icons/GPUParticlesCollisionHeightField.svg new file mode 100644 index 0000000000..b483f299e9 --- /dev/null +++ b/editor/icons/GPUParticlesCollisionHeightField.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c"><path d="m1 10c1-1 3-2 3-4s2-4 4-4 4 2 4 4 2 3 3 4l-7 5z"/><circle cx="2" cy="6" r="1"/><circle cx="14" cy="6" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="4" cy="2" r="1"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionSDF.svg b/editor/icons/GPUParticlesCollisionSDF.svg new file mode 100644 index 0000000000..6279990f3a --- /dev/null +++ b/editor/icons/GPUParticlesCollisionSDF.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 14h-12v-9s3 4 5.9999999 3.9999999c3.0000001-.0000001 6.0000001-3.9999999 6.0000001-3.9999999z" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".996078" stroke-width="2"/><g fill="#fc9c9c" fill-opacity=".996078"><circle cx="2" cy="2" r="1"/><circle cx="14" cy="2" r="1"/><circle cx="10" cy="5" r="1"/><circle cx="6" cy="5" r="1"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionSphere.svg b/editor/icons/GPUParticlesCollisionSphere.svg new file mode 100644 index 0000000000..fc7715445c --- /dev/null +++ b/editor/icons/GPUParticlesCollisionSphere.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" fill-opacity=".996078"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg> diff --git a/editor/icons/Logo.svg b/editor/icons/Logo.svg index d7aef39cc9..a4ad488396 100644 --- a/editor/icons/Logo.svg +++ b/editor/icons/Logo.svg @@ -1 +1 @@ -<svg height="69" viewBox="0 0 187 69" width="187" xmlns="http://www.w3.org/2000/svg"><path d="m91.912 19.51c-3.5233 0-6.278 1.1097-8.2676 3.3281-1.9911 2.2193-2.9844 5.1004-2.9844 8.6465 0 4.1636 1.0165 7.3207 3.0508 9.4707 2.0379 2.1497 4.7123 3.2227 8.0293 3.2227 1.7838 0 3.3686-.15384 4.752-.46289 1.3848-.30784 2.3038-.62367 2.7617-.94336l.13867-10.736c0-.62388-1.6471-.90785-3.4941-.93945-1.847-.02857-3.9609.35742-3.9609.35742v3.6055h2.125l-.023438 1.6055c0 .59532-.59062.89453-1.7676.89453-1.1785 0-2.2182-.4989-3.1211-1.4941-.90498-.99645-1.3555-2.4517-1.3555-4.3711 0-1.9233.43964-3.3428 1.3203-4.2578.87885-.9141 2.0322-1.3711 3.4492-1.3711.59532 0 1.2107.095008 1.8516.29102.64121.19418 1.0686.37639 1.2871.54688.21667.17534.42435.25781.61914.25781.19388 0 .50715-.22698.94141-.68555.43487-.45735.82427-1.1501 1.168-2.0742.34218-.92899.51367-1.6414.51367-2.1465 0-.50111-.011023-.84501-.033203-1.0273-.48045-.52573-1.3668-.94394-2.6602-1.2539-1.2909-.30906-2.7387-.46289-4.3398-.46289zm21.049 0c-3.2367 0-5.8788 1.0413-7.9258 3.1211-2.0464 2.0826-3.0703 5.1404-3.0703 9.1797 0 4.0369 1.0128 7.1085 3.0352 9.2129 2.0251 2.1026 4.6444 3.1543 7.8574 3.1543 3.2145 0 5.8383-1.0111 7.875-3.0332 2.0367-2.0263 3.0527-5.1142 3.0527-9.2656 0-4.1484-.99433-7.2508-2.9863-9.2969-1.9884-2.05-4.6018-3.0723-7.8379-3.0723zm45.504 0c-3.2379 0-5.8792 1.0413-7.9277 3.1211-2.0461 2.0826-3.0684 5.1404-3.0684 9.1797 0 4.0369 1.0104 7.1085 3.0352 9.2129 2.0233 2.1026 4.6432 3.1543 7.8574 3.1543 3.213 0 5.8373-1.0111 7.873-3.0332 2.0364-2.0263 3.0547-5.1142 3.0547-9.2656 0-4.1484-.9939-7.2508-2.9844-9.2969-1.9908-2.05-4.6031-3.0723-7.8398-3.0723zm-30.105.30859c-.45888 0-.82988.16637-1.1152.49609-.28717.33489-.42969.78715-.42969 1.3594v20.584c0 1.053.58624 1.5781 1.752 1.5781h5.8652c7.1824-.000001 10.773-4.2092 10.773-12.627 0-3.9348-.94335-6.8151-2.832-8.6445-1.8853-1.83-4.6472-2.7461-8.2832-2.7461h-5.7305zm42.807 0c-.38928 0-.66468.52801-.82422 1.5801-.0687.50294-.10157 1.0191-.10157 1.543 0 .52694.03287 1.0409.10157 1.543.15954 1.0548.43494 1.5801.82422 1.5801h4.1152v17.225c0 .45462 1.1351.68555 3.3984.68555 2.2655 0 3.3965-.23093 3.3965-.68555v-17.225h4.0137c.38868 0 .66225-.52528.82422-1.5801.0672-.50202.10156-1.016.10156-1.543.00001-.52391-.03436-1.04-.10156-1.543-.16197-1.0521-.43554-1.5801-.82422-1.5801h-14.924zm-58.291 6.2793c1.0989 0 2.0193.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.35955 3.2363-1.0801 4.2188-.72053.98612-1.6597 1.4785-2.8145 1.4785-1.1554 0-2.0859-.48441-2.7949-1.459-.71019-.97154-1.0644-2.3663-1.0644-4.1875 0-1.8173.37148-3.2302 1.1133-4.2363.74574-1.0053 1.6663-1.5098 2.7637-1.5098zm45.504 0c1.0989 0 2.0181.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.3612 3.2363-1.082 4.2188-.71961.98612-1.6574 1.4785-2.8125 1.4785-1.1554 0-2.0888-.48441-2.7969-1.459-.70806-.97154-1.0625-2.3663-1.0625-4.1875 0-1.8173.37179-3.2302 1.1133-4.2363.74453-1.0053 1.666-1.5098 2.7637-1.5098zm-24.977.23828h.34375c1.4638 0 2.5334.33466 3.209.99805.6722.66157 1.0098 2.0859 1.0098 4.2715 0 2.1847-.32289 3.7447-.97656 4.6816-.65214.9378-1.6059 1.4082-2.8652 1.4082-.34218 0-.54909-.063339-.61719-.18945-.06873-.12672-.10352-.42897-.10352-.9082v-10.262z" fill="#fff"/><path d="m137.91 48.551v1.2109h.85938v-1.2109zm-52.396.58984c-.99736 0-1.7963.32424-2.3926.96484-.59745.64576-.89453 1.5712-.89453 2.7773v3.0742c0 1.2329.31639 2.1765.94727 2.832.6333.66066 1.467.98828 2.5039.98828.78586 0 1.4321-.16147 1.9414-.48633.50993-.32273.8592-.67938 1.0488-1.0684v-3.6875h-3.0059v.74805h2.1465v2.6934c-.13766.30115-.38143.55386-.73242.76172-.34978.2109-.8171.31445-1.3984.31445-.79619 0-1.4265-.2632-1.8945-.78711-.46799-.52786-.70312-1.2936-.70312-2.2988v-3.0918c0-.96941.21778-1.7078.65234-2.2168.43578-.51023 1.0297-.76367 1.7812-.76367.74271 0 1.3056.19019 1.6836.56641.38017.37925.58276.91542.61133 1.6113h.79492l.013672-.041016c-.024311-.90802-.30456-1.6179-.83789-2.127-.53484-.50719-1.2907-.76367-2.2656-.76367zm7.6133 2.6641c-.719 0-1.3111.22524-1.7715.67773-.46222.45371-.68069.96571-.6582 1.5449l.013672.041015.79688.007813c0-.42696.14768-.78487.44336-1.0781.2966-.29508.67455-.44141 1.1328-.44141.4926 0 .87459.15388 1.1523.45898.27198.30906.41016.73655.41016 1.2793v.94531h-1.3418c-.85666 0-1.5379.21084-2.0391.63477-.50142.42392-.75195.99502-.75195 1.707 0 .67372.17358 1.2075.51758 1.6035.34613.39445.83497.5918 1.4707.5918.45462 0 .86723-.12355 1.2383-.37305.37166-.24767.67317-.56424.90625-.94531 0 .17413.01089.34527.03125.51758.02097.16927.053163.38614.095703.65234h.88867c-.062302-.24767-.10234-.49621-.12695-.75391-.02401-.25436-.037109-.52051-.037109-.79492v-3.7676c0-.80622-.21809-1.4265-.65234-1.8613-.43669-.43061-1.0083-.64648-1.7188-.64648zm7.1152 0c-.45462 0-.85109.11505-1.1875.3457-.33519.23369-.60486.56357-.80664.99023l-.074219-1.1934h-.75195v7.6816h.85352v-5.5293c.11791-.47346.31244-.84655.58594-1.1191.27168-.27107.63379-.4082 1.082-.4082.4689 0 .83314.19466 1.0957.58789.26378.39323.39258 1.0508.39258 1.9707v4.498h.85351v-4.6211-.19922c.0623-.64455.23396-1.1785.51172-1.6055.27927-.42696.66855-.63672 1.166-.63672.47285 0 .83879.19223 1.0938.57422.25345.38138.38281 1.0443.38281 1.9863v4.502h.85742v-4.4863c0-1.1332-.18468-1.9728-.55664-2.5195-.37044-.54548-.89268-.81836-1.5664-.81836-.48897 0-.91182.1465-1.2598.43945-.34796.29234-.61537.69589-.80469 1.207-.148-.55369-.38151-.966-.69726-1.2383-.31543-.2732-.70589-.4082-1.1699-.4082zm10.316 0c-.74423-.000001-1.3797.32125-1.9082.96094-.52725.64273-.78906 1.4505-.78906 2.4199v1.2754c0 .96758.26259 1.762.7871 2.3828.52604.62206 1.2032.93359 2.0312.93359.5157 0 .95833-.090281 1.3242-.26562.36679-.17626.66658-.41287.89844-.70703l-.34961-.60547c-.21728.27441-.4784.4836-.7832.63281-.3048.14586-.66987.2207-1.0898.2207-.60443 0-1.0864-.24489-1.4414-.74023-.35433-.49412-.53321-1.1138-.53321-1.8574v-.63867h4.3965v-.84375c0-.96667-.22381-1.7371-.66992-2.3105-.44519-.57253-1.0684-.85742-1.873-.85742zm9.4727 0c-.74423-.000001-1.3782.32125-1.9082.96094-.52603.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26241 1.762.78906 2.3828.52512.62206 1.2028.93359 2.0312.93359.51601 0 .95639-.090281 1.3223-.26562.36741-.17626.66822-.41287.90039-.70703l-.34766-.60547c-.21972.27441-.4811.4836-.78711.63281-.30389.14586-.66639.2207-1.0879.2207-.60656 0-1.0883-.24489-1.4414-.74023-.35646-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3945v-.84375c0-.96667-.22338-1.7371-.66797-2.3105-.44398-.57253-1.0699-.85742-1.873-.85742zm6.8672 0c-.45614 0-.85274.12451-1.1894.36914-.33975.24342-.60962.5923-.81445 1.043l-.07031-1.2695h-.76172v7.6816h.85351v-5.4824c.14617-.47923.36569-.85918.66016-1.1445.29325-.28809.65767-.42969 1.0938-.42969.48622 0 .85922.17765 1.1133.5332.25557.35555.38477.96807.38477 1.8457v4.6777h.85937v-4.6855c0-1.0736-.18381-1.866-.55273-2.375-.36497-.50993-.89-.76367-1.5762-.76367zm6.2539 0c-.77674 0-1.386.32888-1.8242.98437-.44186.65883-.66211 1.5326-.66211 2.6211l.00196 1.0508c0 1.0031.21834 1.8072.65625 2.4102.43699.60413 1.0429.90625 1.8144.90625.41602 0 .78387-.091234 1.0996-.27539.31695-.18324.58484-.4491.80273-.79492v.92969c0 .75881-.14785 1.3303-.4414 1.7266-.29235.39111-.74301.58789-1.3535.58789-.30359 0-.59763-.04082-.88086-.125-.28565-.081443-.54279-.19619-.77344-.3457l-.23632.74805c.27047.15164.57916.27315.92773.36523.34795.092075.67388.13867.97656.13867.84208 0 1.494-.27297 1.9531-.81055.45857-.53971.68554-1.3009.68554-2.2852v-7.6895h-.72265l-.08399 1.0684c-.21485-.38533-.48269-.68758-.80664-.89453-.32334-.2109-.70159-.31641-1.1328-.31641zm10.467 0c-.45401 0-.85062.12451-1.1895.36914-.33914.24342-.60902.5923-.81445 1.043l-.07031-1.2695h-.75977v7.6816h.85352v-5.4824c.14556-.47923.3663-.85918.66016-1.1445.29295-.28809.65797-.42969 1.0937-.42969.48775 0 .85711.17765 1.1133.5332.25496.35555.38476.96807.38476 1.8457v4.6777h.85742v-4.6855c0-1.0736-.18081-1.866-.54882-2.375-.36588-.50993-.8939-.76367-1.5801-.76367zm6.4043 0c-.74271-.000001-1.3778.32125-1.9062.96094-.52724.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26334 1.762.78906 2.3828.52361.62206 1.2007.93359 2.0312.93359.5154 0 .9567-.090281 1.3223-.26562.3668-.17626.6667-.41287.90039-.70703l-.34961-.60547c-.2194.27441-.47958.4836-.78711.63281-.30359.14586-.66597.2207-1.0859.2207-.60717 0-1.089-.24489-1.4434-.74023-.35464-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3965v-.84375c0-.96667-.22369-1.7371-.66797-2.3105-.44551-.57253-1.0709-.85742-1.875-.85742zm-12.113.14258v7.6816h.85938v-7.6816zm-27.352.60938c.53029 0 .9445.20789 1.2441.62695.29781.41876.44531.94616.44531 1.5801v.33008h-3.543c.01429-.71688.19281-1.3186.53711-1.8066.34401-.48622.78217-.73047 1.3164-.73047zm9.4727 0c.52998 0 .94406.20789 1.2422.62695.29963.41876.44727.94616.44727 1.5801v.33008h-3.543c.0155-.71688.19298-1.3186.53516-1.8066.3437-.48622.7826-.73047 1.3184-.73047zm29.992 0c.53089 0 .94602.20789 1.2441.62695.29902.41876.44532.94616.44532 1.5801v.33008h-3.543c.01519-.71688.19402-1.3186.53711-1.8066.34218-.48622.78064-.73047 1.3164-.73047zm-16.686.015625c.42119 0 .77033.1246 1.0469.375.27684.25466.4967.58706.65625.99609v3.8047c-.16593.39718-.39.70872-.67383.93359-.28475.22488-.63089.33594-1.043.33594-.6014 0-1.0536-.22975-1.3496-.69531-.29964-.4613-.44727-1.0819-.44727-1.8613v-1.0508c0-.84177.15149-1.527.45508-2.0527.30146-.52482.75528-.78516 1.3555-.78516zm-40.057 3.3281h1.3652v1.6621c-.15286.42089-.40964.76752-.77734 1.041-.3671.27228-.78783.40625-1.2598.40625-.39262 0-.69782-.12824-.91602-.38867-.2185-.25952-.32617-.59591-.32617-1.0059 0-.48531.17262-.89402.52148-1.2207.34795-.32881.81215-.49414 1.3926-.49414z" fill="#e0e0e0"/><path d="m27 3c-3.0948.68801-6.1571 1.6452-9.0273 3.0898.06564 2.5344.23035 4.963.5625 7.4297-1.1147.71414-2.287 1.3281-3.3281 2.1641-1.0578.81382-2.1378 1.5912-3.0957 2.543-1.9136-1.2657-3.9389-2.454-6.0254-3.5039-2.2491 2.4205-4.3524 5.0317-6.0703 7.9551 1.2924 2.0908 2.6428 4.0523 4.0996 5.9121h.041016v14.438 1.834 1.6699c.03282.000304.06514.000806.097656.003906l11 1.0605c.57617.05561 1.0282.52027 1.0684 1.0977l.33789 4.8555 9.5957.68359.66016-4.4805c.0857-.58104.58415-1.0117 1.1719-1.0117h11.605c.58742 0 1.0862.43068 1.1719 1.0117l.66016 4.4805 9.5957-.68359.33789-4.8555c.04042-.57739.49219-1.0417 1.0684-1.0977l10.996-1.0605c.032519-.003.064836-.003606.097656-.003906v-1.4316l.003906-.001953v-16.508h.041016c1.4571-1.8598 2.8066-3.8214 4.0996-5.9121-1.7173-2.9234-3.8232-5.5346-6.0723-7.9551-2.0859 1.0499-4.1118 2.2382-6.0254 3.5039-.95756-.95178-2.0363-1.7292-3.0957-2.543-1.0408-.836-2.2136-1.4499-3.3262-2.1641.33124-2.4667.49656-4.8952.5625-7.4297-2.8706-1.4447-5.933-2.4018-9.0293-3.0898-1.2362 2.0777-2.367 4.3278-3.3516 6.5273-1.1675-.1951-2.3391-.26727-3.5137-.28125v-.0019532c-.0082 0-.016447.0019531-.023437.0019532-.0073 0-.014194-.0019532-.021484-.0019532v.0019532c-1.1767.013979-2.3497.086153-3.5176.28125-.98399-2.1996-2.1135-4.4497-3.3516-6.5273zm-22.863 45.904c.0045599 1.063.019531 2.2271.019531 2.459 0 10.446 13.251 15.468 29.715 15.525h.019531.019531c16.464-.05774 29.711-5.0795 29.711-15.525 0-.23612.014661-1.3954.019531-2.459l-9.8867.95312-.3418 4.8809c-.04102.58833-.50933 1.0574-1.0977 1.0996l-11.717.83594c-.02857.0021-.055724.003906-.083984.003906-.58225 0-1.0859-.42704-1.1719-1.0117l-.67188-4.5566h-9.5586l-.67188 4.5566c-.09025.61325-.63836 1.0531-1.2559 1.0078l-11.717-.83594c-.58833-.04224-1.0566-.51128-1.0977-1.0996l-.3418-4.8809-9.8906-.95312z" fill="#478cbf"/><path d="m18.299 29.246c-3.6594 0-6.6289 2.9669-6.6289 6.627 0 3.6625 2.9695 6.6289 6.6289 6.6289 3.6613 0 6.627-2.9664 6.627-6.6289 0-3.66-2.9657-6.627-6.627-6.627zm31.186 0c-3.6619 0-6.6289 2.9669-6.6289 6.627 0 3.6625 2.967 6.6289 6.6289 6.6289 3.6591 0 6.627-2.9664 6.627-6.6289 0-3.66-2.9678-6.627-6.627-6.627zm-15.594 3.8789c-1.1785 0-2.1348.86781-2.1348 1.9375v6.1035c0 1.0706.95628 1.9395 2.1348 1.9395s2.1348-.86885 2.1348-1.9395v-6.1035c0-1.0697-.95628-1.9375-2.1348-1.9375z" fill="#f6f6f6"/><path d="m18.932 31.865c-2.4299 0-4.4004 1.9711-4.4004 4.4004s1.9705 4.3984 4.4004 4.3984c2.4311 0 4.4004-1.9691 4.4004-4.3984s-1.9693-4.4004-4.4004-4.4004zm29.916 0c-2.4293 0-4.3984 1.9711-4.3984 4.4004s1.9691 4.3984 4.3984 4.3984c2.4317 0 4.4004-1.9691 4.4004-4.3984s-1.9687-4.4004-4.4004-4.4004z" fill="#414042"/></svg> +<svg height="69" viewBox="0 0 187 69" width="187" xmlns="http://www.w3.org/2000/svg"><path d="m91.912 19.51c-3.5233 0-6.278 1.1097-8.2676 3.3281-1.9911 2.2193-2.9844 5.1004-2.9844 8.6465 0 4.1636 1.0165 7.3207 3.0508 9.4707 2.0379 2.1497 4.7123 3.2227 8.0293 3.2227 1.7838 0 3.3686-.15384 4.752-.46289 1.3848-.30784 2.3038-.62367 2.7617-.94336l.13867-10.736c0-.62388-1.6471-.90785-3.4941-.93945-1.847-.02857-3.9609.35742-3.9609.35742v3.6055h2.125l-.023438 1.6055c0 .59532-.59062.89453-1.7676.89453-1.1785 0-2.2182-.4989-3.1211-1.4941-.90498-.99645-1.3555-2.4517-1.3555-4.3711 0-1.9233.43964-3.3428 1.3203-4.2578.87885-.9141 2.0322-1.3711 3.4492-1.3711.59532 0 1.2107.095008 1.8516.29102.64121.19418 1.0686.37639 1.2871.54688.21667.17534.42435.25781.61914.25781.19388 0 .50715-.22698.94141-.68555.43487-.45735.82427-1.1501 1.168-2.0742.34218-.92899.51367-1.6414.51367-2.1465 0-.50111-.011023-.84501-.033203-1.0273-.48045-.52573-1.3668-.94394-2.6602-1.2539-1.2909-.30906-2.7387-.46289-4.3398-.46289zm21.049 0c-3.2367 0-5.8788 1.0413-7.9258 3.1211-2.0464 2.0826-3.0703 5.1404-3.0703 9.1797 0 4.0369 1.0128 7.1085 3.0352 9.2129 2.0251 2.1026 4.6444 3.1543 7.8574 3.1543 3.2145 0 5.8383-1.0111 7.875-3.0332 2.0367-2.0263 3.0527-5.1142 3.0527-9.2656 0-4.1484-.99433-7.2508-2.9863-9.2969-1.9884-2.05-4.6018-3.0723-7.8379-3.0723zm45.504 0c-3.2379 0-5.8792 1.0413-7.9277 3.1211-2.0461 2.0826-3.0684 5.1404-3.0684 9.1797 0 4.0369 1.0104 7.1085 3.0352 9.2129 2.0233 2.1026 4.6432 3.1543 7.8574 3.1543 3.213 0 5.8373-1.0111 7.873-3.0332 2.0364-2.0263 3.0547-5.1142 3.0547-9.2656 0-4.1484-.9939-7.2508-2.9844-9.2969-1.9908-2.05-4.6031-3.0723-7.8398-3.0723zm-30.105.30859c-.45888 0-.82988.16637-1.1152.49609-.28717.33489-.42969.78715-.42969 1.3594v20.584c0 1.053.58624 1.5781 1.752 1.5781h5.8652c7.1824-.000001 10.773-4.2092 10.773-12.627 0-3.9348-.94335-6.8151-2.832-8.6445-1.8853-1.83-4.6472-2.7461-8.2832-2.7461h-5.7305zm42.807 0c-.38928 0-.66468.52801-.82422 1.5801-.0687.50294-.10157 1.0191-.10157 1.543 0 .52694.03287 1.0409.10157 1.543.15954 1.0548.43494 1.5801.82422 1.5801h4.1152v17.225c0 .45462 1.1351.68555 3.3984.68555 2.2655 0 3.3965-.23093 3.3965-.68555v-17.225h4.0137c.38868 0 .66225-.52528.82422-1.5801.0672-.50202.10156-1.016.10156-1.543.00001-.52391-.03436-1.04-.10156-1.543-.16197-1.0521-.43554-1.5801-.82422-1.5801h-14.924zm-58.291 6.2793c1.0989 0 2.0193.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.35955 3.2363-1.0801 4.2188-.72053.98612-1.6597 1.4785-2.8145 1.4785-1.1554 0-2.0859-.48441-2.7949-1.459-.71019-.97154-1.0644-2.3663-1.0644-4.1875 0-1.8173.37148-3.2302 1.1133-4.2363.74574-1.0053 1.6663-1.5098 2.7637-1.5098zm45.504 0c1.0989 0 2.0181.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.3612 3.2363-1.082 4.2188-.71961.98612-1.6574 1.4785-2.8125 1.4785-1.1554 0-2.0888-.48441-2.7969-1.459-.70806-.97154-1.0625-2.3663-1.0625-4.1875 0-1.8173.37179-3.2302 1.1133-4.2363.74453-1.0053 1.666-1.5098 2.7637-1.5098zm-24.977.23828h.34375c1.4638 0 2.5334.33466 3.209.99805.6722.66157 1.0098 2.0859 1.0098 4.2715 0 2.1847-.32289 3.7447-.97656 4.6816-.65214.9378-1.6059 1.4082-2.8652 1.4082-.34218 0-.54909-.063339-.61719-.18945-.06873-.12672-.10352-.42897-.10352-.9082v-10.262z" fill="#fff"/><path d="m137.91 48.551v1.2109h.85938v-1.2109zm-52.396.58984c-.99736 0-1.7963.32424-2.3926.96484-.59745.64576-.89453 1.5712-.89453 2.7773v3.0742c0 1.2329.31639 2.1765.94727 2.832.6333.66066 1.467.98828 2.5039.98828.78586 0 1.4321-.16147 1.9414-.48633.50993-.32273.8592-.67938 1.0488-1.0684v-3.6875h-3.0059v.74805h2.1465v2.6934c-.13766.30115-.38143.55386-.73242.76172-.34978.2109-.8171.31445-1.3984.31445-.79619 0-1.4265-.2632-1.8945-.78711-.46799-.52786-.70312-1.2936-.70312-2.2988v-3.0918c0-.96941.21778-1.7078.65234-2.2168.43578-.51023 1.0297-.76367 1.7812-.76367.74271 0 1.3056.19019 1.6836.56641.38017.37925.58276.91542.61133 1.6113h.79492l.013672-.041016c-.024311-.90802-.30456-1.6179-.83789-2.127-.53484-.50719-1.2907-.76367-2.2656-.76367zm7.6133 2.6641c-.719 0-1.3111.22524-1.7715.67773-.46222.45371-.68069.96571-.6582 1.5449l.013672.041015.79688.007813c0-.42696.14768-.78487.44336-1.0781.2966-.29508.67455-.44141 1.1328-.44141.4926 0 .87459.15388 1.1523.45898.27198.30906.41016.73655.41016 1.2793v.94531h-1.3418c-.85666 0-1.5379.21084-2.0391.63477-.50142.42392-.75195.99502-.75195 1.707 0 .67372.17358 1.2075.51758 1.6035.34613.39445.83497.5918 1.4707.5918.45462 0 .86723-.12355 1.2383-.37305.37166-.24767.67317-.56424.90625-.94531 0 .17413.01089.34527.03125.51758.02097.16927.053163.38614.095703.65234h.88867c-.062302-.24767-.10234-.49621-.12695-.75391-.02401-.25436-.037109-.52051-.037109-.79492v-3.7676c0-.80622-.21809-1.4265-.65234-1.8613-.43669-.43061-1.0083-.64648-1.7188-.64648zm7.1152 0c-.45462 0-.85109.11505-1.1875.3457-.33519.23369-.60486.56357-.80664.99023l-.074219-1.1934h-.75195v7.6816h.85352v-5.5293c.11791-.47346.31244-.84655.58594-1.1191.27168-.27107.63379-.4082 1.082-.4082.4689 0 .83314.19466 1.0957.58789.26378.39323.39258 1.0508.39258 1.9707v4.498h.85351v-4.6211-.19922c.0623-.64455.23396-1.1785.51172-1.6055.27927-.42696.66855-.63672 1.166-.63672.47285 0 .83879.19223 1.0938.57422.25345.38138.38281 1.0443.38281 1.9863v4.502h.85742v-4.4863c0-1.1332-.18468-1.9728-.55664-2.5195-.37044-.54548-.89268-.81836-1.5664-.81836-.48897 0-.91182.1465-1.2598.43945-.34796.29234-.61537.69589-.80469 1.207-.148-.55369-.38151-.966-.69726-1.2383-.31543-.2732-.70589-.4082-1.1699-.4082zm10.316 0c-.74423-.000001-1.3797.32125-1.9082.96094-.52725.64273-.78906 1.4505-.78906 2.4199v1.2754c0 .96758.26259 1.762.7871 2.3828.52604.62206 1.2032.93359 2.0312.93359.5157 0 .95833-.090281 1.3242-.26562.36679-.17626.66658-.41287.89844-.70703l-.34961-.60547c-.21728.27441-.4784.4836-.7832.63281-.3048.14586-.66987.2207-1.0898.2207-.60443 0-1.0864-.24489-1.4414-.74023-.35433-.49412-.53321-1.1138-.53321-1.8574v-.63867h4.3965v-.84375c0-.96667-.22381-1.7371-.66992-2.3105-.44519-.57253-1.0684-.85742-1.873-.85742zm9.4727 0c-.74423-.000001-1.3782.32125-1.9082.96094-.52603.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26241 1.762.78906 2.3828.52512.62206 1.2028.93359 2.0312.93359.51601 0 .95639-.090281 1.3223-.26562.36741-.17626.66822-.41287.90039-.70703l-.34766-.60547c-.21972.27441-.4811.4836-.78711.63281-.30389.14586-.66639.2207-1.0879.2207-.60656 0-1.0883-.24489-1.4414-.74023-.35646-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3945v-.84375c0-.96667-.22338-1.7371-.66797-2.3105-.44398-.57253-1.0699-.85742-1.873-.85742zm6.8672 0c-.45614 0-.85274.12451-1.1894.36914-.33975.24342-.60962.5923-.81445 1.043l-.07031-1.2695h-.76172v7.6816h.85351v-5.4824c.14617-.47923.36569-.85918.66016-1.1445.29325-.28809.65767-.42969 1.0938-.42969.48622 0 .85922.17765 1.1133.5332.25557.35555.38477.96807.38477 1.8457v4.6777h.85937v-4.6855c0-1.0736-.18381-1.866-.55273-2.375-.36497-.50993-.89-.76367-1.5762-.76367zm6.2539 0c-.77674 0-1.386.32888-1.8242.98437-.44186.65883-.66211 1.5326-.66211 2.6211l.00196 1.0508c0 1.0031.21834 1.8072.65625 2.4102.43699.60413 1.0429.90625 1.8144.90625.41602 0 .78387-.091234 1.0996-.27539.31695-.18324.58484-.4491.80273-.79492v.92969c0 .75881-.14785 1.3303-.4414 1.7266-.29235.39111-.74301.58789-1.3535.58789-.30359 0-.59763-.04082-.88086-.125-.28565-.081443-.54279-.19619-.77344-.3457l-.23632.74805c.27047.15164.57916.27315.92773.36523.34795.092075.67388.13867.97656.13867.84208 0 1.494-.27297 1.9531-.81055.45857-.53971.68554-1.3009.68554-2.2852v-7.6895h-.72265l-.08399 1.0684c-.21485-.38533-.48269-.68758-.80664-.89453-.32334-.2109-.70159-.31641-1.1328-.31641zm10.467 0c-.45401 0-.85062.12451-1.1895.36914-.33914.24342-.60902.5923-.81445 1.043l-.07031-1.2695h-.75977v7.6816h.85352v-5.4824c.14556-.47923.3663-.85918.66016-1.1445.29295-.28809.65797-.42969 1.0937-.42969.48775 0 .85711.17765 1.1133.5332.25496.35555.38476.96807.38476 1.8457v4.6777h.85742v-4.6855c0-1.0736-.18081-1.866-.54882-2.375-.36588-.50993-.8939-.76367-1.5801-.76367zm6.4043 0c-.74271-.000001-1.3778.32125-1.9062.96094-.52724.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26334 1.762.78906 2.3828.52361.62206 1.2007.93359 2.0312.93359.5154 0 .9567-.090281 1.3223-.26562.3668-.17626.6667-.41287.90039-.70703l-.34961-.60547c-.2194.27441-.47958.4836-.78711.63281-.30359.14586-.66597.2207-1.0859.2207-.60717 0-1.089-.24489-1.4434-.74023-.35464-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3965v-.84375c0-.96667-.22369-1.7371-.66797-2.3105-.44551-.57253-1.0709-.85742-1.875-.85742zm-12.113.14258v7.6816h.85938v-7.6816zm-27.352.60938c.53029 0 .9445.20789 1.2441.62695.29781.41876.44531.94616.44531 1.5801v.33008h-3.543c.01429-.71688.19281-1.3186.53711-1.8066.34401-.48622.78217-.73047 1.3164-.73047zm9.4727 0c.52998 0 .94406.20789 1.2422.62695.29963.41876.44727.94616.44727 1.5801v.33008h-3.543c.0155-.71688.19298-1.3186.53516-1.8066.3437-.48622.7826-.73047 1.3184-.73047zm29.992 0c.53089 0 .94602.20789 1.2441.62695.29902.41876.44532.94616.44532 1.5801v.33008h-3.543c.01519-.71688.19402-1.3186.53711-1.8066.34218-.48622.78064-.73047 1.3164-.73047zm-16.686.015625c.42119 0 .77033.1246 1.0469.375.27684.25466.4967.58706.65625.99609v3.8047c-.16593.39718-.39.70872-.67383.93359-.28475.22488-.63089.33594-1.043.33594-.6014 0-1.0536-.22975-1.3496-.69531-.29964-.4613-.44727-1.0819-.44727-1.8613v-1.0508c0-.84177.15149-1.527.45508-2.0527.30146-.52482.75528-.78516 1.3555-.78516zm-40.057 3.3281h1.3652v1.6621c-.15286.42089-.40964.76752-.77734 1.041-.3671.27228-.78783.40625-1.2598.40625-.39262 0-.69782-.12824-.91602-.38867-.2185-.25952-.32617-.59591-.32617-1.0059 0-.48531.17262-.89402.52148-1.2207.34795-.32881.81215-.49414 1.3926-.49414z" fill="#e0e0e0"/><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 63.620953 46.532114)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(.30389749 0 0 -.30389749 4.154146 28.589689)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(.30389749 0 0 -.30389749 53.752732 49.859089)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 24.925648 35.87311)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(.30389749 0 0 -.30389749 23.330605 36.266305)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 33.889273 43.105751)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 42.854008 35.87311)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(.30389749 0 0 -.30389749 44.449454 36.266305)"/></svg> diff --git a/editor/icons/NodeDisabled.svg b/editor/icons/NodeDisabled.svg new file mode 100644 index 0000000000..b2d51fc4fb --- /dev/null +++ b/editor/icons/NodeDisabled.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#999"/></svg> diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp index 63b614e436..e38034dd8c 100644 --- a/editor/import/collada.cpp +++ b/editor/import/collada.cpp @@ -289,7 +289,7 @@ void Collada::_parse_image(XMLParser &parser) { String path = parser.get_attribute_value("source").strip_edges(); if (path.find("://") == -1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path - image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path.percent_decode())); + image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path.uri_decode())); } } else { while (parser.read() == OK) { @@ -298,7 +298,7 @@ void Collada::_parse_image(XMLParser &parser) { if (name == "init_from") { parser.read(); - String path = parser.get_node_data().strip_edges().percent_decode(); + String path = parser.get_node_data().strip_edges().uri_decode(); if (path.find("://") == -1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index 3139ef5146..6d2215c379 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -391,8 +391,8 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const bool ok_on_pc = false; bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995); bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565); - bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc"); - bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc"); + bool can_bptc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc"); + bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc"); if (can_bptc) { formats_imported.push_back("bptc"); //needs to be aded anyway @@ -447,13 +447,13 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const ok_on_pc = true; } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { + if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2")) { _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true); r_platform_variants->push_back("etc2"); formats_imported.push_back("etc2"); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { + if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) { _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true); r_platform_variants->push_back("pvrtc"); formats_imported.push_back("pvrtc"); @@ -492,7 +492,7 @@ String ResourceImporterLayeredTexture::get_import_settings_string() const { int index = 0; while (compression_formats[index]) { - String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); bool test = ProjectSettings::get_singleton()->get(setting_path); if (test) { s += String(compression_formats[index]); @@ -524,7 +524,7 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p int index = 0; bool valid = true; while (compression_formats[index]) { - String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); bool test = ProjectSettings::get_singleton()->get(setting_path); if (test) { if (formats_imported.find(compression_formats[index]) == -1) { diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index ead1f7c3e9..d0e5798045 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -964,7 +964,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String if (FileAccess::exists(ext_name) && p_keep_animations) { // Copy custom animation tracks from previously imported files. - Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", true); + Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE); if (old_anim.is_valid()) { for (int i = 0; i < old_anim->get_track_count(); i++) { if (!old_anim->track_is_imported(i)) { @@ -1004,7 +1004,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String p_materials[mat] = ResourceLoader::load(ext_name); } else { ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache. + p_materials[mat] = ResourceLoader::load(ext_name, "", ResourceFormatLoader::CACHE_MODE_IGNORE); // disable loading from the cache. } } @@ -1061,7 +1061,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String p_materials[mat] = ResourceLoader::load(ext_name); } else { ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache. + p_materials[mat] = ResourceLoader::load(ext_name, "", ResourceFormatLoader::CACHE_MODE_IGNORE); // disable loading from the cache. } } @@ -1129,6 +1129,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.mesh),Files (.tres)"), meshes_out ? 1 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Enable,Gen Lightmaps", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true)); @@ -1221,7 +1222,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito return importer->import_animation(p_path, p_flags, p_bake_fps); } -void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods) { +void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods, bool p_create_shadow_meshes) { EditorSceneImporterMeshNode3D *src_mesh_node = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node); if (src_mesh_node) { //is mesh @@ -1237,8 +1238,12 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods) if (p_generate_lods) { src_mesh_node->get_mesh()->generate_lods(); } + if (p_create_shadow_meshes) { + src_mesh_node->get_mesh()->create_shadow_mesh(); + } } mesh = src_mesh_node->get_mesh()->get_mesh(); + if (mesh.is_valid()) { mesh_node->set_mesh(mesh); for (int i = 0; i < mesh->get_surface_count(); i++) { @@ -1252,7 +1257,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods) } for (int i = 0; i < p_node->get_child_count(); i++) { - _generate_meshes(p_node->get_child(i), p_generate_lods); + _generate_meshes(p_node->get_child(i), p_generate_lods, p_create_shadow_meshes); } } Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { @@ -1348,8 +1353,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } bool gen_lods = bool(p_options["meshes/generate_lods"]); + bool create_shadow_meshes = bool(p_options["meshes/create_shadow_meshes"]); - _generate_meshes(scene, gen_lods); + _generate_meshes(scene, gen_lods, create_shadow_meshes); err = OK; diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 66c317f858..aced0226ff 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -121,7 +121,7 @@ class ResourceImporterScene : public ResourceImporter { }; void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner); - void _generate_meshes(Node *p_node, bool p_generate_lods); + void _generate_meshes(Node *p_node, bool p_generate_lods, bool p_create_shadow_meshes); public: static ResourceImporterScene *get_singleton() { return singleton; } diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index eb16e873e6..de8031af35 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -172,7 +172,7 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_option, cons if (compress_mode < COMPRESS_VRAM_COMPRESSED) { return false; } - if (!ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) { + if (!ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc")) { return false; } } @@ -473,8 +473,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String bool ok_on_pc = false; bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995); bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565); - bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc"); - bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc"); + bool can_bptc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc"); + bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc"); if (can_bptc) { //add to the list anyway @@ -524,19 +524,19 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String ok_on_pc = true; } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { + if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2")) { _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("etc2"); formats_imported.push_back("etc2"); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { + if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc")) { _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("etc"); formats_imported.push_back("etc"); } - if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { + if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) { _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC1_4, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("pvrtc"); formats_imported.push_back("pvrtc"); @@ -574,7 +574,7 @@ String ResourceImporterTexture::get_import_settings_string() const { int index = 0; while (compression_formats[index]) { - String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); bool test = ProjectSettings::get_singleton()->get(setting_path); if (test) { s += String(compression_formats[index]); @@ -606,7 +606,7 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co int index = 0; bool valid = true; while (compression_formats[index]) { - String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); bool test = ProjectSettings::get_singleton()->get(setting_path); if (test) { if (formats_imported.find(compression_formats[index]) == -1) { diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index cd7d58c6f6..46eb4e4fdc 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -140,6 +140,12 @@ void EditorSceneImporterMesh::generate_lods() { if (!SurfaceTool::simplify_func) { return; } + if (!SurfaceTool::simplify_scale_func) { + return; + } + if (!SurfaceTool::simplify_sloppy_func) { + return; + } for (int i = 0; i < surfaces.size(); i++) { if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) { @@ -157,20 +163,52 @@ void EditorSceneImporterMesh::generate_lods() { int min_indices = 10; int index_target = indices.size() / 2; - print_line("total: " + itos(indices.size())); + print_line("Total indices: " + itos(indices.size())); + float mesh_scale = SurfaceTool::simplify_scale_func((const float *)vertices_ptr, vertex_count, sizeof(Vector3)); + const float target_error = 1e-3f; + float abs_target_error = target_error / mesh_scale; while (index_target > min_indices) { float error; Vector<int> new_indices; new_indices.resize(indices.size()); - size_t new_len = SurfaceTool::simplify_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, 1e20, &error); - print_line("shoot for " + itos(index_target) + ", got " + itos(new_len) + " distance " + rtos(error)); + size_t new_len = SurfaceTool::simplify_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, abs_target_error, &error); if ((int)new_len > (index_target * 120 / 100)) { + // Attribute discontinuities break normals. + bool is_sloppy = false; + if (is_sloppy) { + abs_target_error = target_error / mesh_scale; + index_target = new_len; + while (index_target > min_indices) { + Vector<int> sloppy_new_indices; + sloppy_new_indices.resize(indices.size()); + new_len = SurfaceTool::simplify_sloppy_func((unsigned int *)sloppy_new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, abs_target_error, &error); + if ((int)new_len > (index_target * 120 / 100)) { + break; // 20 percent tolerance + } + sloppy_new_indices.resize(new_len); + Surface::LOD lod; + lod.distance = error * mesh_scale; + abs_target_error = lod.distance; + if (Math::is_equal_approx(abs_target_error, 0.0f)) { + return; + } + lod.indices = sloppy_new_indices; + print_line("Lod " + itos(surfaces.write[i].lods.size()) + " shoot for " + itos(index_target / 3) + " triangles, got " + itos(new_len / 3) + " triangles. Distance " + rtos(lod.distance) + ". Use simplify sloppy."); + surfaces.write[i].lods.push_back(lod); + index_target /= 2; + } + } break; // 20 percent tolerance } new_indices.resize(new_len); Surface::LOD lod; - lod.distance = error; + lod.distance = error * mesh_scale; + abs_target_error = lod.distance; + if (Math::is_equal_approx(abs_target_error, 0.0f)) { + return; + } lod.indices = new_indices; + print_line("Lod " + itos(surfaces.write[i].lods.size()) + " shoot for " + itos(index_target / 3) + " triangles, got " + itos(new_len / 3) + " triangles. Distance " + rtos(lod.distance)); surfaces.write[i].lods.push_back(lod); index_target /= 2; } @@ -212,6 +250,11 @@ Ref<ArrayMesh> EditorSceneImporterMesh::get_mesh() { mesh->surface_set_name(mesh->get_surface_count() - 1, surfaces[i].name); } } + + if (shadow_mesh.is_valid()) { + Ref<ArrayMesh> shadow = shadow_mesh->get_mesh(); + mesh->set_shadow_mesh(shadow); + } } return mesh; @@ -223,6 +266,103 @@ void EditorSceneImporterMesh::clear() { mesh.unref(); } +void EditorSceneImporterMesh::create_shadow_mesh() { + if (shadow_mesh.is_valid()) { + shadow_mesh.unref(); + } + + //no shadow mesh for blendshapes + if (blend_shapes.size() > 0) { + return; + } + //no shadow mesh for skeletons + for (int i = 0; i < surfaces.size(); i++) { + if (surfaces[i].arrays[RS::ARRAY_BONES].get_type() != Variant::NIL) { + return; + } + if (surfaces[i].arrays[RS::ARRAY_WEIGHTS].get_type() != Variant::NIL) { + return; + } + } + + shadow_mesh.instance(); + + for (int i = 0; i < surfaces.size(); i++) { + LocalVector<int> vertex_remap; + Vector<Vector3> new_vertices; + Vector<Vector3> vertices = surfaces[i].arrays[RS::ARRAY_VERTEX]; + int vertex_count = vertices.size(); + { + Map<Vector3, int> unique_vertices; + const Vector3 *vptr = vertices.ptr(); + for (int j = 0; j < vertex_count; j++) { + Vector3 v = vptr[j]; + + Map<Vector3, int>::Element *E = unique_vertices.find(v); + + if (E) { + vertex_remap.push_back(E->get()); + } else { + int vcount = unique_vertices.size(); + unique_vertices[v] = vcount; + vertex_remap.push_back(vcount); + new_vertices.push_back(v); + } + } + } + + Array new_surface; + new_surface.resize(RS::ARRAY_MAX); + Dictionary lods; + + // print_line("original vertex count: " + itos(vertices.size()) + " new vertex count: " + itos(new_vertices.size())); + + new_surface[RS::ARRAY_VERTEX] = new_vertices; + + Vector<int> indices = surfaces[i].arrays[RS::ARRAY_INDEX]; + if (indices.size()) { + int index_count = indices.size(); + const int *index_rptr = indices.ptr(); + Vector<int> new_indices; + new_indices.resize(indices.size()); + int *index_wptr = new_indices.ptrw(); + + for (int j = 0; j < index_count; j++) { + int index = index_rptr[j]; + ERR_FAIL_INDEX(index, vertex_count); + index_wptr[j] = vertex_remap[index]; + } + + new_surface[RS::ARRAY_INDEX] = new_indices; + + // Make sure the same LODs as the full version are used. + // This makes it more coherent between rendered model and its shadows. + for (int j = 0; j < surfaces[i].lods.size(); j++) { + indices = surfaces[i].lods[j].indices; + + index_count = indices.size(); + index_rptr = indices.ptr(); + new_indices.resize(indices.size()); + index_wptr = new_indices.ptrw(); + + for (int k = 0; k < index_count; k++) { + int index = index_rptr[j]; + ERR_FAIL_INDEX(index, vertex_count); + index_wptr[j] = vertex_remap[index]; + } + + lods[surfaces[i].lods[j].distance] = new_indices; + } + } + + shadow_mesh->add_surface(surfaces[i].primitive, new_surface, Array(), lods, Ref<Material>(), surfaces[i].name); + } +} + +Ref<EditorSceneImporterMesh> EditorSceneImporterMesh::get_shadow_mesh() const { + return shadow_mesh; +} + void EditorSceneImporterMesh::_set_data(const Dictionary &p_data) { clear(); if (p_data.has("blend_shape_names")) { @@ -304,7 +444,7 @@ void EditorSceneImporterMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &EditorSceneImporterMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &EditorSceneImporterMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String())); ClassDB::bind_method(D_METHOD("get_surface_count"), &EditorSceneImporterMesh::get_surface_count); ClassDB::bind_method(D_METHOD("get_surface_primitive_type", "surface_idx"), &EditorSceneImporterMesh::get_surface_primitive_type); diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h index 2adeb76b6c..42507cbe8c 100644 --- a/editor/import/scene_importer_mesh.h +++ b/editor/import/scene_importer_mesh.h @@ -61,6 +61,8 @@ class EditorSceneImporterMesh : public Resource { Ref<ArrayMesh> mesh; + Ref<EditorSceneImporterMesh> shadow_mesh; + protected: void _set_data(const Dictionary &p_data); Dictionary _get_data() const; @@ -89,6 +91,9 @@ public: void generate_lods(); + void create_shadow_mesh(); + Ref<EditorSceneImporterMesh> get_shadow_mesh() const; + bool has_mesh() const; Ref<ArrayMesh> get_mesh(); void clear(); diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp new file mode 100644 index 0000000000..43b97eb910 --- /dev/null +++ b/editor/import_defaults_editor.cpp @@ -0,0 +1,216 @@ +/*************************************************************************/ +/* import_defaults_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "import_defaults_editor.h" + +class ImportDefaultsEditorSettings : public Object { + GDCLASS(ImportDefaultsEditorSettings, Object) + friend class ImportDefaultsEditor; + List<PropertyInfo> properties; + Map<StringName, Variant> values; + Map<StringName, Variant> default_values; + + Ref<ResourceImporter> importer; + +protected: + bool _set(const StringName &p_name, const Variant &p_value) { + if (values.has(p_name)) { + values[p_name] = p_value; + return true; + } else { + return false; + } + } + bool _get(const StringName &p_name, Variant &r_ret) const { + if (values.has(p_name)) { + r_ret = values[p_name]; + return true; + } else { + r_ret = Variant(); + return false; + } + } + void _get_property_list(List<PropertyInfo> *p_list) const { + if (importer.is_null()) { + return; + } + for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { + if (importer->get_option_visibility(E->get().name, values)) { + p_list->push_back(E->get()); + } + } + } +}; + +void ImportDefaultsEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_PREDELETE) { + inspector->edit(nullptr); + } +} + +void ImportDefaultsEditor::_reset() { + if (settings->importer.is_valid()) { + settings->values = settings->default_values; + settings->notify_property_list_changed(); + } +} + +void ImportDefaultsEditor::_save() { + if (settings->importer.is_valid()) { + Dictionary modified; + + for (Map<StringName, Variant>::Element *E = settings->values.front(); E; E = E->next()) { + if (E->get() != settings->default_values[E->key()]) { + modified[E->key()] = E->get(); + } + } + + if (modified.size()) { + ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), modified); + } else { + ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), Variant()); + } + + emit_signal("project_settings_changed"); + } +} + +void ImportDefaultsEditor::_update_importer() { + List<Ref<ResourceImporter>> importer_list; + ResourceFormatImporter::get_singleton()->get_importers(&importer_list); + Ref<ResourceImporter> importer; + for (List<Ref<ResourceImporter>>::Element *E = importer_list.front(); E; E = E->next()) { + if (E->get()->get_visible_name() == importers->get_item_text(importers->get_selected())) { + importer = E->get(); + break; + } + } + + settings->properties.clear(); + settings->values.clear(); + settings->importer = importer; + + if (importer.is_valid()) { + List<ResourceImporter::ImportOption> options; + importer->get_import_options(&options); + Dictionary d; + if (ProjectSettings::get_singleton()->has_setting("importer_defaults/" + importer->get_importer_name())) { + d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); + } + + for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { + settings->properties.push_back(E->get().option); + if (d.has(E->get().option.name)) { + settings->values[E->get().option.name] = d[E->get().option.name]; + } else { + settings->values[E->get().option.name] = E->get().default_value; + } + settings->default_values[E->get().option.name] = E->get().default_value; + } + + save_defaults->set_disabled(false); + reset_defaults->set_disabled(false); + + } else { + save_defaults->set_disabled(true); + reset_defaults->set_disabled(true); + } + + settings->notify_property_list_changed(); + + inspector->edit(settings); +} + +void ImportDefaultsEditor::_importer_selected(int p_index) { + _update_importer(); +} + +void ImportDefaultsEditor::clear() { + String last_selected; + if (importers->get_selected() > 0) { + last_selected = importers->get_item_text(importers->get_selected()); + } + + importers->clear(); + + importers->add_item("<" + TTR("Select Importer") + ">"); + importers->set_item_disabled(0, true); + + List<Ref<ResourceImporter>> importer_list; + ResourceFormatImporter::get_singleton()->get_importers(&importer_list); + Vector<String> names; + for (List<Ref<ResourceImporter>>::Element *E = importer_list.front(); E; E = E->next()) { + String vn = E->get()->get_visible_name(); + names.push_back(vn); + } + names.sort(); + + for (int i = 0; i < names.size(); i++) { + importers->add_item(names[i]); + + if (names[i] == last_selected) { + importers->select(i + 1); + } + } +} + +void ImportDefaultsEditor::_bind_methods() { + ADD_SIGNAL(MethodInfo("project_settings_changed")); +} + +ImportDefaultsEditor::ImportDefaultsEditor() { + HBoxContainer *hb = memnew(HBoxContainer); + hb->add_child(memnew(Label(TTR("Importer:")))); + importers = memnew(OptionButton); + hb->add_child(importers); + hb->add_spacer(); + importers->connect("item_selected", callable_mp(this, &ImportDefaultsEditor::_importer_selected)); + reset_defaults = memnew(Button); + reset_defaults->set_text(TTR("Reset to Defaults")); + reset_defaults->set_disabled(true); + reset_defaults->connect("pressed", callable_mp(this, &ImportDefaultsEditor::_reset)); + hb->add_child(reset_defaults); + add_child(hb); + inspector = memnew(EditorInspector); + add_child(inspector); + inspector->set_v_size_flags(SIZE_EXPAND_FILL); + CenterContainer *cc = memnew(CenterContainer); + save_defaults = memnew(Button); + save_defaults->set_text(TTR("Save")); + save_defaults->connect("pressed", callable_mp(this, &ImportDefaultsEditor::_save)); + cc->add_child(save_defaults); + add_child(cc); + + settings = memnew(ImportDefaultsEditorSettings); +} + +ImportDefaultsEditor::~ImportDefaultsEditor() { + memdelete(settings); +} diff --git a/editor/editor_sub_scene.h b/editor/import_defaults_editor.h index 428bd5a40e..c1becac5e9 100644 --- a/editor/editor_sub_scene.h +++ b/editor/import_defaults_editor.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* editor_sub_scene.h */ +/* import_defaults_editor.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,44 +28,48 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITOR_SUB_SCENE_H -#define EDITOR_SUB_SCENE_H +#ifndef IMPORT_DEFAULTS_EDITOR_H +#define IMPORT_DEFAULTS_EDITOR_H -#include "editor/editor_file_dialog.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/tree.h" +#include "core/object/undo_redo.h" +#include "editor/action_map_editor.h" +#include "editor/editor_data.h" +#include "editor/editor_plugin_settings.h" +#include "editor/editor_sectioned_inspector.h" +#include "editor/localization_editor.h" +#include "editor/shader_globals_editor.h" +#include "editor_autoload_settings.h" +#include "scene/gui/center_container.h" +#include "scene/gui/option_button.h" -class EditorSubScene : public ConfirmationDialog { - GDCLASS(EditorSubScene, ConfirmationDialog); +class ImportDefaultsEditorSettings; - List<Node *> selection; - LineEdit *path; - Tree *tree; - Node *scene; - bool is_root; +class ImportDefaultsEditor : public VBoxContainer { + GDCLASS(ImportDefaultsEditor, VBoxContainer) - EditorFileDialog *file_dialog; + OptionButton *importers; + Button *save_defaults; + Button *reset_defaults; - void _fill_tree(Node *p_node, TreeItem *p_parent); - void _selected_changed(); - void _item_multi_selected(Object *p_object, int p_cell, bool p_selected); - void _item_activated(); - void _remove_selection_child(Node *p_node); - void _reown(Node *p_node, List<Node *> *p_to_reown); + EditorInspector *inspector; - void ok_pressed() override; + ImportDefaultsEditorSettings *settings; + + void _update_importer(); + void _importer_selected(int p_index); + + void _reset(); + void _save(); protected: void _notification(int p_what); static void _bind_methods(); - void _path_browse(); - void _path_selected(const String &p_path); - void _path_changed(const String &p_path); public: - void move(Node *p_new_parent, Node *p_new_owner); void clear(); - EditorSubScene(); + + ImportDefaultsEditor(); + ~ImportDefaultsEditor(); }; -#endif // EDITOR_SUB_SCENE_H +#endif // IMPORT_DEFAULTS_EDITOR_H diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 103e5e81cb..97a04e6557 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -48,7 +48,7 @@ public: values[p_name] = p_value; if (checking) { checked.insert(p_name); - _change_notify(); + notify_property_list_changed(); } return true; } @@ -81,7 +81,7 @@ public: } void update() { - _change_notify(); + notify_property_list_changed(); } ImportDockParameters() { diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp deleted file mode 100644 index 9a5e7d164c..0000000000 --- a/editor/input_map_editor.cpp +++ /dev/null @@ -1,1033 +0,0 @@ -/*************************************************************************/ -/* input_map_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "input_map_editor.h" - -#include "core/input/input_map.h" -#include "core/os/keyboard.h" -#include "editor/editor_node.h" -#include "editor/editor_scale.h" - -void InputMapEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - action_add_error->add_theme_color_override("font_color", input_editor->get_theme_color("error_color", "Editor")); - popup_add->add_icon_item(input_editor->get_theme_icon("Keyboard", "EditorIcons"), TTR("Key"), INPUT_KEY); - popup_add->add_icon_item(input_editor->get_theme_icon("KeyboardPhysical", "EditorIcons"), TTR("Physical Key"), INPUT_KEY_PHYSICAL); - popup_add->add_icon_item(input_editor->get_theme_icon("JoyButton", "EditorIcons"), TTR("Joy Button"), INPUT_JOY_BUTTON); - popup_add->add_icon_item(input_editor->get_theme_icon("JoyAxis", "EditorIcons"), TTR("Joy Axis"), INPUT_JOY_MOTION); - popup_add->add_icon_item(input_editor->get_theme_icon("Mouse", "EditorIcons"), TTR("Mouse Button"), INPUT_MOUSE_BUTTON); - _update_actions(); - } break; - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - action_add_error->add_theme_color_override("font_color", input_editor->get_theme_color("error_color", "Editor")); - popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY), input_editor->get_theme_icon("Keyboard", "EditorIcons")); - popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY_PHYSICAL), input_editor->get_theme_icon("KeyboardPhysical", "EditorIcons")); - popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_BUTTON), input_editor->get_theme_icon("JoyButton", "EditorIcons")); - popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_MOTION), input_editor->get_theme_icon("JoyAxis", "EditorIcons")); - popup_add->set_item_icon(popup_add->get_item_index(INPUT_MOUSE_BUTTON), input_editor->get_theme_icon("Mouse", "EditorIcons")); - _update_actions(); - } break; - } -} - -static bool _validate_action_name(const String &p_name) { - const char32_t *cstr = p_name.get_data(); - for (int i = 0; cstr[i]; i++) { - if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' || - cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) { - return false; - } - } - return true; -} - -void InputMapEditor::_action_selected() { - TreeItem *ti = input_editor->get_selected(); - if (!ti || !ti->is_editable(0)) { - return; - } - - add_at = "input/" + ti->get_text(0); - edit_idx = -1; -} - -void InputMapEditor::_action_edited() { - TreeItem *ti = input_editor->get_selected(); - if (!ti) { - return; - } - - if (input_editor->get_selected_column() == 0) { - String new_name = ti->get_text(0); - String old_name = add_at.substr(add_at.find("/") + 1, add_at.length()); - - if (new_name == old_name) { - return; - } - - if (new_name == "" || !_validate_action_name(new_name)) { - ti->set_text(0, old_name); - add_at = "input/" + old_name; - - message->set_text(TTR("Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or '\"'")); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; - } - - String action_prop = "input/" + new_name; - - if (ProjectSettings::get_singleton()->has_setting(action_prop)) { - ti->set_text(0, old_name); - add_at = "input/" + old_name; - - message->set_text(vformat(TTR("An action with the name '%s' already exists."), new_name)); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; - } - - int order = ProjectSettings::get_singleton()->get_order(add_at); - Dictionary action = ProjectSettings::get_singleton()->get(add_at); - - setting = true; - undo_redo->create_action(TTR("Rename Input Action Event")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", add_at); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_prop, action); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", action_prop, order); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", action_prop); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", add_at, action); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", add_at, order); - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - setting = false; - - add_at = action_prop; - } else if (input_editor->get_selected_column() == 1) { - String name = "input/" + ti->get_text(0); - Dictionary old_action = ProjectSettings::get_singleton()->get(name); - Dictionary new_action = old_action.duplicate(); - new_action["deadzone"] = ti->get_range(1); - - undo_redo->create_action(TTR("Change Action deadzone")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, new_action); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_action); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - } -} - -void InputMapEditor::_device_input_add() { - Ref<InputEvent> ie; - String name = add_at; - int idx = edit_idx; - Dictionary old_val = ProjectSettings::get_singleton()->get(name); - Dictionary action = old_val.duplicate(); - Array events = action["events"]; - - switch (add_type) { - case INPUT_MOUSE_BUTTON: { - Ref<InputEventMouseButton> mb; - mb.instance(); - mb->set_button_index(device_index->get_selected() + 1); - mb->set_device(_get_current_device()); - - for (int i = 0; i < events.size(); i++) { - Ref<InputEventMouseButton> aie = events[i]; - if (aie.is_null()) { - continue; - } - if (aie->get_device() == mb->get_device() && aie->get_button_index() == mb->get_button_index()) { - return; - } - } - - ie = mb; - - } break; - case INPUT_JOY_MOTION: { - Ref<InputEventJoypadMotion> jm; - jm.instance(); - jm->set_axis(device_index->get_selected() >> 1); - jm->set_axis_value((device_index->get_selected() & 1) ? 1 : -1); - jm->set_device(_get_current_device()); - - for (int i = 0; i < events.size(); i++) { - Ref<InputEventJoypadMotion> aie = events[i]; - if (aie.is_null()) { - continue; - } - - if (aie->get_device() == jm->get_device() && aie->get_axis() == jm->get_axis() && aie->get_axis_value() == jm->get_axis_value()) { - return; - } - } - - ie = jm; - - } break; - case INPUT_JOY_BUTTON: { - Ref<InputEventJoypadButton> jb; - jb.instance(); - - jb->set_button_index(device_index->get_selected()); - jb->set_device(_get_current_device()); - - for (int i = 0; i < events.size(); i++) { - Ref<InputEventJoypadButton> aie = events[i]; - if (aie.is_null()) { - continue; - } - if (aie->get_device() == jb->get_device() && aie->get_button_index() == jb->get_button_index()) { - return; - } - } - ie = jb; - - } break; - default: { - } - } - - if (idx < 0 || idx >= events.size()) { - events.push_back(ie); - } else { - events[idx] = ie; - } - action["events"] = events; - - undo_redo->create_action(TTR("Add Input Action Event")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val); - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - - _show_last_added(ie, name); -} - -void InputMapEditor::_set_current_device(int i_device) { - device_id->select(i_device + 1); -} - -int InputMapEditor::_get_current_device() { - return device_id->get_selected() - 1; -} - -String InputMapEditor::_get_device_string(int i_device) { - if (i_device == InputMap::ALL_DEVICES) { - return TTR("All Devices"); - } - return TTR("Device") + " " + itos(i_device); -} - -void InputMapEditor::_press_a_key_confirm() { - if (last_wait_for_key.is_null()) { - return; - } - - Ref<InputEventKey> ie; - ie.instance(); - if (press_a_key_physical) { - ie->set_physical_keycode(last_wait_for_key->get_physical_keycode()); - ie->set_keycode(0); - } else { - ie->set_physical_keycode(0); - ie->set_keycode(last_wait_for_key->get_keycode()); - } - ie->set_shift(last_wait_for_key->get_shift()); - ie->set_alt(last_wait_for_key->get_alt()); - ie->set_control(last_wait_for_key->get_control()); - ie->set_metakey(last_wait_for_key->get_metakey()); - - String name = add_at; - int idx = edit_idx; - - Dictionary old_val = ProjectSettings::get_singleton()->get(name); - Dictionary action = old_val.duplicate(); - Array events = action["events"]; - - for (int i = 0; i < events.size(); i++) { - Ref<InputEventKey> aie = events[i]; - if (aie.is_null()) { - continue; - } - if (!press_a_key_physical) { - if (aie->get_keycode_with_modifiers() == ie->get_keycode_with_modifiers()) { - return; - } - } else { - if (aie->get_physical_keycode_with_modifiers() == ie->get_physical_keycode_with_modifiers()) { - return; - } - } - } - - if (idx < 0 || idx >= events.size()) { - events.push_back(ie); - } else { - events[idx] = ie; - } - action["events"] = events; - - undo_redo->create_action(TTR("Add Input Action Event")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val); - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - - _show_last_added(ie, name); -} - -void InputMapEditor::_show_last_added(const Ref<InputEvent> &p_event, const String &p_name) { - TreeItem *r = input_editor->get_root(); - - String name = p_name; - name.erase(0, 6); - if (!r) { - return; - } - r = r->get_children(); - if (!r) { - return; - } - bool found = false; - while (r) { - if (r->get_text(0) != name) { - r = r->get_next(); - continue; - } - TreeItem *child = r->get_children(); - while (child) { - Variant input = child->get_meta("__input"); - if (p_event == input) { - r->set_collapsed(false); - child->select(0); - found = true; - break; - } - child = child->get_next(); - } - if (found) { - break; - } - r = r->get_next(); - } - - if (found) { - input_editor->ensure_cursor_is_visible(); - } -} - -// Maps to 2*axis if value is neg, or + 1 if value is pos. -static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = { - TTRC("Left Stick Left, Joystick 0 Left"), - TTRC("Left Stick Right, Joystick 0 Right"), - TTRC("Left Stick Up, Joystick 0 Up"), - TTRC("Left Stick Down, Joystick 0 Down"), - TTRC("Right Stick Left, Joystick 1 Left"), - TTRC("Right Stick Right, Joystick 1 Right"), - TTRC("Right Stick Up, Joystick 1 Up"), - TTRC("Right Stick Down, Joystick 1 Down"), - TTRC("Joystick 2 Left"), - TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"), - TTRC("Joystick 2 Up"), - TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"), - TTRC("Joystick 3 Left"), - TTRC("Joystick 3 Right"), - TTRC("Joystick 3 Up"), - TTRC("Joystick 3 Down"), - TTRC("Joystick 4 Left"), - TTRC("Joystick 4 Right"), - TTRC("Joystick 4 Up"), - TTRC("Joystick 4 Down"), -}; - -// Separate from `InputEvent::as_text()` since the descriptions need to be different for the input map editor. See #43660. -String InputMapEditor::_get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event) { - ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEventJoypadMotion"); - - String desc = TTR("Unknown Joypad Axis"); - if (p_event->get_axis() < JOY_AXIS_MAX) { - desc = RTR(_joy_axis_descriptions[2 * p_event->get_axis() + (p_event->get_axis_value() < 0 ? 0 : 1)]); - } - - return vformat("Joypad Axis %s %s (%s)", itos(p_event->get_axis()), p_event->get_axis_value() < 0 ? "-" : "+", desc); -} - -void InputMapEditor::_wait_for_key(const Ref<InputEvent> &p_event) { - Ref<InputEventKey> k = p_event; - - if (k.is_valid() && k->is_pressed() && k->get_keycode() != 0) { - last_wait_for_key = p_event; - const String str = (press_a_key_physical) ? keycode_get_string(k->get_physical_keycode_with_modifiers()) + TTR(" (Physical)") : keycode_get_string(k->get_keycode_with_modifiers()); - - press_a_key_label->set_text(str); - press_a_key->get_ok_button()->set_disabled(false); - press_a_key->set_input_as_handled(); - } -} - -void InputMapEditor::_edit_item(Ref<InputEvent> p_exiting_event) { - InputType ie_type; - - if ((Ref<InputEventKey>(p_exiting_event)).is_valid()) { - if ((Ref<InputEventKey>(p_exiting_event))->get_keycode() != 0) { - ie_type = INPUT_KEY; - } else { - ie_type = INPUT_KEY_PHYSICAL; - } - } else if ((Ref<InputEventJoypadButton>(p_exiting_event)).is_valid()) { - ie_type = INPUT_JOY_BUTTON; - } else if ((Ref<InputEventMouseButton>(p_exiting_event)).is_valid()) { - ie_type = INPUT_MOUSE_BUTTON; - } else if ((Ref<InputEventJoypadMotion>(p_exiting_event)).is_valid()) { - ie_type = INPUT_JOY_MOTION; - } else { - return; - } - - _add_item(ie_type, p_exiting_event); -} - -void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) { - add_type = InputType(p_item); - - switch (add_type) { - case INPUT_KEY: { - press_a_key_physical = false; - press_a_key_label->set_text(TTR("Press a Key...")); - press_a_key->get_ok_button()->set_disabled(true); - last_wait_for_key = Ref<InputEvent>(); - press_a_key->popup_centered(Size2(250, 80) * EDSCALE); - //press_a_key->grab_focus(); - - } break; - case INPUT_KEY_PHYSICAL: { - press_a_key_physical = true; - press_a_key_label->set_text(TTR("Press a Key...")); - - last_wait_for_key = Ref<InputEvent>(); - press_a_key->popup_centered(Size2(250, 80) * EDSCALE); - press_a_key->grab_focus(); - - } break; - case INPUT_MOUSE_BUTTON: { - device_index_label->set_text(TTR("Mouse Button Index:")); - device_index->clear(); - device_index->add_item(TTR("Left Button")); - device_index->add_item(TTR("Right Button")); - device_index->add_item(TTR("Middle Button")); - device_index->add_item(TTR("Wheel Up Button")); - device_index->add_item(TTR("Wheel Down Button")); - device_index->add_item(TTR("Wheel Left Button")); - device_index->add_item(TTR("Wheel Right Button")); - device_index->add_item(TTR("X Button 1")); - device_index->add_item(TTR("X Button 2")); - device_input->popup_centered(Size2(350, 95) * EDSCALE); - - Ref<InputEventMouseButton> mb = p_exiting_event; - if (mb.is_valid()) { - device_index->select(mb->get_button_index() - 1); - _set_current_device(mb->get_device()); - device_input->get_ok_button()->set_text(TTR("Change")); - } else { - _set_current_device(0); - device_input->get_ok_button()->set_text(TTR("Add")); - } - - } break; - case INPUT_JOY_MOTION: { - device_index_label->set_text(TTR("Joypad Axis Index:")); - device_index->clear(); - for (int i = 0; i < JOY_AXIS_MAX * 2; i++) { - Ref<InputEventJoypadMotion> jm; - jm.instance(); - jm->set_axis(i / 2); - jm->set_axis_value((i & 1) ? 1 : -1); - device_index->add_item(_get_joypad_motion_event_text(jm)); - } - device_input->popup_centered(Size2(350, 95) * EDSCALE); - - Ref<InputEventJoypadMotion> jm = p_exiting_event; - if (jm.is_valid()) { - device_index->select(jm->get_axis() * 2 + (jm->get_axis_value() > 0 ? 1 : 0)); - _set_current_device(jm->get_device()); - device_input->get_ok_button()->set_text(TTR("Change")); - } else { - _set_current_device(0); - device_input->get_ok_button()->set_text(TTR("Add")); - } - - } break; - case INPUT_JOY_BUTTON: { - device_index_label->set_text(TTR("Joypad Button Index:")); - device_index->clear(); - for (int i = 0; i < JOY_BUTTON_MAX; i++) { - Ref<InputEventJoypadButton> jb; - jb.instance(); - jb->set_button_index(i); - device_index->add_item(jb->as_text()); - } - device_input->popup_centered(Size2(350, 95) * EDSCALE); - - Ref<InputEventJoypadButton> jb = p_exiting_event; - if (jb.is_valid()) { - device_index->select(jb->get_button_index()); - _set_current_device(jb->get_device()); - device_input->get_ok_button()->set_text(TTR("Change")); - } else { - _set_current_device(0); - device_input->get_ok_button()->set_text(TTR("Add")); - } - - } break; - default: { - } - } -} - -void InputMapEditor::_action_activated() { - TreeItem *ti = input_editor->get_selected(); - - if (!ti || ti->get_parent() == input_editor->get_root()) { - return; - } - - String name = "input/" + ti->get_parent()->get_text(0); - Dictionary action = ProjectSettings::get_singleton()->get(name); - Array events = action["events"]; - int idx = ti->get_metadata(0); - - ERR_FAIL_INDEX(idx, events.size()); - Ref<InputEvent> event = events[idx]; - if (event.is_null()) { - return; - } - - add_at = name; - edit_idx = idx; - _edit_item(event); -} - -void InputMapEditor::_action_button_pressed(Object *p_obj, int p_column, int p_id) { - TreeItem *ti = Object::cast_to<TreeItem>(p_obj); - - ERR_FAIL_COND(!ti); - - if (p_id == 1) { - // Add action event - Point2 ofs = input_editor->get_global_position(); - Rect2 ir = input_editor->get_item_rect(ti); - ir.position.y -= input_editor->get_scroll().y; - ofs += ir.position + ir.size; - ofs.x -= 100; - popup_add->set_position(ofs); - popup_add->popup(); - add_at = "input/" + ti->get_text(0); - edit_idx = -1; - - } else if (p_id == 2) { - // Remove - - if (ti->get_parent() == input_editor->get_root()) { - // Remove action - String name = "input/" + ti->get_text(0); - Dictionary old_val = ProjectSettings::get_singleton()->get(name); - int order = ProjectSettings::get_singleton()->get_order(name); - - undo_redo->create_action(TTR("Erase Input Action")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", name); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", name, order); - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - - } else { - // Remove action event - String name = "input/" + ti->get_parent()->get_text(0); - Dictionary old_val = ProjectSettings::get_singleton()->get(name); - Dictionary action = old_val.duplicate(); - int idx = ti->get_metadata(0); - - Array events = action["events"]; - ERR_FAIL_INDEX(idx, events.size()); - events.remove(idx); - action["events"] = events; - - undo_redo->create_action(TTR("Erase Input Action Event")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val); - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - } - } else if (p_id == 3) { - // Edit - - if (ti->get_parent() == input_editor->get_root()) { - // Edit action name - ti->set_as_cursor(0); - input_editor->edit_selected(); - - } else { - // Edit action event - String name = "input/" + ti->get_parent()->get_text(0); - int idx = ti->get_metadata(0); - Dictionary action = ProjectSettings::get_singleton()->get(name); - - Array events = action["events"]; - ERR_FAIL_INDEX(idx, events.size()); - - Ref<InputEvent> event = events[idx]; - - if (event.is_null()) { - return; - } - - ti->set_as_cursor(0); - add_at = name; - edit_idx = idx; - _edit_item(event); - } - } -} - -void InputMapEditor::_update_actions() { - if (setting) { - return; - } - - Map<String, bool> collapsed; - - if (input_editor->get_root() && input_editor->get_root()->get_children()) { - for (TreeItem *item = input_editor->get_root()->get_children(); item; item = item->get_next()) { - collapsed[item->get_text(0)] = item->is_collapsed(); - } - } - - input_editor->clear(); - TreeItem *root = input_editor->create_item(); - input_editor->set_hide_root(true); - - List<PropertyInfo> props; - ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - const String property_name = E->get().name; - - if (!property_name.begins_with("input/")) { - continue; - } - - const String name = property_name.get_slice("/", 1); - - TreeItem *item = input_editor->create_item(root); - item->set_text(0, name); - item->set_custom_bg_color(0, input_editor->get_theme_color("prop_subsection", "Editor")); - if (collapsed.has(name)) { - item->set_collapsed(collapsed[name]); - } - - item->set_editable(1, true); - item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE); - item->set_range_config(1, 0.0, 1.0, 0.01); - - item->set_custom_bg_color(1, input_editor->get_theme_color("prop_subsection", "Editor")); - - const bool is_builtin_input = ProjectSettings::get_singleton()->get_input_presets().find(property_name) != nullptr; - const String tooltip_remove = is_builtin_input ? TTR("Built-in actions can't be removed as they're used for UI navigation.") : TTR("Remove"); - item->add_button(2, input_editor->get_theme_icon("Add", "EditorIcons"), 1, false, TTR("Add Event")); - item->add_button(2, input_editor->get_theme_icon("Remove", "EditorIcons"), 2, false, tooltip_remove); - - if (is_builtin_input) { - item->set_button_disabled(2, 1, true); - } else { - item->set_editable(0, true); - } - - Dictionary action = ProjectSettings::get_singleton()->get(property_name); - Array events = action["events"]; - item->set_range(1, action["deadzone"]); - - for (int i = 0; i < events.size(); i++) { - Ref<InputEvent> event = events[i]; - if (event.is_null()) { - continue; - } - - TreeItem *action2 = input_editor->create_item(item); - - Ref<InputEventKey> k = event; - if (k.is_valid()) { - if (k->get_keycode() != 0) { - action2->set_text(0, keycode_get_string(k->get_keycode_with_modifiers())); - action2->set_icon(0, input_editor->get_theme_icon("Keyboard", "EditorIcons")); - } else { - action2->set_text(0, keycode_get_string(k->get_physical_keycode_with_modifiers()) + TTR(" (Physical)")); - action2->set_icon(0, input_editor->get_theme_icon("KeyboardPhysical", "EditorIcons")); - } - } - - Ref<InputEventJoypadButton> jb = event; - if (jb.is_valid()) { - action2->set_text(0, jb->as_text()); - action2->set_icon(0, input_editor->get_theme_icon("JoyButton", "EditorIcons")); - } - - Ref<InputEventMouseButton> mb = event; - if (mb.is_valid()) { - String str = _get_device_string(mb->get_device()) + ", "; - switch (mb->get_button_index()) { - case BUTTON_LEFT: - str += TTR("Left Button"); - break; - case BUTTON_RIGHT: - str += TTR("Right Button"); - break; - case BUTTON_MIDDLE: - str += TTR("Middle Button"); - break; - case BUTTON_WHEEL_UP: - str += TTR("Wheel Up"); - break; - case BUTTON_WHEEL_DOWN: - str += TTR("Wheel Down"); - break; - default: - str += vformat(TTR("%d Button"), mb->get_button_index()); - } - - action2->set_text(0, str); - action2->set_icon(0, input_editor->get_theme_icon("Mouse", "EditorIcons")); - } - - Ref<InputEventJoypadMotion> jm = event; - if (jm.is_valid()) { - device_index->add_item(_get_joypad_motion_event_text(jm)); - action2->set_text(0, jm->as_text()); - action2->set_icon(0, input_editor->get_theme_icon("JoyAxis", "EditorIcons")); - } - action2->set_metadata(0, i); - action2->set_meta("__input", event); - - action2->add_button(2, input_editor->get_theme_icon("Edit", "EditorIcons"), 3, false, TTR("Edit")); - action2->add_button(2, input_editor->get_theme_icon("Remove", "EditorIcons"), 2, false, TTR("Remove")); - // Fade out the individual event buttons slightly to make the - // Add/Remove buttons stand out more. - action2->set_button_color(2, 0, Color(1, 1, 1, 0.75)); - action2->set_button_color(2, 1, Color(1, 1, 1, 0.75)); - } - } - - _action_check(action_name->get_text()); -} - -void InputMapEditor::_action_check(String p_action) { - if (p_action == "") { - action_add->set_disabled(true); - } else { - if (!_validate_action_name(p_action)) { - action_add_error->set_text(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'.")); - action_add_error->show(); - action_add->set_disabled(true); - return; - } - if (ProjectSettings::get_singleton()->has_setting("input/" + p_action)) { - action_add_error->set_text(vformat(TTR("An action with the name '%s' already exists."), p_action)); - action_add_error->show(); - action_add->set_disabled(true); - return; - } - - action_add->set_disabled(false); - } - - action_add_error->hide(); -} - -void InputMapEditor::_action_adds(String) { - if (!action_add->is_disabled()) { - _action_add(); - } -} - -void InputMapEditor::_action_add() { - Dictionary action; - action["events"] = Array(); - action["deadzone"] = 0.5f; - String name = "input/" + action_name->get_text(); - undo_redo->create_action(TTR("Add Input Action")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); - - TreeItem *r = input_editor->get_root(); - - if (!r) { - return; - } - r = r->get_children(); - if (!r) { - return; - } - while (r->get_next()) { - r = r->get_next(); - } - - r->select(0); - input_editor->ensure_cursor_is_visible(); - action_add_error->hide(); - action_name->clear(); -} - -Variant InputMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { - TreeItem *selected = input_editor->get_selected(); - if (!selected || selected->get_parent() != input_editor->get_root()) { - return Variant(); - } - - String name = selected->get_text(0); - VBoxContainer *vb = memnew(VBoxContainer); - HBoxContainer *hb = memnew(HBoxContainer); - Label *label = memnew(Label(name)); - hb->set_modulate(Color(1, 1, 1, 1.0f)); - hb->add_child(label); - vb->add_child(hb); - input_editor->set_drag_preview(vb); - - Dictionary drag_data; - drag_data["type"] = "nodes"; - - input_editor->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); - - return drag_data; -} - -bool InputMapEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { - Dictionary d = p_data; - if (!d.has("type") || d["type"] != "nodes") { - return false; - } - - TreeItem *selected = input_editor->get_selected(); - TreeItem *item = input_editor->get_item_at_position(p_point); - if (!selected || !item || item == selected || item->get_parent() == selected) { - return false; - } - - return true; -} - -void InputMapEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - if (!can_drop_data_fw(p_point, p_data, p_from)) { - return; - } - - TreeItem *selected = input_editor->get_selected(); - TreeItem *item = input_editor->get_item_at_position(p_point); - if (!item) { - return; - } - TreeItem *target = item->get_parent() == input_editor->get_root() ? item : item->get_parent(); - - String selected_name = "input/" + selected->get_text(0); - int old_order = ProjectSettings::get_singleton()->get_order(selected_name); - String target_name = "input/" + target->get_text(0); - int target_order = ProjectSettings::get_singleton()->get_order(target_name); - - int order = old_order; - bool is_below = target_order > old_order; - TreeItem *iterator = is_below ? selected->get_next() : selected->get_prev(); - - undo_redo->create_action(TTR("Moved Input Action Event")); - while (iterator != target) { - String iterator_name = "input/" + iterator->get_text(0); - int iterator_order = ProjectSettings::get_singleton()->get_order(iterator_name); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", iterator_name, order); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", iterator_name, iterator_order); - order = iterator_order; - iterator = is_below ? iterator->get_next() : iterator->get_prev(); - } - - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", target_name, order); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", selected_name, target_order); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", target_name, target_order); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_name, old_order); - - undo_redo->add_do_method(this, "_update_actions"); - undo_redo->add_undo_method(this, "_update_actions"); - undo_redo->add_do_method(this, "emit_signal", inputmap_changed); - undo_redo->add_undo_method(this, "emit_signal", inputmap_changed); - undo_redo->commit_action(); -} - -void InputMapEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_update_actions"), &InputMapEditor::_update_actions); - - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &InputMapEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &InputMapEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &InputMapEditor::drop_data_fw); - - ADD_SIGNAL(MethodInfo("inputmap_changed")); -} - -InputMapEditor::InputMapEditor() { - undo_redo = EditorNode::get_undo_redo(); - press_a_key_physical = false; - inputmap_changed = "inputmap_changed"; - - VBoxContainer *vbc = memnew(VBoxContainer); - vbc->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_BEGIN, 0); - vbc->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, 0); - vbc->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 0); - vbc->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, 0); - add_child(vbc); - - HBoxContainer *hbc = memnew(HBoxContainer); - vbc->add_child(hbc); - - Label *l = memnew(Label); - l->set_text(TTR("Action:")); - hbc->add_child(l); - - action_name = memnew(LineEdit); - action_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); - action_name->connect("text_entered", callable_mp(this, &InputMapEditor::_action_adds)); - action_name->connect("text_changed", callable_mp(this, &InputMapEditor::_action_check)); - hbc->add_child(action_name); - - action_add_error = memnew(Label); - action_add_error->hide(); - hbc->add_child(action_add_error); - - Button *add = memnew(Button); - add->set_text(TTR("Add")); - add->set_disabled(true); - add->connect("pressed", callable_mp(this, &InputMapEditor::_action_add)); - hbc->add_child(add); - action_add = add; - - input_editor = memnew(Tree); - input_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - input_editor->set_columns(3); - input_editor->set_column_titles_visible(true); - input_editor->set_column_title(0, TTR("Action")); - input_editor->set_column_title(1, TTR("Deadzone")); - input_editor->set_column_expand(1, false); - input_editor->set_column_min_width(1, 80 * EDSCALE); - input_editor->set_column_expand(2, false); - input_editor->set_column_min_width(2, 50 * EDSCALE); - input_editor->connect("item_edited", callable_mp(this, &InputMapEditor::_action_edited)); - input_editor->connect("item_activated", callable_mp(this, &InputMapEditor::_action_activated)); - input_editor->connect("cell_selected", callable_mp(this, &InputMapEditor::_action_selected)); - input_editor->connect("button_pressed", callable_mp(this, &InputMapEditor::_action_button_pressed)); -#ifndef _MSC_VER -#warning need to make drag data forwarding to non controls happen -#endif - //input_editor->set_drag_forwarding(this); - vbc->add_child(input_editor); - - // Popups - - popup_add = memnew(PopupMenu); - popup_add->connect("id_pressed", callable_mp(this, &InputMapEditor::_add_item), make_binds(Ref<InputEvent>())); - add_child(popup_add); - - press_a_key = memnew(ConfirmationDialog); - press_a_key->get_ok_button()->set_disabled(true); - //press_a_key->set_focus_mode(Control::FOCUS_ALL); - press_a_key->connect("window_input", callable_mp(this, &InputMapEditor::_wait_for_key)); - press_a_key->connect("confirmed", callable_mp(this, &InputMapEditor::_press_a_key_confirm)); - add_child(press_a_key); - - l = memnew(Label); - l->set_text(TTR("Press a Key...")); - l->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - l->set_align(Label::ALIGN_CENTER); - l->set_offset(SIDE_TOP, 20); - l->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_BEGIN, 30); - press_a_key->add_child(l); - press_a_key_label = l; - - device_input = memnew(ConfirmationDialog); - device_input->get_ok_button()->set_text(TTR("Add")); - device_input->connect("confirmed", callable_mp(this, &InputMapEditor::_device_input_add)); - add_child(device_input); - - hbc = memnew(HBoxContainer); - device_input->add_child(hbc); - - VBoxContainer *vbc_left = memnew(VBoxContainer); - hbc->add_child(vbc_left); - - l = memnew(Label); - l->set_text(TTR("Device:")); - vbc_left->add_child(l); - - device_id = memnew(OptionButton); - for (int i = -1; i < 8; i++) { - device_id->add_item(_get_device_string(i)); - } - _set_current_device(0); - vbc_left->add_child(device_id); - - VBoxContainer *vbc_right = memnew(VBoxContainer); - vbc_right->set_h_size_flags(Control::SIZE_EXPAND_FILL); - hbc->add_child(vbc_right); - - l = memnew(Label); - l->set_text(TTR("Index:")); - vbc_right->add_child(l); - - device_index_label = l; - device_index = memnew(OptionButton); - device_index->set_clip_text(true); - vbc_right->add_child(device_index); - - message = memnew(AcceptDialog); - add_child(message); -} diff --git a/editor/input_map_editor.h b/editor/input_map_editor.h deleted file mode 100644 index cc6ac1660d..0000000000 --- a/editor/input_map_editor.h +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************/ -/* input_map_editor.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef INPUT_MAP_EDITOR_H -#define INPUT_MAP_EDITOR_H - -#include "core/object/undo_redo.h" -#include "editor/editor_data.h" - -class InputMapEditor : public Control { - GDCLASS(InputMapEditor, Control); - - enum InputType { - INPUT_KEY, - INPUT_KEY_PHYSICAL, - INPUT_JOY_BUTTON, - INPUT_JOY_MOTION, - INPUT_MOUSE_BUTTON - }; - - Tree *input_editor; - LineEdit *action_name; - Button *action_add; - Label *action_add_error; - - InputType add_type; - String add_at; - int edit_idx; - - PopupMenu *popup_add; - ConfirmationDialog *press_a_key; - bool press_a_key_physical; - Label *press_a_key_label; - ConfirmationDialog *device_input; - OptionButton *device_id; - OptionButton *device_index; - Label *device_index_label; - MenuButton *popup_copy_to_feature; - - Ref<InputEventKey> last_wait_for_key; - - AcceptDialog *message; - UndoRedo *undo_redo; - String inputmap_changed; - bool setting = false; - - void _update_actions(); - void _add_item(int p_item, Ref<InputEvent> p_exiting_event = Ref<InputEvent>()); - void _edit_item(Ref<InputEvent> p_exiting_event); - - void _action_check(String p_action); - void _action_adds(String); - void _action_add(); - void _device_input_add(); - - void _action_selected(); - void _action_edited(); - void _action_activated(); - void _action_button_pressed(Object *p_obj, int p_column, int p_id); - void _wait_for_key(const Ref<InputEvent> &p_event); - void _press_a_key_confirm(); - void _show_last_added(const Ref<InputEvent> &p_event, const String &p_name); - - String _get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event); - - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; - void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); - -protected: - int _get_current_device(); - void _set_current_device(int i_device); - String _get_device_string(int i_device); - - void _notification(int p_what); - static void _bind_methods(); - -public: - InputMapEditor(); -}; - -#endif // INPUT_MAP_EDITOR_H diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 60553143d5..0e68af06f0 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -84,7 +84,7 @@ void LocalizationEditor::add_translation(const String &p_translation) { } void LocalizationEditor::_translation_add(const PackedStringArray &p_paths) { - PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations"); + PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); for (int i = 0; i < p_paths.size(); i++) { if (!translations.has(p_paths[i])) { // Don't add duplicate translation paths. @@ -93,8 +93,8 @@ void LocalizationEditor::_translation_add(const PackedStringArray &p_paths) { } undo_redo->create_action(vformat(TTR("Add %d Translations"), p_paths.size())); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations", translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations", ProjectSettings::get_singleton()->get("locale/translations")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", ProjectSettings::get_singleton()->get("internationalization/locale/translations")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -112,15 +112,15 @@ void LocalizationEditor::_translation_delete(Object *p_item, int p_column, int p int idx = ti->get_metadata(0); - PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations"); + PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); ERR_FAIL_INDEX(idx, translations.size()); translations.remove(idx); undo_redo->create_action(TTR("Remove Translation")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations", translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations", ProjectSettings::get_singleton()->get("locale/translations")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", ProjectSettings::get_singleton()->get("internationalization/locale/translations")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -136,8 +136,8 @@ void LocalizationEditor::_translation_res_add(const PackedStringArray &p_paths) Variant prev; Dictionary remaps; - if (ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) { - remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { + remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); prev = remaps; } @@ -149,8 +149,8 @@ void LocalizationEditor::_translation_res_add(const PackedStringArray &p_paths) } undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Path(s)"), p_paths.size())); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", prev); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", prev); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -163,9 +163,9 @@ void LocalizationEditor::_translation_res_option_file_open() { } void LocalizationEditor::_translation_res_option_add(const PackedStringArray &p_paths) { - ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")); + ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")); - Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); TreeItem *k = translation_remap->get_selected(); ERR_FAIL_COND(!k); @@ -180,8 +180,8 @@ void LocalizationEditor::_translation_res_option_add(const PackedStringArray &p_ remaps[key] = r; undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Remap(s)"), p_paths.size())); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -202,11 +202,11 @@ void LocalizationEditor::_translation_res_option_changed() { return; } - if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) { + if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); TreeItem *k = translation_remap->get_selected(); ERR_FAIL_COND(!k); @@ -234,8 +234,8 @@ void LocalizationEditor::_translation_res_option_changed() { updating_translations = true; undo_redo->create_action(TTR("Change Resource Remap Language")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -249,11 +249,11 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i return; } - if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) { + if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); TreeItem *k = Object::cast_to<TreeItem>(p_item); @@ -263,8 +263,8 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i remaps.erase(key); undo_redo->create_action(TTR("Remove Resource Remap")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -277,11 +277,11 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co return; } - if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) { + if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); TreeItem *k = translation_remap->get_selected(); ERR_FAIL_COND(!k); @@ -298,8 +298,8 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co remaps[key] = r; undo_redo->create_action(TTR("Remove Resource Remap Option")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -316,8 +316,8 @@ void LocalizationEditor::_translation_filter_option_changed() { Variant prev; Array f_locales_all; - if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) { - f_locales_all = ProjectSettings::get_singleton()->get("locale/locale_filter"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter")) { + f_locales_all = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter"); prev = f_locales_all; if (f_locales_all.size() != 2) { @@ -346,8 +346,8 @@ void LocalizationEditor::_translation_filter_option_changed() { f_locales.sort(); undo_redo->create_action(TTR("Changed Locale Filter")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/locale_filter", f_locales_all); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/locale_filter", prev); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", f_locales_all); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", prev); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -361,8 +361,8 @@ void LocalizationEditor::_translation_filter_mode_changed(int p_mode) { Variant prev; Array f_locales_all; - if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) { - f_locales_all = ProjectSettings::get_singleton()->get("locale/locale_filter"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter")) { + f_locales_all = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter"); prev = f_locales_all; if (f_locales_all.size() != 2) { @@ -378,8 +378,8 @@ void LocalizationEditor::_translation_filter_mode_changed(int p_mode) { } undo_redo->create_action(TTR("Changed Locale Filter Mode")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/locale_filter", f_locales_all); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/locale_filter", prev); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", f_locales_all); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", prev); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -388,7 +388,7 @@ void LocalizationEditor::_translation_filter_mode_changed(int p_mode) { } void LocalizationEditor::_pot_add(const PackedStringArray &p_paths) { - PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("locale/translations_pot_files"); + PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); for (int i = 0; i < p_paths.size(); i++) { for (int j = 0; j < pot_translations.size(); j++) { @@ -401,8 +401,8 @@ void LocalizationEditor::_pot_add(const PackedStringArray &p_paths) { } undo_redo->create_action(vformat(TTR("Add %d file(s) for POT generation"), p_paths.size())); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", pot_translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", ProjectSettings::get_singleton()->get("locale/translations_pot_files")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -416,15 +416,15 @@ void LocalizationEditor::_pot_delete(Object *p_item, int p_column, int p_button) int idx = ti->get_metadata(0); - PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("locale/translations_pot_files"); + PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); ERR_FAIL_INDEX(idx, pot_translations.size()); pot_translations.remove(idx); undo_redo->create_action(TTR("Remove file from POT generation")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", pot_translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", ProjectSettings::get_singleton()->get("locale/translations_pot_files")); + undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -463,8 +463,8 @@ void LocalizationEditor::update_translations() { translation_list->clear(); TreeItem *root = translation_list->create_item(nullptr); translation_list->set_hide_root(true); - if (ProjectSettings::get_singleton()->has_setting("locale/translations")) { - PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations")) { + PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); for (int i = 0; i < translations.size(); i++) { TreeItem *t = translation_list->create_item(root); t->set_editable(0, false); @@ -482,8 +482,8 @@ void LocalizationEditor::update_translations() { Array l_filter_all; bool is_arr_empty = true; - if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) { - l_filter_all = ProjectSettings::get_singleton()->get("locale/locale_filter"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter")) { + l_filter_all = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter"); if (l_filter_all.size() == 2) { translation_locale_filter_mode->select(l_filter_all[0]); @@ -573,8 +573,8 @@ void LocalizationEditor::update_translations() { } } - if (ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) { - Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { + Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); List<Variant> rk; remaps.get_key_list(&rk); Vector<String> keys; @@ -631,8 +631,8 @@ void LocalizationEditor::update_translations() { translation_pot_list->clear(); root = translation_pot_list->create_item(nullptr); translation_pot_list->set_hide_root(true); - if (ProjectSettings::get_singleton()->has_setting("locale/translations_pot_files")) { - PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("locale/translations_pot_files"); + if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations_pot_files")) { + PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); for (int i = 0; i < pot_translations.size(); i++) { TreeItem *t = translation_pot_list->create_item(root); t->set_editable(0, false); diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index 96ebb131ad..e6b99fa63f 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -557,7 +557,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, Transform t = spatial_node->get_global_transform(); Vector3 camera_position = p_camera->get_camera_transform().origin; if (camera_position.distance_squared_to(t.origin) > 0.01) { - t.set_look_at(t.origin, camera_position, Vector3(0, 1, 0)); + t.set_look_at(t.origin, camera_position); } float scale = t.origin.distance_to(p_camera->get_camera_transform().origin); @@ -574,7 +574,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, if (orig_camera_transform.origin.distance_squared_to(t.origin) > 0.01 && ABS(orig_camera_transform.basis.get_axis(Vector3::AXIS_Z).dot(Vector3(0, 1, 0))) < 0.99) { - p_camera->look_at(t.origin, Vector3(0, 1, 0)); + p_camera->look_at(t.origin); } Vector3 c0 = t.xform(Vector3(selectable_icon_size, selectable_icon_size, 0) * scale); @@ -844,7 +844,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec //min_p = p_arc_xform.affine_inverse().xform(min_p); float a = (Math_PI * 0.5) - Vector2(min_p.x, -min_p.z).angle(); - return a * 180.0 / Math_PI; + return Math::rad2deg(a); } void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { @@ -1033,12 +1033,9 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_lines(points_primary, material_primary, false, color); p_gizmo->add_lines(points_secondary, material_secondary, false, color); - const float ra = 16 * Math_PI * 2.0 / 64.0; - const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w; - Vector<Vector3> handles; handles.push_back(Vector3(0, 0, -r)); - handles.push_back(Vector3(a.x, a.y, -d)); + handles.push_back(Vector3(w, 0, -d)); p_gizmo->add_handles(handles, get_material("handles")); p_gizmo->add_unscaled_billboard(icon, 0.05, color); @@ -1095,8 +1092,8 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int float closest_angle = 1e20; for (int i = 0; i < 180; i++) { - float a = i * Math_PI / 180.0; - float an = (i + 1) * Math_PI / 180.0; + float a = Math::deg2rad((float)i); + float an = Math::deg2rad((float)(i + 1)); Vector3 from(Math::sin(a), 0, -Math::cos(a)); Vector3 to(Math::sin(an), 0, -Math::cos(an)); @@ -1145,9 +1142,10 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> points_primary; points_primary.resize(200); + real_t step = Math_TAU / 100.0; for (int i = 0; i < 100; i++) { - const float a = i * 2.0 * Math_PI / 100.0; - const float an = (i + 1) * 2.0 * Math_PI / 100.0; + const float a = i * step; + const float an = (i + 1) * step; const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs); const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs); @@ -1163,7 +1161,7 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { points_secondary.resize(16); for (int i = 0; i < 8; i++) { - const float a = i * 2.0 * Math_PI / 8.0; + const float a = i * (Math_TAU / 8.0); const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs); points_secondary.write[i * 2 + 0] = from; @@ -2616,8 +2614,8 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; @@ -3317,7 +3315,7 @@ void BakedLightmapGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { int stack_count = 8; int sector_count = 16; - float sector_step = 2 * Math_PI / sector_count; + float sector_step = (Math_PI * 2.0) / sector_count; float stack_step = Math_PI / stack_count; Vector<Vector3> vertices; @@ -3454,7 +3452,7 @@ void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { int stack_count = 8; int sector_count = 16; - float sector_step = 2 * Math_PI / sector_count; + float sector_step = (Math_PI * 2.0) / sector_count; float stack_step = Math_PI / stack_count; Vector<Vector3> vertices; @@ -3507,6 +3505,57 @@ void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { //// +CollisionObject3DGizmoPlugin::CollisionObject3DGizmoPlugin() { + const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); + create_material("shape_material", gizmo_color); + const float gizmo_value = gizmo_color.get_v(); + const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65); + create_material("shape_material_disabled", gizmo_color_disabled); +} + +bool CollisionObject3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<CollisionObject3D>(p_spatial) != nullptr; +} + +String CollisionObject3DGizmoPlugin::get_gizmo_name() const { + return "CollisionObject3D"; +} + +int CollisionObject3DGizmoPlugin::get_priority() const { + return -1; +} + +void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); + + List<uint32_t> owners; + co->get_shape_owners(&owners); + for (List<uint32_t>::Element *E = owners.front(); E; E = E->next()) { + uint32_t owner_id = E->get(); + Transform xform = co->shape_owner_get_transform(owner_id); + Object *owner = co->shape_owner_get_owner(owner_id); + // Exclude CollisionShape3D and CollisionPolygon3D as they have their gizmo. + if (!Object::cast_to<CollisionShape3D>(owner) && !Object::cast_to<CollisionPolygon3D>(owner)) { + Ref<Material> material = get_material(!co->is_shape_owner_disabled(owner_id) ? "shape_material" : "shape_material_disabled", p_gizmo); + for (int shape_id = 0; shape_id < co->shape_owner_get_shape_count(owner_id); shape_id++) { + Ref<Shape3D> s = co->shape_owner_get_shape(owner_id, shape_id); + if (s.is_null()) { + continue; + } + SurfaceTool st; + st.append_from(s->get_debug_mesh(), 0, xform); + + p_gizmo->add_mesh(st.commit(), false, Ref<SkinReference>(), material); + p_gizmo->add_collision_segments(s->get_debug_mesh_lines()); + } + } + } +} + +//// + CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() { const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); create_material("shape_material", gizmo_color); @@ -3854,8 +3903,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; @@ -3939,8 +3988,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; @@ -4002,8 +4051,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h index df4ed15a8e..6f98d3a08c 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/node_3d_editor_gizmos.h @@ -355,6 +355,18 @@ public: LightmapProbeGizmoPlugin(); }; +class CollisionObject3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(CollisionObject3DGizmoPlugin, EditorNode3DGizmoPlugin); + +public: + bool has_gizmo(Node3D *p_spatial) override; + String get_gizmo_name() const override; + int get_priority() const override; + void redraw(EditorNode3DGizmo *p_gizmo) override; + + CollisionObject3DGizmoPlugin(); +}; + class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index fbfcac3d22..e7e069e8b6 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -255,6 +255,9 @@ void AnimationNodeBlendTreeEditor::_update_graph() { graph->connect_node(from, 0, to, to_idx); } + + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); } void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) { @@ -888,6 +891,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed)); graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request)); graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request)); + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); VSeparator *vs = memnew(VSeparator); graph->get_zoom_hbox()->add_child(vs); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 56d82acd2f..7c623505b5 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -78,7 +78,6 @@ void AnimationPlayerEditor::_notification(int p_what) { } frame->set_value(player->get_current_animation_position()); track_editor->set_anim_pos(player->get_current_animation_position()); - EditorNode::get_singleton()->get_inspector()->refresh(); } else if (!player->is_valid()) { // Reset timeline when the player has been stopped externally @@ -1072,8 +1071,6 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) frame->set_value(Math::snapped(p_pos, _get_editor_step())); updating = false; _seek_value_changed(p_pos, !p_drag); - - EditorNode::get_singleton()->get_inspector()->refresh(); } void AnimationPlayerEditor::_animation_tool_menu(int p_option) { @@ -1400,7 +1397,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() { // Render every past/future step with the capture shader. RS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid()); - onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/default_clear_color")); + onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color")); onion.capture.material->set_shader_param("differences_only", onion.differences_only); onion.capture.material->set_shader_param("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID()); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index b2d143c416..4d9c5625a3 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -350,7 +350,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int if (sha256 != download_sha256) { error_text = TTR("Bad download hash, assuming file has been tampered with.") + "\n"; error_text += TTR("Expected:") + " " + sha256 + "\n" + TTR("Got:") + " " + download_sha256; - status->set_text(TTR("Failed sha256 hash check")); + status->set_text(TTR("Failed SHA-256 hash check")); } } } break; @@ -359,6 +359,8 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int if (error_text != String()) { download_error->set_text(TTR("Asset Download Error:") + "\n" + error_text); download_error->popup_centered(); + // Let the user retry the download. + retry->show(); return; } @@ -459,6 +461,9 @@ void EditorAssetLibraryItemDownload::_install() { } void EditorAssetLibraryItemDownload::_make_request() { + // Hide the Retry button if we've just pressed it. + retry->hide(); + download->cancel_request(); download->set_download_file(EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); @@ -516,6 +521,8 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() { retry = memnew(Button); retry->set_text(TTR("Retry")); retry->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_make_request)); + // Only show the Retry button in case of a failure. + retry->hide(); hb2->add_child(retry); hb2->add_child(install); @@ -900,7 +907,7 @@ void EditorAssetLibrary::_search(int p_page) { } if (filter->get_text() != String()) { - args += "&filter=" + filter->get_text().http_escape(); + args += "&filter=" + filter->get_text().uri_encode(); } if (p_page > 0) { @@ -1364,10 +1371,18 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { search_hb2->add_child(memnew(Label(TTR("Site:") + " "))); repository = memnew(OptionButton); - repository->add_item("godotengine.org"); - repository->set_item_metadata(0, "https://godotengine.org/asset-library/api"); - repository->add_item("localhost"); - repository->set_item_metadata(1, "http://127.0.0.1/asset-library/api"); + { + Dictionary default_urls; + default_urls["godotengine.org"] = "https://godotengine.org/asset-library/api"; + default_urls["localhost"] = "http://127.0.0.1/asset-library/api"; + Dictionary available_urls = _EDITOR_DEF("asset_library/available_urls", default_urls, true); + Array keys = available_urls.keys(); + for (int i = 0; i < available_urls.size(); i++) { + String key = keys[i]; + repository->add_item(key); + repository->set_item_metadata(i, available_urls[key]); + } + } repository->connect("item_selected", callable_mp(this, &EditorAssetLibrary::_repository_changed)); diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 1765c99572..5963092860 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -96,7 +96,7 @@ void AudioStreamEditor::_preview_changed(ObjectID p_which) { } } -void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void AudioStreamEditor::_audio_changed() { if (!is_visible()) { return; } @@ -172,7 +172,7 @@ void AudioStreamEditor::_seek_to(real_t p_x) { void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { if (!stream.is_null()) { - stream->remove_change_receptor(this); + stream->disconnect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); } stream = p_stream; @@ -182,7 +182,7 @@ void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { _duration_label->set_text(text); if (!stream.is_null()) { - stream->add_change_receptor(this); + stream->connect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); update(); } else { hide(); diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h index f27add7229..aa906a6a05 100644 --- a/editor/plugins/audio_stream_editor_plugin.h +++ b/editor/plugins/audio_stream_editor_plugin.h @@ -53,6 +53,8 @@ class AudioStreamEditor : public ColorRect { float _current; bool _dragging; + void _audio_changed(); + protected: void _notification(int p_what); void _preview_changed(ObjectID p_which); @@ -63,7 +65,6 @@ protected: void _draw_indicator(); void _on_input_indicator(Ref<InputEvent> p_event); void _seek_to(real_t p_x); - void _changed_callback(Object *p_changed, const char *p_prop) override; static void _bind_methods(); public: diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index b1ce472043..82ebf48242 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -216,8 +216,8 @@ public: grid_step_x->set_value(p_grid_step.x); grid_step_y->set_value(p_grid_step.y); primary_grid_steps->set_value(p_primary_grid_steps); - rotation_offset->set_value(p_rotation_offset * (180 / Math_PI)); - rotation_step->set_value(p_rotation_step * (180 / Math_PI)); + rotation_offset->set_value(Math::rad2deg(p_rotation_offset)); + rotation_step->set_value(Math::rad2deg(p_rotation_step)); scale_step->set_value(p_scale_step); } @@ -225,8 +225,8 @@ public: p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value()); p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value()); p_primary_grid_steps = int(primary_grid_steps->get_value()); - p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI); - p_rotation_step = rotation_step->get_value() / (180 / Math_PI); + p_rotation_offset = Math::deg2rad(rotation_offset->get_value()); + p_rotation_step = Math::deg2rad(rotation_step->get_value()); p_scale_step = scale_step->get_value(); } }; @@ -629,9 +629,9 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel Node *node = r_items[i].item; // Make sure the selected node is in the current scene, or editable - while (node && node != get_tree()->get_edited_scene_root() && node->get_owner() != scene && !scene->is_editable_instance(node->get_owner())) { - node = node->get_parent(); - }; + if (node && node != get_tree()->get_edited_scene_root()) { + node = scene->get_deepest_editable_node(node); + } CanvasItem *canvas_item = Object::cast_to<CanvasItem>(node); if (!p_allow_locked) { @@ -762,7 +762,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); Node *scene = editor->get_edited_scene(); - bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner()); + bool editable = p_node == scene || p_node->get_owner() == scene || p_node == scene->get_deepest_editable_node(p_node); bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); bool locked = _is_node_locked(p_node); @@ -2902,21 +2902,22 @@ void CanvasItemEditor::_draw_guides() { // Dragged guide Color text_color = get_theme_color("font_color", "Editor"); - text_color.a = 0.5; + Color outline_color = text_color.inverted(); + const float outline_size = 2; if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) { String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x))); - Ref<Font> font = get_theme_font("font", "Label"); - int font_size = get_theme_font_size("font_size", "Label"); + Ref<Font> font = get_theme_font("bold", "EditorFonts"); + int font_size = get_theme_font_size("bold_size", "EditorFonts"); Size2 text_size = font->get_string_size(str, font_size); - viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color); + viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, outline_size, outline_color); viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) { String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y))); - Ref<Font> font = get_theme_font("font", "Label"); - int font_size = get_theme_font_size("font_size", "Label"); + Ref<Font> font = get_theme_font("bold", "EditorFonts"); + int font_size = get_theme_font_size("bold_size", "EditorFonts"); Size2 text_size = font->get_string_size(str, font_size); - viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color); + viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, outline_size, outline_color); viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE)); } } @@ -3183,16 +3184,16 @@ void CanvasItemEditor::_draw_ruler_tool() { float arc_1_start_angle = end_to_begin.x < 0 ? - (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) : - (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad); + (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) : + (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad); float arc_1_end_angle = arc_1_start_angle + vertical_angle_rad; // Constrain arc to triangle height & max size float arc_1_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.y)), arc_max_radius); float arc_2_start_angle = end_to_begin.x < 0 ? - (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) : - (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI); + (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) : + (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI); float arc_2_end_angle = arc_2_start_angle + horizontal_angle_rad; // Constrain arc to triangle width & max size float arc_2_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.x)), arc_max_radius); @@ -3901,7 +3902,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) { CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); Node *scene = editor->get_edited_scene(); - if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner()))) { + if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && canvas_item != scene->get_deepest_editable_node(canvas_item))) { return false; } @@ -4197,7 +4198,7 @@ void CanvasItemEditor::_notification(int p_what) { // the icon will be dark, so we need to lighten it before blending it // with the red color. const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25); - key_auto_insert_button->add_theme_color_override("icon_color_pressed", key_auto_color.lerp(Color(1, 0, 0), 0.55)); + key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55)); animation_menu->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons")); zoom_minus->set_icon(get_theme_icon("ZoomLess", "EditorIcons")); @@ -5673,7 +5674,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { primary_grid_steps = 8; // A power-of-two value works better as a default grid_step_multiplier = 0; snap_rotation_offset = 0; - snap_rotation_step = 15 / (180 / Math_PI); + snap_rotation_step = Math::deg2rad(15.0); snap_scale_step = 0.1f; smart_snap_active = false; grid_snap_active = false; @@ -5817,7 +5818,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_reset->set_flat(true); zoom_hb->add_child(zoom_reset); zoom_reset->add_theme_constant_override("outline_size", 1); - zoom_reset->add_theme_color_override("font_outline_modulate", Color(0, 0, 0)); + zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0)); zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1)); zoom_reset->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_zoom_reset)); zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0)); @@ -6657,7 +6658,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte } label = memnew(Label); - label->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 1)); + label->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 1)); label->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE); label->hide(); canvas_item_editor->get_controls_container()->add_child(label); @@ -6665,7 +6666,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte label_desc = memnew(Label); label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type")); label_desc->add_theme_color_override("font_color", Color(0.6f, 0.6f, 0.6f, 1)); - label_desc->add_theme_color_override("font_color_shadow", Color(0.2f, 0.2f, 0.2f, 1)); + label_desc->add_theme_color_override("font_shadow_color", Color(0.2f, 0.2f, 0.2f, 1)); label_desc->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE); label_desc->add_theme_constant_override("line_spacing", 0); label_desc->hide(); diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index a1e7d3d6e0..141ee35cdb 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -207,7 +207,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } break; } - node->get_shape()->_change_notify(); + node->get_shape()->notify_property_list_changed(); } void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 88e56ccfb9..bff5cb8d2a 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -353,8 +353,8 @@ void CurveEditor::open_context_menu(Vector2 pos) { _context_menu->add_check_item(TTR("Linear"), CONTEXT_LINEAR); bool is_linear = _selected_tangent == TANGENT_LEFT ? - _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR : - _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR; + _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR : + _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR; _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LINEAR), is_linear); diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index bdf88b82e4..eb3c06fba1 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -301,7 +301,7 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() { ////////////////////////////////////////////////////////////////// void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) { - preview_done = true; + preview_done.set(); } void EditorMaterialPreviewPlugin::_bind_methods() { @@ -325,10 +325,10 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture - preview_done = false; + preview_done.clear(); RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant()); - while (!preview_done) { + while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); } @@ -382,7 +382,9 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { int lats = 32; int lons = 32; - float radius = 1.0; + const double lat_step = Math_TAU / lats; + const double lon_step = Math_TAU / lons; + real_t radius = 1.0; Vector<Vector3> vertices; Vector<Vector3> normals; @@ -391,20 +393,20 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { Basis tt = Basis(Vector3(0, 1, 0), Math_PI * 0.5); for (int i = 1; i <= lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); @@ -675,7 +677,7 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) { - preview_done = true; + preview_done.set(); } void EditorMeshPreviewPlugin::_bind_methods() { @@ -712,10 +714,10 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture - preview_done = false; + preview_done.clear(); RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant()); - while (!preview_done) { + while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); } @@ -790,7 +792,7 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { /////////////////////////////////////////////////////////////////////////// void EditorFontPreviewPlugin::_preview_done(const Variant &p_udata) { - preview_done = true; + preview_done.set(); } void EditorFontPreviewPlugin::_bind_methods() { @@ -881,11 +883,11 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, font->draw_string(canvas_item, pos, sample, HALIGN_LEFT, -1.f, 50, Color(1, 1, 1)); - preview_done = false; + preview_done.clear(); RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorFontPreviewPlugin *>(this), "_preview_done", Variant()); - while (!preview_done) { + while (!preview_done.is_set()) { OS::get_singleton()->delay_usec(10); } diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 57e2911c89..6e8b9a34cf 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -33,6 +33,8 @@ #include "editor/editor_resource_preview.h" +#include "core/templates/safe_refcount.h" + void post_process_preview(Ref<Image> p_image); class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { @@ -90,7 +92,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { RID light2; RID light_instance2; RID camera; - mutable volatile bool preview_done = false; + mutable SafeFlag preview_done; void _preview_done(const Variant &p_udata); @@ -134,7 +136,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { RID light2; RID light_instance2; RID camera; - mutable volatile bool preview_done = false; + mutable SafeFlag preview_done; void _preview_done(const Variant &p_udata); @@ -156,7 +158,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator { RID viewport_texture; RID canvas; RID canvas_item; - mutable volatile bool preview_done = false; + mutable SafeFlag preview_done; void _preview_done(const Variant &p_udata); diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index 1aaa98d02e..b447304a3f 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -81,7 +81,7 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) { cpu_particles->set_name(particles->get_name()); cpu_particles->set_transform(particles->get_transform()); cpu_particles->set_visible(particles->is_visible()); - cpu_particles->set_pause_mode(particles->get_pause_mode()); + cpu_particles->set_process_mode(particles->get_process_mode()); cpu_particles->set_z_index(particles->get_z_index()); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index 5b840ddbcf..433a5ae51c 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -263,7 +263,7 @@ void GPUParticles3DEditor::_menu_option(int p_option) { cpu_particles->set_name(node->get_name()); cpu_particles->set_transform(node->get_transform()); cpu_particles->set_visible(node->is_visible()); - cpu_particles->set_pause_mode(node->get_pause_mode()); + cpu_particles->set_process_mode(node->get_process_mode()); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Convert to CPUParticles3D")); diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index c0f690bb6a..1ea6630622 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -145,7 +145,7 @@ int ItemListOptionButtonPlugin::get_flags() const { void ItemListOptionButtonPlugin::add_item() { ob->add_item(vformat(TTR("Item %d"), ob->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListOptionButtonPlugin::get_item_count() const { @@ -154,7 +154,7 @@ int ItemListOptionButtonPlugin::get_item_count() const { void ItemListOptionButtonPlugin::erase(int p_idx) { ob->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() { @@ -181,7 +181,7 @@ int ItemListPopupMenuPlugin::get_flags() const { void ItemListPopupMenuPlugin::add_item() { pp->add_item(vformat(TTR("Item %d"), pp->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListPopupMenuPlugin::get_item_count() const { @@ -190,7 +190,7 @@ int ItemListPopupMenuPlugin::get_item_count() const { void ItemListPopupMenuPlugin::erase(int p_idx) { pp->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() { @@ -213,7 +213,7 @@ int ItemListItemListPlugin::get_flags() const { void ItemListItemListPlugin::add_item() { pp->add_item(vformat(TTR("Item %d"), pp->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListItemListPlugin::get_item_count() const { @@ -222,7 +222,7 @@ int ItemListItemListPlugin::get_item_count() const { void ItemListItemListPlugin::erase(int p_idx) { pp->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListItemListPlugin::ItemListItemListPlugin() { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 3e8547439f..9643881f96 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -48,6 +48,7 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/gui/center_container.h" #include "scene/gui/subviewport_container.h" #include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" @@ -535,8 +536,8 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b if (dist < closest_dist) { item = Object::cast_to<Node>(spat); - while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) { - item = item->get_owner(); + if (item != edited_scene) { + item = edited_scene->get_deepest_editable_node(item); } closest = item->get_instance_id(); @@ -697,8 +698,8 @@ void Node3DEditorViewport::_select_region() { } Node *item = Object::cast_to<Node>(sp); - while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) { - item = item->get_owner(); + if (item != edited_scene) { + item = edited_scene->get_deepest_editable_node(item); } // Replace the node by the group if grouped @@ -1027,7 +1028,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { for (int i = 0; i < selection_results.size(); i++) { Node3D *item = selection_results[i].item; - if (item != scene && item->get_owner() != scene && !scene->is_editable_instance(item->get_owner())) { + if (item != scene && item->get_owner() != scene && item != scene->get_deepest_editable_node(item)) { //invalid result selection_results.remove(i); i--; @@ -2335,7 +2336,43 @@ void Node3DEditorPlugin::edited_scene_changed() { } } +void Node3DEditorViewport::_project_settings_changed() { + //update shadow atlas if changed + int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/size"); + bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/16_bits"); + int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_0_subdiv"); + int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_1_subdiv"); + int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_2_subdiv"); + int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_3_subdiv"); + + viewport->set_shadow_atlas_size(shadowmap_size); + viewport->set_shadow_atlas_16_bits(shadowmap_16_bits); + viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); + viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); + viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); + viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); + + bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); + + if (shrink != (subviewport_container->get_stretch_shrink() > 1)) { + subviewport_container->set_stretch_shrink(shrink ? 2 : 1); + } + + // Update MSAA, screen-space AA and debanding if changed + + const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/anti_aliasing/quality/msaa"); + viewport->set_msaa(Viewport::MSAA(msaa_mode)); + const int ssaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/screen_space_aa"); + viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + const bool use_debanding = GLOBAL_GET("rendering/anti_aliasing/quality/use_debanding"); + viewport->set_use_debanding(use_debanding); +} + void Node3DEditorViewport::_notification(int p_what) { + if (p_what == NOTIFICATION_READY) { + EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed)); + } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { bool visible = is_visible_in_tree(); @@ -2442,35 +2479,6 @@ void Node3DEditorViewport::_notification(int p_what) { } } - //update shadow atlas if changed - - int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size"); - int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv"); - int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv"); - int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv"); - int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv"); - - viewport->set_shadow_atlas_size(shadowmap_size); - viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); - viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); - viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); - viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); - - bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION)); - - if (shrink != (subviewport_container->get_stretch_shrink() > 1)) { - subviewport_container->set_stretch_shrink(shrink ? 2 : 1); - } - - // Update MSAA, screen-space AA and debanding if changed - - const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); - viewport->set_msaa(Viewport::MSAA(msaa_mode)); - const int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); - viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); - const bool use_debanding = GLOBAL_GET("rendering/quality/screen_filters/use_debanding"); - viewport->set_use_debanding(use_debanding); - bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); if (show_info != info_label->is_visible()) { info_label->set_visible(show_info); @@ -2491,6 +2499,13 @@ void Node3DEditorViewport::_notification(int p_what) { text += "Z: " + rtos(current_camera->get_translation().z).pad_decimals(1) + "\n"; text += TTR("Pitch") + ": " + itos(Math::round(current_camera->get_rotation_degrees().x)) + "\n"; text += TTR("Yaw") + ": " + itos(Math::round(current_camera->get_rotation_degrees().y)) + "\n\n"; + + text += TTR("Size") + + vformat( + ": %dx%d (%.1fMP)\n", + viewport->get_size().x, + viewport->get_size().y, + viewport->get_size().x * viewport->get_size().y * 0.000'001); text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n"; text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n"; text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n"; @@ -2822,7 +2837,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { } break; case VIEW_FRONT: { cursor.x_rot = 0; - cursor.y_rot = 0; + cursor.y_rot = Math_PI; set_message(TTR("Front View."), 2); name = TTR("Front"); _set_auto_orthogonal(); @@ -2831,7 +2846,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { } break; case VIEW_REAR: { cursor.x_rot = 0; - cursor.y_rot = Math_PI; + cursor.y_rot = 0; set_message(TTR("Rear View."), 2); name = TTR("Rear"); _set_auto_orthogonal(); @@ -3043,7 +3058,11 @@ void Node3DEditorViewport::_menu_option(int p_option) { case VIEW_DISPLAY_DEBUG_SDFGI: case VIEW_DISPLAY_DEBUG_SDFGI_PROBES: case VIEW_DISPLAY_DEBUG_GI_BUFFER: - case VIEW_DISPLAY_DEBUG_DISABLE_LOD: { + case VIEW_DISPLAY_DEBUG_DISABLE_LOD: + case VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS: + case VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS: + case VIEW_DISPLAY_DEBUG_CLUSTER_DECALS: + case VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES: { static const int display_options[] = { VIEW_DISPLAY_NORMAL, VIEW_DISPLAY_WIREFRAME, @@ -3065,6 +3084,10 @@ void Node3DEditorViewport::_menu_option(int p_option) { VIEW_DISPLAY_DEBUG_DECAL_ATLAS, VIEW_DISPLAY_DEBUG_SDFGI, VIEW_DISPLAY_DEBUG_SDFGI_PROBES, + VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_DECALS, + VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES, VIEW_MAX }; static const Viewport::DebugDraw debug_draw_modes[] = { @@ -3088,6 +3111,10 @@ void Node3DEditorViewport::_menu_option(int p_option) { Viewport::DEBUG_DRAW_DECAL_ATLAS, Viewport::DEBUG_DRAW_SDFGI, Viewport::DEBUG_DRAW_SDFGI_PROBES, + Viewport::DEBUG_DRAW_CLUSTER_OMNI_LIGHTS, + Viewport::DEBUG_DRAW_CLUSTER_SPOT_LIGHTS, + Viewport::DEBUG_DRAW_CLUSTER_DECALS, + Viewport::DEBUG_DRAW_CLUSTER_REFLECTION_PROBES, }; int idx = 0; @@ -3215,6 +3242,8 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) { void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) { previewing_cinema = p_activate; + rotation_control->set_visible(!p_activate); + if (!previewing_cinema) { if (previewing != nullptr) { previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); @@ -3305,6 +3334,21 @@ void Node3DEditorViewport::update_transform_gizmo_view() { xform.basis.scale(scale); + // if the determinant is zero, we should disable the gizmo from being rendered + // this prevents supplying bad values to the renderer and then having to filter it out again + if (xform.basis.determinant() == 0) { + for (int i = 0; i < 3; i++) { + RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false); + } + // Rotation white outline + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false); + return; + } + for (int i = 0; i < 3; i++) { RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform); RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE)); @@ -3989,6 +4033,12 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito display_submenu->add_radio_check_item(TTR("GI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER); display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Disable LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD); + display_submenu->add_separator(); + display_submenu->add_radio_check_item(TTR("Omni Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS); + display_submenu->add_radio_check_item(TTR("Spot Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS); + display_submenu->add_radio_check_item(TTR("Decal Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_DECALS); + display_submenu->add_radio_check_item(TTR("Reflection Probe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES); + display_submenu->set_name("display_advanced"); view_menu->get_popup()->add_submenu_item(TTR("Display Advanced..."), "display_advanced", VIEW_DISPLAY_ADVANCED); view_menu->get_popup()->add_separator(); @@ -4663,11 +4713,33 @@ Dictionary Node3DEditor::get_state() const { continue; } int state = gizmos_menu->get_item_state(gizmos_menu->get_item_index(i)); - String name = gizmo_plugins_by_name[i]->get_name(); + String name = gizmo_plugins_by_name[i]->get_gizmo_name(); gizmos_status[name] = state; } d["gizmos_status"] = gizmos_status; + { + Dictionary pd; + + pd["sun_rotation"] = sun_rotation; + + pd["environ_sky_color"] = environ_sky_color->get_pick_color(); + pd["environ_ground_color"] = environ_ground_color->get_pick_color(); + pd["environ_energy"] = environ_energy->get_value(); + pd["environ_glow_enabled"] = environ_glow_button->is_pressed(); + pd["environ_tonemap_enabled"] = environ_tonemap_button->is_pressed(); + pd["environ_ao_enabled"] = environ_ao_button->is_pressed(); + pd["environ_gi_enabled"] = environ_gi_button->is_pressed(); + pd["sun_max_distance"] = sun_max_distance->get_value(); + + pd["sun_color"] = sun_color->get_pick_color(); + pd["sun_energy"] = sun_energy->get_value(); + + pd["sun_disabled"] = sun_button->is_pressed(); + pd["environ_disabled"] = environ_button->is_pressed(); + + d["preview_sun_env"] = pd; + } return d; } @@ -4767,7 +4839,7 @@ void Node3DEditor::set_state(const Dictionary &p_state) { } int state = EditorNode3DGizmoPlugin::VISIBLE; for (int i = 0; i < keys.size(); i++) { - if (gizmo_plugins_by_name.write[j]->get_name() == String(keys[i])) { + if (gizmo_plugins_by_name.write[j]->get_gizmo_name() == String(keys[i])) { state = gizmos_status[keys[i]]; break; } @@ -4777,6 +4849,38 @@ void Node3DEditor::set_state(const Dictionary &p_state) { } _update_gizmos_menu(); } + + if (d.has("preview_sun_env")) { + sun_environ_updating = true; + Dictionary pd = d["preview_sun_env"]; + sun_rotation = pd["sun_rotation"]; + + environ_sky_color->set_pick_color(pd["environ_sky_color"]); + environ_ground_color->set_pick_color(pd["environ_ground_color"]); + environ_energy->set_value(pd["environ_energy"]); + environ_glow_button->set_pressed(pd["environ_glow_enabled"]); + environ_tonemap_button->set_pressed(pd["environ_tonemap_enabled"]); + environ_ao_button->set_pressed(pd["environ_ao_enabled"]); + environ_gi_button->set_pressed(pd["environ_gi_enabled"]); + sun_max_distance->set_value(pd["sun_max_distance"]); + + sun_color->set_pick_color(pd["sun_color"]); + sun_energy->set_value(pd["sun_energy"]); + + sun_button->set_pressed(pd["sun_disabled"]); + environ_button->set_pressed(pd["environ_disabled"]); + + sun_environ_updating = false; + + _preview_settings_changed(); + _update_preview_environment(); + } else { + _load_default_preview_settings(); + sun_button->set_pressed(false); + environ_button->set_pressed(false); + _preview_settings_changed(); + _update_preview_environment(); + } } void Node3DEditor::edit(Node3D *p_spatial) { @@ -5222,6 +5326,42 @@ void Node3DEditor::_init_indicators() { origin_points.push_back(axis * -1048576); } + Ref<Shader> grid_shader = memnew(Shader); + grid_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded; \n" + "uniform bool orthogonal; \n" + "uniform float grid_size; \n" + "\n" + "void vertex() { \n" + " // From FLAG_SRGB_VERTEX_COLOR \n" + " if (!OUTPUT_IS_SRGB) { \n" + " COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045))); \n" + " } \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = COLOR.rgb; \n" + " vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n" + " float angle_fade = abs(dot(dir, NORMAL)); \n" + " angle_fade = smoothstep(0.05, 0.2, angle_fade); \n" + " \n" + " vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n" + " vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n" + " vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n" + " vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n" + " float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n" + " dist_fade = smoothstep(0.02, 0.3, dist_fade); \n" + " \n" + " ALPHA = COLOR.a * dist_fade * angle_fade; \n" + "}"); + + for (int i = 0; i < 3; i++) { + grid_mat[i].instance(); + grid_mat[i]->set_shader(grid_shader); + } + grid_enable[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane"); grid_enable[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane"); grid_enable[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane"); @@ -5314,9 +5454,10 @@ void Node3DEditor::_init_indicators() { int arrow_sides = 16; + const real_t arrow_sides_step = Math_TAU / arrow_sides; for (int k = 0; k < arrow_sides; k++) { - Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides); - Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides); + Basis ma(ivec, k * arrow_sides_step); + Basis mb(ivec, (k + 1) * arrow_sides_step); for (int j = 0; j < arrow_points - 1; j++) { Vector3 points[4] = { @@ -5391,13 +5532,14 @@ void Node3DEditor::_init_indicators() { int n = 128; // number of circle segments int m = 6; // number of thickness segments + real_t step = Math_TAU / n; for (int j = 0; j < n; ++j) { - Basis basis = Basis(ivec, (Math_PI * 2.0f * j) / n); + Basis basis = Basis(ivec, j * step); Vector3 vertex = basis.xform(ivec2 * GIZMO_CIRCLE_SIZE); for (int k = 0; k < m; ++k) { - Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m)); + Vector2 ofs = Vector2(Math::cos((Math_TAU * k) / m), Math::sin((Math_TAU * k) / m)); Vector3 normal = ivec * ofs.x + ivec2 * ofs.y; surftool->set_normal(basis.xform(normal)); @@ -5424,32 +5566,33 @@ void Node3DEditor::_init_indicators() { Ref<Shader> rotate_shader = memnew(Shader); - rotate_shader->set_code("\n" - "shader_type spatial; \n" - "render_mode unshaded, depth_test_disabled; \n" - "uniform vec4 albedo; \n" - "\n" - "mat3 orthonormalize(mat3 m) { \n" - " vec3 x = normalize(m[0]); \n" - " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" - " vec3 z = m[2] - x * dot(x, m[2]); \n" - " z = normalize(z - y * (dot(y,m[2]))); \n" - " return mat3(x,y,z); \n" - "} \n" - "\n" - "void vertex() { \n" - " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" - " vec3 n = mv * VERTEX; \n" - " float orientation = dot(vec3(0,0,-1),n); \n" - " if (orientation <= 0.005) { \n" - " VERTEX += NORMAL*0.02; \n" - " } \n" - "} \n" - "\n" - "void fragment() { \n" - " ALBEDO = albedo.rgb; \n" - " ALPHA = albedo.a; \n" - "}"); + rotate_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded, depth_test_disabled; \n" + "uniform vec4 albedo; \n" + "\n" + "mat3 orthonormalize(mat3 m) { \n" + " vec3 x = normalize(m[0]); \n" + " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" + " vec3 z = m[2] - x * dot(x, m[2]); \n" + " z = normalize(z - y * (dot(y,m[2]))); \n" + " return mat3(x,y,z); \n" + "} \n" + "\n" + "void vertex() { \n" + " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" + " vec3 n = mv * VERTEX; \n" + " float orientation = dot(vec3(0,0,-1),n); \n" + " if (orientation <= 0.005) { \n" + " VERTEX += NORMAL*0.02; \n" + " } \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = albedo.rgb; \n" + " ALPHA = albedo.a; \n" + "}"); Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX); @@ -5469,33 +5612,34 @@ void Node3DEditor::_init_indicators() { Ref<ShaderMaterial> border_mat = rotate_mat->duplicate(); Ref<Shader> border_shader = memnew(Shader); - border_shader->set_code("\n" - "shader_type spatial; \n" - "render_mode unshaded, depth_test_disabled; \n" - "uniform vec4 albedo; \n" - "\n" - "mat3 orthonormalize(mat3 m) { \n" - " vec3 x = normalize(m[0]); \n" - " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" - " vec3 z = m[2] - x * dot(x, m[2]); \n" - " z = normalize(z - y * (dot(y,m[2]))); \n" - " return mat3(x,y,z); \n" - "} \n" - "\n" - "void vertex() { \n" - " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" - " mv = inverse(mv); \n" - " VERTEX += NORMAL*0.008; \n" - " vec3 camera_dir_local = mv * vec3(0,0,1); \n" - " vec3 camera_up_local = mv * vec3(0,1,0); \n" - " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" - " VERTEX = rotation_matrix * VERTEX; \n" - "} \n" - "\n" - "void fragment() { \n" - " ALBEDO = albedo.rgb; \n" - " ALPHA = albedo.a; \n" - "}"); + border_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded, depth_test_disabled; \n" + "uniform vec4 albedo; \n" + "\n" + "mat3 orthonormalize(mat3 m) { \n" + " vec3 x = normalize(m[0]); \n" + " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" + " vec3 z = m[2] - x * dot(x, m[2]); \n" + " z = normalize(z - y * (dot(y,m[2]))); \n" + " return mat3(x,y,z); \n" + "} \n" + "\n" + "void vertex() { \n" + " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" + " mv = inverse(mv); \n" + " VERTEX += NORMAL*0.008; \n" + " vec3 camera_dir_local = mv * vec3(0,0,1); \n" + " vec3 camera_up_local = mv * vec3(0,1,0); \n" + " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" + " VERTEX = rotation_matrix * VERTEX; \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = albedo.rgb; \n" + " ALPHA = albedo.a; \n" + "}"); border_mat->set_shader(border_shader); border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); @@ -5524,9 +5668,10 @@ void Node3DEditor::_init_indicators() { int arrow_sides = 4; + const real_t arrow_sides_step = Math_TAU / arrow_sides; for (int k = 0; k < 4; k++) { - Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides); - Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides); + Basis ma(ivec, k * arrow_sides_step); + Basis mb(ivec, (k + 1) * arrow_sides_step); for (int j = 0; j < arrow_points - 1; j++) { Vector3 points[4] = { @@ -5605,7 +5750,7 @@ void Node3DEditor::_update_gizmos_menu() { if (!gizmo_plugins_by_name[i]->can_be_hidden()) { continue; } - String plugin_name = gizmo_plugins_by_name[i]->get_name(); + String plugin_name = gizmo_plugins_by_name[i]->get_gizmo_name(); const int plugin_state = gizmo_plugins_by_name[i]->get_state(); gizmos_menu->add_multistate_item(plugin_name, 3, plugin_state, i); const int idx = gizmos_menu->get_item_index(i); @@ -5657,8 +5802,11 @@ void Node3DEditor::_init_grid() { return; // Camera3D is invalid, don't draw the grid. } + bool orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL; + Vector<Color> grid_colors[3]; Vector<Vector3> grid_points[3]; + Vector<Vector3> grid_normals[3]; Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color"); Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color"); @@ -5694,10 +5842,26 @@ void Node3DEditor::_init_grid() { int b = (a + 1) % 3; int c = (a + 2) % 3; - real_t division_level = Math::log(Math::abs(camera_position[c])) / Math::log((double)primary_grid_steps) + division_level_bias; - division_level = CLAMP(division_level, division_level_min, division_level_max); - real_t division_level_floored = Math::floor(division_level); - real_t division_level_decimals = division_level - division_level_floored; + Vector3 normal; + normal[c] = 1.0; + + real_t camera_distance = Math::abs(camera_position[c]); + + if (orthogonal) { + camera_distance = camera->get_size() / 2.0; + Vector3 camera_direction = -camera->get_global_transform().get_basis().get_axis(2); + Plane grid_plane = Plane(Vector3(), normal); + Vector3 intersection; + if (grid_plane.intersects_ray(camera_position, camera_direction, &intersection)) { + camera_position = intersection; + } + } + + real_t division_level = Math::log(Math::abs(camera_distance)) / Math::log((double)primary_grid_steps) + division_level_bias; + + real_t clamped_division_level = CLAMP(division_level, division_level_min, division_level_max); + real_t division_level_floored = Math::floor(clamped_division_level); + real_t division_level_decimals = clamped_division_level - division_level_floored; real_t small_step_size = Math::pow(primary_grid_steps, division_level_floored); real_t large_step_size = small_step_size * primary_grid_steps; @@ -5709,6 +5873,15 @@ void Node3DEditor::_init_grid() { real_t bgn_b = center_b - grid_size * small_step_size; real_t end_b = center_b + grid_size * small_step_size; + real_t fade_size = Math::pow(primary_grid_steps, division_level - 1.0); + real_t min_fade_size = Math::pow(primary_grid_steps, float(division_level_min)); + real_t max_fade_size = Math::pow(primary_grid_steps, float(division_level_max)); + fade_size = CLAMP(fade_size, min_fade_size, max_fade_size); + + real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size; + grid_mat[c]->set_shader_param("grid_size", grid_fade_size); + grid_mat[c]->set_shader_param("orthogonal", orthogonal); + // In each iteration of this loop, draw one line in each direction (so two lines per loop, in each if statement). for (int i = -grid_size; i <= grid_size; i++) { Color line_color; @@ -5719,11 +5892,6 @@ void Node3DEditor::_init_grid() { line_color = secondary_grid_color; line_color.a = line_color.a * (1 - division_level_decimals); } - // Makes lines farther from the center fade out. - // Due to limitations of lines, any that come near the camera have full opacity always. - // This should eventually be replaced by some kind of "distance fade" system, outside of this function. - // But the effect is still somewhat convincing... - line_color.a *= 1 - (1 - division_level_decimals * 0.9) * (Math::abs(i / (float)grid_size)); real_t position_a = center_a + i * small_step_size; real_t position_b = center_b + i * small_step_size; @@ -5740,6 +5908,8 @@ void Node3DEditor::_init_grid() { grid_points[c].push_back(line_end); grid_colors[c].push_back(line_color); grid_colors[c].push_back(line_color); + grid_normals[c].push_back(normal); + grid_normals[c].push_back(normal); } if (!(origin_enabled && Math::is_zero_approx(position_b))) { @@ -5753,6 +5923,8 @@ void Node3DEditor::_init_grid() { grid_points[c].push_back(line_end); grid_colors[c].push_back(line_color); grid_colors[c].push_back(line_color); + grid_normals[c].push_back(normal); + grid_normals[c].push_back(normal); } } @@ -5762,8 +5934,9 @@ void Node3DEditor::_init_grid() { d.resize(RS::ARRAY_MAX); d[RenderingServer::ARRAY_VERTEX] = grid_points[c]; d[RenderingServer::ARRAY_COLOR] = grid_colors[c]; + d[RenderingServer::ARRAY_NORMAL] = grid_normals[c]; RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[c], RenderingServer::PRIMITIVE_LINES, d); - RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, indicator_mat->get_rid()); + RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, grid_mat[c]->get_rid()); grid_instance[c] = RenderingServer::get_singleton()->instance_create2(grid[c], get_tree()->get_root()->get_world_3d()->get_scenario()); // Yes, the end of this line is supposed to be a. @@ -5880,17 +6053,20 @@ void Node3DEditor::snap_selected_nodes_to_floor() { // Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin Set<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp); Set<CollisionShape3D *> cs = _get_child_nodes<CollisionShape3D>(sp); + bool found_valid_shape = false; if (cs.size()) { AABB aabb; - bool found_valid_shape = false; - if (cs.front()->get()->get_shape().is_valid()) { - aabb = sp->get_global_transform().xform(cs.front()->get()->get_shape()->get_debug_mesh()->get_aabb()); + Set<CollisionShape3D *>::Element *I = cs.front(); + if (I->get()->get_shape().is_valid()) { + CollisionShape3D *collision_shape = cs.front()->get(); + aabb = collision_shape->get_global_transform().xform(collision_shape->get_shape()->get_debug_mesh()->get_aabb()); found_valid_shape = true; } - for (Set<CollisionShape3D *>::Element *I = cs.front(); I; I = I->next()) { - if (I->get()->get_shape().is_valid()) { - aabb.merge_with(sp->get_global_transform().xform(I->get()->get_shape()->get_debug_mesh()->get_aabb())); + for (I = I->next(); I; I = I->next()) { + CollisionShape3D *col_shape = I->get(); + if (col_shape->get_shape().is_valid()) { + aabb.merge_with(col_shape->get_global_transform().xform(col_shape->get_shape()->get_debug_mesh()->get_aabb())); found_valid_shape = true; } } @@ -5898,10 +6074,9 @@ void Node3DEditor::snap_selected_nodes_to_floor() { Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5); from = aabb.position + size; position_offset.y = from.y - sp->get_global_transform().origin.y; - } else { - from = sp->get_global_transform().origin; } - } else if (vi.size()) { + } + if (!found_valid_shape && vi.size()) { AABB aabb = vi.front()->get()->get_transformed_aabb(); for (Set<VisualInstance3D *>::Element *I = vi.front(); I; I = I->next()) { aabb.merge_with(I->get()->get_transformed_aabb()); @@ -5909,7 +6084,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() { Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5); from = aabb.position + size; position_offset.y = from.y - sp->get_global_transform().origin.y; - } else { + } else if (!found_valid_shape) { from = sp->get_global_transform().origin; } @@ -5992,6 +6167,51 @@ void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) { snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL); } +void Node3DEditor::_sun_environ_settings_pressed() { + Vector2 pos = sun_environ_settings->get_screen_position() + sun_environ_settings->get_size(); + sun_environ_popup->set_position(pos - Vector2(sun_environ_popup->get_contents_minimum_size().width / 2, 0)); + sun_environ_popup->popup(); +} + +void Node3DEditor::_add_sun_to_scene() { + sun_environ_popup->hide(); + + Node *base = get_tree()->get_edited_scene_root(); + if (!base) { + EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation")); + return; + } + ERR_FAIL_COND(!base); + Node *new_sun = preview_sun->duplicate(); + + undo_redo->create_action("Add Preview Sun to Scene"); + undo_redo->add_do_method(base, "add_child", new_sun); + undo_redo->add_do_method(new_sun, "set_owner", base); + undo_redo->add_undo_method(base, "remove_child", new_sun); + undo_redo->add_do_reference(new_sun); + undo_redo->commit_action(); +} +void Node3DEditor::_add_environment_to_scene() { + sun_environ_popup->hide(); + + Node *base = get_tree()->get_edited_scene_root(); + if (!base) { + EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation")); + return; + } + ERR_FAIL_COND(!base); + + WorldEnvironment *new_env = memnew(WorldEnvironment); + new_env->set_environment(preview_environment->get_environment()->duplicate(true)); + + undo_redo->create_action("Add Preview Environment to Scene"); + undo_redo->add_do_method(base, "add_child", new_env); + undo_redo->add_do_method(new_env, "set_owner", base); + undo_redo->add_undo_method(base, "remove_child", new_env); + undo_redo->add_do_reference(new_env); + undo_redo->commit_action(); +} + void Node3DEditor::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { tool_button[Node3DEditor::TOOL_MODE_SELECT]->set_icon(get_theme_icon("ToolSelect", "EditorIcons")); @@ -6020,17 +6240,31 @@ void Node3DEditor::_notification(int p_what) { _refresh_menu_icons(); get_tree()->connect("node_removed", callable_mp(this, &Node3DEditor::_node_removed)); + get_tree()->connect("node_added", callable_mp(this, &Node3DEditor::_node_added)); EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false)); editor->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true)); + + sun_button->set_icon(get_theme_icon("DirectionalLight3D", "EditorIcons")); + environ_button->set_icon(get_theme_icon("WorldEnvironment", "EditorIcons")); + sun_environ_settings->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons")); + + _update_preview_environment(); + sun_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); + environ_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); + + sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size()); + environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size()); } else if (p_what == NOTIFICATION_ENTER_TREE) { _register_all_gizmos(); _update_gizmos_menu(); _init_indicators(); } else if (p_what == NOTIFICATION_THEME_CHANGED) { _update_gizmos_menu_theme(); + sun_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); + environ_title->add_theme_font_override("font", get_theme_font("title_font", "Window")); } else if (p_what == NOTIFICATION_EXIT_TREE) { _finish_indicators(); } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { @@ -6167,7 +6401,37 @@ void Node3DEditor::_toggle_maximize_view(Object *p_viewport) { } } +void Node3DEditor::_node_added(Node *p_node) { + if (EditorNode::get_singleton()->get_scene_root()->is_a_parent_of(p_node)) { + if (Object::cast_to<WorldEnvironment>(p_node)) { + world_env_count++; + if (world_env_count == 1) { + _update_preview_environment(); + } + } else if (Object::cast_to<DirectionalLight3D>(p_node)) { + directional_light_count++; + if (directional_light_count == 1) { + _update_preview_environment(); + } + } + } +} + void Node3DEditor::_node_removed(Node *p_node) { + if (EditorNode::get_singleton()->get_scene_root()->is_a_parent_of(p_node)) { + if (Object::cast_to<WorldEnvironment>(p_node)) { + world_env_count--; + if (world_env_count == 0) { + _update_preview_environment(); + } + } else if (Object::cast_to<DirectionalLight3D>(p_node)) { + directional_light_count--; + if (directional_light_count == 0) { + _update_preview_environment(); + } + } + } + if (p_node == selected) { selected = nullptr; } @@ -6194,6 +6458,7 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin))); add_gizmo_plugin(Ref<BakedLightmapGizmoPlugin>(memnew(BakedLightmapGizmoPlugin))); add_gizmo_plugin(Ref<LightmapProbeGizmoPlugin>(memnew(LightmapProbeGizmoPlugin))); + add_gizmo_plugin(Ref<CollisionObject3DGizmoPlugin>(memnew(CollisionObject3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionPolygon3DGizmoPlugin>(memnew(CollisionPolygon3DGizmoPlugin))); add_gizmo_plugin(Ref<NavigationRegion3DGizmoPlugin>(memnew(NavigationRegion3DGizmoPlugin))); @@ -6237,6 +6502,128 @@ void Node3DEditor::clear() { view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true); } +void Node3DEditor::_sun_direction_draw() { + sun_direction->draw_rect(Rect2(Vector2(), sun_direction->get_size()), Color(1, 1, 1, 1)); + sun_direction_material->set_shader_param("sun_direction", -preview_sun->get_transform().basis.get_axis(Vector3::AXIS_Z)); + float nrg = sun_energy->get_value(); + sun_direction_material->set_shader_param("sun_color", Vector3(sun_color->get_pick_color().r * nrg, sun_color->get_pick_color().g * nrg, sun_color->get_pick_color().b * nrg)); +} + +void Node3DEditor::_preview_settings_changed() { + if (sun_environ_updating) { + return; + } + + { // preview sun + Transform t; + t.basis = sun_rotation; + preview_sun->set_transform(t); + sun_direction->update(); + preview_sun->set_param(Light3D::PARAM_ENERGY, sun_energy->get_value()); + preview_sun->set_param(Light3D::PARAM_SHADOW_MAX_DISTANCE, sun_max_distance->get_value()); + preview_sun->set_color(sun_color->get_pick_color()); + } + + { //preview env + sky_material->set_sky_energy(environ_energy->get_value()); + Color hz_color = environ_sky_color->get_pick_color().lerp(environ_ground_color->get_pick_color(), 0.5).lerp(Color(1, 1, 1), 0.5); + sky_material->set_sky_top_color(environ_sky_color->get_pick_color()); + sky_material->set_sky_horizon_color(hz_color); + sky_material->set_ground_bottom_color(environ_ground_color->get_pick_color()); + sky_material->set_ground_horizon_color(hz_color); + + environment->set_ssao_enabled(environ_ao_button->is_pressed()); + environment->set_glow_enabled(environ_glow_button->is_pressed()); + environment->set_sdfgi_enabled(environ_gi_button->is_pressed()); + environment->set_tonemapper(environ_tonemap_button->is_pressed() ? Environment::TONE_MAPPER_FILMIC : Environment::TONE_MAPPER_LINEAR); + } +} +void Node3DEditor::_load_default_preview_settings() { + sun_environ_updating = true; + + sun_rotation = Basis(Vector3(0, 1, 0), Math_PI * 3.0 / 4) * Basis(Vector3(1, 0, 0), -Math_PI / 4); + + sun_direction->update(); + environ_sky_color->set_pick_color(Color::hex(0x91b2ceff)); + environ_ground_color->set_pick_color(Color::hex(0x1f1f21ff)); + environ_energy->set_value(1.0); + environ_glow_button->set_pressed(true); + environ_tonemap_button->set_pressed(true); + environ_ao_button->set_pressed(false); + environ_gi_button->set_pressed(false); + sun_max_distance->set_value(250); + + sun_color->set_pick_color(Color(1, 1, 1)); + sun_energy->set_value(1.0); + + sun_environ_updating = false; +} + +void Node3DEditor::_update_preview_environment() { + bool disable_light = directional_light_count > 0 || sun_button->is_pressed(); + + sun_button->set_disabled(directional_light_count > 0); + + if (disable_light) { + if (preview_sun->get_parent()) { + preview_sun->get_parent()->remove_child(preview_sun); + sun_state->show(); + sun_vb->hide(); + } + + if (directional_light_count > 0) { + sun_state->set_text(TTR("Scene contains\nDirectionalLight3D.\nPreview disabled.")); + } else { + sun_state->set_text(TTR("Preview disabled.")); + } + + } else { + if (!preview_sun->get_parent()) { + add_child(preview_sun); + sun_state->hide(); + sun_vb->show(); + } + } + + bool disable_env = world_env_count > 0 || environ_button->is_pressed(); + + environ_button->set_disabled(world_env_count > 0); + + if (disable_env) { + if (preview_environment->get_parent()) { + preview_environment->get_parent()->remove_child(preview_environment); + environ_state->show(); + environ_vb->hide(); + } + if (world_env_count > 0) { + environ_state->set_text(TTR("Scene contains\nWorldEnvironment.\nPreview disabled.")); + } else { + environ_state->set_text(TTR("Preview disabled.")); + } + + } else { + if (!preview_environment->get_parent()) { + add_child(preview_environment); + environ_state->hide(); + environ_vb->show(); + } + } +} + +void Node3DEditor::_sun_direction_input(const Ref<InputEvent> &p_event) { + Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + float x = -mm->get_relative().y * 0.02 * EDSCALE; + float y = mm->get_relative().x * 0.02 * EDSCALE; + + Basis rot = Basis(Vector3(0, 1, 0), y) * Basis(Vector3(1, 0, 0), x); + + sun_rotation = rot * sun_rotation; + sun_rotation.orthonormalize(); + _preview_settings_changed(); + } +} + Node3DEditor::Node3DEditor(EditorNode *p_editor) { gizmo.visible = true; gizmo.scale = 1.0; @@ -6374,6 +6761,32 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { _update_camera_override_button(false); hbc_menu->add_child(memnew(VSeparator)); + sun_button = memnew(Button); + sun_button->set_tooltip(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled.")); + sun_button->set_toggle_mode(true); + sun_button->set_flat(true); + sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); + sun_button->set_disabled(true); + + hbc_menu->add_child(sun_button); + + environ_button = memnew(Button); + environ_button->set_tooltip(TTR("Toggle preview environment.\nIf a WorldEnvironment node is added to the scene, preview environment is disabled.")); + environ_button->set_toggle_mode(true); + environ_button->set_flat(true); + environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); + environ_button->set_disabled(true); + + hbc_menu->add_child(environ_button); + + sun_environ_settings = memnew(Button); + sun_environ_settings->set_tooltip(TTR("Edit Sun and Environment settings.")); + sun_environ_settings->set_flat(true); + sun_environ_settings->connect("pressed", callable_mp(this, &Node3DEditor::_sun_environ_settings_pressed)); + + hbc_menu->add_child(sun_environ_settings); + + hbc_menu->add_child(memnew(VSeparator)); // Drag and drop support; preview_node = memnew(Node3D); @@ -6603,6 +7016,152 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true); over_gizmo_handle = -1; + { + //sun popup + + sun_environ_popup = memnew(PopupPanel); + add_child(sun_environ_popup); + + HBoxContainer *sun_environ_hb = memnew(HBoxContainer); + + sun_environ_popup->add_child(sun_environ_hb); + + sun_vb = memnew(VBoxContainer); + sun_environ_hb->add_child(sun_vb); + sun_vb->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); + sun_vb->hide(); + + sun_title = memnew(Label); + sun_vb->add_child(sun_title); + sun_title->set_text(TTR("Preview Sun")); + sun_title->set_align(Label::ALIGN_CENTER); + + CenterContainer *sun_direction_center = memnew(CenterContainer); + sun_direction = memnew(Control); + sun_direction->set_custom_minimum_size(Size2i(128, 128) * EDSCALE); + sun_direction_center->add_child(sun_direction); + sun_vb->add_margin_child(TTR("Sun Direction"), sun_direction_center); + sun_direction->connect("gui_input", callable_mp(this, &Node3DEditor::_sun_direction_input)); + sun_direction->connect("draw", callable_mp(this, &Node3DEditor::_sun_direction_draw)); + sun_direction->set_default_cursor_shape(CURSOR_MOVE); + + String sun_dir_shader_code = "shader_type canvas_item; uniform vec3 sun_direction; uniform vec3 sun_color; void fragment() { vec3 n; n.xy = UV * 2.0 - 1.0; n.z = sqrt(max(0.0, 1.0 - dot(n.xy, n.xy))); COLOR.rgb = dot(n,sun_direction) * sun_color; COLOR.a = 1.0 - smoothstep(0.99,1.0,length(n.xy)); }"; + sun_direction_shader.instance(); + sun_direction_shader->set_code(sun_dir_shader_code); + sun_direction_material.instance(); + sun_direction_material->set_shader(sun_direction_shader); + sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1)); + sun_direction_material->set_shader_param("sun_color", Vector3(1, 1, 1)); + sun_direction->set_material(sun_direction_material); + + sun_color = memnew(ColorPickerButton); + sun_color->set_edit_alpha(false); + sun_vb->add_margin_child(TTR("Sun Color"), sun_color); + sun_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + + sun_energy = memnew(EditorSpinSlider); + sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy); + sun_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + sun_energy->set_max(64.0); + + sun_max_distance = memnew(EditorSpinSlider); + sun_vb->add_margin_child(TTR("Shadow Max Distance"), sun_max_distance); + sun_max_distance->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + sun_max_distance->set_min(1); + sun_max_distance->set_max(4096); + + sun_add_to_scene = memnew(Button); + sun_add_to_scene->set_text(TTR("Add Sun to Scene")); + sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene)); + sun_vb->add_spacer(); + sun_vb->add_child(sun_add_to_scene); + + sun_state = memnew(Label); + sun_environ_hb->add_child(sun_state); + sun_state->set_align(Label::ALIGN_CENTER); + sun_state->set_valign(Label::VALIGN_CENTER); + sun_state->set_h_size_flags(SIZE_EXPAND_FILL); + + VSeparator *sc = memnew(VSeparator); + sc->set_custom_minimum_size(Size2(50 * EDSCALE, 0)); + sc->set_v_size_flags(SIZE_EXPAND_FILL); + sun_environ_hb->add_child(sc); + + environ_vb = memnew(VBoxContainer); + sun_environ_hb->add_child(environ_vb); + environ_vb->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); + environ_vb->hide(); + + environ_title = memnew(Label); + environ_vb->add_child(environ_title); + environ_title->set_text(TTR("Preview Environment")); + environ_title->set_align(Label::ALIGN_CENTER); + + environ_sky_color = memnew(ColorPickerButton); + environ_sky_color->set_edit_alpha(false); + environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_vb->add_margin_child(TTR("Sky Color"), environ_sky_color); + environ_ground_color = memnew(ColorPickerButton); + environ_ground_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_ground_color->set_edit_alpha(false); + environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color); + environ_energy = memnew(EditorSpinSlider); + environ_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_energy->set_max(8.0); + environ_vb->add_margin_child(TTR("Sky Energy"), environ_energy); + HBoxContainer *fx_vb = memnew(HBoxContainer); + fx_vb->set_h_size_flags(SIZE_EXPAND_FILL); + + environ_ao_button = memnew(Button); + environ_ao_button->set_text(TTR("AO")); + environ_ao_button->set_toggle_mode(true); + environ_ao_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_ao_button); + environ_glow_button = memnew(Button); + environ_glow_button->set_text(TTR("Glow")); + environ_glow_button->set_toggle_mode(true); + environ_glow_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_glow_button); + environ_tonemap_button = memnew(Button); + environ_tonemap_button->set_text(TTR("Tonemap")); + environ_tonemap_button->set_toggle_mode(true); + environ_tonemap_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_tonemap_button); + environ_gi_button = memnew(Button); + environ_gi_button->set_text(TTR("GI")); + environ_gi_button->set_toggle_mode(true); + environ_gi_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED); + fx_vb->add_child(environ_gi_button); + environ_vb->add_margin_child(TTR("Post Process"), fx_vb); + + environ_add_to_scene = memnew(Button); + environ_add_to_scene->set_text(TTR("Add Environment to Scene")); + environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene)); + environ_vb->add_spacer(); + environ_vb->add_child(environ_add_to_scene); + + environ_state = memnew(Label); + sun_environ_hb->add_child(environ_state); + environ_state->set_align(Label::ALIGN_CENTER); + environ_state->set_valign(Label::VALIGN_CENTER); + environ_state->set_h_size_flags(SIZE_EXPAND_FILL); + + preview_sun = memnew(DirectionalLight3D); + preview_sun->set_shadow(true); + preview_sun->set_shadow_mode(DirectionalLight3D::SHADOW_PARALLEL_4_SPLITS); + preview_environment = memnew(WorldEnvironment); + environment.instance(); + preview_environment->set_environment(environment); + Ref<Sky> sky; + sky.instance(); + sky_material.instance(); + sky->set_material(sky_material); + environment->set_sky(sky); + environment->set_background(Environment::BG_SKY); + + _load_default_preview_settings(); + _preview_settings_changed(); + } } Node3DEditor::~Node3DEditor() { @@ -6693,7 +7252,7 @@ void Node3DEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) { struct _GizmoPluginPriorityComparator { bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const { if (p_a->get_priority() == p_b->get_priority()) { - return p_a->get_name() < p_b->get_name(); + return p_a->get_gizmo_name() < p_b->get_gizmo_name(); } return p_a->get_priority() > p_b->get_priority(); } @@ -6701,7 +7260,7 @@ struct _GizmoPluginPriorityComparator { struct _GizmoPluginNameComparator { bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const { - return p_a->get_name() < p_b->get_name(); + return p_a->get_gizmo_name() < p_b->get_gizmo_name(); } }; @@ -6912,7 +7471,7 @@ void EditorNode3DGizmoPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material, DEFVAL(Ref<EditorNode3DGizmo>())); - BIND_VMETHOD(MethodInfo(Variant::STRING, "get_name")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "get_gizmo_name")); BIND_VMETHOD(MethodInfo(Variant::INT, "get_priority")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_be_hidden")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_selectable_when_hidden")); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 0cefaa6557..cf4aa33257 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -37,7 +37,10 @@ #include "scene/3d/immediate_geometry_3d.h" #include "scene/3d/light_3d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/3d/world_environment.h" #include "scene/gui/panel_container.h" +#include "scene/resources/environment.h" +#include "scene/resources/sky_material.h" class Camera3D; class Node3DEditor; @@ -213,6 +216,11 @@ class Node3DEditorViewport : public Control { VIEW_DISPLAY_DEBUG_SDFGI_PROBES, VIEW_DISPLAY_DEBUG_GI_BUFFER, VIEW_DISPLAY_DEBUG_DISABLE_LOD, + VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS, + VIEW_DISPLAY_DEBUG_CLUSTER_DECALS, + VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES, + VIEW_LOCK_ROTATION, VIEW_CINEMATIC_PREVIEW, VIEW_AUTO_ORTHOGONAL, @@ -458,6 +466,8 @@ private: bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + void _project_settings_changed(); + protected: void _notification(int p_what); static void _bind_methods(); @@ -585,7 +595,6 @@ private: ///// ToolMode tool_mode; - bool orthogonal; RenderingServer::ScenarioDebugMode scenario_debug; @@ -618,6 +627,7 @@ private: RID cursor_mesh; RID cursor_instance; Ref<StandardMaterial3D> indicator_mat; + Ref<ShaderMaterial> grid_mat[3]; Ref<StandardMaterial3D> cursor_material; // Scene drag and drop support @@ -725,6 +735,7 @@ private: static Node3DEditor *singleton; + void _node_added(Node *p_node); void _node_removed(Node *p_node); Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_priority; Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_name; @@ -737,6 +748,61 @@ private: void _refresh_menu_icons(); + // Preview Sun and Environment + + uint32_t world_env_count = 0; + uint32_t directional_light_count = 0; + + Button *sun_button; + Label *sun_state; + Label *sun_title; + VBoxContainer *sun_vb; + Popup *sun_environ_popup; + Control *sun_direction; + ColorPickerButton *sun_color; + EditorSpinSlider *sun_energy; + EditorSpinSlider *sun_max_distance; + Button *sun_add_to_scene; + + void _sun_direction_draw(); + void _sun_direction_input(const Ref<InputEvent> &p_event); + + Basis sun_rotation; + + Ref<Shader> sun_direction_shader; + Ref<ShaderMaterial> sun_direction_material; + + Button *environ_button; + Label *environ_state; + Label *environ_title; + VBoxContainer *environ_vb; + ColorPickerButton *environ_sky_color; + ColorPickerButton *environ_ground_color; + EditorSpinSlider *environ_energy; + Button *environ_ao_button; + Button *environ_glow_button; + Button *environ_tonemap_button; + Button *environ_gi_button; + Button *environ_add_to_scene; + + Button *sun_environ_settings; + + DirectionalLight3D *preview_sun; + WorldEnvironment *preview_environment; + Ref<Environment> environment; + Ref<ProceduralSkyMaterial> sky_material; + + bool sun_environ_updating = false; + + void _load_default_preview_settings(); + void _update_preview_environment(); + + void _preview_settings_changed(); + void _sun_environ_settings_pressed(); + + void _add_sun_to_scene(); + void _add_environment_to_scene(); + protected: void _notification(int p_what); //void _gui_input(InputEvent p_event); diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 1f20a87565..0a949c8610 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -42,7 +42,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, // These properties are translated with the tr() function in the C++ code when being set or updated. Error err; - RES loaded_res = ResourceLoader::load(p_path, "PackedScene", false, &err); + RES loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 1af790c48d..a6afd45686 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -894,7 +894,7 @@ void ScriptEditor::_reload_scripts() { Ref<Script> script = edited_res; if (script != nullptr) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); @@ -1954,7 +1954,20 @@ void ScriptEditor::_update_script_names() { Vector<String> disambiguated_script_names; Vector<String> full_script_paths; for (int j = 0; j < sedata.size(); j++) { - disambiguated_script_names.append(sedata[j].name.replace("(*)", "").get_file()); + String name = sedata[j].name.replace("(*)", ""); + ScriptListName script_display = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/script_list/list_script_names_as"); + switch (script_display) { + case DISPLAY_NAME: { + name = name.get_file(); + } break; + case DISPLAY_DIR_AND_NAME: { + name = name.get_base_dir().get_file().plus_file(name.get_file()); + } break; + default: + break; + } + + disambiguated_script_names.append(name); full_script_paths.append(sedata[j].tooltip); } @@ -2198,7 +2211,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra args.push_back(script_path); } - Error err = OS::get_singleton()->execute(path, args, false); + Error err = OS::get_singleton()->create_process(path, args); if (err == OK) { return false; } diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 1b0e9ec781..b6df66b8af 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -214,7 +214,7 @@ void ScriptTextEditor::_load_theme_settings() { text_edit->add_theme_color_override("line_number_color", line_number_color); text_edit->add_theme_color_override("caret_color", caret_color); text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_color_selected", text_selected_color); + text_edit->add_theme_color_override("font_selected_color", text_selected_color); text_edit->add_theme_color_override("selection_color", selection_color); text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); text_edit->add_theme_color_override("current_line_color", current_line_color); @@ -688,7 +688,7 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo uint64_t date = FileAccess::get_modified_time(script->get_path()); if (last_date != date) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); @@ -1066,7 +1066,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->indent_left(); + tx->indent_selected_lines_left(); } break; case EDIT_INDENT_RIGHT: { Ref<Script> scr = script; @@ -1074,7 +1074,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->indent_right(); + tx->indent_selected_lines_right(); } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); @@ -1632,16 +1632,16 @@ void ScriptTextEditor::_color_changed(const Color &p_color) { void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos) { context_menu->clear(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); @@ -1743,14 +1743,14 @@ void ScriptTextEditor::_enable_code_editor() { search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); edit_hb->add_child(edit_menu); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); @@ -1763,7 +1763,7 @@ void ScriptTextEditor::_enable_code_editor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); @@ -1915,12 +1915,6 @@ static ScriptEditorBase *create_editor(const RES &p_resource) { } void ScriptTextEditor::register_editor() { - ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD | KEY_Z); - ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD | KEY_Y); - ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD | KEY_X); - ED_SHORTCUT("script_text_editor/copy", TTR("Copy"), KEY_MASK_CMD | KEY_C); - ED_SHORTCUT("script_text_editor/paste", TTR("Paste"), KEY_MASK_CMD | KEY_V); - ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD | KEY_A); ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT | KEY_UP); ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN); ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K); @@ -1936,10 +1930,8 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0); #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE); #else ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D); - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE); #endif ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E); ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index d6a816f606..c8a46715ad 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -117,7 +117,7 @@ void ShaderTextEditor::_load_theme_settings() { get_text_editor()->add_theme_color_override("line_number_color", line_number_color); get_text_editor()->add_theme_color_override("caret_color", caret_color); get_text_editor()->add_theme_color_override("caret_background_color", caret_background_color); - get_text_editor()->add_theme_color_override("font_color_selected", text_selected_color); + get_text_editor()->add_theme_color_override("font_selected_color", text_selected_color); get_text_editor()->add_theme_color_override("selection_color", selection_color); get_text_editor()->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); get_text_editor()->add_theme_color_override("current_line_color", current_line_color); @@ -282,7 +282,7 @@ void ShaderEditor::_menu_option(int p_option) { } CodeEdit *tx = shader_editor->get_text_editor(); - tx->indent_left(); + tx->indent_selected_lines_left(); } break; case EDIT_INDENT_RIGHT: { @@ -291,7 +291,7 @@ void ShaderEditor::_menu_option(int p_option) { } CodeEdit *tx = shader_editor->get_text_editor(); - tx->indent_right(); + tx->indent_selected_lines_right(); } break; case EDIT_DELETE_LINE: { @@ -405,7 +405,7 @@ void ShaderEditor::_check_for_external_edit() { } void ShaderEditor::_reload_shader_from_disk() { - Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), true); + Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_FAIL_COND(!rel_shader.is_valid()); shader->set_code(rel_shader->get_code()); @@ -533,15 +533,15 @@ void ShaderEditor::_bookmark_item_pressed(int p_idx) { void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) { context_menu->clear(); if (p_selection) { - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); } - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); @@ -585,14 +585,14 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { edit_menu->set_text(TTR("Edit")); edit_menu->set_switch_on_hover(true); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); @@ -602,7 +602,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); search_menu = memnew(MenuButton); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index ea58a4535b..121ccfa417 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -383,8 +383,12 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi CollisionShape3D *bone_shape = memnew(CollisionShape3D); bone_shape->set_shape(bone_shape_capsule); + Transform capsule_transform; + capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0)); + bone_shape->set_transform(capsule_transform); + Transform body_transform; - body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin, Vector3(0, 1, 0)); + body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin); body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height)); Transform joint_transform; diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index 03ddaa2c74..4949d2b9b7 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -173,6 +173,11 @@ void Sprite2DEditor::_update_mesh_data() { Ref<Image> image = texture->get_data(); ERR_FAIL_COND(image.is_null()); + + if (image->is_compressed()) { + image->decompress(); + } + Rect2 rect; if (node->is_region()) { rect = node->get_region_rect(); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 2aa6ad0eaa..0547f99079 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "scene/3d/sprite_3d.h" @@ -952,7 +953,11 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "files") { Vector<String> files = d["files"]; - _file_load_request(files, at_pos); + if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + _prepare_sprite_sheet(files[0]); + } else { + _file_load_request(files, at_pos); + } } } diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 3628a2e4d1..b88f1c91e6 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -96,7 +96,7 @@ void TextEditor::_load_theme_settings() { text_edit->add_theme_color_override("line_number_color", line_number_color); text_edit->add_theme_color_override("caret_color", caret_color); text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_color_selected", text_selected_color); + text_edit->add_theme_color_override("font_selected_color", text_selected_color); text_edit->add_theme_color_override("selection_color", selection_color); text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); text_edit->add_theme_color_override("current_line_color", current_line_color); @@ -363,10 +363,10 @@ void TextEditor::_edit_option(int p_op) { code_editor->move_lines_down(); } break; case EDIT_INDENT_LEFT: { - tx->indent_left(); + tx->indent_selected_lines_left(); } break; case EDIT_INDENT_RIGHT: { - tx->indent_right(); + tx->indent_selected_lines_right(); } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); @@ -514,15 +514,15 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded, Vector2 p_position) { context_menu->clear(); if (p_selection) { - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); } - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); @@ -584,14 +584,14 @@ TextEditor::TextEditor() { edit_menu->set_switch_on_hover(true); edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextEditor::_edit_option)); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("un_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 099257daa1..36297c8a4a 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -57,7 +57,7 @@ void Texture3DEditor::_notification(int p_what) { } } -void Texture3DEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void Texture3DEditor::_texture_changed() { if (!is_visible()) { return; } @@ -118,7 +118,7 @@ void Texture3DEditor::_texture_rect_update_area() { void Texture3DEditor::edit(Ref<Texture3D> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); } texture = p_texture; @@ -128,7 +128,7 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) { _make_shaders(); } - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); update(); texture_rect->set_material(material); setting = true; @@ -173,8 +173,7 @@ Texture3DEditor::Texture3DEditor() { info->set_h_grow_direction(GROW_DIRECTION_BEGIN); info->set_v_grow_direction(GROW_DIRECTION_BEGIN); info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5)); info->add_theme_constant_override("shadow_as_outline", 1); info->add_theme_constant_override("shadow_offset_x", 2); info->add_theme_constant_override("shadow_offset_y", 2); @@ -185,7 +184,7 @@ Texture3DEditor::Texture3DEditor() { Texture3DEditor::~Texture3DEditor() { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); } } diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h index 944abf16d9..9d90d3653f 100644 --- a/editor/plugins/texture_3d_editor_plugin.h +++ b/editor/plugins/texture_3d_editor_plugin.h @@ -61,10 +61,12 @@ class Texture3DEditor : public Control { void _texture_rect_update_area(); void _texture_rect_draw(); + void _texture_changed(); + protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; + static void _bind_methods(); public: diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 1d3fd668c6..253f8878d2 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -104,7 +104,7 @@ void TextureEditor::_notification(int p_what) { } } -void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureEditor::_texture_changed() { if (!is_visible()) { return; } @@ -113,13 +113,13 @@ void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { void TextureEditor::edit(Ref<Texture2D> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed)); } texture = p_texture; if (!texture.is_null()) { - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &TextureEditor::_texture_changed)); update(); } else { hide(); @@ -137,7 +137,7 @@ TextureEditor::TextureEditor() { TextureEditor::~TextureEditor() { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed)); } } diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 621d737028..ebe8882194 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -43,7 +43,7 @@ class TextureEditor : public Control { protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; + void _texture_changed(); static void _bind_methods(); public: diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 3b95ed813f..254ad3d56e 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -63,7 +63,7 @@ void TextureLayeredEditor::_notification(int p_what) { } } -void TextureLayeredEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureLayeredEditor::_texture_changed() { if (!is_visible()) { return; } @@ -173,7 +173,7 @@ void TextureLayeredEditor::_texture_rect_update_area() { void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); } texture = p_texture; @@ -183,7 +183,7 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { _make_shaders(); } - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); update(); texture_rect->set_material(materials[texture->get_layered_type()]); setting = true; @@ -238,8 +238,7 @@ TextureLayeredEditor::TextureLayeredEditor() { info->set_h_grow_direction(GROW_DIRECTION_BEGIN); info->set_v_grow_direction(GROW_DIRECTION_BEGIN); info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); - info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5)); info->add_theme_constant_override("shadow_as_outline", 1); info->add_theme_constant_override("shadow_offset_x", 2); info->add_theme_constant_override("shadow_offset_y", 2); @@ -249,9 +248,6 @@ TextureLayeredEditor::TextureLayeredEditor() { } TextureLayeredEditor::~TextureLayeredEditor() { - if (!texture.is_null()) { - texture->remove_change_receptor(this); - } } // diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h index 4bcc8fa1f1..c4ced62fb9 100644 --- a/editor/plugins/texture_layered_editor_plugin.h +++ b/editor/plugins/texture_layered_editor_plugin.h @@ -63,10 +63,11 @@ class TextureLayeredEditor : public Control { void _texture_rect_update_area(); void _texture_rect_draw(); + void _texture_changed(); + protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; static void _bind_methods(); public: diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 53e127d4c8..63255e6547 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -42,8 +42,21 @@ void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) { Vector2 line = (to - from).normalized() * 10; + + // Draw a translucent background line to make the foreground line visible on any background. + edit_draw->draw_line( + from, + to, + EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor").inverted() * Color(1, 1, 1, 0.5), + Math::round(2 * EDSCALE)); + while ((to - from).length_squared() > 200) { - edit_draw->draw_line(from, from + line, EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor"), 2); + edit_draw->draw_line( + from, + from + line, + EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor"), + Math::round(2 * EDSCALE)); + from += line * 2; } } @@ -467,20 +480,41 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom); hscroll->set_value(hscroll->get_value() - dragged.x); vscroll->set_value(vscroll->get_value() - dragged.y); - } else if (drag) { if (edited_margin >= 0) { float new_margin = 0; - if (edited_margin == 0) { - new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom; - } else if (edited_margin == 1) { - new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom; - } else if (edited_margin == 2) { - new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom; - } else if (edited_margin == 3) { - new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom; + + if (snap_mode != SNAP_GRID) { + if (edited_margin == 0) { + new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom; + } else if (edited_margin == 1) { + new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom; + } else if (edited_margin == 2) { + new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom; + } else if (edited_margin == 3) { + new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom; + } else { + ERR_PRINT("Unexpected edited_margin"); + } + + if (snap_mode == SNAP_PIXEL) { + new_margin = Math::round(new_margin); + } } else { - ERR_PRINT("Unexpected edited_margin"); + Vector2 pos_snapped = snap_point(mtx.affine_inverse().xform(mm->get_position())); + Rect2 rect_rounded = Rect2(rect.position.round(), rect.size.round()); + + if (edited_margin == 0) { + new_margin = pos_snapped.y - rect_rounded.position.y; + } else if (edited_margin == 1) { + new_margin = rect_rounded.size.y + rect_rounded.position.y - pos_snapped.y; + } else if (edited_margin == 2) { + new_margin = pos_snapped.x - rect_rounded.position.x; + } else if (edited_margin == 3) { + new_margin = rect_rounded.size.x + rect_rounded.position.x - pos_snapped.x; + } else { + ERR_PRINT("Unexpected edited_margin"); + } } if (new_margin < 0) { @@ -829,19 +863,19 @@ Sprite2D *TextureRegionEditor::get_sprite() { void TextureRegionEditor::edit(Object *p_obj) { if (node_sprite) { - node_sprite->remove_change_receptor(this); + node_sprite->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_sprite_3d) { - node_sprite_3d->remove_change_receptor(this); + node_sprite_3d->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_ninepatch) { - node_ninepatch->remove_change_receptor(this); + node_ninepatch->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (obj_styleBox.is_valid()) { - obj_styleBox->remove_change_receptor(this); + obj_styleBox->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (atlas_tex.is_valid()) { - atlas_tex->remove_change_receptor(this); + atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (p_obj) { node_sprite = Object::cast_to<Sprite2D>(p_obj); @@ -853,7 +887,7 @@ void TextureRegionEditor::edit(Object *p_obj) { if (Object::cast_to<AtlasTexture>(p_obj)) { atlas_tex = Ref<AtlasTexture>(Object::cast_to<AtlasTexture>(p_obj)); } - p_obj->add_change_receptor(this); + p_obj->connect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); _edit_region(); } else { node_sprite = nullptr; @@ -871,14 +905,11 @@ void TextureRegionEditor::edit(Object *p_obj) { } } -void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureRegionEditor::_texture_changed() { if (!is_visible()) { return; } - String prop = p_prop; - if (prop == "atlas" || prop == "texture" || prop == "region") { - _edit_region(); - } + _edit_region(); } void TextureRegionEditor::_edit_region() { diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index 56ccefb025..d3db0a08a9 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -117,6 +117,8 @@ class TextureRegionEditor : public VBoxContainer { void _update_rect(); void _update_autoslice(); + void _texture_changed(); + protected: void _notification(int p_what); void _node_removed(Object *p_obj); @@ -124,8 +126,6 @@ protected: Vector2 snap_point(Vector2 p_target) const; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; - public: void _edit_region(); void _region_draw(); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 6a16aa28a9..74b01b3c36 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -40,9 +40,12 @@ void TileMapEditor::_node_removed(Node *p_node) { if (p_node == node && node) { - // Fixes #44824, which describes a situation where you can reselect a TileMap node without first de-selecting it when switching scenes. - node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + if (node->is_connected("settings_changed", callable_tileset_settings_changed)) { + // Fixes #44824, which describes a situation where you can reselect a TileMap node without first de-selecting it when switching scenes. + node->disconnect("settings_changed", callable_tileset_settings_changed); + } node = nullptr; } } @@ -1870,7 +1873,11 @@ void TileMapEditor::edit(Node *p_tile_map) { } if (node) { - node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (node->is_connected("settings_changed", callable_tileset_settings_changed)) { + node->disconnect("settings_changed", callable_tileset_settings_changed); + } } if (p_tile_map) { node = Object::cast_to<TileMap>(p_tile_map); @@ -1897,7 +1904,11 @@ void TileMapEditor::edit(Node *p_tile_map) { } if (node) { - node->connect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (!node->is_connected("settings_changed", callable_tileset_settings_changed)) { + node->connect("settings_changed", callable_tileset_settings_changed); + } } _clear_bucket_cache(); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index deeab2fbc7..c628fe8367 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -39,7 +39,6 @@ void TileSetEditor::edit(const Ref<TileSet> &p_tileset) { tileset = p_tileset; - tileset->add_change_receptor(this); texture_list->clear(); texture_map.clear(); @@ -1859,7 +1858,7 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { _update_toggle_shape_button(); workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } else if (p_tool == SELECT_NEXT) { _select_next_shape(); @@ -2173,7 +2172,7 @@ Array TileSetEditor::_get_tiles_in_current_texture(bool sorted) { } } if (sorted) { - a.sort_custom(this, "_sort_tiles"); + a.sort_custom(callable_mp(this, &TileSetEditor::_sort_tiles)); } return a; } @@ -2287,7 +2286,7 @@ void TileSetEditor::_select_next_shape() { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } @@ -2349,7 +2348,7 @@ void TileSetEditor::_select_previous_shape() { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } @@ -3012,7 +3011,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { undo_redo->add_undo_method(this, "_select_edited_shape_coord"); undo_redo->commit_action(); } - tileset->_change_notify(""); + tileset->notify_property_list_changed(); } void TileSetEditor::select_coord(const Vector2 &coord) { @@ -3115,7 +3114,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } Vector2 TileSetEditor::snap_point(const Vector2 &point) { @@ -3225,7 +3224,7 @@ void TileSetEditor::update_texture_list() { workspace_overlay->update(); } update_texture_list_icon(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } void TileSetEditor::update_texture_list_icon() { @@ -3389,7 +3388,7 @@ int TileSetEditor::get_current_tile() const { void TileSetEditor::set_current_tile(int p_id) { if (current_tile != p_id) { current_tile = p_id; - helper->_change_notify(""); + helper->notify_property_list_changed(); select_coord(Vector2(0, 0)); update_workspace_tile_mode(); if (p_id == -1) { @@ -3414,7 +3413,7 @@ void TilesetEditorContext::set_tileset(const Ref<TileSet> &p_tileset) { void TilesetEditorContext::set_snap_options_visible(bool p_visible) { snap_options_visible = p_visible; - _change_notify(""); + notify_property_list_changed(); } bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value) { @@ -3450,7 +3449,7 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/" + name2, p_value, &v); } if (v) { - tileset->_change_notify(""); + tileset->notify_property_list_changed(); tileset_editor->workspace->update(); tileset_editor->workspace_overlay->update(); } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 056562a7a7..a63e641c2b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -44,6 +44,7 @@ #include "scene/gui/panel.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" +#include "scene/resources/visual_shader_sdf_nodes.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -618,7 +619,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) { Label *hint_label = memnew(Label); hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]"); - hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_color_readonly", "TextEdit")); + hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_readonly_color", "TextEdit")); hint_label->add_theme_style_override("normal", label_style); hb->add_child(hint_label); } @@ -1022,7 +1023,7 @@ void VisualShaderEditor::_update_options_menu() { Color unsupported_color = get_theme_color("error_color", "Editor"); Color supported_color = get_theme_color("warning_color", "Editor"); - static bool low_driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES2"; + static bool low_driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES2"; Map<String, TreeItem *> folders; @@ -1281,6 +1282,9 @@ void VisualShaderEditor::_update_graph() { graph->connect_node(itos(from), from_idx, itos(to), to_idx); } + + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); } VisualShader::Type VisualShaderEditor::get_current_shader_type() const { @@ -1733,114 +1737,220 @@ void VisualShaderEditor::_add_curve_node(const String &p_path) { curve->set_texture(ResourceLoader::load(p_path)); } -VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { - ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); +void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { + // FLOAT_OP + { + VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(p_node); - Ref<VisualShaderNode> vsnode; + if (floatOp) { + floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); + return; + } + } - bool is_custom = add_options[p_idx].is_custom; + // FLOAT_FUNC + { + VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(p_node); - if (!is_custom && add_options[p_idx].type != String()) { - VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); - ERR_FAIL_COND_V(!vsn, nullptr); + if (floatFunc) { + floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); + // VECTOR_OP + { + VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(p_node); - if (constant) { - if ((int)add_options[p_idx].value != -1) { - constant->set_constant(add_options[p_idx].value); - } + if (vecOp) { + vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx); + return; } + } - if (p_op_idx != -1) { - VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn); + // VECTOR_FUNC + { + VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(p_node); - if (input) { - input->set_input_name(add_options[p_idx].sub_func_str); - } + if (vecFunc) { + vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(vsn); + // COLOR_OP + { + VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(p_node); - if (is) { - is->set_function((VisualShaderNodeIs::Function)p_op_idx); - } + if (colorOp) { + colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx); + return; + } + } - VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(vsn); + // COLOR_FUNC + { + VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(p_node); - if (cmp) { - cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); - } + if (colorFunc) { + colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(vsn); + // INT_OP + { + VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(p_node); - if (colorOp) { - colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx); - } + if (intOp) { + intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); + return; + } + } - VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(vsn); + // INT_FUNC + { + VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(p_node); - if (colorFunc) { - colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); - } + if (intFunc) { + intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(vsn); + // TRANSFORM_FUNC + { + VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(p_node); - if (floatOp) { - floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); - } + if (matFunc) { + matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(vsn); + // IS + { + VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node); - if (intOp) { - intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); - } + if (is) { + is->set_function((VisualShaderNodeIs::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(vsn); + // COMPARE + { + VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(p_node); - if (floatFunc) { - floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); - } + if (cmp) { + cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); + return; + } + } - VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(vsn); + // DERIVATIVE + { + VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(p_node); - if (intFunc) { - intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); - } + if (sderFunc) { + sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx); + return; + } - VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(vsn); + VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(p_node); - if (vecOp) { - vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx); - } + if (vderFunc) { + vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(vsn); + // MIX + { + VisualShaderNodeMix *mix = Object::cast_to<VisualShaderNodeMix>(p_node); - if (vecFunc) { - vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx); - } + if (mix) { + mix->set_op_type((VisualShaderNodeMix::OpType)p_op_idx); + return; + } + } - VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(vsn); + // CLAMP + { + VisualShaderNodeClamp *clampFunc = Object::cast_to<VisualShaderNodeClamp>(p_node); - if (matFunc) { - matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx); - } + if (clampFunc) { + clampFunc->set_op_type((VisualShaderNodeClamp::OpType)p_op_idx); + return; + } + } - VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(vsn); + // SWITCH + { + VisualShaderNodeSwitch *switchFunc = Object::cast_to<VisualShaderNodeSwitch>(p_node); - if (sderFunc) { - sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx); - } + if (switchFunc) { + switchFunc->set_op_type((VisualShaderNodeSwitch::OpType)p_op_idx); + return; + } + } - VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(vsn); + // SMOOTHSTEP + { + VisualShaderNodeSmoothStep *smoothStepFunc = Object::cast_to<VisualShaderNodeSmoothStep>(p_node); - if (vderFunc) { - vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx); - } + if (smoothStepFunc) { + smoothStepFunc->set_op_type((VisualShaderNodeSmoothStep::OpType)p_op_idx); + return; + } + } + + // STEP + { + VisualShaderNodeStep *stepFunc = Object::cast_to<VisualShaderNodeStep>(p_node); + + if (stepFunc) { + stepFunc->set_op_type((VisualShaderNodeStep::OpType)p_op_idx); + return; + } + } + + // MULTIPLY_ADD + { + VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(p_node); + + if (fmaFunc) { + fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx); + } + } +} + +VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { + ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); + + Ref<VisualShaderNode> vsnode; + + bool is_custom = add_options[p_idx].is_custom; - VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(vsn); + if (!is_custom && add_options[p_idx].type != String()) { + VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); + ERR_FAIL_COND_V(!vsn, nullptr); - if (fmaFunc) { - fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx); + VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); + + if (constant) { + if ((int)add_options[p_idx].value != -1) { + constant->set_constant(add_options[p_idx].value); + } + } else { + if (p_op_idx != -1) { + VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn); + + if (input) { + input->set_input_name(add_options[p_idx].sub_func_str); + } else { + _setup_node(vsn, p_op_idx); + } } } @@ -1879,28 +1989,95 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { undo_redo->add_do_method(expr, "set_size", Size2(250 * EDSCALE, 150 * EDSCALE)); } + bool created_expression_port = false; + if (to_node != -1 && to_slot != -1) { - if (vsnode->get_output_port_count() > 0) { + VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot); + + if (expr && expr->is_editable() && input_port_type != VisualShaderNode::PORT_TYPE_SAMPLER) { + undo_redo->add_do_method(expr, "add_output_port", 0, input_port_type, "output0"); + undo_redo->add_undo_method(expr, "remove_output_port", 0); + + String initial_expression_code; + + switch (input_port_type) { + case VisualShaderNode::PORT_TYPE_SCALAR: + initial_expression_code = "output0 = 1.0;"; + break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: + initial_expression_code = "output0 = 1;"; + break; + case VisualShaderNode::PORT_TYPE_VECTOR: + initial_expression_code = "output0 = vec3(1.0, 1.0, 1.0);"; + break; + case VisualShaderNode::PORT_TYPE_BOOLEAN: + initial_expression_code = "output0 = true;"; + break; + case VisualShaderNode::PORT_TYPE_TRANSFORM: + initial_expression_code = "output0 = mat4(1.0);"; + break; + default: + break; + } + + undo_redo->add_do_method(expr, "set_expression", initial_expression_code); + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, id_to_use); + + created_expression_port = true; + } + if (vsnode->get_output_port_count() > 0 || created_expression_port) { int _from_node = id_to_use; int _from_slot = 0; - if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(_from_slot), visual_shader->get_node(type, to_node)->get_input_port_type(to_slot))) { + if (created_expression_port) { undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot); + } else { + // Attempting to connect to the first correct port. + for (int i = 0; i < vsnode->get_output_port_count(); i++) { + if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type)) { + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); + break; + } + } } } } else if (from_node != -1 && from_slot != -1) { - if (vsnode->get_input_port_count() > 0) { + VisualShaderNode::PortType output_port_type = visual_shader->get_node(type, from_node)->get_output_port_type(from_slot); + + if (expr && expr->is_editable()) { + undo_redo->add_do_method(expr, "add_input_port", 0, output_port_type, "input0"); + undo_redo->add_undo_method(expr, "remove_input_port", 0); + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, id_to_use); + + created_expression_port = true; + } + + if (vsnode->get_input_port_count() > 0 || created_expression_port) { int _to_node = id_to_use; int _to_slot = 0; - if (visual_shader->is_port_types_compatible(visual_shader->get_node(type, from_node)->get_output_port_type(from_slot), vsnode->get_input_port_type(_to_slot))) { + if (created_expression_port) { undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + } else { + // Attempting to connect to the first correct port. + for (int i = 0; i < vsnode->get_input_port_count(); i++) { + if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) { + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i); + break; + } + } } } } @@ -2087,6 +2264,197 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { } } +void VisualShaderEditor::_replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to) { + undo_redo->add_do_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_to); + undo_redo->add_undo_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_from); +} + +void VisualShaderEditor::_update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) { + Ref<VisualShaderNode> node = visual_shader->get_node(p_type_id, p_node_id); + ERR_FAIL_COND(!node.is_valid()); + ERR_FAIL_COND(!node->has_method("set_constant")); + node->call("set_constant", p_var); + if (p_preview_port != -1) { + node->set_output_port_for_preview(p_preview_port); + } +} + +void VisualShaderEditor::_update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) { + Ref<VisualShaderNodeUniform> uniform = visual_shader->get_node(p_type_id, p_node_id); + ERR_FAIL_COND(!uniform.is_valid()); + + String valid_name = visual_shader->validate_uniform_name(uniform->get_uniform_name(), uniform); + uniform->set_uniform_name(valid_name); + graph_plugin->set_uniform_name(p_type_id, p_node_id, valid_name); + + if (uniform->has_method("set_default_value_enabled")) { + uniform->call("set_default_value_enabled", true); + uniform->call("set_default_value", p_var); + } + if (p_preview_port != -1) { + uniform->set_output_port_for_preview(p_preview_port); + } +} + +void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { + VisualShader::Type type_id = get_current_shader_type(); + + if (!p_vice_versa) { + undo_redo->create_action(TTR("Convert Constant Node(s) To Uniform(s)")); + } else { + undo_redo->create_action(TTR("Convert Uniform Node(s) To Constant(s)")); + } + + const Set<int> ¤t_set = p_vice_versa ? selected_uniforms : selected_constants; + Set<String> deleted_names; + + for (Set<int>::Element *E = current_set.front(); E; E = E->next()) { + int node_id = E->get(); + Ref<VisualShaderNode> node = visual_shader->get_node(type_id, node_id); + bool catched = false; + Variant var; + + // float + if (!p_vice_versa) { + Ref<VisualShaderNodeFloatConstant> float_const = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr()); + if (float_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatUniform"); + var = float_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeFloatUniform> float_uniform = Object::cast_to<VisualShaderNodeFloatUniform>(node.ptr()); + if (float_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeFloatUniform", "VisualShaderNodeFloatConstant"); + var = float_uniform->get_default_value(); + catched = true; + } + } + + // int + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeIntConstant> int_const = Object::cast_to<VisualShaderNodeIntConstant>(node.ptr()); + if (int_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntUniform"); + var = int_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeIntUniform> int_uniform = Object::cast_to<VisualShaderNodeIntUniform>(node.ptr()); + if (int_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeIntUniform", "VisualShaderNodeIntConstant"); + var = int_uniform->get_default_value(); + catched = true; + } + } + } + + // boolean + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeBooleanConstant> boolean_const = Object::cast_to<VisualShaderNodeBooleanConstant>(node.ptr()); + if (boolean_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanUniform"); + var = boolean_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeBooleanUniform> boolean_uniform = Object::cast_to<VisualShaderNodeBooleanUniform>(node.ptr()); + if (boolean_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanConstant"); + var = boolean_uniform->get_default_value(); + catched = true; + } + } + } + + // vec3 + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeVec3Constant> vec3_const = Object::cast_to<VisualShaderNodeVec3Constant>(node.ptr()); + if (vec3_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Uniform"); + var = vec3_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeVec3Uniform> vec3_uniform = Object::cast_to<VisualShaderNodeVec3Uniform>(node.ptr()); + if (vec3_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Constant"); + var = vec3_uniform->get_default_value(); + catched = true; + } + } + } + + // color + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeColorConstant> color_const = Object::cast_to<VisualShaderNodeColorConstant>(node.ptr()); + if (color_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorUniform"); + var = color_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeColorUniform> color_uniform = Object::cast_to<VisualShaderNodeColorUniform>(node.ptr()); + if (color_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeColorUniform", "VisualShaderNodeColorConstant"); + var = color_uniform->get_default_value(); + catched = true; + } + } + } + + // transform + if (!catched) { + if (!p_vice_versa) { + Ref<VisualShaderNodeTransformConstant> transform_const = Object::cast_to<VisualShaderNodeTransformConstant>(node.ptr()); + if (transform_const.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformUniform"); + var = transform_const->get_constant(); + catched = true; + } + } else { + Ref<VisualShaderNodeTransformUniform> transform_uniform = Object::cast_to<VisualShaderNodeTransformUniform>(node.ptr()); + if (transform_uniform.is_valid()) { + _replace_node(type_id, node_id, "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformConstant"); + var = transform_uniform->get_default_value(); + catched = true; + } + } + } + ERR_CONTINUE(!catched); + int preview_port = node->get_output_port_for_preview(); + + if (!p_vice_versa) { + undo_redo->add_do_method(this, "_update_uniform", type_id, node_id, var, preview_port); + undo_redo->add_undo_method(this, "_update_constant", type_id, node_id, var, preview_port); + } else { + undo_redo->add_do_method(this, "_update_constant", type_id, node_id, var, preview_port); + undo_redo->add_undo_method(this, "_update_uniform", type_id, node_id, var, preview_port); + + Ref<VisualShaderNodeUniform> uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); + ERR_CONTINUE(!uniform.is_valid()); + + deleted_names.insert(uniform->get_uniform_name()); + } + + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, node_id); + undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, node_id); + } + + undo_redo->add_do_method(this, "_update_uniforms", true); + undo_redo->add_undo_method(this, "_update_uniforms", true); + + if (deleted_names.size() > 0) { + _update_uniform_refs(deleted_names); + } + + undo_redo->commit_action(); +} + void VisualShaderEditor::_delete_node_request(int p_type, int p_node) { List<int> to_erase; to_erase.push_back(p_node); @@ -2134,14 +2502,29 @@ void VisualShaderEditor::_node_selected(Object *p_node) { void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; + VisualShader::Type type = get_current_shader_type(); if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { + selected_constants.clear(); + selected_uniforms.clear(); + List<int> to_change; for (int i = 0; i < graph->get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); if (gn) { if (gn->is_selected() && gn->is_close_button_visible()) { - to_change.push_back(gn->get_name().operator String().to_int()); + int id = gn->get_name().operator String().to_int(); + to_change.push_back(id); + + Ref<VisualShaderNode> node = visual_shader->get_node(type, id); + VisualShaderNodeConstant *cnode = Object::cast_to<VisualShaderNodeConstant>(node.ptr()); + if (cnode != nullptr) { + selected_constants.insert(id); + } + VisualShaderNodeUniform *unode = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); + if (unode != nullptr) { + selected_uniforms.insert(id); + } } } } @@ -2152,9 +2535,36 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_nodes_buffer.is_empty()); popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty()); popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty()); + + int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2); + if (temp != -1) { + popup_menu->remove_item(temp); + } + temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); + if (temp != -1) { + popup_menu->remove_item(temp); + } + temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS); + if (temp != -1) { + popup_menu->remove_item(temp); + } + + if (selected_constants.size() > 0 || selected_uniforms.size() > 0) { + popup_menu->add_separator("", NodeMenuOptions::SEPARATOR2); + + if (selected_constants.size() > 0) { + popup_menu->add_item(TTR("Convert Constant(s) to Uniform(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); + } + + if (selected_uniforms.size() > 0) { + popup_menu->add_item(TTR("Convert Uniforms(s) to Constant(s)"), NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS); + } + } + menu_point = graph->get_local_mouse_position(); Point2 gpos = Input::get_singleton()->get_mouse_position(); popup_menu->set_position(gpos); + popup_menu->set_size(Size2(-1, -1)); popup_menu->popup(); } } @@ -2695,6 +3105,14 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) { case NodeMenuOptions::DUPLICATE: _duplicate_nodes(); break; + case NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS: + _convert_constants_to_uniforms(false); + break; + case NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS: + _convert_constants_to_uniforms(true); + break; + default: + break; } } @@ -2799,15 +3217,35 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da void VisualShaderEditor::_show_preview_text() { preview_showed = !preview_showed; - preview_vbox->set_visible(preview_showed); if (preview_showed) { + if (preview_first) { + preview_window->set_size(Size2(400 * EDSCALE, 600 * EDSCALE)); + preview_window->popup_centered(); + preview_first = false; + } else { + preview_window->popup(); + } + _preview_size_changed(); + if (pending_update_preview) { _update_preview(); pending_update_preview = false; } + } else { + preview_window->hide(); } } +void VisualShaderEditor::_preview_close_requested() { + preview_showed = false; + preview_window->hide(); + preview_shader->set_pressed(false); +} + +void VisualShaderEditor::_preview_size_changed() { + preview_vbox->set_custom_minimum_size(preview_window->get_size()); +} + static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); return RS::global_variable_type_get_shader_datatype(gvt); @@ -2843,6 +3281,16 @@ void VisualShaderEditor::_update_preview() { } } +void VisualShaderEditor::_visibility_changed() { + if (!is_visible()) { + if (preview_window->is_visible()) { + preview_shader->set_pressed(false); + preview_window->hide(); + preview_showed = false; + } + } +} + void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph); ClassDB::bind_method("_update_options_menu", &VisualShaderEditor::_update_options_menu); @@ -2856,6 +3304,8 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_set_mode", &VisualShaderEditor::_set_mode); ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged); ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected); + ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant); + ClassDB::bind_method("_update_uniform", &VisualShaderEditor::_update_uniform); ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw); @@ -2873,7 +3323,6 @@ VisualShaderEditor::VisualShaderEditor() { saved_node_pos = Point2(0, 0); ShaderLanguage::get_keyword_list(&keyword_list); - preview_showed = false; pending_update_preview = false; shader_error = false; @@ -2882,17 +3331,14 @@ VisualShaderEditor::VisualShaderEditor() { from_node = -1; from_slot = -1; - main_box = memnew(HSplitContainer); - main_box->set_v_size_flags(SIZE_EXPAND_FILL); - main_box->set_h_size_flags(SIZE_EXPAND_FILL); - add_child(main_box); - graph = memnew(GraphEdit); graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL); graph->set_v_size_flags(SIZE_EXPAND_FILL); graph->set_h_size_flags(SIZE_EXPAND_FILL); - main_box->add_child(graph); + add_child(graph); graph->set_drag_forwarding(this); + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN); @@ -2912,6 +3358,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect("gui_input", callable_mp(this, &VisualShaderEditor::_graph_gui_input)); graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty)); graph->connect("connection_from_empty", callable_mp(this, &VisualShaderEditor::_connection_from_empty)); + graph->connect("visibility_changed", callable_mp(this, &VisualShaderEditor::_visibility_changed)); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR); @@ -2966,29 +3413,35 @@ VisualShaderEditor::VisualShaderEditor() { preview_shader = memnew(Button); preview_shader->set_flat(true); preview_shader->set_toggle_mode(true); - preview_shader->set_tooltip(TTR("Show resulted shader code.")); + preview_shader->set_tooltip(TTR("Show generated shader code.")); graph->get_zoom_hbox()->add_child(preview_shader); preview_shader->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_preview_text)); /////////////////////////////////////// - // PREVIEW PANEL + // PREVIEW WINDOW /////////////////////////////////////// + preview_window = memnew(Window); + preview_window->set_title(TTR("Generated shader code")); + preview_window->set_visible(preview_showed); + preview_window->connect("close_requested", callable_mp(this, &VisualShaderEditor::_preview_close_requested)); + preview_window->connect("size_changed", callable_mp(this, &VisualShaderEditor::_preview_size_changed)); + add_child(preview_window); + preview_vbox = memnew(VBoxContainer); - preview_vbox->set_visible(preview_showed); - main_box->add_child(preview_vbox); + preview_window->add_child(preview_vbox); + preview_text = memnew(CodeEdit); syntax_highlighter.instance(); preview_vbox->add_child(preview_text); - preview_text->set_h_size_flags(SIZE_EXPAND_FILL); - preview_text->set_v_size_flags(SIZE_EXPAND_FILL); - preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0)); + preview_text->set_v_size_flags(Control::SIZE_EXPAND_FILL); preview_text->set_syntax_highlighter(syntax_highlighter); preview_text->set_draw_line_numbers(true); preview_text->set_readonly(true); error_text = memnew(Label); preview_vbox->add_child(error_text); + error_text->set_autowrap(true); error_text->set_visible(false); /////////////////////////////////////// @@ -3121,8 +3574,11 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SwitchS", "Conditional", "Functions", "VisualShaderNodeScalarSwitch", TTR("Returns an associated scalar if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SwitchInt", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("SwitchTransform", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); @@ -3345,8 +3801,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeScalarClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Constrains a value to lie between two further values."), VisualShaderNodeIntFunc::FUNC_CLAMP, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeFloatFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -3359,7 +3815,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), VisualShaderNodeFloatOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), VisualShaderNodeFloatOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeScalarInterp", TTR("Linear interpolation between two scalars."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), VisualShaderNodeMix::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("MultiplyAdd", "Scalar", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeFloatFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeIntFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR_INT)); @@ -3375,8 +3831,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeFloatOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeFloatFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -3397,7 +3853,17 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + // SDF + { + add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + } + // TEXTURES + cubemap_node_option_idx = add_options.size(); add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1)); curve_node_option_idx = add_options.size(); @@ -3450,7 +3916,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeVectorClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -3468,8 +3934,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeVectorInterp", TTR("Linear interpolation between two vectors."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeVectorScalarMix", TTR("Linear interpolation between two vectors using scalar."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), VisualShaderNodeMix::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), VisualShaderNodeMix::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -3486,10 +3952,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -4007,10 +4473,17 @@ void VisualShaderNodePortPreview::_shader_changed() { for (int i = EditorNode::get_singleton()->get_editor_history()->get_path_size() - 1; i >= 0; i--) { Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(i)); + ShaderMaterial *src_mat; if (!object) { continue; } - ShaderMaterial *src_mat = Object::cast_to<ShaderMaterial>(object); + if (object->has_method("get_material_override")) { // trying getting material from MeshInstance + src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material_override")); + } else if (object->has_method("get_material")) { // from CanvasItem/Node2D + src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material")); + } else { + src_mat = Object::cast_to<ShaderMaterial>(object); + } if (src_mat && src_mat->get_shader().is_valid()) { List<PropertyInfo> params; src_mat->get_shader()->get_param_list(¶ms); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 6e8ac92dc2..182bed6ba6 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -134,7 +134,6 @@ class VisualShaderEditor : public VBoxContainer { int editing_port; Ref<VisualShader> visual_shader; - HSplitContainer *main_box; GraphEdit *graph; Button *add_node; Button *preview_shader; @@ -148,6 +147,7 @@ class VisualShaderEditor : public VBoxContainer { bool pending_update_preview; bool shader_error; + Window *preview_window; VBoxContainer *preview_vbox; CodeEdit *preview_text; Ref<CodeHighlighter> syntax_highlighter; @@ -161,7 +161,8 @@ class VisualShaderEditor : public VBoxContainer { PopupMenu *popup_menu; MenuButton *tools; - bool preview_showed; + bool preview_first = true; + bool preview_showed = false; bool particles_mode; enum TypeFlags { @@ -188,6 +189,9 @@ class VisualShaderEditor : public VBoxContainer { PASTE, DELETE, DUPLICATE, + SEPARATOR2, // ignore + CONVERT_CONSTANTS_TO_UNIFORMS, + CONVERT_UNIFORMS_TO_CONSTANTS, }; Tree *members; @@ -272,11 +276,14 @@ class VisualShaderEditor : public VBoxContainer { void _add_texture3d_node(const String &p_path); void _add_curve_node(const String &p_path); + void _setup_node(VisualShaderNode *p_node, int p_op_idx); VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1); void _update_options_menu(); void _set_mode(int p_which); void _show_preview_text(); + void _preview_close_requested(); + void _preview_size_changed(); void _update_preview(); String _get_description(int p_idx); @@ -316,6 +323,14 @@ class VisualShaderEditor : public VBoxContainer { int from_node; int from_slot; + Set<int> selected_constants; + Set<int> selected_uniforms; + + void _convert_constants_to_uniforms(bool p_vice_versa); + void _replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to); + void _update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); + void _update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port); + void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position); void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position); @@ -388,6 +403,8 @@ class VisualShaderEditor : public VBoxContainer { void _update_uniforms(bool p_update_refs); void _update_uniform_refs(Set<String> &p_names); + void _visibility_changed(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/pot_generator.cpp b/editor/pot_generator.cpp index 2d65c00a89..497cc0cbdc 100644 --- a/editor/pot_generator.cpp +++ b/editor/pot_generator.cpp @@ -55,7 +55,7 @@ void POTGenerator::_print_all_translation_strings() { #endif void POTGenerator::generate_pot(const String &p_file) { - if (!ProjectSettings::get_singleton()->has_setting("locale/translations_pot_files")) { + if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations_pot_files")) { WARN_PRINT("No files selected for POT generation."); return; } @@ -63,7 +63,7 @@ void POTGenerator::generate_pot(const String &p_file) { // Clear all_translation_strings of the previous round. all_translation_strings.clear(); - Vector<String> files = ProjectSettings::get_singleton()->get("locale/translations_pot_files"); + Vector<String> files = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); // Collect all translatable strings according to files order in "POT Generation" setting. for (int i = 0; i < files.size(); i++) { @@ -100,7 +100,7 @@ void POTGenerator::_write_to_pot(const String &p_file) { } String project_name = ProjectSettings::get_singleton()->get("application/config/name"); - Vector<String> files = ProjectSettings::get_singleton()->get("locale/translations_pot_files"); + Vector<String> files = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); String extracted_files = ""; for (int i = 0; i < files.size(); i++) { extracted_files += "# " + files[i] + "\n"; diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 4a8990daa9..4bcb616fbd 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -830,6 +830,12 @@ void ProjectExportDialog::_refresh_parent_checks(TreeItem *p_item) { } void ProjectExportDialog::_export_pck_zip() { + Ref<EditorExportPreset> current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + String dir = current->get_export_path().get_base_dir(); + export_pck_zip->set_current_dir(dir); + export_pck_zip->popup_file_dialog(); } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index dacd0162ba..7d421bdf81 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -474,15 +474,15 @@ private: } ProjectSettings::CustomMap initial_settings; if (rasterizer_button_group->get_pressed_button()->get_meta("driver_name") == "Vulkan") { - initial_settings["rendering/quality/driver/driver_name"] = "Vulkan"; + initial_settings["rendering/driver/driver_name"] = "Vulkan"; } else { - initial_settings["rendering/quality/driver/driver_name"] = "GLES2"; - initial_settings["rendering/vram_compression/import_etc2"] = false; - initial_settings["rendering/vram_compression/import_etc"] = true; + initial_settings["rendering/driver/driver_name"] = "GLES2"; + initial_settings["rendering/textures/vram_compression/import_etc2"] = false; + initial_settings["rendering/textures/vram_compression/import_etc"] = true; } initial_settings["application/config/name"] = project_name->get_text(); initial_settings["application/config/icon"] = "res://icon.png"; - initial_settings["rendering/environment/default_environment"] = "res://default_env.tres"; + initial_settings["rendering/environment/defaults/default_environment"] = "res://default_env.tres"; if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) { set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR); @@ -1297,9 +1297,7 @@ void ProjectList::_global_menu_new_window(const Variant &p_tag) { List<String> args; args.push_back("-p"); String exec = OS::get_singleton()->get_executable_path(); - - OS::ProcessID pid = 0; - OS::get_singleton()->execute(exec, args, false, &pid); + OS::get_singleton()->create_process(exec, args); } void ProjectList::_global_menu_open_project(const Variant &p_tag) { @@ -1310,9 +1308,7 @@ void ProjectList::_global_menu_open_project(const Variant &p_tag) { List<String> args; args.push_back(conf); String exec = OS::get_singleton()->get_executable_path(); - - OS::ProcessID pid = 0; - OS::get_singleton()->execute(exec, args, false, &pid); + OS::get_singleton()->create_process(exec, args); } } @@ -1379,11 +1375,10 @@ void ProjectList::create_project_item_control(int p_index) { vb->add_child(path_hb); Button *show = memnew(Button); - // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't + // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't. show->set_icon(get_theme_icon(!item.missing ? "Load" : "FileBroken", "EditorIcons")); - show->set_flat(true); if (!item.grayed) { - // Don't make the icon less prominent if the parent is already grayed out + // Don't make the icon less prominent if the parent is already grayed out. show->set_modulate(Color(1, 1, 1, 0.5)); } path_hb->add_child(show); @@ -2020,6 +2015,10 @@ void ProjectManager::_confirm_update_settings() { } void ProjectManager::_open_selected_projects() { + // Show loading text to tell the user that the project manager is busy loading. + // This is especially important for the HTML5 project manager. + loading_label->set_modulate(Color(1, 1, 1)); + const Set<String> &selected_list = _project_list->get_selected_project_keys(); for (const Set<String>::Element *E = selected_list.front(); E; E = E->next()) { @@ -2055,9 +2054,7 @@ void ProjectManager::_open_selected_projects() { } String exec = OS::get_singleton()->get_executable_path(); - - OS::ProcessID pid = 0; - Error err = OS::get_singleton()->execute(exec, args, false, &pid); + Error err = OS::get_singleton()->create_process(exec, args); ERR_FAIL_COND(err); } @@ -2143,9 +2140,7 @@ void ProjectManager::_run_project_confirm() { } String exec = OS::get_singleton()->get_executable_path(); - - OS::ProcessID pid = 0; - Error err = OS::get_singleton()->execute(exec, args, false, &pid); + Error err = OS::get_singleton()->create_process(exec, args); ERR_FAIL_COND(err); } } @@ -2166,8 +2161,9 @@ void ProjectManager::_run_project() { } void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { - DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->change_dir(path); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Error error = da->change_dir(path); + ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path); da->list_dir_begin(); String n = da->get_next(); while (n != String()) { @@ -2179,7 +2175,6 @@ void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { n = da->get_next(); } da->list_dir_end(); - memdelete(da); } void ProjectManager::_scan_begin(const String &p_base) { @@ -2270,19 +2265,13 @@ void ProjectManager::_language_selected(int p_id) { void ProjectManager::_restart_confirm() { List<String> args = OS::get_singleton()->get_cmdline_args(); String exec = OS::get_singleton()->get_executable_path(); - OS::ProcessID pid = 0; - Error err = OS::get_singleton()->execute(exec, args, false, &pid); + Error err = OS::get_singleton()->create_process(exec, args); ERR_FAIL_COND(err); _dim_window(); get_tree()->quit(); } -void ProjectManager::_exit_dialog() { - _dim_window(); - get_tree()->quit(); -} - void ProjectManager::_install_project(const String &p_zip_path, const String &p_title) { npdialog->set_mode(ProjectDialog::MODE_INSTALL); npdialog->set_zip_path(p_zip_path); @@ -2291,6 +2280,11 @@ void ProjectManager::_install_project(const String &p_zip_path, const String &p_ } void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) { + if (p_files.size() == 1 && p_files[0].ends_with(".zip")) { + const String file = p_files[0].get_file(); + _install_project(p_files[0], file.substr(0, file.length() - 4).capitalize()); + return; + } Set<String> folders_set; DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < p_files.size(); i++) { @@ -2356,7 +2350,6 @@ void ProjectManager::_on_search_term_changed(const String &p_term) { } void ProjectManager::_bind_methods() { - ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog); ClassDB::bind_method("_unhandled_key_input", &ProjectManager::_unhandled_key_input); ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons); } @@ -2380,6 +2373,8 @@ ProjectManager::ProjectManager() { switch (display_scale) { case 0: { // Try applying a suitable display scale automatically. + // The code below is adapted in `editor/editor_settings.cpp` and `editor/editor_node.cpp`. + // Make sure to update those when modifying the code below. #ifdef OSX_ENABLED editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale()); #else @@ -2388,6 +2383,10 @@ ProjectManager::ProjectManager() { if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) { // hiDPI display. scale = 2.0; + } else if (DisplayServer::get_singleton()->screen_get_size(screen).y >= 1700) { + // Likely a hiDPI display, but we aren't certain due to the returned DPI. + // Use an intermediate scale to handle this situation. + scale = 1.5; } else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) { // Small loDPI display. Use a smaller display scale so that editor elements fit more easily. // Icons won't look great, but this is better than having editor elements overflow from its window. @@ -2484,7 +2483,12 @@ ProjectManager::ProjectManager() { search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); hb->add_child(search_box); - hb->add_spacer(); + loading_label = memnew(Label(TTR("Loading, please wait..."))); + loading_label->add_theme_font_override("font", get_theme_font("bold", "EditorFonts")); + loading_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + hb->add_child(loading_label); + // Hide the label but make it still take up space. This prevents reflows when showing the label. + loading_label->set_modulate(Color(0, 0, 0, 0)); Label *sort_label = memnew(Label); sort_label->set_text(TTR("Sort:")); @@ -2691,8 +2695,26 @@ ProjectManager::ProjectManager() { _load_recent_projects(); - if (EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path")) { - _scan_begin(EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path")); + DirAccessRef dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM); + + String default_project_path = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path"); + if (!dir_access->dir_exists(default_project_path)) { + Error error = dir_access->make_dir_recursive(default_project_path); + if (error != OK) { + ERR_PRINT("Could not create default project directory at: " + default_project_path); + } + } + + String autoscan_path = EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"); + if (autoscan_path != "") { + if (dir_access->dir_exists(autoscan_path)) { + _scan_begin(autoscan_path); + } else { + Error error = dir_access->make_dir_recursive(autoscan_path); + if (error != OK) { + ERR_PRINT("Could not create project autoscan directory at: " + autoscan_path); + } + } } SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped)); diff --git a/editor/project_manager.h b/editor/project_manager.h index db8cb8410c..6dc0e67cba 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -54,6 +54,7 @@ class ProjectManager : public Control { ProjectList *_project_list; LineEdit *search_box; + Label *loading_label; OptionButton *filter_option; Button *run_btn; @@ -98,7 +99,6 @@ class ProjectManager : public Control { void _update_project_buttons(); void _language_selected(int p_id); void _restart_confirm(); - void _exit_dialog(); void _confirm_update_settings(); void _nonempty_confirmation_ok_pressed(); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 98cdab0b70..de7996eaa2 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -52,9 +52,11 @@ void ProjectSettingsEditor::popup_project_settings() { localization_editor->update_translations(); autoload_settings->update_autoload(); plugin_settings->update_plugins(); + import_defaults_editor->clear(); } void ProjectSettingsEditor::queue_save() { + EditorNode::get_singleton()->notify_settings_changed(); timer->start(); } @@ -74,8 +76,12 @@ void ProjectSettingsEditor::_advanced_pressed() { if (advanced->is_pressed()) { _update_advanced_bar(); advanced_bar->show(); + EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", true); + inspector->set_restrict_to_basic_settings(false); } else { advanced_bar->hide(); + EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", false); + inspector->set_restrict_to_basic_settings(true); } } @@ -190,9 +196,6 @@ void ProjectSettingsEditor::_update_advanced_bar() { add_button->set_disabled(disable_add); del_button->set_disabled(disable_del); - - error_label->set_text(error_msg); - error_label->set_visible(error_msg != ""); } String ProjectSettingsEditor::_get_setting_name() const { @@ -255,6 +258,7 @@ void ProjectSettingsEditor::_add_feature_overrides() { } void ProjectSettingsEditor::_editor_restart() { + ProjectSettings::get_singleton()->save(); EditorNode::get_singleton()->save_all_scenes(); EditorNode::get_singleton()->restart_editor(); } @@ -267,21 +271,216 @@ void ProjectSettingsEditor::_editor_restart_close() { restart_container->hide(); } +void ProjectSettingsEditor::_action_added(const String &p_name) { + String name = "input/" + p_name; + + if (ProjectSettings::get_singleton()->has_setting(name)) { + action_map->show_message(vformat(TTR("An action with the name '%s' already exists."), name)); + return; + } + + Dictionary action; + action["events"] = Array(); + action["deadzone"] = 0.5f; + + undo_redo->create_action(TTR("Add Input Action")); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); + + undo_redo->add_do_method(this, "_update_action_map_editor"); + undo_redo->add_undo_method(this, "_update_action_map_editor"); + undo_redo->add_do_method(this, "queue_save"); + undo_redo->add_undo_method(this, "queue_save"); + undo_redo->commit_action(); +} + +void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionary &p_action) { + const String property_name = "input/" + p_name; + Dictionary old_val = ProjectSettings::get_singleton()->get(property_name); + + if (old_val["deadzone"] != p_action["deadzone"]) { + // Deadzone Changed + undo_redo->create_action(TTR("Change Action deadzone")); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", property_name, p_action); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val); + + } else { + // Events changed + int event_count = ((Array)p_action["events"]).size(); + int old_event_count = ((Array)old_val["events"]).size(); + + if (event_count == old_event_count) { + undo_redo->create_action(TTR("Edit Input Action Event")); + } else if (event_count > old_event_count) { + undo_redo->create_action(TTR("Add Input Action Event")); + } else if (event_count < old_event_count) { + undo_redo->create_action(TTR("Remove Input Action Event")); + } + + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", property_name, p_action); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val); + } + + undo_redo->add_do_method(this, "_update_action_map_editor"); + undo_redo->add_undo_method(this, "_update_action_map_editor"); + undo_redo->add_do_method(this, "queue_save"); + undo_redo->add_undo_method(this, "queue_save"); + undo_redo->commit_action(); +} + +void ProjectSettingsEditor::_action_removed(const String &p_name) { + const String property_name = "input/" + p_name; + + Dictionary old_val = ProjectSettings::get_singleton()->get(property_name); + int order = ProjectSettings::get_singleton()->get_order(property_name); + + undo_redo->create_action(TTR("Erase Input Action")); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", property_name); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", property_name, order); + + undo_redo->add_do_method(this, "_update_action_map_editor"); + undo_redo->add_undo_method(this, "_update_action_map_editor"); + undo_redo->add_do_method(this, "queue_save"); + undo_redo->add_undo_method(this, "queue_save"); + undo_redo->commit_action(); +} + +void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const String &p_new_name) { + const String old_property_name = "input/" + p_old_name; + const String new_property_name = "input/" + p_new_name; + + if (ProjectSettings::get_singleton()->has_setting(new_property_name)) { + action_map->show_message(vformat(TTR("An action with the name '%s' already exists."), new_property_name)); + return; + } + + int order = ProjectSettings::get_singleton()->get_order(old_property_name); + Dictionary action = ProjectSettings::get_singleton()->get(old_property_name); + + undo_redo->create_action(TTR("Rename Input Action Event")); + // Do: clear old, set new + undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", old_property_name); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", new_property_name, action); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", new_property_name, order); + // Undo: clear new, set old + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", new_property_name); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", old_property_name, action); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", old_property_name, order); + + undo_redo->add_do_method(this, "_update_action_map_editor"); + undo_redo->add_undo_method(this, "_update_action_map_editor"); + undo_redo->add_do_method(this, "queue_save"); + undo_redo->add_undo_method(this, "queue_save"); + undo_redo->commit_action(); +} + +void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const String &p_relative_to, bool p_before) { + const String action_name = "input/" + p_action_name; + const String target_name = "input/" + p_relative_to; + + // It is much easier to rebuild the custom "input" properties rather than messing around with the "order" values of them. + Variant action_value = ps->get(action_name); + Variant target_value = ps->get(target_name); + + List<PropertyInfo> props; + OrderedHashMap<String, Variant> action_values; + ProjectSettings::get_singleton()->get_property_list(&props); + + undo_redo->create_action(TTR("Update Input Action Order")); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + PropertyInfo prop = E->get(); + // Skip builtins and non-inputs + if (ProjectSettings::get_singleton()->is_builtin_setting(prop.name) || !prop.name.begins_with("input/")) { + continue; + } + + action_values.insert(prop.name, ps->get(prop.name)); + + undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", prop.name); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", prop.name); + } + + for (OrderedHashMap<String, Variant>::Element E = action_values.front(); E; E = E.next()) { + String name = E.key(); + Variant value = E.get(); + + if (name == target_name) { + if (p_before) { + // Insert before target + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_name, action_value); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", target_name, target_value); + + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", target_name, target_value); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", action_name, action_value); + } else { + // Insert after target + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", target_name, target_value); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_name, action_value); + + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", action_name, action_value); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", target_name, target_value); + } + + } else if (name != action_name) { + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, value); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, value); + } + } + + undo_redo->add_do_method(this, "_update_action_map_editor"); + undo_redo->add_undo_method(this, "_update_action_map_editor"); + undo_redo->add_do_method(this, "queue_save"); + undo_redo->add_undo_method(this, "queue_save"); + undo_redo->commit_action(); +} + +void ProjectSettingsEditor::_update_action_map_editor() { + Vector<ActionMapEditor::ActionInfo> actions; + + List<PropertyInfo> props; + ProjectSettings::get_singleton()->get_property_list(&props); + + const Ref<Texture2D> builtin_icon = get_theme_icon("PinPressed", "EditorIcons"); + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + const String property_name = E->get().name; + + if (!property_name.begins_with("input/")) { + continue; + } + + // Strip the "input/" from the left. + String display_name = property_name.substr(String("input/").size() - 1); + Dictionary action = ProjectSettings::get_singleton()->get(property_name); + + ActionMapEditor::ActionInfo action_info; + action_info.action = action; + action_info.editable = true; + action_info.name = display_name; + + const bool is_builtin_input = ProjectSettings::get_singleton()->get_input_presets().find(property_name) != nullptr; + if (is_builtin_input) { + action_info.editable = false; + action_info.icon = builtin_icon; + } + + actions.push_back(action_info); + } + + action_map->update_action_list(actions); +} + void ProjectSettingsEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { if (!is_visible()) { EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "project_settings", Rect2(get_position(), get_size())); - if (advanced->is_pressed()) { - advanced->set_pressed(false); - advanced_bar->hide(); - } } } break; case NOTIFICATION_ENTER_TREE: { inspector->edit(ps); - error_label->add_theme_color_override("font_color", error_label->get_theme_color("error_color", "Editor")); add_button->set_icon(get_theme_icon("Add", "EditorIcons")); del_button->set_icon(get_theme_icon("Remove", "EditorIcons")); @@ -292,6 +491,8 @@ void ProjectSettingsEditor::_notification(int p_what) { restart_container->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree")); restart_icon->set_texture(get_theme_icon("StatusWarning", "EditorIcons")); restart_label->add_theme_color_override("font_color", get_theme_color("warning_color", "Editor")); + + _update_action_map_editor(); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { search_box->set_right_icon(get_theme_icon("Search", "EditorIcons")); @@ -302,6 +503,8 @@ void ProjectSettingsEditor::_notification(int p_what) { void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("queue_save"), &ProjectSettingsEditor::queue_save); + + ClassDB::bind_method(D_METHOD("_update_action_map_editor"), &ProjectSettingsEditor::_update_action_map_editor); } ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { @@ -339,23 +542,19 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { search_bar->add_child(search_box); advanced = memnew(CheckButton); - advanced->set_text(TTR("Advanced")); + advanced->set_text(TTR("Advanced Settings")); advanced->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_advanced_pressed)); search_bar->add_child(advanced); } { // Advanced bar. - advanced_bar = memnew(VBoxContainer); - advanced_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL); + advanced_bar = memnew(HBoxContainer); advanced_bar->hide(); header->add_child(advanced_bar); - advanced_bar->add_child(memnew(HSeparator)); - - HBoxContainer *hbc = memnew(HBoxContainer); + HBoxContainer *hbc = advanced_bar; hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); - advanced_bar->add_margin_child(TTR("Add or Remove Custom Project Settings:"), hbc, true); category_box = memnew(LineEdit); category_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -364,7 +563,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { hbc->add_child(category_box); Label *l = memnew(Label); - l->set_text("/"); + l->set_text(" / "); hbc->add_child(l); property_box = memnew(LineEdit); @@ -381,9 +580,12 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { type->set_custom_minimum_size(Size2(100, 0) * EDSCALE); hbc->add_child(type); - // Start at 1 to avoid adding "Nil" as an option - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - type->add_item(Variant::get_type_name(Variant::Type(i))); + for (int i = 0; i < Variant::VARIANT_MAX; i++) { + // There's no point in adding Nil types, and Object types + // can't be serialized correctly in the project settings. + if (i != Variant::NIL && i != Variant::OBJECT) { + type->add_item(Variant::get_type_name(Variant::Type(i))); + } } l = memnew(Label); @@ -404,9 +606,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { del_button->set_flat(true); del_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_delete_setting), varray(false)); hbc->add_child(del_button); - - error_label = memnew(Label); - advanced_bar->add_child(error_label); } inspector = memnew(SectionedInspector); @@ -444,10 +643,16 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { restart_close_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_editor_restart_close)); restart_hb->add_child(restart_close_button); - inputmap_editor = memnew(InputMapEditor); - inputmap_editor->set_name(TTR("Input Map")); - inputmap_editor->connect("inputmap_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); - tab_container->add_child(inputmap_editor); + action_map = memnew(ActionMapEditor); + action_map->set_name(TTR("Input Map")); + action_map->connect("action_added", callable_mp(this, &ProjectSettingsEditor::_action_added)); + action_map->connect("action_edited", callable_mp(this, &ProjectSettingsEditor::_action_edited)); + action_map->connect("action_removed", callable_mp(this, &ProjectSettingsEditor::_action_removed)); + action_map->connect("action_renamed", callable_mp(this, &ProjectSettingsEditor::_action_renamed)); + action_map->connect("action_reordered", callable_mp(this, &ProjectSettingsEditor::_action_reordered)); + action_map->set_toggle_editable_label(TTR("Show Built-in Actions")); + action_map->set_show_uneditable(false); + tab_container->add_child(action_map); localization_editor = memnew(LocalizationEditor); localization_editor->set_name(TTR("Localization")); @@ -480,4 +685,18 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { get_ok_button()->set_text(TTR("Close")); set_hide_on_ok(true); + + bool use_advanced = EditorSettings::get_singleton()->get_project_metadata("project_settings", "advanced_mode", false); + + if (use_advanced) { + advanced->set_pressed(true); + advanced_bar->show(); + } + + inspector->set_restrict_to_basic_settings(!use_advanced); + + import_defaults_editor = memnew(ImportDefaultsEditor); + import_defaults_editor->set_name(TTR("Import Defaults")); + tab_container->add_child(import_defaults_editor); + import_defaults_editor->connect("project_settings_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); } diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 88c96540ff..cde46ac4c4 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -32,10 +32,11 @@ #define PROJECT_SETTINGS_EDITOR_H #include "core/object/undo_redo.h" +#include "editor/action_map_editor.h" #include "editor/editor_data.h" #include "editor/editor_plugin_settings.h" #include "editor/editor_sectioned_inspector.h" -#include "editor/input_map_editor.h" +#include "editor/import_defaults_editor.h" #include "editor/localization_editor.h" #include "editor/shader_globals_editor.h" #include "editor_autoload_settings.h" @@ -44,38 +45,29 @@ class ProjectSettingsEditor : public AcceptDialog { GDCLASS(ProjectSettingsEditor, AcceptDialog); - enum InputType { - INPUT_KEY, - INPUT_KEY_PHYSICAL, - INPUT_JOY_BUTTON, - INPUT_JOY_MOTION, - INPUT_MOUSE_BUTTON - }; - static ProjectSettingsEditor *singleton; ProjectSettings *ps; Timer *timer; TabContainer *tab_container; SectionedInspector *inspector; - InputMapEditor *inputmap_editor; LocalizationEditor *localization_editor; EditorAutoloadSettings *autoload_settings; ShaderGlobalsEditor *shaders_global_variables_editor; EditorPluginSettings *plugin_settings; + ActionMapEditor *action_map; HBoxContainer *search_bar; LineEdit *search_box; CheckButton *advanced; - VBoxContainer *advanced_bar; + HBoxContainer *advanced_bar; LineEdit *category_box; LineEdit *property_box; Button *add_button; Button *del_button; OptionButton *type; OptionButton *feature_override; - Label *error_label; ConfirmationDialog *del_confirmation; @@ -84,6 +76,7 @@ class ProjectSettingsEditor : public AcceptDialog { PanelContainer *restart_container; Button *restart_close_button; + ImportDefaultsEditor *import_defaults_editor; EditorData *data; UndoRedo *undo_redo; @@ -103,6 +96,14 @@ class ProjectSettingsEditor : public AcceptDialog { void _editor_restart_close(); void _add_feature_overrides(); + + void _action_added(const String &p_name); + void _action_edited(const String &p_name, const Dictionary &p_action); + void _action_removed(const String &p_name); + void _action_renamed(const String &p_old_name, const String &p_new_name); + void _action_reordered(const String &p_action_name, const String &p_relative_to, bool p_before); + void _update_action_map_editor(); + ProjectSettingsEditor(); protected: diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 894d606c9c..16a0576af4 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -57,10 +57,7 @@ void SceneTreeDock::_nodes_drag_begin() { } void SceneTreeDock::_quick_open() { - Vector<String> files = quick_open->get_selected_files(); - for (int i = 0; i < files.size(); i++) { - instance(files[i]); - } + instance_scenes(quick_open->get_selected_files(), scene_tree->get_selected()); } void SceneTreeDock::_input(Ref<InputEvent> p_event) { @@ -90,6 +87,12 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) { _tool_selected(TOOL_INSTANCE); } else if (ED_IS_SHORTCUT("scene_tree/expand_collapse_all", p_event)) { _tool_selected(TOOL_EXPAND_COLLAPSE); + } else if (ED_IS_SHORTCUT("scene_tree/cut_node", p_event)) { + _tool_selected(TOOL_CUT); + } else if (ED_IS_SHORTCUT("scene_tree/copy_node", p_event)) { + _tool_selected(TOOL_COPY); + } else if (ED_IS_SHORTCUT("scene_tree/paste_node", p_event)) { + _tool_selected(TOOL_PASTE); } else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) { _tool_selected(TOOL_REPLACE); } else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) { @@ -104,8 +107,6 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) { _tool_selected(TOOL_MOVE_DOWN); } else if (ED_IS_SHORTCUT("scene_tree/reparent", p_event)) { _tool_selected(TOOL_REPARENT); - } else if (ED_IS_SHORTCUT("scene_tree/merge_from_scene", p_event)) { - _tool_selected(TOOL_MERGE_FROM_SCENE); } else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) { _tool_selected(TOOL_NEW_SCENE_FROM); } else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", p_event)) { @@ -123,24 +124,9 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) { } void SceneTreeDock::instance(const String &p_file) { - Node *parent = scene_tree->get_selected(); - - if (!parent) { - parent = edited_scene; - }; - - if (!edited_scene) { - current_option = -1; - accept->set_text(TTR("No parent to instance a child at.")); - accept->popup_centered(); - return; - }; - - ERR_FAIL_COND(!parent); - Vector<String> scenes; scenes.push_back(p_file); - _perform_instance_scenes(scenes, parent, -1); + instance_scenes(scenes, scene_tree->get_selected()); } void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_parent) { @@ -151,7 +137,11 @@ void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_paren } if (!parent || !edited_scene) { - accept->set_text(TTR("No parent to instance the scenes at.")); + if (p_files.size() == 1) { + accept->set_text(TTR("No parent to instance a child at.")); + } else { + accept->set_text(TTR("No parent to instance the scenes at.")); + } accept->popup_centered(); return; }; @@ -424,11 +414,127 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { tree->ensure_cursor_is_visible(); } break; + case TOOL_CUT: + case TOOL_COPY: { + if (!edited_scene || !_validate_no_foreign()) { + break; + } + + List<Node *> selection = editor_selection->get_selected_node_list(); + if (selection.size() == 0) { + break; + } + + if (!node_clipboard.is_empty()) { + _clear_clipboard(); + } + clipboard_source_scene = editor->get_edited_scene()->get_filename(); + + selection.sort_custom<Node::Comparator>(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node *node = E->get(); + Map<const Node *, Node *> duplimap; + Node *dup = node->duplicate_from_editor(duplimap); + + ERR_CONTINUE(!dup); + + node_clipboard.push_back(dup); + } + + if (p_tool == TOOL_CUT) { + _delete_confirm(true); + } + } break; + case TOOL_PASTE: { + if (node_clipboard.is_empty() || !edited_scene) { + break; + } + + bool has_cycle = false; + if (edited_scene->get_filename() != String()) { + for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { + if (edited_scene->get_filename() == E->get()->get_filename()) { + has_cycle = true; + break; + } + } + } + + if (has_cycle) { + current_option = -1; + accept->set_text(TTR("Can't paste root node into the same scene.")); + accept->popup_centered(); + break; + } + + Node *paste_parent = edited_scene; + List<Node *> selection = editor_selection->get_selected_node_list(); + if (selection.size() > 0) { + paste_parent = selection.back()->get(); + } + + Node *owner = paste_parent->get_owner(); + if (!owner) { + owner = paste_parent; + } + + editor_data->get_undo_redo().create_action(TTR("Paste Node(s)")); + editor_data->get_undo_redo().add_do_method(editor_selection, "clear"); + + Map<RES, RES> resource_remap; + String target_scene = editor->get_edited_scene()->get_filename(); + if (target_scene != clipboard_source_scene) { + if (!clipboard_resource_remap.has(target_scene)) { + Map<RES, RES> remap; + for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { + _create_remap_for_node(E->get(), remap); + } + clipboard_resource_remap[target_scene] = remap; + } + resource_remap = clipboard_resource_remap[target_scene]; + } + + for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { + Node *node = E->get(); + Map<const Node *, Node *> duplimap; + + Node *dup = node->duplicate_from_editor(duplimap, resource_remap); + + ERR_CONTINUE(!dup); + + editor_data->get_undo_redo().add_do_method(paste_parent, "add_child", dup); + + for (Map<const Node *, Node *>::Element *E2 = duplimap.front(); E2; E2 = E2->next()) { + Node *d = E2->value(); + editor_data->get_undo_redo().add_do_method(d, "set_owner", owner); + } + + editor_data->get_undo_redo().add_do_method(dup, "set_owner", owner); + editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup); + editor_data->get_undo_redo().add_undo_method(paste_parent, "remove_child", dup); + editor_data->get_undo_redo().add_do_reference(dup); + + if (node_clipboard.size() == 1) { + editor_data->get_undo_redo().add_do_method(editor, "push_item", dup); + } + } + + editor_data->get_undo_redo().commit_action(); + } break; case TOOL_REPLACE: { if (!profile_allow_editing) { break; } + if (!_validate_no_foreign()) { + break; + } + + if (!_validate_no_instance()) { + break; + } + Node *selected = scene_tree->get_selected(); if (!selected && !editor_selection->get_selected_node_list().is_empty()) { selected = editor_selection->get_selected_node_list().front()->get(); @@ -793,13 +899,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } break; - case TOOL_MERGE_FROM_SCENE: { - if (!profile_allow_editing) { - break; - } - - EditorNode::get_singleton()->merge_from_scene(); - } break; case TOOL_NEW_SCENE_FROM: { if (!profile_allow_editing) { break; @@ -1537,6 +1636,20 @@ bool SceneTreeDock::_validate_no_foreign() { return true; } +bool SceneTreeDock::_validate_no_instance() { + List<Node *> selection = editor_selection->get_selected_node_list(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + if (E->get() != edited_scene && E->get()->get_filename() != "") { + accept->set_text(TTR("This operation can't be done on instanced scenes.")); + accept->popup_centered(); + return false; + } + } + + return true; +} + void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) { Node *new_parent = scene_root->get_node(p_path); ERR_FAIL_COND(!new_parent); @@ -1822,7 +1935,7 @@ void SceneTreeDock::_toggle_editable_children(Node *p_node) { } } -void SceneTreeDock::_delete_confirm() { +void SceneTreeDock::_delete_confirm(bool p_cut) { List<Node *> remove_list = editor_selection->get_selected_node_list(); if (remove_list.is_empty()) { @@ -1831,7 +1944,11 @@ void SceneTreeDock::_delete_confirm() { editor->get_editor_plugins_over()->make_visible(false); - editor_data->get_undo_redo().create_action(TTR("Remove Node(s)")); + if (p_cut) { + editor_data->get_undo_redo().create_action(TTR("Cut Node(s)")); + } else { + editor_data->get_undo_redo().create_action(TTR("Remove Node(s)")); + } bool entire_scene = false; @@ -2169,7 +2286,6 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop if (n == edited_scene) { edited_scene = newnode; editor->set_edited_scene(newnode); - newnode->set_editable_instances(n->get_editable_instances()); } //small hack to make collisionshapes and other kind of nodes to work @@ -2203,21 +2319,6 @@ void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) { scene_tree->set_selected(p_node, p_emit_selected); } -void SceneTreeDock::import_subscene() { - import_subscene_dialog->popup_centered_clamped(Size2(500, 800) * EDSCALE, 0.8); -} - -void SceneTreeDock::_import_subscene() { - Node *parent = scene_tree->get_selected(); - if (!parent) { - parent = editor_data->get_edited_scene_root(); - ERR_FAIL_COND(!parent); - } - - import_subscene_dialog->move(parent, edited_scene); - editor_data->get_undo_redo().clear_history(); //no undo for now.. -} - void SceneTreeDock::_new_scene_from(String p_file) { List<Node *> selection = editor_selection->get_selected_node_list(); @@ -2235,10 +2336,14 @@ void SceneTreeDock::_new_scene_from(String p_file) { Node *base = selection.front()->get(); - Map<Node *, Node *> reown; - reown[editor_data->get_edited_scene_root()] = base; - Node *copy = base->duplicate_and_reown(reown); + Map<const Node *, Node *> duplimap; + Node *copy = base->duplicate_from_editor(duplimap); + if (copy) { + for (int i = 0; i < copy->get_child_count(); i++) { + _set_node_owner_recursive(copy->get_child(i), copy); + } + Ref<PackedScene> sdata = memnew(PackedScene); Error err = sdata->pack(copy); memdelete(copy); @@ -2268,6 +2373,16 @@ void SceneTreeDock::_new_scene_from(String p_file) { } } +void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner) { + if (!p_node->get_owner()) { + p_node->set_owner(p_owner); + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _set_node_owner_recursive(p_node->get_child(i), p_owner); + } +} + static bool _is_node_visible(Node *p_node) { if (!p_node->get_owner()) { return false; @@ -2474,6 +2589,13 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { } if (profile_allow_script_editing) { + menu->add_shortcut(ED_GET_SHORTCUT("scene_tree/cut_node"), TOOL_CUT); + menu->add_shortcut(ED_GET_SHORTCUT("scene_tree/copy_node"), TOOL_COPY); + if (selection.size() == 1 && !node_clipboard.is_empty()) { + menu->add_shortcut(ED_GET_SHORTCUT("scene_tree/paste_node"), TOOL_PASTE); + } + menu->add_separator(); + bool add_separator = false; if (full_selection.size() == 1) { @@ -2510,7 +2632,18 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { if (full_selection.size() == 1) { menu->add_icon_shortcut(get_theme_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME); } - menu->add_icon_shortcut(get_theme_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE); + + bool can_replace = true; + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + if (E->get() != edited_scene && (E->get()->get_owner() != edited_scene || E->get()->get_filename() != "")) { + can_replace = false; + break; + } + } + + if (can_replace) { + menu->add_icon_shortcut(get_theme_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE); + } if (scene_tree->get_selected() != edited_scene) { menu->add_separator(); @@ -2527,7 +2660,6 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { if (selection.size() == 1) { if (profile_allow_editing) { menu->add_separator(); - menu->add_icon_shortcut(get_theme_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE); menu->add_icon_shortcut(get_theme_icon("CreateNewSceneFrom", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM); } if (full_selection.size() == 1) { @@ -2815,6 +2947,62 @@ void SceneTreeDock::_feature_profile_changed() { _update_script_button(); } +void SceneTreeDock::_clear_clipboard() { + for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) { + memdelete(E->get()); + } + node_clipboard.clear(); + clipboard_resource_remap.clear(); +} + +void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) { + List<PropertyInfo> props; + p_node->get_property_list(&props); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + + Variant v = p_node->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) { + _create_remap_for_resource(res, r_remap); + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _create_remap_for_node(p_node->get_child(i), r_remap); + } +} + +void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_remap) { + r_remap[p_resource] = p_resource->duplicate(); + + List<PropertyInfo> props; + p_resource->get_property_list(&props); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + + Variant v = p_resource->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) { + _create_remap_for_resource(res, r_remap); + } + } + } + } +} + void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_owners"), &SceneTreeDock::_set_owners); ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input); @@ -2848,6 +3036,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KEY_MASK_CMD | KEY_A); ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene")); ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse All")); + ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KEY_MASK_CMD | KEY_X); + ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KEY_MASK_CMD | KEY_C); + ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KEY_MASK_CMD | KEY_V); ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type")); ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script")); ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script")); @@ -2858,9 +3049,8 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/reparent", TTR("Reparent")); ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node")); ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root")); - ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene")); ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); - ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_C); + ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_C); ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT | KEY_DELETE); ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE); @@ -2883,7 +3073,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel filter->set_h_size_flags(SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter nodes")); filter_hbc->add_child(filter); - filter->add_theme_constant_override("minimum_spaces", 0); + filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed)); button_create_script = memnew(Button); @@ -2978,7 +3168,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel delete_dialog = memnew(ConfirmationDialog); add_child(delete_dialog); - delete_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_delete_confirm)); + delete_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_delete_confirm), varray(false)); editable_instance_remove_dialog = memnew(ConfirmationDialog); add_child(editable_instance_remove_dialog); @@ -2988,10 +3178,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel add_child(placeholder_editable_instance_remove_dialog); placeholder_editable_instance_remove_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_toggle_placeholder_from_selection)); - import_subscene_dialog = memnew(EditorSubScene); - add_child(import_subscene_dialog); - import_subscene_dialog->connect("subscene_selected", callable_mp(this, &SceneTreeDock::_import_subscene)); - new_scene_from_dialog = memnew(EditorFileDialog); new_scene_from_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); add_child(new_scene_from_dialog); @@ -3023,3 +3209,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel EDITOR_DEF("interface/editors/derive_script_globals_by_name", true); EDITOR_DEF("_use_favorites_root_selection", false); } + +SceneTreeDock::~SceneTreeDock() { + if (!node_clipboard.is_empty()) { + _clear_clipboard(); + } +} diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 45f4ea02c3..aa62c93cb5 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -34,7 +34,6 @@ #include "editor/connections_dialog.h" #include "editor/create_dialog.h" #include "editor/editor_data.h" -#include "editor/editor_sub_scene.h" #include "editor/groups_editor.h" #include "editor/quick_open.h" #include "editor/rename_dialog.h" @@ -58,6 +57,9 @@ class SceneTreeDock : public VBoxContainer { TOOL_NEW, TOOL_INSTANCE, TOOL_EXPAND_COLLAPSE, + TOOL_CUT, + TOOL_COPY, + TOOL_PASTE, TOOL_RENAME, TOOL_BATCH_RENAME, TOOL_REPLACE, @@ -71,7 +73,6 @@ class SceneTreeDock : public VBoxContainer { TOOL_REPARENT_TO_NEW_NODE, TOOL_MAKE_ROOT, TOOL_NEW_SCENE_FROM, - TOOL_MERGE_FROM_SCENE, TOOL_MULTI_EDIT, TOOL_ERASE, TOOL_COPY_NODE_PATH, @@ -127,6 +128,10 @@ class SceneTreeDock : public VBoxContainer { EditorData *editor_data; EditorSelection *editor_selection; + List<Node *> node_clipboard; + String clipboard_source_scene; + HashMap<String, Map<RES, RES>> clipboard_resource_remap; + ScriptCreateDialog *script_create_dialog; AcceptDialog *accept; ConfirmationDialog *delete_dialog; @@ -135,7 +140,6 @@ class SceneTreeDock : public VBoxContainer { ReparentDialog *reparent_dialog; EditorQuickOpen *quick_open; - EditorSubScene *import_subscene_dialog; EditorFileDialog *new_scene_from_dialog; LineEdit *filter; @@ -184,7 +188,7 @@ class SceneTreeDock : public VBoxContainer { void _script_created(Ref<Script> p_script); void _script_creation_closed(); - void _delete_confirm(); + void _delete_confirm(bool p_cut = false); void _toggle_editable_children_from_selection(); void _toggle_editable_children(Node *p_node); @@ -200,8 +204,10 @@ class SceneTreeDock : public VBoxContainer { void _import_subscene(); void _new_scene_from(String p_file); + void _set_node_owner_recursive(Node *p_node, Node *p_owner); bool _validate_no_foreign(); + bool _validate_no_instance(); void _selection_changed(); void _update_script_button(); @@ -231,6 +237,10 @@ class SceneTreeDock : public VBoxContainer { void _feature_profile_changed(); + void _clear_clipboard(); + void _create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap); + void _create_remap_for_resource(RES p_resource, Map<RES, RES> &r_remap); + bool profile_allow_editing; bool profile_allow_script_editing; @@ -271,6 +281,7 @@ public: ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; } SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data); + ~SceneTreeDock(); }; #endif // SCENE_TREE_DOCK_H diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index b8475656ee..b6347d3b46 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -156,7 +156,7 @@ void SceneTreeEditor::_toggle_visible(Node *p_node) { } } -bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { +bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected) { if (!p_node) { return false; } @@ -236,6 +236,8 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->set_text(0, node_name); item->set_selectable(0, marked_selectable); item->set_custom_color(0, get_theme_color("accent_color", "Editor")); + } else if (!p_node->can_process()) { + item->set_custom_color(0, get_theme_color("disabled_font_color", "Editor")); } else if (!marked_selectable && !marked_children_selectable) { Node *node = p_node; while (node) { @@ -391,15 +393,19 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } } + bool scroll = false; + if (editor_selection) { if (editor_selection->is_selected(p_node)) { item->select(0); + scroll = p_scroll_to_selected; } } if (selected == p_node) { if (!editor_selection) { item->select(0); + scroll = p_scroll_to_selected; } item->set_as_cursor(0); } @@ -407,7 +413,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { bool keep = (filter.is_subsequence_ofi(String(p_node->get_name()))); for (int i = 0; i < p_node->get_child_count(); i++) { - bool child_keep = _add_nodes(p_node->get_child(i), item); + bool child_keep = _add_nodes(p_node->get_child(i), item, p_scroll_to_selected); keep = keep || child_keep; } @@ -438,6 +444,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { memdelete(item); return false; } else { + if (scroll) { + tree->scroll_to_item(item); + } return true; } } @@ -525,7 +534,7 @@ void SceneTreeEditor::_node_renamed(Node *p_node) { } } -void SceneTreeEditor::_update_tree() { +void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { if (!is_inside_tree()) { tree_dirty = false; return; @@ -534,7 +543,7 @@ void SceneTreeEditor::_update_tree() { updating_tree = true; tree->clear(); if (get_scene_node()) { - _add_nodes(get_scene_node(), nullptr); + _add_nodes(get_scene_node(), nullptr, p_scroll_to_selected); last_hash = hash_djb2_one_64(0); _compute_hash(get_scene_node(), last_hash); } @@ -578,6 +587,11 @@ void SceneTreeEditor::_test_update_tree() { tree_dirty = true; } +void SceneTreeEditor::_tree_process_mode_changed() { + MessageQueue::get_singleton()->push_call(this, "_update_tree"); + tree_dirty = true; +} + void SceneTreeEditor::_tree_changed() { if (EditorNode::get_singleton()->is_exiting()) { return; //speed up exit @@ -648,6 +662,7 @@ void SceneTreeEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { get_tree()->connect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed)); + get_tree()->connect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed)); get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed)); get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed)); get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed)); @@ -658,6 +673,7 @@ void SceneTreeEditor::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { get_tree()->disconnect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed)); + get_tree()->disconnect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed)); get_tree()->disconnect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed)); get_tree()->disconnect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed)); tree->disconnect("item_collapsed", callable_mp(this, &SceneTreeEditor::_cell_collapsed)); @@ -817,7 +833,7 @@ void SceneTreeEditor::set_marked(Node *p_marked, bool p_selectable, bool p_child void SceneTreeEditor::set_filter(const String &p_filter) { filter = p_filter; - _update_tree(); + _update_tree(true); } String SceneTreeEditor::get_filter() const { @@ -1103,7 +1119,7 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) { } void SceneTreeEditor::_bind_methods() { - ClassDB::bind_method("_update_tree", &SceneTreeEditor::_update_tree); // Still used by some connect_compat. + ClassDB::bind_method(D_METHOD("_update_tree", "scroll_to_selected"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by some connect_compat. ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node); ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree); @@ -1187,7 +1203,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope blocked = 0; update_timer = memnew(Timer); - update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree)); + update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree), varray(false)); update_timer->set_one_shot(true); update_timer->set_wait_time(0.5); add_child(update_timer); @@ -1253,7 +1269,7 @@ SceneTreeDialog::SceneTreeDialog() { filter = memnew(LineEdit); filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter nodes")); - filter->add_theme_constant_override("minimum_spaces", 0); + filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed)); vbc->add_child(filter); diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 831723a27c..6b505a6784 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -71,10 +71,11 @@ class SceneTreeEditor : public Control { void _compute_hash(Node *p_node, uint64_t &hash); - bool _add_nodes(Node *p_node, TreeItem *p_parent); + bool _add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected = false); void _test_update_tree(); - void _update_tree(); + void _update_tree(bool p_scroll_to_selected = false); void _tree_changed(); + void _tree_process_mode_changed(); void _node_removed(Node *p_node); void _node_renamed(Node *p_node); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 1dad3c091d..3852c389c7 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -31,6 +31,7 @@ #include "settings_config_dialog.h" #include "core/config/project_settings.h" +#include "core/input/input_map.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" #include "editor_file_system.h" @@ -143,7 +144,7 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) { if (k.is_valid() && k->is_pressed()) { bool handled = false; - if (ED_IS_SHORTCUT("editor/undo", p_event)) { + if (ED_IS_SHORTCUT("ui_undo", p_event)) { String action = undo_redo->get_current_action_name(); if (action != "") { EditorNode::get_log()->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR); @@ -152,7 +153,7 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) { handled = true; } - if (ED_IS_SHORTCUT("editor/redo", p_event)) { + if (ED_IS_SHORTCUT("ui_redo", p_event)) { undo_redo->redo(); String action = undo_redo->get_current_action_name(); if (action != "") { @@ -184,7 +185,52 @@ void EditorSettingsDialog::_update_icons() { restart_label->add_theme_color_override("font_color", shortcuts->get_theme_color("warning_color", "Editor")); } +void EditorSettingsDialog::_event_config_confirmed() { + Ref<InputEventKey> k = shortcut_editor->get_event(); + if (k.is_null()) { + return; + } + + if (editing_action) { + if (current_action_event_index == -1) { + // Add new event + current_action_events.push_back(k); + } else { + // Edit existing event + current_action_events[current_action_event_index] = k; + } + + _update_builtin_action(current_action, current_action_events); + } else { + k = k->duplicate(); + Ref<Shortcut> current_sc = EditorSettings::get_singleton()->get_shortcut(shortcut_being_edited); + + undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_being_edited + "'"); + undo_redo->add_do_method(current_sc.ptr(), "set_shortcut", k); + undo_redo->add_undo_method(current_sc.ptr(), "set_shortcut", current_sc->get_shortcut()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); + } +} + +void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Array &p_events) { + Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(current_action); + + undo_redo->create_action(TTR("Edit Built-in Action")); + undo_redo->add_do_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, p_events); + undo_redo->add_undo_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, old_input_array); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); + + _update_shortcuts(); +} + void EditorSettingsDialog::_update_shortcuts() { + // Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated. Map<String, bool> collapsed; if (shortcuts->get_root() && shortcuts->get_root()->get_children()) { @@ -192,15 +238,93 @@ void EditorSettingsDialog::_update_shortcuts() { collapsed[item->get_text(0)] = item->is_collapsed(); } } - shortcuts->clear(); - List<String> slist; - EditorSettings::get_singleton()->get_shortcut_list(&slist); TreeItem *root = shortcuts->create_item(); - Map<String, TreeItem *> sections; + // Set up section for Common/Built-in actions + TreeItem *common_section = shortcuts->create_item(root); + + sections["Common"] = common_section; + common_section->set_text(0, TTR("Common")); + if (collapsed.has("Common")) { + common_section->set_collapsed(collapsed["Common"]); + } + common_section->set_custom_bg_color(0, shortcuts->get_theme_color("prop_subsection", "Editor")); + common_section->set_custom_bg_color(1, shortcuts->get_theme_color("prop_subsection", "Editor")); + + // Get the action map for the editor, and add each item to the "Common" section. + OrderedHashMap<StringName, InputMap::Action> action_map = InputMap::get_singleton()->get_action_map(); + for (OrderedHashMap<StringName, InputMap::Action>::Element E = action_map.front(); E; E = E.next()) { + String action_name = E.key(); + + if (!shortcut_filter.is_subsequence_ofi(action_name)) { + continue; + } + + InputMap::Action action = E.get(); + + Array events; // Need to get the list of events into an array so it can be set as metadata on the item. + Vector<String> event_strings; + + List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins().find(action_name).value(); + // Remove all non-key events from the defaults. + for (List<Ref<InputEvent>>::Element *I = defaults.front(); I; I = I->next()) { + Ref<InputEventKey> k = I->get(); + if (k.is_null()) { + I->erase(); + } + } + + bool same_as_defaults = defaults.size() == action.inputs.size(); // Initially this is set to just whether the arrays are equal. Later we check the events if needed. + + int count = 0; + for (List<Ref<InputEvent>>::Element *I = action.inputs.front(); I; I = I->next()) { + // Add event and event text to respective arrays. + events.push_back(I->get()); + event_strings.push_back(I->get()->as_text()); + + // Only check if the events have been the same so far - once one fails, we don't need to check any more. + if (same_as_defaults) { + Ref<InputEventKey> k = defaults[count]; + // Only check keys, since we are in the editor. + if (k.is_valid() && !defaults[count]->shortcut_match(I->get())) { + same_as_defaults = false; + } + } + count++; + } + + // Join the text of the events with a delimiter so they can all be displayed in one cell. + String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings); + + TreeItem *item = shortcuts->create_item(common_section); + item->set_text(0, action_name); + item->set_text(1, events_display_string); + + if (!same_as_defaults) { + item->add_button(1, shortcuts->get_theme_icon("Reload", "EditorIcons"), 2); + } + + if (events_display_string == "None") { + // Fade out unassigned shortcut labels for easier visual grepping. + item->set_custom_color(1, shortcuts->get_theme_color("font_color", "Label") * Color(1, 1, 1, 0.5)); + } + + item->add_button(1, shortcuts->get_theme_icon("Edit", "EditorIcons"), 0); + item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), 1); + item->set_tooltip(0, action_name); + item->set_tooltip(1, events_display_string); + item->set_metadata(0, "Common"); + item->set_metadata(1, events); + } + + // Editor Shortcuts + + List<String> slist; + EditorSettings::get_singleton()->get_shortcut_list(&slist); + for (List<String>::Element *E = slist.front(); E; E = E->next()) { Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E->get()); if (!sc->has_meta("original")) { @@ -267,84 +391,119 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column TreeItem *ti = Object::cast_to<TreeItem>(p_item); ERR_FAIL_COND(!ti); - String item = ti->get_metadata(0); - Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item); - - if (p_idx == 0) { - press_a_key_label->set_text(TTR("Press a Key...")); - last_wait_for_key = Ref<InputEventKey>(); - press_a_key->popup_centered(Size2(250, 80) * EDSCALE); - //press_a_key->grab_focus(); - press_a_key->get_ok_button()->set_focus_mode(Control::FOCUS_NONE); - press_a_key->get_cancel_button()->set_focus_mode(Control::FOCUS_NONE); - shortcut_configured = item; - - } else if (p_idx == 1) { //erase - if (!sc.is_valid()) { - return; //pointless, there is nothing + if (ti->get_metadata(0) == "Common") { + // Editing a Built-in action, which can have multiple bindings. + button_idx = p_idx; + editing_action = true; + current_action = ti->get_text(0); + + switch (button_idx) { + case SHORTCUT_REVERT: { + Array events; + List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins()[current_action]; + + // Convert the list to an array, and only keep key events as this is for the editor. + for (List<Ref<InputEvent>>::Element *E = defaults.front(); E; E = E->next()) { + Ref<InputEventKey> k = E->get(); + if (k.is_valid()) { + events.append(E->get()); + } + } + + _update_builtin_action(current_action, events); + } break; + case SHORTCUT_EDIT: + case SHORTCUT_ERASE: { + // For Edit end Delete, we will show a popup which displays each event so the user can select which one to edit/delete. + current_action_events = ti->get_metadata(1); + action_popup->clear(); + + for (int i = 0; i < current_action_events.size(); i++) { + Ref<InputEvent> ie = current_action_events[i]; + action_popup->add_item(ie->as_text()); + action_popup->set_item_metadata(i, ie); + } + + if (button_idx == SHORTCUT_EDIT) { + // If editing, add a button which can be used to add an additional event. + action_popup->add_icon_item(get_theme_icon("Add", "EditorIcons"), TTR("Add")); + } + + action_popup->set_position(get_position() + get_mouse_position()); + action_popup->take_mouse_focus(); + action_popup->popup(); + action_popup->set_as_minsize(); + } break; + default: + break; } - - undo_redo->create_action(TTR("Erase Shortcut")); - undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>()); - undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); - undo_redo->add_do_method(this, "_update_shortcuts"); - undo_redo->add_undo_method(this, "_update_shortcuts"); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); - } else if (p_idx == 2) { //revert to original - if (!sc.is_valid()) { - return; //pointless, there is nothing + } else { + // Editing an Editor Shortcut, which can only have 1 binding. + String item = ti->get_metadata(0); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item); + editing_action = false; + + switch (button_idx) { + case EditorSettingsDialog::SHORTCUT_EDIT: + shortcut_editor->popup_and_configure(sc->get_shortcut()); + shortcut_being_edited = item; + break; + case EditorSettingsDialog::SHORTCUT_ERASE: { + if (!sc.is_valid()) { + return; //pointless, there is nothing + } + + undo_redo->create_action(TTR("Erase Shortcut")); + undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>()); + undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); + } break; + case EditorSettingsDialog::SHORTCUT_REVERT: { + if (!sc.is_valid()) { + return; //pointless, there is nothing + } + + Ref<InputEvent> original = sc->get_meta("original"); + + undo_redo->create_action(TTR("Restore Shortcut")); + undo_redo->add_do_method(sc.ptr(), "set_shortcut", original); + undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); + } break; + default: + break; } - - Ref<InputEvent> original = sc->get_meta("original"); - - undo_redo->create_action(TTR("Restore Shortcut")); - undo_redo->add_do_method(sc.ptr(), "set_shortcut", original); - undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); - undo_redo->add_do_method(this, "_update_shortcuts"); - undo_redo->add_undo_method(this, "_update_shortcuts"); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); } } -void EditorSettingsDialog::_wait_for_key(const Ref<InputEvent> &p_event) { - Ref<InputEventKey> k = p_event; - - if (k.is_valid() && k->is_pressed() && k->get_keycode() != 0) { - last_wait_for_key = k; - const String str = keycode_get_string(k->get_keycode_with_modifiers()); - - press_a_key_label->set_text(str); - press_a_key->set_input_as_handled(); - } -} - -void EditorSettingsDialog::_press_a_key_confirm() { - if (last_wait_for_key.is_null()) { - return; +void EditorSettingsDialog::_builtin_action_popup_index_pressed(int p_index) { + switch (button_idx) { + case SHORTCUT_EDIT: { + if (p_index == action_popup->get_item_count() - 1) { + // Selected last item in list (Add button), therefore add new + current_action_event_index = -1; + shortcut_editor->popup_and_configure(); + } else { + // Configure existing + current_action_event_index = p_index; + shortcut_editor->popup_and_configure(action_popup->get_item_metadata(p_index)); + } + } break; + case SHORTCUT_ERASE: { + current_action_events.remove(p_index); + _update_builtin_action(current_action, current_action_events); + } break; + default: + break; } - - Ref<InputEventKey> ie; - ie.instance(); - ie->set_keycode(last_wait_for_key->get_keycode()); - ie->set_shift(last_wait_for_key->get_shift()); - ie->set_control(last_wait_for_key->get_control()); - ie->set_alt(last_wait_for_key->get_alt()); - ie->set_metakey(last_wait_for_key->get_metakey()); - - Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured); - - undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_configured + "'"); - undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie); - undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); - undo_redo->add_do_method(this, "_update_shortcuts"); - undo_redo->add_undo_method(this, "_update_shortcuts"); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); } void EditorSettingsDialog::_tabs_tab_changed(int p_tab) { @@ -382,9 +541,14 @@ void EditorSettingsDialog::_editor_restart_close() { void EditorSettingsDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorSettingsDialog::_unhandled_input); ClassDB::bind_method(D_METHOD("_update_shortcuts"), &EditorSettingsDialog::_update_shortcuts); + ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed); } EditorSettingsDialog::EditorSettingsDialog() { + action_popup = memnew(PopupMenu); + action_popup->connect("index_pressed", callable_mp(this, &EditorSettingsDialog::_builtin_action_popup_index_pressed)); + add_child(action_popup); + set_title(TTR("Editor Settings")); undo_redo = memnew(UndoRedo); @@ -442,21 +606,17 @@ EditorSettingsDialog::EditorSettingsDialog() { // Shortcuts Tab tab_shortcuts = memnew(VBoxContainer); + tabs->add_child(tab_shortcuts); tab_shortcuts->set_name(TTR("Shortcuts")); - hbc = memnew(HBoxContainer); - hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); - tab_shortcuts->add_child(hbc); - shortcut_search_box = memnew(LineEdit); shortcut_search_box->set_placeholder(TTR("Search")); shortcut_search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - hbc->add_child(shortcut_search_box); + tab_shortcuts->add_child(shortcut_search_box); shortcut_search_box->connect("text_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts)); shortcuts = memnew(Tree); - tab_shortcuts->add_child(shortcuts, true); shortcuts->set_v_size_flags(Control::SIZE_EXPAND_FILL); shortcuts->set_columns(2); shortcuts->set_hide_root(true); @@ -464,21 +624,13 @@ EditorSettingsDialog::EditorSettingsDialog() { shortcuts->set_column_title(0, TTR("Name")); shortcuts->set_column_title(1, TTR("Binding")); shortcuts->connect("button_pressed", callable_mp(this, &EditorSettingsDialog::_shortcut_button_pressed)); + tab_shortcuts->add_child(shortcuts); - press_a_key = memnew(ConfirmationDialog); - //press_a_key->set_focus_mode(Control::FOCUS_ALL); - add_child(press_a_key); - - Label *l = memnew(Label); - l->set_text(TTR("Press a Key...")); - l->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - l->set_align(Label::ALIGN_CENTER); - l->set_offset(SIDE_TOP, 20); - l->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_BEGIN, 30); - press_a_key_label = l; - press_a_key->add_child(l); - press_a_key->connect("window_input", callable_mp(this, &EditorSettingsDialog::_wait_for_key)); - press_a_key->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_press_a_key_confirm)); + // Adding event dialog + shortcut_editor = memnew(InputEventConfigurationDialog); + shortcut_editor->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_event_config_confirmed)); + shortcut_editor->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY); + add_child(shortcut_editor); set_hide_on_ok(true); diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h index b1ee58ae8f..c38fceedf1 100644 --- a/editor/settings_config_dialog.h +++ b/editor/settings_config_dialog.h @@ -31,6 +31,7 @@ #ifndef SETTINGS_CONFIG_DIALOG_H #define SETTINGS_CONFIG_DIALOG_H +#include "editor/action_map_editor.h" #include "editor/editor_sectioned_inspector.h" #include "editor_inspector.h" #include "scene/gui/dialogs.h" @@ -52,16 +53,28 @@ class EditorSettingsDialog : public AcceptDialog { LineEdit *shortcut_search_box; SectionedInspector *inspector; + enum ShortcutButton { + SHORTCUT_EDIT, + SHORTCUT_ERASE, + SHORTCUT_REVERT + }; + + int button_idx; + int current_action_event_index = -1; + bool editing_action = false; + String current_action; + Array current_action_events; + PopupMenu *action_popup; + Timer *timer; UndoRedo *undo_redo; - Tree *shortcuts; - ConfirmationDialog *press_a_key; - Label *press_a_key_label; - Ref<InputEventKey> last_wait_for_key; - String shortcut_configured; + // Shortcuts String shortcut_filter; + Tree *shortcuts; + InputEventConfigurationDialog *shortcut_editor; + String shortcut_being_edited; virtual void cancel_pressed() override; virtual void ok_pressed() override; @@ -74,20 +87,20 @@ class EditorSettingsDialog : public AcceptDialog { void _notification(int p_what); void _update_icons(); - void _press_a_key_confirm(); - void _wait_for_key(const Ref<InputEvent> &p_event); + void _event_config_confirmed(); + + void _update_builtin_action(const String &p_name, const Array &p_events); void _tabs_tab_changed(int p_tab); void _focus_current_search_box(); - void _clear_shortcut_search_box(); - void _clear_search_box(); - void _filter_shortcuts(const String &p_filter); void _update_shortcuts(); void _shortcut_button_pressed(Object *p_item, int p_column, int p_idx); + void _builtin_action_popup_index_pressed(int p_index); + static void _undo_redo_callback(void *p_self, const String &p_name); Label *restart_label; diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 14d305e34f..ebef5be9ed 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -427,7 +427,7 @@ void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { void ShaderGlobalsEditor::_changed() { emit_signal("globals_changed"); if (!interface->block_update) { - interface->_change_notify(); + interface->notify_property_list_changed(); } } @@ -483,8 +483,5 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() { } ShaderGlobalsEditor::~ShaderGlobalsEditor() { - if (is_visible_in_tree()) { - inspector->edit(nullptr); - } memdelete(interface); } diff --git a/editor/translations/af.po b/editor/translations/af.po index 0f26618d10..e2a66e1acc 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -659,7 +659,7 @@ msgstr "Stel Oorgange na:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -2011,10 +2011,6 @@ msgstr "Voorskou:" msgid "File:" msgstr "Lêer:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Moet 'n geldige uitbreiding gebruik." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "SkandeerBronne" @@ -2442,6 +2438,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2486,18 +2486,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2546,6 +2534,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2589,7 +2581,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2989,14 +2981,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Soek" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3151,6 +3135,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3357,7 +3357,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -5077,7 +5077,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5218,8 +5218,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5233,9 +5232,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Skep Vouer" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6324,6 +6343,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Hernoem AutoLaai" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6384,10 +6408,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6994,6 +7014,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Soek" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7046,16 +7074,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7155,8 +7173,8 @@ msgstr "Skep" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7390,6 +7408,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10005,6 +10027,11 @@ msgid "Projects" msgstr "Projek Stigters" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Laai" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10620,6 +10647,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Anim Dupliseer Sleutels" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Deursoek Hulp" @@ -10746,6 +10782,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Anim Dupliseer Sleutels" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11561,6 +11602,35 @@ msgstr "Eienskappe" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Beskrywing" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12077,11 +12147,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12093,11 +12165,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12105,9 +12177,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12509,27 +12591,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12589,6 +12671,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12806,6 +12892,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Moet 'n geldige uitbreiding gebruik." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12851,6 +12941,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index a99dde217a..d12383f798 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -684,7 +684,7 @@ msgstr "إختر المقاطع المراد نسخها" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "نسخ" @@ -1977,10 +1977,6 @@ msgstr "إستعراض:" msgid "File:" msgstr "الملÙ:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "يجب أن يستخدم صيغة صØÙŠØØ©." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "ÙØØµ المصادر" @@ -2409,6 +2405,10 @@ msgid "There is no defined scene to run." msgstr "ليس هناك مشهد Ù…ØØ¯Ø¯ ليتم تشغيله." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "لا يمكن بدء عملية جانبية!" @@ -2452,18 +2452,6 @@ msgstr "يتطلب ØÙظ المشهد ØªÙˆØ§ÙØ± عÙقدة رئيسة." msgid "Save Scene As..." msgstr "ØÙظ المشهد كـ…" -#: editor/editor_node.cpp -msgid "No" -msgstr "لا" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "نعم" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "هذا المشهد لم يتم ØÙظه. هل تود ØÙظه قبل تشغيله؟" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "هذه العملية لا يمكن الإكتمال من غير مشهد." @@ -2513,6 +2501,10 @@ msgid "Quit" msgstr "إنهاء" #: editor/editor_node.cpp +msgid "Yes" +msgstr "نعم" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "خروج من Ø§Ù„Ù…ÙØ¹Ø¯Ù„ØŸ" @@ -2559,7 +2551,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "غير قادر علي ØªÙØ¹ÙŠÙ„ Ø¥Ø¶Ø§ÙØ© البرنامج Ø§Ù„Ù…ÙØ³Ø§Ø¹Ø¯ ÙÙŠ: '%s' تØÙ…يل الظبط ÙØ´Ù„." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "غير قادر علي إيجاد منطقة النص البرمجي من أجل Ø¥Ø¶Ø§ÙØ© البرنامج ÙÙŠ: 'res://" "addons/%s'." @@ -2991,14 +2984,6 @@ msgid "Help" msgstr "مساعدة" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Ø¨ØØ«" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "مستندات الإنترنت" @@ -3162,6 +3147,25 @@ msgid "Open & Run a Script" msgstr "ÙØªØ Ùˆ تشغيل كود" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Ø§Ù„Ù…Ù„ÙØ§Øª التالية Ø£ØØ¯Ø« على القرص.\n" +"ما الإجراء الذي ينبغي اتخاذه؟:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "إعادة تØÙ…يل" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "إعادة ØÙظ" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "موروث جديد" @@ -3371,7 +3375,7 @@ msgstr "إجعلة مميزاً" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "لصق" @@ -5036,7 +5040,8 @@ msgid "Got:" msgstr "ما تم Ø§Ù„ØØµÙˆÙ„ عليه:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "ÙØ´Ù„ التاكد من ترميز sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5169,10 +5174,10 @@ msgid "Assets ZIP File" msgstr "مل٠أصول مضغوط" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "لا يمكن ØªØØ¯ÙŠØ¯ مسار ØÙظ لصور خرائط الضوء.\n" "اØÙظ مشهدك (لكي تØÙظ الصور ÙÙŠ المسار ذاته), او اختر مسار ØÙظ لخصائص خرائط " @@ -5191,9 +5196,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "لا يمكن انشاء خرائط الضوء, تاكد من ان المسار صØÙŠØ." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "إعداد خرائط الضوء" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "ØØ¯Ø¯ مل٠القالب" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6284,6 +6309,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "لا يمكن إنشاء سوى نقطة ÙˆØÙŠØ¯Ø© داخل ParticlesMaterial معالج المواد" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "تØÙˆÙŠÙ„ إلى %s" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "وقت التوليد (تانية):" @@ -6344,10 +6374,6 @@ msgstr "توليد AABB" msgid "Generate Visibility AABB" msgstr "ولد رؤية AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "ولد AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "إزالة نقطة من المنØÙ†Ù‰" @@ -6942,6 +6968,14 @@ msgstr "إغلاق المستندات" msgid "Run" msgstr "تشغيل" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Ø¨ØØ«" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "اخط خطوة ضمن" @@ -6995,16 +7029,6 @@ msgstr "" "Ø§Ù„Ù…Ù„ÙØ§Øª التالية Ø£ØØ¯Ø« على القرص.\n" "ما الإجراء الذي ينبغي اتخاذه؟:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "إعادة تØÙ…يل" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "إعادة ØÙظ" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Ù…ÙÙ†Ù‚Ø Ø§Ù„Ø£Ø®Ø·Ø§Ø¡" @@ -7098,8 +7122,8 @@ msgstr "نقاط التكسّر" msgid "Go To" msgstr "التوجه إلى" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "قص" @@ -7322,6 +7346,11 @@ msgid "Yaw" msgstr "Ø§Ù„Ø¥Ù†ØØ±Ø§Ù Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Ø§Ù„ØØ¬Ù…: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "كائنات مرسومة" @@ -10010,6 +10039,11 @@ msgid "Projects" msgstr "المشاريع" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "يستقبل المرايا، من ÙØ¶Ù„Ùƒ إنتظر..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "آخر ما تم تعديله" @@ -10631,6 +10665,16 @@ msgid "Instance Child Scene" msgstr "نمذجة المشهد الابن" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "لا يمكن تنÙيذ الإجراء على عÙقدة من مشهد أجنبي!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "لصق العÙقد" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "ÙØµÙ„ النص البرمجي" @@ -10758,6 +10802,11 @@ msgid "Attach Script" msgstr "Ø¥Ù„ØØ§Ù‚ نص برمجي" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "قص العÙقد" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "إزالة عÙقدة (عÙقد)" @@ -11563,6 +11612,39 @@ msgstr "" "Ø§Ù…Ù†Ø Ù…ÙƒØªØ¨Ø© Ø§Ù„Ø³Ø·ÙˆØ MeshLibrary وصولاً لخريطة الشبكة لتستخدم Ø§Ù„Ø³Ø·ÙˆØ Ø§Ù„Ù…Ø¬Ø³Ù…Ø© " "الخاصة بها meshes." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "ولد AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "الاتجاهات" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Ø§Ù„Ù…Ø³Ø§ÙØ© البادئة يميناً" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "المعالجة-اللاØÙ‚Ø© Post-Process" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "تخطيط الإضاءات:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "لا يمكن أن يكون اسم الص٠كلمة Ù…ØØ¬ÙˆØ²Ø©" @@ -12071,14 +12153,15 @@ msgid "Select device from the list" msgstr "اختر جهازاً من القائمة" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "لم يتم تهيئة Ù…ÙÙ†Ùّذ ADB ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." +msgid "Unable to find the 'apksigner' tool." +msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" -"‌مÙوقّع Ù…Ù„ÙØ§Øª الجار jarsigner Ø§Ù„Ù…ÙØªÙˆØ الخاص Ø¨ØØ²Ù…Ø© التطوير OpenJDK غير Ù…Ùهيّئ ÙÙŠ " -"إعدادات Ø§Ù„Ù…ÙØØ±Ø±." +"لم يتم تنزيل قالب بناء Android لهذا المشروع. نزّل ÙˆØ§ØØ¯Ø§Ù‹ من قائمة المشروع." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12091,12 +12174,14 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "ØªØØ±Ø± مخزن Ø§Ù„Ù…ÙØ§ØªÙŠØ غير Ù…Ùهيئ بشكل صØÙŠØ ÙÙŠ إعدادت المسبقة للتصدير." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"البÙنى المخصوصة تتطلب مساراً Ù„ØØ²Ù…Ø© تطوير Android SDK ØµØ§Ù„ØØ© ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." +"مسار ØØ²Ù…Ø© تطوير Android SDK للبÙنى المخصوصة، غير ØµØ§Ù„Ø ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "" "مسار ØØ²Ù…Ø© تطوير Android SDK للبÙنى المخصوصة، غير ØµØ§Ù„Ø ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." @@ -12105,11 +12190,22 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"مسار ØØ²Ù…Ø© تطوير Android SDK للبÙنى المخصوصة، غير ØµØ§Ù„Ø ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"لم يتم تنزيل قالب بناء Android لهذا المشروع. نزّل ÙˆØ§ØØ¯Ø§Ù‹ من قائمة المشروع." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12589,28 +12685,32 @@ msgstr "" "(KinematicBody2D)ØŒ وما إلى ذلك لمنØÙ‡Ù… شكلاً." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(الوقت المتبقي: %d:%02d ثانية)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "توزيع الأشكال الهندسية..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "تخطيط المجسمات: " +#, fuzzy +msgid "Preparing environment" +msgstr "عرض البيئة" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "تخطيط الإضاءات:" +#, fuzzy +msgid "Generating capture" +msgstr "انشاء خارطة الضوء" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "الانتهاء من التخطيط" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "انشاء خارطة الضوء" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "إضاءة المجسمات: " +msgid "Done" +msgstr "تم" #: scene/3d/collision_object.cpp msgid "" @@ -12688,6 +12788,10 @@ msgid "Plotting Meshes" msgstr "تخطيط المجسمات" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "الانتهاء من التخطيط" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12944,6 +13048,10 @@ msgstr "تنبيه!" msgid "Please Confirm..." msgstr "ÙŠÙØ±Ø¬Ù‰ التأكيد..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "يجب أن يستخدم صيغة صØÙŠØØ©." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -13001,6 +13109,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "ينبغي أن يكون ØØ¬Ù… إطار العرض أكبر من 0 ليتم الإخراج البصري لأي شيء." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "مصدر غير ØµØ§Ù„Ø Ù„Ù„Ù…Ø¹Ø§ÙŠÙ†Ø©." @@ -13028,6 +13142,37 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ." msgid "Constants cannot be modified." msgstr "لا يمكن تعديل الثوابت." +#~ msgid "No" +#~ msgstr "لا" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "هذا المشهد لم يتم ØÙظه. هل تود ØÙظه قبل تشغيله؟" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "لم يتم تهيئة Ù…ÙÙ†Ùّذ ADB ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "" +#~ "‌مÙوقّع Ù…Ù„ÙØ§Øª الجار jarsigner Ø§Ù„Ù…ÙØªÙˆØ الخاص Ø¨ØØ²Ù…Ø© التطوير OpenJDK غير Ù…Ùهيّئ " +#~ "ÙÙŠ إعدادات Ø§Ù„Ù…ÙØØ±Ø±." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "البÙنى المخصوصة تتطلب مساراً Ù„ØØ²Ù…Ø© تطوير Android SDK ØµØ§Ù„ØØ© ÙÙŠ إعدادات " +#~ "Ø§Ù„Ù…ÙØØ±Ø±." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(الوقت المتبقي: %d:%02d ثانية)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "تخطيط المجسمات: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "إضاءة المجسمات: " + #~ msgid "Search complete" #~ msgstr "إكتمل Ø§Ù„Ø¨ØØ«" @@ -13262,9 +13407,6 @@ msgstr "لا يمكن تعديل الثوابت." #~ msgid "Failed to save solution." #~ msgstr "ÙØ´Ù„ ØÙظ الØÙ„." -#~ msgid "Done" -#~ msgstr "تم" - #~ msgid "Failed to create C# project." #~ msgstr "ÙØ´Ù„ إنشاء مشروع C#‎." diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 83885ff225..595899152d 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -11,13 +11,13 @@ # Whod <whodizhod@gmail.com>, 2020. # Stoyan <stoyan.stoyanov99@protonmail.com>, 2020. # zooid <the.zooid@gmail.com>, 2020. -# Любомир ВаÑилев <lyubomirv@gmx.com>, 2020. +# Любомир ВаÑилев <lyubomirv@gmx.com>, 2020, 2021. # Ziv D <wizdavid@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-07 08:11+0000\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" "Last-Translator: Любомир ВаÑилев <lyubomirv@gmx.com>\n" "Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/" "godot/bg/>\n" @@ -26,7 +26,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -640,7 +640,7 @@ msgstr "Изберете пътечки за копиране" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Копиране" @@ -681,13 +681,12 @@ msgid "Line Number:" msgstr "Ðомер на реда:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "ЗамÑна..." +msgstr "%d заменени." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "" +msgstr "%d Ñъвпадение." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." @@ -695,7 +694,7 @@ msgstr "%d ÑъвпадениÑ." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "" +msgstr "Различаване на малки и главни букви" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" @@ -1904,10 +1903,6 @@ msgstr "" msgid "File:" msgstr "Файл:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "ТрÑбва да Ñе използва правилно разширение." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2237,11 +2232,11 @@ msgstr "" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "" +msgstr "Ðе може да Ñе зареди библиотеката Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи за Ñливане!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "" +msgstr "Грешка при запазването на библиотеката Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" @@ -2311,6 +2306,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2354,25 +2353,13 @@ msgstr "" msgid "Save Scene As..." msgstr "Запазване на Ñцената като..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ðе" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Тази Ñцена не е била запазвана преди. Запазване преди изпълнението?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "ОперациÑта не може да Ñе извърши без Ñцена." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "ИзнаÑÑне на библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." @@ -2413,6 +2400,10 @@ msgid "Quit" msgstr "Изход" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2455,8 +2446,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." -msgstr "" +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "Ðе може да Ñе зареди Ñкриптът на добавка от: „%s“." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." @@ -2650,7 +2642,7 @@ msgstr "" #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи…" #: editor/editor_node.cpp msgid "TileSet..." @@ -2767,6 +2759,8 @@ msgid "" "When this option is enabled, navigation meshes and polygons will be visible " "in the running project." msgstr "" +"Ðко тази наÑтройка е включено, навигационните полигони и мрежи ще бъдат " +"видими в изпълнÑÐ²Ð°Ñ‰Ð¸Ñ Ñе проект." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -2845,14 +2839,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "ТърÑене" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3007,6 +2993,25 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Следните файлове Ñа по-нови на диÑка.\n" +"Кое дейÑтвие трÑбва да Ñе предприеме?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Презареждане" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "ПрезапиÑване" + +#: editor/editor_node.cpp +#, fuzzy msgid "New Inherited" msgstr "Ðов Ñкрипт" @@ -3209,7 +3214,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "ПоÑтавÑне" @@ -3745,19 +3750,16 @@ msgid "Searching..." msgstr "ТърÑене..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d ÑъвпадениÑ." +msgstr "%d Ñъвпадение в %d файл." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d ÑъвпадениÑ." +msgstr "%d ÑÑŠÐ²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð² %d файл." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d ÑъвпадениÑ." +msgstr "%d ÑÑŠÐ²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð² %d файла." #: editor/groups_editor.cpp msgid "Add to Group" @@ -3867,7 +3869,7 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "Създаване за полигонна мрежа: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -3981,15 +3983,15 @@ msgstr "" #: editor/inspector_dock.cpp msgid "Save the currently edited resource." -msgstr "" +msgstr "Запазване на текущо Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ð¸Ñ Ñ€ÐµÑурÑ." #: editor/inspector_dock.cpp msgid "Go to the previous edited object in history." -msgstr "" +msgstr "Преминаване към Ð¿Ñ€ÐµÐ´Ñ…Ð¾Ð´Ð½Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½ обект в иÑториÑта." #: editor/inspector_dock.cpp msgid "Go to the next edited object in history." -msgstr "" +msgstr "Преминаване към ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½ обект в иÑториÑта." #: editor/inspector_dock.cpp msgid "History of recently edited objects." @@ -4013,7 +4015,7 @@ msgstr "" #: editor/node_dock.cpp msgid "Select a single node to edit its signals and groups." -msgstr "" +msgstr "Изберете един възел, за да редактирате Ñигналите и групите му." #: editor/plugin_config_dialog.cpp msgid "Edit a Plugin" @@ -4075,11 +4077,11 @@ msgstr "Редактиране на полигона" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "Вмъкване на точка" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Edit Polygon (Remove Point)" -msgstr "" +msgstr "Редактиране на полигона (премахване на точка)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Polygon And Point" @@ -4118,6 +4120,7 @@ msgstr "" #: editor/plugins/animation_state_machine_editor.cpp msgid "This type of node can't be used. Only root nodes are allowed." msgstr "" +"Този тип възел не може да бъде използван. Разрешени Ñа Ñамо коренни възли." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4145,11 +4148,14 @@ msgid "" "AnimationTree is inactive.\n" "Activate to enable playback, check node warnings if activation fails." msgstr "" +"AnimationTree не е активен.\n" +"Ðктивирайте го, за да включите възпроизвеждането. Ðко не Ñтане, проверете " +"дали има предупредителни ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñно възлите." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Set the blending position within the space" -msgstr "" +msgstr "Задаване на точката на ÑмеÑване в проÑтранÑтвото" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4159,12 +4165,12 @@ msgstr "Избиране и премеÑтване на точки; Ñъздав #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp msgid "Enable snap and show grid." -msgstr "" +msgstr "Включване на прилепването и показване на решетката." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Point" -msgstr "" +msgstr "Точка" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4209,7 +4215,7 @@ msgstr "BlendSpace2D не принадлежи на възел от тип Anima #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "No triangles exist, so no blending can take place." -msgstr "" +msgstr "СмеÑването е невъзможно, тъй като нÑма нито един триъгълник." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Toggle Auto Triangles" @@ -4217,24 +4223,24 @@ msgstr "Превключване на автоматичните триъгълР#: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Create triangles by connecting points." -msgstr "" +msgstr "Създаване на триъгълници чрез Ñвързване на точки." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Erase points and triangles." -msgstr "" +msgstr "Изтриване на точки и триъгълници." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Generate blend triangles automatically (instead of manually)" -msgstr "" +msgstr "Създаване на триъгълници за ÑмеÑване автоматично (а не ръчно)" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend:" -msgstr "" +msgstr "СмеÑване:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Parameter Changed" -msgstr "" +msgstr "Параметърът е променен" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -4256,6 +4262,8 @@ msgstr "Възелът е премеÑтен" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Unable to connect, port may be in use or connection may be invalid." msgstr "" +"Свързването е невъзможно. Портът може би е зает, или връзката да е " +"неправилна." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -4279,7 +4287,7 @@ msgstr "Изтриване на възела" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "" +msgstr "Изтриване на възела/възлите" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Toggle Filter On/Off" @@ -4287,7 +4295,7 @@ msgstr "Превключване на филтъра ВКЛ/ИЗКЛ" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Change Filter" -msgstr "" +msgstr "ПромÑна на филтъра" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "No animation player set, so unable to retrieve track names." @@ -4345,7 +4353,7 @@ msgstr "Ðово име на анимациÑта:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Ðова анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" @@ -4359,20 +4367,20 @@ msgstr "Изтриване на анимациÑта?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Премахване на анимациÑта" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Invalid animation name!" -msgstr "" +msgstr "Ðеправилно име на анимациÑта!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation name already exists!" -msgstr "" +msgstr "Вече ÑъщеÑтвува Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ñ Ñ‚Ð¾Ð²Ð° име!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "Преименуване на анимациÑта" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" @@ -4380,19 +4388,19 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "" +msgstr "ПромÑна на времето на ÑмеÑване" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "Зареждане на анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Дублиране на анимациÑта" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to copy!" -msgstr "" +msgstr "ÐÑма Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° копиране!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation resource on clipboard!" @@ -4400,11 +4408,11 @@ msgstr "ÐÑма реÑурÑâ€“Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð² буфера за обмен #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "" +msgstr "ПоÑтавена анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "" +msgstr "ПоÑтавÑне на анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to edit!" @@ -4413,30 +4421,32 @@ msgstr "ÐÑма Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° редактиране!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" msgstr "" +"Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ от текущата позициÑ. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ от краÑ. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "Спиране на възпроизвеждането на анимациÑта. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ началото. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ текущата позициÑ. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð² анимациÑта (в Ñекунди)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." msgstr "" +"Скалиране на ÑкороÑтта на възпроизвеждане на анимациÑта глобално за възела." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" @@ -4444,7 +4454,7 @@ msgstr "ИнÑтрументи за анимациите" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "ÐнимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -4452,7 +4462,7 @@ msgstr "Редактиране на преходите..." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Open in Inspector" -msgstr "" +msgstr "ОтварÑне в инÑпектора" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." @@ -4460,52 +4470,51 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Ðвт. възпроизвеждане при зареждане" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "Показване на избледнÑващи кадри" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning Options" -msgstr "" +msgstr "ÐаÑтройки на режима Ñ Ð¸Ð·Ð±Ð»ÐµÐ´Ð½Ñващи кадри" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" msgstr "ÐаправлениÑ" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Past" -msgstr "ПоÑтавÑне" +msgstr "Минало" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "Бъдеще" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" -msgstr "" +msgstr "Дълбочина" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "" +msgstr "1 Ñтъпка" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" -msgstr "" +msgstr "2 Ñтъпки" #: editor/plugins/animation_player_editor_plugin.cpp msgid "3 steps" -msgstr "" +msgstr "3 Ñтъпки" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Само разликите" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "Принудително модулиране на бÑлото" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" @@ -4517,11 +4526,11 @@ msgstr "Закачане на AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Създаване на нова анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Име на анимациÑта:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp @@ -4532,15 +4541,15 @@ msgstr "Грешка!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "" +msgstr "Времена на ÑмеÑване:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "" +msgstr "Следваща (авт. опашка):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" -msgstr "" +msgstr "Времена на ÑмеÑване между анимациите" #: editor/plugins/animation_state_machine_editor.cpp msgid "Move Node" @@ -4557,23 +4566,23 @@ msgstr "ДобавÑне на преход" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "" +msgstr "ДобавÑне на възел" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "" +msgstr "Край" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "Ðезабавно" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "Синхронизиране" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" -msgstr "" +msgstr "Ðа краÑ" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" @@ -4801,17 +4810,15 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, return code:" -msgstr "ЗаÑвката Ñе провали. Код:" +msgstr "ЗаÑвката беше неуÑпешна. Код:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request failed." -msgstr "Запитване..." +msgstr "ЗаÑвката беше неуÑпешна." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Cannot save response to:" -msgstr "Ðе може да Ñе премахне:" +msgstr "Отговорът не може да бъде запазен в:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Write error." @@ -4846,7 +4853,8 @@ msgid "Got:" msgstr "Получено:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "ÐеуÑпешна проверка на хеш от вид „sha256“" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4906,14 +4914,12 @@ msgid "Name (Z-A)" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "License (A-Z)" -msgstr "Лиценз" +msgstr "Лиценз (Ð-Я)" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "License (Z-A)" -msgstr "Лиценз" +msgstr "Лиценз (Я-Ð)" #: editor/plugins/asset_library_editor_plugin.cpp msgid "First" @@ -4973,9 +4979,8 @@ msgid "Testing" msgstr "ТеÑтово" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Loading..." -msgstr "Зареди..." +msgstr "Зареждане…" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -4984,23 +4989,54 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" +"Ðе може да Ñе уÑтанови пътÑÑ‚ за запазване на Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÐºÐ°Ñ€Ñ‚Ð¸ на " +"оÑветеноÑÑ‚.\n" +"Запазете Ñцената и опитайте отново." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " "Light' flag is on." msgstr "" +"ÐÑма полигонни мрежи за изпичане. Уверете Ñе, че те Ñъдържат канал UV2 и че " +"флагът „Изпичане на Ñветлината“ е включен." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed creating lightmap images, make sure path is writable." msgstr "" +"Грешка при Ñъздаването на Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÐºÐ°Ñ€Ñ‚Ð¸ на оÑветеноÑÑ‚. Уверете Ñе, че " +"пътÑÑ‚ е доÑтъпен за запиÑ." #: editor/plugins/baked_lightmap_editor_plugin.cpp -msgid "Bake Lightmaps" +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Ðе може да Ñе определи размерът на картата на оÑветеноÑÑ‚. Твърде малък ли е " +"макÑималниÑÑ‚ размер?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." msgstr "" +"Има неподходÑща полигонна мрежа. Уверете Ñе, че ÑтойноÑтите в канала UV2 Ñе " +"принадлежат на квадратната облаÑÑ‚ [0.0,1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Редакторът на Godot е бил компилиран без поддръжка за траÑиране на лъчи. Ðе " +"могат да Ñе изпичат карти на оÑветеноÑÑ‚." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Bake Lightmaps" +msgstr "Изпичане на карти на оÑветеноÑÑ‚" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Изберете файл за изпичане на карта на оÑветеноÑÑ‚:" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5009,71 +5045,63 @@ msgstr "Преглед" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "" +msgstr "ÐаÑтройване на прилепването" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Offset:" -msgstr "" +msgstr "ОтмеÑтване на мрежата:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Step:" -msgstr "" +msgstr "Стъпка на мрежата:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Primary Line Every:" -msgstr "" +msgstr "ОÑновна Ð»Ð¸Ð½Ð¸Ñ Ð½Ð° вÑеки:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "steps" -msgstr "" +msgstr "Ñтъпки" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" -msgstr "ИзмеÑтване на въртенето:" +msgstr "ОтмеÑтване при завъртане:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Step:" msgstr "Стъпка при завъртане:" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale Step:" -msgstr "Мащаб:" +msgstr "Стъпка на мащабиране:" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move Vertical Guide" -msgstr "ПемеÑти вертикална помощна линиÑ" +msgstr "ПремеÑтване на Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Vertical Guide" -msgstr "Създай нова вертикална помощна линиÑ" +msgstr "Създаване на нов вертикален водач" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Remove Vertical Guide" -msgstr "Премахни вертикална помощна линиÑ" +msgstr "Премахване на Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move Horizontal Guide" -msgstr "ПремеÑти хоризонтална помощна линиÑ" +msgstr "ПремеÑтване на Ñ…Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Horizontal Guide" -msgstr "Създай нова хоризонтална помощна линиÑ" +msgstr "Създаване на нов хоризонтален водач" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Remove Horizontal Guide" -msgstr "Премахни хоризонтална помощна линиÑ" +msgstr "Премахване на Ñ…Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Horizontal and Vertical Guides" -msgstr "Създай нова хоризонтална и вертикална помощна линиÑ" +msgstr "Създаване на нов хоризонтален и вертикален водач" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" @@ -5132,44 +5160,36 @@ msgid "" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Left" -msgstr "Режим на Завъртане" +msgstr "Горе влÑво" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Right" -msgstr "Завъртане на Полигон" +msgstr "Горе вдÑÑно" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Right" -msgstr "Завъртане на Полигон" +msgstr "Долу вдÑÑно" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Left" -msgstr "Режим на Завъртане" +msgstr "Долу влÑво" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Left" -msgstr "Центрирай върху СелекциÑта" +msgstr "По Ñредата влÑво" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Top" -msgstr "Центрирай върху СелекциÑта" +msgstr "По Ñредата горе" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Right" -msgstr "Завъртане на Полигон" +msgstr "По Ñредата вдÑÑно" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Bottom" -msgstr "Центрирай върху СелекциÑта" +msgstr "По Ñредата долу" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center" @@ -5235,9 +5255,8 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Изберете метод" +msgstr "Заключване на избраното" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5246,29 +5265,25 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Ðова Ñцена" +msgstr "Групиране на избраното" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Ðова Ñцена" +msgstr "Разгрупиране на избраното" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Guides" -msgstr "Възпроизвеждане на Ñцена по избор" +msgstr "ИзчиÑтване на водачите" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "Възпроизвеждане на Ñцена по избор" +msgstr "Създаване на перÑонализирана(и) коÑÑ‚(и) от възела(възлите)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Bones" @@ -5463,7 +5478,7 @@ msgstr "Преглед" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Always Show Grid" -msgstr "" +msgstr "Винаги да Ñе показва решетката" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" @@ -5471,11 +5486,11 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Rulers" -msgstr "" +msgstr "Показване на линиите" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Guides" -msgstr "" +msgstr "Показване на водачите" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Origin" @@ -5670,12 +5685,12 @@ msgstr "" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "" +msgstr "Създаване на излъчващи точки от полигонната мрежа" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "" +msgstr "Създаване на излъчващи точки от възела" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 0" @@ -5772,7 +5787,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "" +msgstr "Полигонната мрежа е празна!" #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5817,19 +5832,21 @@ msgstr "Създаване на нÑколко изпъкнали форми" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "" +msgstr "Създаване на навигационна полигонна мрежа" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "Съдържащата Ñе полигонна мрежа не е от тип ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" msgstr "" +"Разгъването на UV беше неуÑпешно. Възможно ли е полигонната мрежа да Ñе " +"ÑÑŠÑтои от повече от една форма?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." -msgstr "" +msgstr "ÐÑма полигонна мрежа за дебъгване." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Model has no UV in this layer" @@ -5837,15 +5854,15 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "" +msgstr "Ð’ MeshInstance нÑма полигонна мрежа!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" -msgstr "" +msgstr "Полигонната мрежа нÑма повърхноÑÑ‚, от коÑто да Ñе Ñъздадат контури!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "" +msgstr "ПримитивниÑÑ‚ тип на полигонната мрежа не е PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" @@ -5857,7 +5874,7 @@ msgstr "Създаване на контур" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "" +msgstr "Полигонна мрежа" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" @@ -5904,7 +5921,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." -msgstr "" +msgstr "Създаване на контурна полигонна мрежа…" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -5913,6 +5930,10 @@ msgid "" "This can be used instead of the SpatialMaterial Grow property when using " "that property isn't possible." msgstr "" +"Създава Ñтатична полигонна мрежа за контура. Ðормалите на контурната " +"полигонна мрежа ще бъдат автоматично обърнати.\n" +"Това може да Ñе използва вмеÑто ÑвойÑтвото Grow на SpatialMaterial, когато " +"това ÑвойÑтво не може да Ñе променÑ." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" @@ -5928,7 +5949,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "" +msgstr "Създаване на контурна полигонна мрежа" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" @@ -5951,9 +5972,8 @@ msgstr "" "%s" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Mesh Library" -msgstr "ИзнаÑÑне на библиотеката" +msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи" #: editor/plugins/mesh_library_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -5975,22 +5995,27 @@ msgstr "ОбновÑване от Ñцена" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." msgstr "" +"ÐÑма поÑочен източник за полигонна мрежа (и във възела нÑма MultiMesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." msgstr "" +"ÐÑма поÑочен източник за полигонна мрежа (и MultiMesh не Ñъдържа полигонна " +"мрежа)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "" +msgstr "Източникът за полигонна мрежа е неправилен (грешен път)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "" +msgstr "Източникът за полигонна мрежа е неправилен (не е MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." msgstr "" +"Източникът за полигонна мрежа е неправилен (не Ñъдържа реÑурÑ, който е " +"полигонна мрежа)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." @@ -6010,7 +6035,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "" +msgstr "Изберете източник за полигонна мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" @@ -6030,7 +6055,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" -msgstr "" +msgstr "Източник за полигонна мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" @@ -6046,7 +6071,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" -msgstr "" +msgstr "ÐžÑ Ñочеща нагоре за полигонната мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Rotation:" @@ -6087,6 +6112,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Преобразуване в CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6096,9 +6125,8 @@ msgid "The geometry's faces don't contain any area." msgstr "" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "The geometry doesn't contain any faces." -msgstr "Възелът не Ñъдържа Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ (лица)." +msgstr "ГеометриÑта не Ñъдържа Ñтрани." #: editor/plugins/particles_editor_plugin.cpp msgid "\"%s\" doesn't inherit from Spatial." @@ -6109,9 +6137,8 @@ msgid "\"%s\" doesn't contain geometry." msgstr "„%s“ не Ñъдържа геометриÑ." #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "\"%s\" doesn't contain face geometry." -msgstr "Възелът не Ñъдържа геометриÑ." +msgstr "„%s“ не Ñъдържа Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ ÑÑŠÑ Ñтрани." #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emitter" @@ -6119,15 +6146,15 @@ msgstr "" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Points:" -msgstr "" +msgstr "Излъчващи точки:" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points" -msgstr "" +msgstr "Точки на повърхноÑтта" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points+Normal (Directed)" -msgstr "" +msgstr "Точки на повърхноÑтта + нормали (наÑочени)" #: editor/plugins/particles_editor_plugin.cpp msgid "Volume" @@ -6135,7 +6162,7 @@ msgstr "Обем" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Source: " -msgstr "" +msgstr "Източник на излъчването: " #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -6149,10 +6176,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6734,6 +6757,14 @@ msgstr "ЗатварÑне на документациÑта" msgid "Run" msgstr "ПуÑкане" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "ТърÑене" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6787,16 +6818,6 @@ msgstr "" "Следните файлове Ñа по-нови на диÑка.\n" "Кое дейÑтвие трÑбва да Ñе предприеме?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Презареждане" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "ПрезапиÑване" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Дебъгер" @@ -6889,8 +6910,8 @@ msgstr "Точки на прекъÑване" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "ИзрÑзване" @@ -7113,6 +7134,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -7285,9 +7310,8 @@ msgid "Freelook Speed Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Slow Modifier" -msgstr "Свободен Изглед Отпред" +msgstr "Модификатор за забавÑне на ÑÐ²Ð¾Ð±Ð¾Ð´Ð½Ð¸Ñ Ð¸Ð·Ð³Ð»ÐµÐ´" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Rotation Locked" @@ -7539,15 +7563,15 @@ msgstr "" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." -msgstr "" +msgstr "Ðеправилна геометриÑ. Ðе може да Ñе замени Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð° мрежа." #: editor/plugins/sprite_editor_plugin.cpp msgid "Convert to Mesh2D" -msgstr "" +msgstr "Преобразуване в Mesh2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." -msgstr "" +msgstr "Ðеправилна геометриÑ, не може да Ñе Ñъздаде полигон." #: editor/plugins/sprite_editor_plugin.cpp msgid "Convert to Polygon2D" @@ -7555,7 +7579,7 @@ msgstr "Превръщане в Polygon2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "" +msgstr "Ðеправилна геометриÑ, не може да Ñе Ñъздаде полигон за колизии." #: editor/plugins/sprite_editor_plugin.cpp msgid "Create CollisionPolygon2D Sibling" @@ -7567,7 +7591,7 @@ msgstr "" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create LightOccluder2D Sibling" -msgstr "" +msgstr "Създаване на ÑÑŠÑеден LightOccluder2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" @@ -7575,15 +7599,15 @@ msgstr "" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " -msgstr "" +msgstr "ОпроÑÑ‚Ñване: " #: editor/plugins/sprite_editor_plugin.cpp msgid "Shrink (Pixels): " -msgstr "" +msgstr "СмалÑване (пикÑели): " #: editor/plugins/sprite_editor_plugin.cpp msgid "Grow (Pixels): " -msgstr "" +msgstr "УголемÑване (пикÑели): " #: editor/plugins/sprite_editor_plugin.cpp msgid "Update Preview" @@ -7599,11 +7623,11 @@ msgstr "ÐÑма избрани кадри" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add %d Frame(s)" -msgstr "" +msgstr "ДобавÑне на %d кадър/кадри" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" -msgstr "" +msgstr "ДобавÑне на кадър" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Unable to load images" @@ -7611,27 +7635,27 @@ msgstr "ИзображениÑта не могат да бъдат заредеР#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" -msgstr "" +msgstr "ГРЕШКÐ: Ðе може да Ñе зареди реÑурÑÑŠÑ‚ Ñ ÐºÐ°Ð´ÑŠÑ€Ð°!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Resource clipboard is empty or not a texture!" -msgstr "" +msgstr "Буферът за обмен на реÑурÑи е празен или не Ñъдържа текÑтура!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Paste Frame" -msgstr "" +msgstr "ПоÑтавÑне на кадър" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Empty" -msgstr "" +msgstr "ДобавÑне на празен" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation FPS" -msgstr "" +msgstr "ПромÑна на ÑкороÑтта (кадри/Ñек) на анимациÑта" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "(empty)" -msgstr "" +msgstr "(празно)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move Frame" @@ -7651,7 +7675,7 @@ msgstr "СкороÑÑ‚:" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Loop" -msgstr "" +msgstr "ПовтарÑне" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Animation Frames:" @@ -7667,11 +7691,11 @@ msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" -msgstr "" +msgstr "Вмъкване на празен (преди)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (After)" -msgstr "" +msgstr "Вмъкване на празен (Ñлед)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move (Before)" @@ -7679,7 +7703,7 @@ msgstr "ПремеÑтване (преди)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move (After)" -msgstr "" +msgstr "ПремеÑтване (Ñлед)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Select Frames" @@ -7687,11 +7711,11 @@ msgstr "Избиране на кадри" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Horizontal:" -msgstr "" +msgstr "Хоризонтала:" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Vertical:" -msgstr "" +msgstr "Вертикала:" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Select/Clear All Frames" @@ -7711,57 +7735,56 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Margin" -msgstr "" +msgstr "Задаване на отÑтъп" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" -msgstr "" +msgstr "Режим на прилепване:" #: editor/plugins/texture_region_editor_plugin.cpp #: scene/resources/visual_shader.cpp msgid "None" -msgstr "" +msgstr "ÐÑма" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Pixel Snap" -msgstr "" +msgstr "Прилепване към пикÑелите" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "" +msgstr "Прилепване към решетката" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" -msgstr "" +msgstr "Ðвтоматично отрÑзване" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Offset:" -msgstr "" +msgstr "ОтмеÑтване:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Step:" -msgstr "" +msgstr "Стъпка:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Sep.:" -msgstr "" +msgstr "Разделител:" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "TextureRegion" -msgstr "Двуизмерна текÑтура" +msgstr "ТекÑтурна облаÑÑ‚" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All Items" -msgstr "" +msgstr "ДобавÑне на вÑички елементи" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All" -msgstr "" +msgstr "ДобавÑне на вÑичко" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove All Items" -msgstr "" +msgstr "Премахване на вÑички елементи" #: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp msgid "Remove All" @@ -7773,7 +7796,7 @@ msgstr "Редактиране на темата" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." -msgstr "" +msgstr "Меню за редактиране на темата." #: editor/plugins/theme_editor_plugin.cpp msgid "Add Class Items" @@ -7805,7 +7828,7 @@ msgstr "Заключен бутон" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" -msgstr "" +msgstr "Елемент" #: editor/plugins/theme_editor_plugin.cpp msgid "Disabled Item" @@ -7813,11 +7836,11 @@ msgstr "Заключен елемент" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" -msgstr "" +msgstr "Елемент за отметка" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Item" -msgstr "" +msgstr "Отметнат елемент" #: editor/plugins/theme_editor_plugin.cpp msgid "Radio Item" @@ -7829,27 +7852,27 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Именуван разд." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Подменю" #: editor/plugins/theme_editor_plugin.cpp msgid "Subitem 1" -msgstr "" +msgstr "Поделемент 1" #: editor/plugins/theme_editor_plugin.cpp msgid "Subitem 2" -msgstr "" +msgstr "Поделемент 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" -msgstr "" +msgstr "Има" #: editor/plugins/theme_editor_plugin.cpp msgid "Many" -msgstr "" +msgstr "Много" #: editor/plugins/theme_editor_plugin.cpp msgid "Disabled LineEdit" @@ -7857,15 +7880,15 @@ msgstr "Заключено текÑтово поле" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" -msgstr "" +msgstr "Раздел 1" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 2" -msgstr "" +msgstr "Раздел 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 3" -msgstr "" +msgstr "Раздел 3" #: editor/plugins/theme_editor_plugin.cpp msgid "Editable Item" @@ -7873,32 +7896,32 @@ msgstr "Редактируем елемент" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Поддърво" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" -msgstr "" +msgstr "Има,Много,Опции" #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" -msgstr "" +msgstr "Тип на данните:" #: editor/plugins/theme_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp msgid "Icon" -msgstr "" +msgstr "Иконка" #: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp msgid "Style" -msgstr "" +msgstr "Стил" #: editor/plugins/theme_editor_plugin.cpp msgid "Font" -msgstr "" +msgstr "Шрифт" #: editor/plugins/theme_editor_plugin.cpp msgid "Color" -msgstr "" +msgstr "Цват" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme File" @@ -7906,11 +7929,11 @@ msgstr "Файл Ñ Ñ‚ÐµÐ¼Ð°" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase Selection" -msgstr "" +msgstr "Изтриване на избраното" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Fix Invalid Tiles" -msgstr "" +msgstr "Поправка на неправилните плочки" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp @@ -8006,9 +8029,8 @@ msgid "Add Texture(s) to TileSet." msgstr "" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove selected Texture from TileSet." -msgstr "ПремеÑтване на пътечката нагоре." +msgstr "Изтриване на избраната текÑтура от Ð¿Ð»Ð¾Ñ‡Ð½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ€." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -8023,9 +8045,8 @@ msgid "New Single Tile" msgstr "" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "New Autotile" -msgstr "Ðов TextFile" +msgstr "Ðова авт. плочка" #: editor/plugins/tile_set_editor_plugin.cpp msgid "New Atlas" @@ -8260,9 +8281,8 @@ msgid "Edit Collision Polygon" msgstr "Редактиране на полигона за колизии" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Occlusion Polygon" -msgstr "ПриÑтавки" +msgstr "Редактиране на полигона за прикриване" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Navigation Polygon" @@ -8293,9 +8313,8 @@ msgid "Remove Collision Polygon" msgstr "Премахване на полигона за колизии" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Occlusion Polygon" -msgstr "ПремеÑтване на Полигон" +msgstr "Премахване на полигона за прикриване" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Navigation Polygon" @@ -9653,6 +9672,11 @@ msgid "Projects" msgstr "Проекти" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Зареждане…" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10256,6 +10280,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "ПоÑтавÑне на възлите" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Разкачане на Ñкрипта" @@ -10376,6 +10409,11 @@ msgid "Attach Script" msgstr "Закачане на Ñкрипт" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "ИзрÑзване на възлите" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -10441,9 +10479,8 @@ msgid "Reparent to New Node" msgstr "ПремеÑтване под нов възел" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Make Scene Root" -msgstr "Запазване на Ñцената" +msgstr "Превръщане на Ñцената в коренна" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -10462,9 +10499,8 @@ msgid "Delete (No Confirm)" msgstr "Изтриване (без потвърждение)" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Add/Create a New Node." -msgstr "Създай нови възли." +msgstr "ДобавÑне/Ñъздаване на нов възел." #: editor/scene_tree_dock.cpp msgid "" @@ -10481,9 +10517,8 @@ msgid "Detach the script from the selected node." msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Remote" -msgstr "ЗатварÑне на вÑичко" +msgstr "Отдалечен" #: editor/scene_tree_dock.cpp msgid "Local" @@ -10498,14 +10533,12 @@ msgid "Toggle Visible" msgstr "" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Unlock Node" -msgstr "Избиране на вÑичко" +msgstr "Отключване на възела" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Button Group" -msgstr "Копче 7" +msgstr "Група бутони" #: editor/scene_tree_editor.cpp msgid "(Connecting From)" @@ -10589,38 +10622,35 @@ msgstr "" #: editor/script_create_dialog.cpp msgid "Path is not local." -msgstr "" +msgstr "ПътÑÑ‚ не е локален." #: editor/script_create_dialog.cpp msgid "Invalid base path." msgstr "Ðеправилен базов път." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Вече ÑъщеÑтвува файл или папка Ñ Ñ‚Ð¾Ð²Ð° име." +msgstr "Вече ÑъщеÑтвува папка Ñ Ñ‚Ð¾Ð²Ð° име." #: editor/script_create_dialog.cpp msgid "File does not exist." msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "ТрÑбва да Ñе използва правилно разширение." +msgstr "Ðеправилно разширение." #: editor/script_create_dialog.cpp msgid "Wrong extension chosen." -msgstr "" +msgstr "Избрано е грешно разширение." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" msgstr "Грешка при зареждане на шаблона „%s“" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Error - Could not create script in filesystem." -msgstr "ÐеуÑпешно Ñъздаване на папка." +msgstr "Грешка: Ñкриптът не може да бъде Ñъздаден във файловата ÑиÑтема." #: editor/script_create_dialog.cpp msgid "Error loading script from %s" @@ -10639,9 +10669,8 @@ msgid "Open Script / Choose Location" msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script" -msgstr "Ðова Ñцена" +msgstr "ОтварÑне на Ñкрипта" #: editor/script_create_dialog.cpp msgid "File exists, it will be reused." @@ -10652,9 +10681,8 @@ msgid "Invalid path." msgstr "Ðеправилен път." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "невалидно име на Група." +msgstr "Ðеправилно име на клаÑ." #: editor/script_create_dialog.cpp msgid "Invalid inherited parent name or path." @@ -10681,9 +10709,8 @@ msgid "Will load an existing script file." msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script file already exists." -msgstr "Група Ñ Ñ‚Ð¾Ð²Ð° име вече ÑъщеÑтвува." +msgstr "СкриптовиÑÑ‚ файл вече ÑъщеÑтвува." #: editor/script_create_dialog.cpp msgid "" @@ -10692,9 +10719,8 @@ msgid "" msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Class Name:" -msgstr "КлаÑ:" +msgstr "Име на клаÑа:" #: editor/script_create_dialog.cpp msgid "Template:" @@ -10705,9 +10731,8 @@ msgid "Built-in Script:" msgstr "Вграден Ñкрипт:" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Attach Node Script" -msgstr "Ðова Ñцена" +msgstr "Закачане на Ñкрипт" #: editor/script_editor_debugger.cpp msgid "Remote " @@ -10786,9 +10811,8 @@ msgid "Profiler" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Network Profiler" -msgstr "ИзнаÑÑне на проекта" +msgstr "Профилиране на мрежата" #: editor/script_editor_debugger.cpp msgid "Monitor" @@ -10815,9 +10839,8 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Export list to a CSV file" -msgstr "ИзнаÑÑне на профила" +msgstr "ИзнаÑÑне на ÑпиÑъка като файл CSV" #: editor/script_editor_debugger.cpp msgid "Resource Path" @@ -10988,9 +11011,8 @@ msgid "Add an architecture entry" msgstr "" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "GDNativeLibrary" -msgstr "ИзнаÑÑне на библиотеката" +msgstr "Библиотека GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" @@ -11022,66 +11044,59 @@ msgid "Not a script with an instance" msgstr "Скриптът нÑма инÑтанциÑ" #: modules/gdscript/gdscript_functions.cpp -#, fuzzy msgid "Not based on a script" -msgstr "Обектът не е базиран на Ñкрипт" +msgstr "Ðе Ñе базира на Ñкрипт" #: modules/gdscript/gdscript_functions.cpp -#, fuzzy msgid "Not based on a resource file" -msgstr "Обектът не е базиран на реÑурÑен файл" +msgstr "Ðе Ñе базира на реÑурÑен файл" #: modules/gdscript/gdscript_functions.cpp -#, fuzzy msgid "Invalid instance dictionary format (missing @path)" -msgstr "Ðевалиден формат на инÑтанциÑта в речника (липÑва @path)" +msgstr "Ðеправилен формат в речника на инÑтанциите (липÑва @path)" #: modules/gdscript/gdscript_functions.cpp msgid "Invalid instance dictionary format (can't load script at @path)" msgstr "" -"Ðеправилен формат на инÑтанциÑта в речника (Ñкриптът в @path не може да бъде " +"Ðеправилен формат в речника на инÑтанциите (Ñкриптът в @path не може да бъде " "зареден)" #: modules/gdscript/gdscript_functions.cpp msgid "Invalid instance dictionary format (invalid script at @path)" msgstr "" -"Ðеправилен формат на инÑтанциÑта в речника (Ñкриптът в @path е невалиден)" +"Ðеправилен формат в речника на инÑтанциите (Ñкриптът в @path е невалиден)" #: modules/gdscript/gdscript_functions.cpp -#, fuzzy msgid "Invalid instance dictionary (invalid subclasses)" -msgstr "Ðевалиден формат на инÑтанциÑта в речника (невалиден подклаÑ)" +msgstr "Ðеправилен формат в речника на инÑтанциите (невалиден подклаÑ)" #: modules/gdscript/gdscript_functions.cpp msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Next Plane" -msgstr "Следващ подпрозорец" +msgstr "Следваща равнина" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Previous Plane" -msgstr "Предишен подпрозорец" +msgstr "Предходна равнина" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Plane:" -msgstr "" +msgstr "Равнина:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Floor" -msgstr "" +msgstr "Следващ под" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Previous Floor" -msgstr "Предишен подпрозорец" +msgstr "Предходен под" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" -msgstr "" +msgstr "Под:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Delete Selection" @@ -11164,37 +11179,63 @@ msgid "Cursor Clear Rotation" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Paste Selects" -msgstr "ÐаÑтройки" +msgstr "ПоÑтавÑне на избраното" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Clear Selection" -msgstr "Ðова Ñцена" +msgstr "ИзчиÑтване на избраното" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Fill Selection" -msgstr "Ðова Ñцена" +msgstr "Запълване на избраното" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Settings" -msgstr "ÐаÑтройки" +msgstr "ÐаÑтройки на GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Pick Distance:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Filter meshes" -msgstr "ПоÑтавÑне на възелите" +msgstr "Филтриране на полигонните мрежи" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +"Задайте реÑÑƒÑ€Ñ Ð¾Ñ‚ тип MeshLibrary в този GridMap, за да можете да използвате " +"полигонните му мрежи." + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Директно оÑветÑване" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Задаване на израз" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -11206,11 +11247,11 @@ msgstr "" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Bake NavMesh" -msgstr "" +msgstr "Изпичане на NavMesh" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "" +msgstr "ИзчиÑтване на навигационната полигонна мрежа." #: modules/recast/navigation_mesh_generator.cpp msgid "Setting up Configuration..." @@ -11246,15 +11287,15 @@ msgstr "" #: modules/recast/navigation_mesh_generator.cpp msgid "Creating polymesh..." -msgstr "" +msgstr "Създаване на полигонна мрежа…" #: modules/recast/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." -msgstr "" +msgstr "Преобразуване на навигационната полигонна мрежа в ÑобÑÑ‚Ð²ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚â€¦" #: modules/recast/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "" +msgstr "ÐаÑтройка на генератора на навигационни полигонни мрежи:" #: modules/recast/navigation_mesh_generator.cpp msgid "Parsing Geometry..." @@ -11327,86 +11368,80 @@ msgid "Override an existing built-in function." msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create a new function." -msgstr "Създай нови възли." +msgstr "Създаване на нова функциÑ." #: modules/visual_script/visual_script_editor.cpp msgid "Variables:" -msgstr "" +msgstr "Променливи:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create a new variable." -msgstr "Създай нови възли." +msgstr "Създаване на нова променлива." #: modules/visual_script/visual_script_editor.cpp msgid "Signals:" -msgstr "" +msgstr "Сигнали:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create a new signal." -msgstr "Създай нов полигон от нулата." +msgstr "Създаване на нов Ñигнал." #: modules/visual_script/visual_script_editor.cpp msgid "Name is not a valid identifier:" -msgstr "" +msgstr "Името не е правилен идентификатор:" #: modules/visual_script/visual_script_editor.cpp msgid "Name already in use by another func/var/signal:" -msgstr "" +msgstr "Името вече е заето от друга функциÑ/променлива/Ñигнал:" #: modules/visual_script/visual_script_editor.cpp msgid "Rename Function" -msgstr "" +msgstr "Преименуване на функциÑта" #: modules/visual_script/visual_script_editor.cpp msgid "Rename Variable" -msgstr "" +msgstr "Преименуване на променливата" #: modules/visual_script/visual_script_editor.cpp msgid "Rename Signal" -msgstr "" +msgstr "Преименуване на Ñигнала" #: modules/visual_script/visual_script_editor.cpp msgid "Add Function" -msgstr "" +msgstr "ДобавÑне на функциÑ" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Delete input port" -msgstr "ЗатварÑне на вÑичко" +msgstr "Изтриване на входÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚" #: modules/visual_script/visual_script_editor.cpp msgid "Add Variable" -msgstr "" +msgstr "ДобавÑне на променлива" #: modules/visual_script/visual_script_editor.cpp msgid "Add Signal" -msgstr "" +msgstr "ДобавÑне на Ñигнал" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Remove Input Port" -msgstr "ЗатварÑне на вÑичко" +msgstr "Премахване на входÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Remove Output Port" -msgstr "ВнаÑÑне на текÑтури" +msgstr "Премахване на изходÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚" #: modules/visual_script/visual_script_editor.cpp msgid "Change Expression" -msgstr "" +msgstr "ПромÑна на израза" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Nodes" -msgstr "" +msgstr "Премахване на възлите Ñ VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Duplicate VisualScript Nodes" -msgstr "" +msgstr "Дублиране на възлите Ñ VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." @@ -11459,23 +11494,20 @@ msgid "Change Base Type" msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Move Node(s)" -msgstr "ПоÑтавÑне на възелите" +msgstr "ПремеÑтване на възела(възлите)" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Node" msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Connect Nodes" -msgstr "ИзрÑзване на възелите" +msgstr "Свързване на възлите" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Disconnect Nodes" -msgstr "ИзрÑзване на възелите" +msgstr "Разкачане на възлите" #: modules/visual_script/visual_script_editor.cpp #, fuzzy @@ -11496,9 +11528,8 @@ msgid "Change Input Value" msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Resize Comment" -msgstr "Вкарай Коментар" +msgstr "ПреоразмерÑване на коментара" #: modules/visual_script/visual_script_editor.cpp msgid "Can't copy the function node." @@ -11509,9 +11540,8 @@ msgid "Clipboard is empty!" msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Paste VisualScript Nodes" -msgstr "ПоÑтавÑне на възелите" +msgstr "ПоÑтавÑне на възлите Ñ VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Can't create function with a function node." @@ -11530,9 +11560,8 @@ msgid "Try to only have one sequence input in selection." msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create Function" -msgstr "Създай Очертание" +msgstr "Създаване на функциÑ" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Function" @@ -11567,9 +11596,8 @@ msgid "Change Base Type:" msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Add Nodes..." -msgstr "Добави Възел..." +msgstr "ДобавÑне на възли…" #: modules/visual_script/visual_script_editor.cpp msgid "Add Function..." @@ -11600,9 +11628,8 @@ msgid "Cut Nodes" msgstr "ИзрÑзване на възлите" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Make Function" -msgstr "Отиди на Ред" +msgstr "Преобразуване във функциÑ" #: modules/visual_script/visual_script_editor.cpp msgid "Refresh Graph" @@ -11667,9 +11694,8 @@ msgid "" msgstr "" #: modules/visual_script/visual_script_property_selector.cpp -#, fuzzy msgid "Search VisualScript" -msgstr "ПоÑтавÑне на възелите" +msgstr "ТърÑене във VisualScript" #: modules/visual_script/visual_script_property_selector.cpp msgid "Get %s" @@ -11708,11 +11734,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11724,11 +11752,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11736,9 +11764,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11878,9 +11916,8 @@ msgid "Could not read boot splash image file:" msgstr "Ðе може да Ñе прочете файл Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ при Ñтартиране:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Using default boot splash image." -msgstr "ÐеуÑпешно Ñъздаване на папка." +msgstr "Използва Ñе Ñтандартното изображение при Ñтартиране." #: platform/uwp/export/export.cpp msgid "Invalid package short name." @@ -11896,16 +11933,15 @@ msgstr "Ðеправилно име за показване на Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ #: platform/uwp/export/export.cpp msgid "Invalid product GUID." -msgstr "Ðевалиден продуктов GUID." +msgstr "Ðеправилен продуктов GUID." #: platform/uwp/export/export.cpp msgid "Invalid publisher GUID." -msgstr "" +msgstr "Ðеправилен GUID на издател." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid background color." -msgstr "невалидно име на Група." +msgstr "Ðеправилен фонов цвÑÑ‚." #: platform/uwp/export/export.cpp msgid "Invalid Store Logo image dimensions (should be 50x50)." @@ -11936,22 +11972,21 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "" #: scene/2d/animated_sprite.cpp -#, fuzzy msgid "" "A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" -"За да може AnimatedSprite да показва кадри, първо трÑбва да му Ñе даде " -"SpriteFrames реÑÑƒÑ€Ñ Ð² парамертъра 'Frames'." +"За да може AnimatedSprite да показва кадри, първо трÑбва Ñе Ñъздаде или " +"зададе реÑÑƒÑ€Ñ Ð¾Ñ‚ тип SpriteFrames в ÑвойÑтвото „Frames“." #: scene/2d/canvas_modulate.cpp -#, fuzzy msgid "" "Only one visible CanvasModulate is allowed per scene (or set of instanced " "scenes). The first created one will work, while the rest will be ignored." msgstr "" -"Може да има Ñамо един видим CanvasModulate на Ñцене (или нÑколко " -"инÑтанцирани Ñцени). Само първиÑÑ‚ ще работи, а вÑички оÑтанали - игнорирани." +"Може да има Ñамо един видим CanvasModulate на Ñцена (или нÑколко " +"инÑтанцирани Ñцени). Само първиÑÑ‚ ще работи, а вÑички оÑтанали ще бъдат " +"пренебрегнати." #: scene/2d/collision_object_2d.cpp msgid "" @@ -12027,13 +12062,12 @@ msgid "Node A and Node B must be different PhysicsBody2Ds" msgstr "" #: scene/2d/light_2d.cpp -#, fuzzy msgid "" "A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" -"ТеÑктура Ñ Ð½ÑƒÐ¶Ð½Ð°Ñ‚Ð° форма на Ñветлината трÑбва да бъде дадена в параметъра " -"'texture'." +"Ð’ ÑвойÑтвото „Texture“ трÑбва да бъде зададена текÑтура Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° на " +"Ñветлината." #: scene/2d/light_occluder_2d.cpp msgid "" @@ -12043,9 +12077,10 @@ msgstr "" "работи прикриването." #: scene/2d/light_occluder_2d.cpp -#, fuzzy msgid "The occluder polygon for this occluder is empty. Please draw a polygon." -msgstr "ЗатъмнÑващиÑÑ‚ многоъгълник е празен. МолÑ, нариÑувайте един." +msgstr "" +"ПрикриващиÑÑ‚ полигон за този прикриващ обект е празен. МолÑ, нариÑувайте " +"полигон." #: scene/2d/navigation_polygon.cpp msgid "" @@ -12117,15 +12152,15 @@ msgid "" msgstr "" #: scene/2d/tile_map.cpp -#, fuzzy msgid "" "TileMap with Use Parent on needs a parent CollisionObject2D to give shapes " "to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " "KinematicBody2D, etc. to give them a shape." msgstr "" -"CollisionShape2D Ñлужи Ñамо за да даде форма за колизии на " -"CollisionObject2D. МолÑ, използвайте го Ñамо като наÑледник на Area2D, " -"StaticBody2D, RigidBody2D, KinematicBody2D, и Ñ‚.н. за да им дадете форма." +"Възел от типа TileMap Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¾ ÑвойÑтво „Use Parent“ трÑбва да има " +"родителÑки елемент от тип CollisionShape2D, на който да придаде форма. МолÑ, " +"използвайте го Ñамо като дъщерен елемент на Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D и Ñ‚.н., за да им придадете форма." #: scene/2d/visibility_notifier_2d.cpp msgid "" @@ -12162,28 +12197,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "" +msgid "Finding meshes and lights" +msgstr "ТърÑене на полигонни мрежи и Ñветлини" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "" +msgid "Done" +msgstr "Готово" #: scene/3d/collision_object.cpp msgid "" @@ -12211,13 +12246,12 @@ msgid "" msgstr "" #: scene/3d/collision_shape.cpp -#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " "shape resource for it." msgstr "" "За да работи CollisionShape2D, е нужно да му Ñе даде форма. МолÑ, Ñъздайте " -"му Shape2D реÑурÑ." +"му реÑурÑ-форма." #: scene/3d/collision_shape.cpp msgid "" @@ -12232,7 +12266,7 @@ msgstr "" #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." -msgstr "" +msgstr "Ðе Ñе вижда нищо, той като нÑма зададена полигонна мрежа." #: scene/3d/cpu_particles.cpp msgid "" @@ -12242,6 +12276,10 @@ msgstr "" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" +msgstr "ПоÑтроÑване на полигонните мрежи" + +#: scene/3d/gi_probe.cpp +msgid "Finishing Plot" msgstr "" #: scene/3d/gi_probe.cpp @@ -12262,12 +12300,16 @@ msgstr "" #: scene/3d/navigation_mesh.cpp msgid "A NavigationMesh resource must be set or created for this node to work." msgstr "" +"ТрÑбва да Ñе зададе или Ñъздаде реÑÑƒÑ€Ñ Ð¾Ñ‚ тип NavigationMesh, за може да " +"работи този възел." #: scene/3d/navigation_mesh.cpp msgid "" "NavigationMeshInstance must be a child or grandchild to a Navigation node. " "It only provides navigation data." msgstr "" +"NavigationMeshInstance трÑбва да бъде дъщерен или под-дъщерен на възел от " +"тип Navigation. Той Ñамо предоÑÑ‚Ð°Ð²Ñ Ð´Ð°Ð½Ð½Ð¸Ñ‚Ðµ за навигирането." #: scene/3d/particles.cpp msgid "" @@ -12280,6 +12322,8 @@ msgstr "" msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" +"Ðе Ñе вижда нищо, тъй като полигонните мрежи не Ñа били Ñвързани към Ñтъпки " +"на изчертаване." #: scene/3d/particles.cpp msgid "" @@ -12288,9 +12332,8 @@ msgid "" msgstr "" #: scene/3d/path.cpp -#, fuzzy msgid "PathFollow only works when set as a child of a Path node." -msgstr "PathFollow2D работи Ñамо когато е наÑледник на Path2D." +msgstr "PathFollow работи Ñамо когато е дъщерен елемент на възел от тип Path." #: scene/3d/path.cpp msgid "" @@ -12326,17 +12369,16 @@ msgid "Node A and Node B must be different PhysicsBodies" msgstr "" #: scene/3d/remote_transform.cpp -#, fuzzy msgid "" "The \"Remote Path\" property must point to a valid Spatial or Spatial-" "derived node to work." msgstr "" -"Параметърът 'Path' трÑбва да Ñочи към дейÑтвителен възел Particles2D, за да " -"работи." +"СвойÑтвото „Remote Path“ трÑбва да Ñочи към дейÑтвителен възел от тип " +"Spatial или негов наÑледник, за да работи." #: scene/3d/soft_body.cpp msgid "This body will be ignored until you set a mesh." -msgstr "" +msgstr "Това Ñ‚Ñло ще бъде игнорирано, докато не зададете полигонна мрежа." #: scene/3d/soft_body.cpp msgid "" @@ -12346,13 +12388,12 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp -#, fuzzy msgid "" "A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" -"За да може AnimatedSprite да показва кадри, първо трÑбва да му Ñе даде " -"SpriteFrames реÑÑƒÑ€Ñ Ð² парамертъра 'Frames'." +"За да може AnimatedSprite3D да показва кадри, първо трÑбва Ñе Ñъздаде или " +"зададе реÑÑƒÑ€Ñ Ð¾Ñ‚ тип SpriteFrames в ÑвойÑтвото „Frames“." #: scene/3d/vehicle_body.cpp msgid "" @@ -12465,6 +12506,10 @@ msgstr "Тревога!" msgid "Please Confirm..." msgstr "МолÑ, потвърдете..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "ТрÑбва да Ñе използва правилно разширение." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12510,6 +12555,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12537,6 +12588,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "КонÑтантите не могат да бъдат променени." +#~ msgid "No" +#~ msgstr "Ðе" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Тази Ñцена не е била запазвана преди. Запазване преди изпълнението?" + #~ msgid "Search complete" #~ msgstr "ТърÑенето е завършено" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index c85147c40c..18ac61a269 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -8,14 +8,14 @@ # Tawhid H. <Tawhidk757@yahoo.com>, 2019. # Hasibul Hasan <hasibeng78@gmail.com>, 2019. # Oymate <dhruboadittya96@gmail.com>, 2020. -# Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020. +# Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020, 2021. # Sagen Soren <sagensoren03@gmail.com>, 2020. # Hasibul Hasan <d1hasib@yahoo.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-27 02:25+0000\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" "Last-Translator: Mokarrom Hossain <mhb2016.bzs@gmail.com>\n" "Language-Team: Bengali <https://hosted.weblate.org/projects/godot-engine/" "godot/bn/>\n" @@ -24,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -268,7 +268,6 @@ msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" msgstr "লà§à¦ª Wrap মোড (লà§à¦ª দিয়ে শà§à¦°à§ দিয়ে ইনà§à¦Ÿà¦¾à¦°à¦ªà§‹à¦²à§‡à¦Ÿ শেষ)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Remove this track." msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ টà§à¦°à§à¦¯à¦¾à¦•/পথ অপসারণ করà§à¦¨à¥¤" @@ -440,28 +439,24 @@ msgid "Track is not of type Spatial, can't insert key" msgstr "টà§à¦°à§à¦¯à¦¾à¦• Spatial টাইপের নয়, কী সনà§à¦¨à¦¿à¦¬à§‡à¦¶ করতে পারে না" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Transform Track Key" -msgstr "রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à§‡à¦° ধরণ" +msgstr "টà§à¦°à¦¾à¦¨à§à¦¸à¦«à¦°à§à¦® টà§à¦°à§à¦¯à¦¾à¦• কী যà§à¦•à§à¦¤ করà§à¦¨" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Track Key" -msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• যোগ করà§à¦¨" +msgstr "টà§à¦°à§à¦¯à¦¾à¦• কী যà§à¦•à§à¦¤ করà§à¦¨" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "টà§à¦°à§à¦¯à¦¾à¦• পাথটি অবৈধ, সà§à¦¤à¦°à¦¾à¦‚ কোনও পদà§à¦§à¦¤à¦¿ key যà§à¦•à§à¦¤ করতে পারে না।" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Method Track Key" -msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡ (Anim) টà§à¦°à§à¦¯à¦¾à¦•/পথ à¦à¦¬à¦‚ চাবি যোগ করà§à¦¨" +msgstr "Method Track Key যà§à¦•à§à¦¤ করà§à¦¨" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Method not found in object: " -msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-পà§à¦°à¦¾à¦ªà¦• (VariableGet) পাওয়া যায়নি: " +msgstr "Object ঠMethod পাওয়া যায় নি: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -472,7 +467,6 @@ msgid "Clipboard is empty" msgstr "কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Paste Tracks" msgstr "মানসমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨" @@ -484,6 +478,7 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° (Anim) চাবিসমূহেà msgid "" "This option does not work for Bezier editing, as it's only a single track." msgstr "" +"à¦à¦‡ বিকলà§à¦ªà¦Ÿà¦¿ বেজিয়ার সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦° জনà§à¦¯ কাজ করে না, কারণ à¦à¦Ÿà¦¿ কেবলমাতà§à¦° Single টà§à¦°à§à¦¯à¦¾à¦•।" #: editor/animation_track_editor.cpp msgid "" @@ -497,24 +492,31 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"à¦à¦‡ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦Ÿà¦¿ আমদানি করা দৃশà§à¦¯à§‡à¦° সাথে সমà§à¦ªà¦°à§à¦•িত, তাই আমদানি করা টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿à¦¤à§‡ " +"পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করা হবে না।\n" +"\n" +"কাসà§à¦Ÿà¦® টà§à¦°à§à¦¯à¦¾à¦• যà§à¦•à§à¦¤ করার কà§à¦·à¦®à¦¤à¦¾ সকà§à¦·à¦® করতে, দৃশà§à¦¯à§‡à¦° আমদানি সেটিংসে নেà¦à¦¿à¦—েট করà§à¦¨ à¦à¦¬à¦‚ " +"সেট করà§à¦¨\n" +"\"ফাইলগà§à¦²à¦¿\" ঠ\"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨> সঞà§à¦šà¦¯à¦¼à¦¸à§à¦¥à¦¾à¦¨\", \"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨> কাসà§à¦Ÿà¦® টà§à¦°à§à¦¯à¦¾à¦• রাখà§à¦¨\" সকà§à¦·à¦® " +"করà§à¦¨, তারপরে পà§à¦¨à¦°à¦¾à¦¯à¦¼ আমদানি করà§à¦¨à¥¤\n" +"বিকলà§à¦ªà¦à¦¾à¦¬à§‡, à¦à¦•টি আমদানি পà§à¦°à¦¿à¦¸à§‡à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ যা পৃথক ফাইলগà§à¦²à¦¿à¦¤à§‡ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦—à§à¦²à¦¿ " +"আমদানি করে।" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "সতরà§à¦•তা: Imported অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করা হচà§à¦›à§‡" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select an AnimationPlayer node to create and edit animations." -msgstr "" -"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦¸à¦®à§‚হ সমà§à¦ªà¦¾à¦¦à¦¨ করতে দৃশà§à¦¯à§‡à¦° তালিকা থেকে à¦à¦•টি AnimationPlayer নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤" +msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ তৈরি à¦à¦¬à¦‚ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করতে à¦à¦•টি অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নোড নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." -msgstr "" +msgstr "Tree মধà§à¦¯à§‡ নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ নোডগà§à¦²à¦¿ থেকে কেবল টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ দেখান।" #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." -msgstr "" +msgstr "নোড দà§à¦¬à¦¾à¦°à¦¾ গà§à¦°à§à¦ª টà§à¦°à§à¦¯à¦¾à¦• করà§à¦¨ বা তাদের সরল তালিকা হিসাবে পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨à¥¤" #: editor/animation_track_editor.cpp msgid "Snap:" @@ -548,9 +550,8 @@ msgid "Animation properties." msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ বৈশিষà§à¦Ÿà§à¦¯à¥¤" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Copy Tracks" -msgstr "মানসমূহ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿/কপি করà§à¦¨" +msgstr "টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨" #: editor/animation_track_editor.cpp msgid "Scale Selection" @@ -569,9 +570,8 @@ msgid "Duplicate Transposed" msgstr "পকà§à¦·à¦¾à¦¨à§à¦¤à¦°à¦¿à¦¤ (Transposed) সমূহ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Selection" -msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨" +msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ Delete করà§à¦¨" #: editor/animation_track_editor.cpp msgid "Go to Next Step" @@ -595,7 +595,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" -msgstr "" +msgstr "বেজিয়ার কারà§à¦ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" @@ -642,16 +642,15 @@ msgid "Scale Ratio:" msgstr "সà§à¦•েল/মাপের অনà§à¦ªà¦¾à¦¤:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select Tracks to Copy" -msgstr "গà§à¦£à¦¾à¦—à§à¦£/বৈশিষà§à¦Ÿà§à¦¯ বাছাই করà§à¦¨" +msgstr "গà§à¦£à¦¾à¦—à§à¦£/বৈশিষà§à¦Ÿà§à¦¯ copy করà§à¦¨" #: editor/animation_track_editor.cpp editor/editor_log.cpp #: editor/editor_properties.cpp #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿/কপি করà§à¦¨" @@ -1487,14 +1486,12 @@ msgstr "" "পারবে না।" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing built-in type name." msgstr "" "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ পূরà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ ধরণের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ " "হতে পারবে না।" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." msgstr "" "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ সারà§à¦¬à¦œà¦¨à§€à¦¨ ধà§à¦°à§à¦¬à¦•ের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ " @@ -1774,14 +1771,12 @@ msgid "Enabled Properties:" msgstr "পà§à¦°à§‹à¦ªà¦¾à¦°à§à¦Ÿà¦¿-সমূহ:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "গঠনবিনà§à¦¯à¦¾à¦¸" +msgstr "গঠনবিনà§à¦¯à¦¾à¦¸ :" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" +msgstr "Enabled কà§à¦²à¦¾à¦¸:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." @@ -2031,10 +2026,6 @@ msgstr "পà§à¦°à¦¿à¦à¦¿à¦‰:" msgid "File:" msgstr "ফাইল:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "à¦à¦•টি কারà§à¦¯à¦•র à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা আবশà§à¦¯à¦•।" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "উৎসসমূহ সà§à¦•à§à¦¯à¦¾à¦¨ করà§à¦¨" @@ -2498,6 +2489,10 @@ msgid "There is no defined scene to run." msgstr "চালানোর জনà§à¦¯ কোনো দৃশà§à¦¯ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা নেই।" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "উপ-পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾à¦•ে শà§à¦°à§ করা সমà§à¦à¦¬ হয়নি!" @@ -2545,19 +2540,6 @@ msgstr "বৃহৎ গঠনবিনà§à¦¯à¦¾à¦¸à§‡à¦° জনà§à¦¯ শà§à¦§ msgid "Save Scene As..." msgstr "দৃশà§à¦¯ à¦à¦‡à¦°à§‚পে সংরকà§à¦·à¦£ করà§à¦¨..." -#: editor/editor_node.cpp -#, fuzzy -msgid "No" -msgstr "নোড" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "হà§à¦¯à¦¾à¦" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "à¦à¦‡ দৃশà§à¦¯à¦Ÿà¦¿ কখনোই সংরকà§à¦·à¦£ করা হয় নি। চালানোর পূরà§à¦¬à§‡ সংরকà§à¦·à¦£ করবেন?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "দৃশà§à¦¯ ছাড়া à¦à¦Ÿà¦¿ করা সমà§à¦à¦¬ হবে না।" @@ -2608,6 +2590,10 @@ msgid "Quit" msgstr "পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨" #: editor/editor_node.cpp +msgid "Yes" +msgstr "হà§à¦¯à¦¾à¦" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "à¦à¦¡à¦¿à¦Ÿà¦° হতে পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করবেন?" @@ -2655,7 +2641,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "অà§à¦¯à¦¾à¦¡-অন পà§à¦²à¦¾à¦—ইন à¦à¦¨à¦¾à¦¬à¦² করা সমà§à¦à¦¬ হয় নি। কনফিগার পারà§à¦¸à¦¿à¦‚ ('%s') বà§à¦¯à¦°à§à¦¥ হয়েছে।" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "'res://addons/%s' লোকেশনে অà§à¦¯à¦¾à¦¡-অন পà§à¦²à¦¾à¦—ইনের সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ ফাইল খà§à¦à¦œà§‡ পাওয়া যায়নি।" @@ -3119,14 +3106,6 @@ msgid "Help" msgstr "হেলà§à¦ª" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp #, fuzzy msgid "Online Docs" @@ -3293,6 +3272,25 @@ msgstr "à¦à¦•টি সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ খà§à¦²à§à¦¨ à¦à¦¬à¦‚ চঠ#: editor/editor_node.cpp #, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"নিমà§à¦¨à§‹à¦•à§à¦¤ ফাইলসমূহ ডিসà§à¦•ে নতà§à¦¨à¦¤à¦°à¥¤\n" +"কোন সিধানà§à¦¤à¦Ÿà¦¿ নেয়া উচিত হবে?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "রিলোড" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "পà§à¦¨à¦ƒà¦¸à¦‚রকà§à¦·à¦£" + +#: editor/editor_node.cpp +#, fuzzy msgid "New Inherited" msgstr "নতà§à¦¨ উতà§à¦¤à¦°à¦¾à¦§à¦¿à¦•ারী দৃশà§à¦¯..." @@ -3518,7 +3516,7 @@ msgstr "বোনà§â€Œ/হাড় তৈরি করà§à¦¨" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨" @@ -5353,7 +5351,8 @@ msgid "Got:" msgstr "পà§à¦°à¦¾à¦ªà§à¦¤:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "sha256 হà§à¦¯à¦¾à¦¶ চেক বà§à¦¯à¦°à§à¦¥ হয়েছে" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5502,8 +5501,7 @@ msgstr "পà§à¦°à¦¯à¦¼à§‡à¦¾à¦œà¦¨à§€à¦¯à¦¼ উপকরণসমূহের Z #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5517,10 +5515,30 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp #, fuzzy msgid "Bake Lightmaps" msgstr "লাইটà§à¦®à§à¦¯à¦¾à¦ªà§‡ হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨:" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ ফাইলসমূহ অপসারণ করবেন?" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6685,6 +6703,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° ParticlesMaterial পà§à¦°à¦¸à§‡à¦¸ মà§à¦¯à¦¾à¦Ÿà§‡à¦°à¦¿à§Ÿà¦¾à¦²à§‡ বিনà§à¦¦à§ সà§à¦¥à¦¾à¦ªà¦¨ সমà§à¦à¦¬" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "à¦à¦¤à§‡ রূপানà§à¦¤à¦° করà§à¦¨..." + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp #, fuzzy msgid "Generation Time (sec):" @@ -6754,10 +6777,6 @@ msgstr "AABB উৎপনà§à¦¨ করà§à¦¨" msgid "Generate Visibility AABB" msgstr "AABB উৎপনà§à¦¨ করà§à¦¨" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "AABB উৎপনà§à¦¨ করà§à¦¨" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "বকà§à¦°à¦°à§‡à¦–া হতে বিনà§à¦¦à§ অপসারণ করà§à¦¨" @@ -7397,6 +7416,14 @@ msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦®à§‚হ বনà§à¦§ করà§à¦¨" msgid "Run" msgstr "চালান" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "পদারà§à¦ªà¦£ করà§à¦¨" @@ -7453,16 +7480,6 @@ msgstr "" "নিমà§à¦¨à§‹à¦•à§à¦¤ ফাইলসমূহ ডিসà§à¦•ে নতà§à¦¨à¦¤à¦°à¥¤\n" "কোন সিধানà§à¦¤à¦Ÿà¦¿ নেয়া উচিত হবে?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "রিলোড" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "পà§à¦¨à¦ƒà¦¸à¦‚রকà§à¦·à¦£" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "ডিবাগার" @@ -7565,8 +7582,8 @@ msgstr "বিনà§à¦¦à§ অপসারণ করà§à¦¨" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "করà§à¦¤à¦¨/কাট করà§à¦¨" @@ -7812,6 +7829,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "সেল (Cell)-à¦à¦° আকার:" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "অবজেকà§à¦Ÿ আà¦à¦•া হয়েছে" @@ -10600,6 +10622,11 @@ msgid "Projects" msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "মিরর রিটà§à¦°à¦¾à¦‡à¦ করা হচà§à¦›à§‡, দযা করে অপেকà§à¦·à¦¾ করà§à¦¨..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -11251,6 +11278,16 @@ msgstr "শীষà§à¦¯ নোড ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸ করà§à¦¨ #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "বাহিরের দৃশà§à¦¯à§‡à¦° নোডে à¦à¦Ÿà¦¿ করা সমà§à¦à¦¬ হবে না!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "নোড-সমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Detach Script" msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ সংযà§à¦•à§à¦¤ করà§à¦¨" @@ -11382,6 +11419,11 @@ msgid "Attach Script" msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ সংযà§à¦•à§à¦¤ করà§à¦¨" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "নোড-সমূহ করà§à¦¤à¦¨/কাট করà§à¦¨" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "নোড(সমূহ) অপসারণ করà§à¦¨" @@ -12278,6 +12320,39 @@ msgstr "ফিলà§à¦Ÿà¦¾à¦°à¦¸à¦®à§‚হ" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "AABB উৎপনà§à¦¨ করà§à¦¨" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "অংশাদি:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "ডানে মাতà§à¦°à¦¾ দিন" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾-পরবরà§à¦¤à§€ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12841,11 +12916,13 @@ msgid "Select device from the list" msgstr "লিসà§à¦Ÿ থেকে ডিà¦à¦¾à¦‡à¦¸ সিলেকà§à¦Ÿ করà§à¦¨" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12857,11 +12934,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12869,9 +12946,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -13304,31 +13391,33 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "জà§à¦¯à¦¾à¦®à¦¿à¦¤à¦¿à¦•-আকার বিশà§à¦²à§‡à¦·à¦£ করা হচà§à¦›à§‡" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Plotting Meshes: " -msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" +msgid "Preparing environment" +msgstr "পরিবেশ (Environment)" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Plotting Lights:" -msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" +msgid "Generating capture" +msgstr "লাইটà§à¦®à§à¦¯à¦¾à¦ªà§‡ হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨:" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "লাইটà§à¦®à§à¦¯à¦¾à¦ªà§‡ হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨:" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Lighting Meshes: " -msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" +msgid "Done" +msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!" #: scene/3d/collision_object.cpp msgid "" @@ -13397,6 +13486,10 @@ msgid "Plotting Meshes" msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13627,6 +13720,10 @@ msgstr "সতরà§à¦•তা!" msgid "Please Confirm..." msgstr "অনà§à¦—à§à¦°à¦¹ করে নিশà§à¦šà¦¿à¦¤ করà§à¦¨..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "à¦à¦•টি কারà§à¦¯à¦•র à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা আবশà§à¦¯à¦•।" + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -13681,6 +13778,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "অকারà§à¦¯à¦•র উৎস!" @@ -13712,6 +13815,21 @@ msgid "Constants cannot be modified." msgstr "" #, fuzzy +#~ msgid "No" +#~ msgstr "নোড" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "à¦à¦‡ দৃশà§à¦¯à¦Ÿà¦¿ কখনোই সংরকà§à¦·à¦£ করা হয় নি। চালানোর পূরà§à¦¬à§‡ সংরকà§à¦·à¦£ করবেন?" + +#, fuzzy +#~ msgid "Plotting Meshes: " +#~ msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" + +#, fuzzy +#~ msgid "Lighting Meshes: " +#~ msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" + +#, fuzzy #~ msgid "Search complete" #~ msgstr "টেকà§à¦¸à¦Ÿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" @@ -14045,10 +14163,6 @@ msgstr "" #~ msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।" #, fuzzy -#~ msgid "Done" -#~ msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!" - -#, fuzzy #~ msgid "Failed to create C# project." #~ msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।" diff --git a/editor/translations/br.po b/editor/translations/br.po index 2085d843df..3651e8fb0e 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -643,7 +643,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1904,10 +1904,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2311,6 +2307,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2354,18 +2354,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2413,6 +2401,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2455,7 +2447,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2845,14 +2837,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3006,6 +2990,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3208,7 +3208,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4836,7 +4836,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4971,8 +4971,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4986,9 +4985,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6044,6 +6062,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6104,10 +6126,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6689,6 +6707,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6740,16 +6766,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6842,8 +6858,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7064,6 +7080,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9584,6 +9604,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10187,6 +10211,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10307,6 +10339,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11091,6 +11127,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11586,11 +11650,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11602,11 +11668,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11614,9 +11680,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12007,27 +12083,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12087,6 +12163,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12300,6 +12380,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12345,6 +12429,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 3019abd016..38f08f66cd 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -655,7 +655,7 @@ msgstr "Seleccioneu les Pistes a Copiar" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copiar" @@ -1963,10 +1963,6 @@ msgstr "Vista prèvia:" msgid "File:" msgstr "Fitxer:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Cal utilitzar una extensió và lida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Escaneja Fonts" @@ -2400,6 +2396,10 @@ msgid "There is no defined scene to run." msgstr "No s'ha definit cap escena per executar." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "No s'ha pogut començar el subprocés!" @@ -2443,19 +2443,6 @@ msgstr "Es requereix un node arrel per a guardar l'escena." msgid "Save Scene As..." msgstr "Anomena i Desa l'Escena..." -#: editor/editor_node.cpp -msgid "No" -msgstr "No" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "SÃ" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" -"Aquesta escena no s'ha desat mai encara. Voleu desar-la abans d'executar-la?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Aquesta operació no pot dur-se a terme sense cap escena." @@ -2508,6 +2495,10 @@ msgid "Quit" msgstr "Surt" #: editor/editor_node.cpp +msgid "Yes" +msgstr "SÃ" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Voleu Sortir de l'editor?" @@ -2556,7 +2547,8 @@ msgstr "" "configuració." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "No s'ha pogut trobar el camp d'Script per al complement a: 'res: // addons /" "%s'." @@ -2996,14 +2988,6 @@ msgid "Help" msgstr "Ajuda" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Cerca" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentació en lÃnia" @@ -3175,6 +3159,25 @@ msgid "Open & Run a Script" msgstr "Obre i Executa un Script" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"El disc conté versions més recents dels fitxer següents. \n" +"Quina acció voleu seguir?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Torna a Carregar" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Torna a Desar" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nou Heretat" @@ -3388,7 +3391,7 @@ msgstr "Fes-lo Únic" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Enganxa" @@ -5084,7 +5087,8 @@ msgid "Got:" msgstr "Rebut:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Ha fallat la comprovació del hash sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5222,10 +5226,10 @@ msgid "Assets ZIP File" msgstr "Arxiu ZIP d'Actius" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "No es pot determinar un camà per desar les imatges corresponents als " "lightmaps.\n" @@ -5247,9 +5251,29 @@ msgstr "" "permisos d'escriptura." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Precalcular Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Seleccioneu un Fitxer de Plantilla" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6387,6 +6411,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Només es poden establir punts en materials de procés ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Convertir a ParticulesCPU" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Temps de generació (s):" @@ -6451,10 +6480,6 @@ msgstr "Generant AABB" msgid "Generate Visibility AABB" msgstr "Genera un AABB de Visibilitat" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Genera AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Elimina un Punt de la Corba" @@ -7059,6 +7084,14 @@ msgstr "Tanca la Documentació" msgid "Run" msgstr "Executar" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Cerca" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Pas a Pas (per instruccions)" @@ -7112,16 +7145,6 @@ msgstr "" "El disc conté versions més recents dels fitxer següents. \n" "Quina acció voleu seguir?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Torna a Carregar" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Torna a Desar" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Depurador" @@ -7220,8 +7243,8 @@ msgstr "Punts d’interrupció" msgid "Go To" msgstr "Anar a" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Talla" @@ -7454,6 +7477,11 @@ msgid "Yaw" msgstr "Guinyada" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Mida: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objectes Dibuixats" @@ -10280,6 +10308,11 @@ msgstr "Projecte" #: editor/project_manager.cpp #, fuzzy +msgid "Loading, please wait..." +msgstr "S'estan buscant rèpliques..." + +#: editor/project_manager.cpp +#, fuzzy msgid "Last Modified" msgstr "Última modificació" @@ -10913,6 +10946,16 @@ msgstr "Instancia una Escena Filla" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "No es pot operar en Nodes d'una escena externa!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Enganxa els Nodes" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Detach Script" msgstr "Adjunta-li un Script" @@ -11047,6 +11090,11 @@ msgid "Attach Script" msgstr "Adjunta-li un Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Talla els Nodes" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Elimina els Nodes" @@ -11890,6 +11938,39 @@ msgstr "Filtrar malles" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "Genera AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Direccions" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Sagnia Dreta" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Post-Processat" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "S'està traçant l'Il·luminació:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "El nom de la classe no pot ser una paraula clau reservada" @@ -12432,14 +12513,17 @@ msgid "Select device from the list" msgstr "Selecciona un dispositiu de la llista" #: platform/android/export/export.cpp -#, fuzzy -msgid "ADB executable not configured in the Editor Settings." -msgstr "L'executable ADB no està configurat a la configuració de l'editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "" #: platform/android/export/export.cpp #, fuzzy -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK Jarsigner no està configurat en la configuració de l'editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"El projecte Android no està instal·lat per a la compilació. Instal·leu-lo " +"des del menú Editor." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12451,14 +12535,14 @@ msgstr "" #: platform/android/export/export.cpp #, fuzzy -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"La compilació personalitzada requereix un camà d'Android SDK và lid en la " -"configuració de l'editor." +"El camà de l'SDK d'Android no és và lid per a la compilació personalitzada en " +"la configuració de l'editor." #: platform/android/export/export.cpp #, fuzzy -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" "El camà de l'SDK d'Android no és và lid per a la compilació personalitzada en " "la configuració de l'editor." @@ -12468,13 +12552,23 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp #, fuzzy -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"El camà de l'SDK d'Android no és và lid per a la compilació personalitzada en " +"la configuració de l'editor." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"El projecte Android no està instal·lat per a la compilació. Instal·leu-lo " -"des del menú Editor." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12941,28 +13035,32 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "El node ARVROrigin requreix un node Fill del tipus ARVRCamera" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Temps restant: %d:%02d s)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Analitzant la Geometria..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "S'està n traçant les Malles: " +#, fuzzy +msgid "Preparing environment" +msgstr "Mostra l'Entorn" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "S'està traçant l'Il·luminació:" +#, fuzzy +msgid "Generating capture" +msgstr "S'estan generant els Lightmaps" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "S'està finalitzant el Traçat" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "S'estan generant els Lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Il·luminant les Malles: " +msgid "Done" +msgstr "Fet" #: scene/3d/collision_object.cpp #, fuzzy @@ -13038,6 +13136,10 @@ msgid "Plotting Meshes" msgstr "S'està n traçant les Malles" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "S'està finalitzant el Traçat" + +#: scene/3d/gi_probe.cpp #, fuzzy msgid "" "GIProbes are not supported by the GLES2 video driver.\n" @@ -13293,6 +13395,10 @@ msgstr "Ep!" msgid "Please Confirm..." msgstr "Confirmeu..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Cal utilitzar una extensió và lida." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -13354,6 +13460,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Font no và lida pel Shader." @@ -13383,6 +13495,41 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Les constants no es poden modificar." +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Aquesta escena no s'ha desat mai encara. Voleu desar-la abans d'executar-" +#~ "la?" + +#, fuzzy +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "L'executable ADB no està configurat a la configuració de l'editor." + +#, fuzzy +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "" +#~ "OpenJDK Jarsigner no està configurat en la configuració de l'editor." + +#, fuzzy +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "La compilació personalitzada requereix un camà d'Android SDK và lid en la " +#~ "configuració de l'editor." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Temps restant: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "S'està n traçant les Malles: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Il·luminant les Malles: " + #~ msgid "Search complete" #~ msgstr "Cerca completa" @@ -13723,9 +13870,6 @@ msgstr "Les constants no es poden modificar." #~ msgid "Failed to save solution." #~ msgstr "No s'ha pogut desar la solució." -#~ msgid "Done" -#~ msgstr "Fet" - #~ msgid "Failed to create C# project." #~ msgstr "No s'ha pogut crear el projecte en C#." diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 199112d674..625daea641 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -9,7 +9,7 @@ # LudÄ›k Novotný <gladosicek@gmail.com>, 2016, 2018. # Martin Novák <maidx@seznam.cz>, 2017, 2019. # zxey <r.hozak@seznam.cz>, 2018. -# VojtÄ›ch Å amla <auzkok@seznam.cz>, 2018, 2019, 2020. +# VojtÄ›ch Å amla <auzkok@seznam.cz>, 2018, 2019, 2020, 2021. # Peeter Angelo <contact@peeterangelo.com>, 2019. # VojtechBrezina <vojta.brezina@gmail.com>, 2019. # Garrom Orc Shaman <garromorcshaman@gmail.com>, 2019. @@ -23,12 +23,12 @@ # Daniel KřÞ <Daniel.kriz@protonmail.com>, 2020. # VladimirBlazek <vblazek042@gmail.com>, 2020. # kubajz22 <til.jakubesko@seznam.cz>, 2020. -# Václav Blažej <vaclavblazej@seznam.cz>, 2020. +# Václav Blažej <vaclavblazej@seznam.cz>, 2020, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-01-22 10:21+0000\n" "Last-Translator: Václav Blažej <vaclavblazej@seznam.cz>\n" "Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/" "cs/>\n" @@ -37,7 +37,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -666,7 +666,7 @@ msgstr "Vybrat stopy ke kopÃrovánÃ" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "KopÃrovat" @@ -1959,10 +1959,6 @@ msgstr "Náhled:" msgid "File:" msgstr "Soubor:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Je nutné použÃt platnou pÅ™Ãponu." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Sken zdrojů" @@ -2397,6 +2393,10 @@ msgid "There is no defined scene to run." msgstr "Neexistuje žádná scéna pro spuÅ¡tÄ›nÃ." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Uložit scénu pÅ™ed spuÅ¡tÄ›nÃm..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Nelze spustit podproces!" @@ -2440,18 +2440,6 @@ msgstr "Pro uloženà scény je vyžadován koÅ™enový uzel." msgid "Save Scene As..." msgstr "Uložit scénu jako..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ne" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ano" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Tato scéna nebyla nikdy uložena. Uložit pÅ™ed spuÅ¡tÄ›nÃm?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Tato operace nemůže být provedena bez scény." @@ -2501,6 +2489,10 @@ msgid "Quit" msgstr "UkonÄit" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ano" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "UkonÄit editor?" @@ -2546,7 +2538,8 @@ msgstr "" "Nelze povolit rozÅ¡iÅ™ujÃcà plugin: '%s' parsovánà konfigurace se nezdaÅ™ilo." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Nelze najÃt záznam skriptu pro rozÅ¡iÅ™ujÃcà plugin v: 'res://addons/%s'." @@ -2975,14 +2968,6 @@ msgid "Help" msgstr "NápovÄ›da" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Hledat" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online dokumentace" @@ -3147,6 +3132,25 @@ msgid "Open & Run a Script" msgstr "OtevÅ™Ãt a spustit skript" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"NásledujÃcà soubory majà novÄ›jšà verzi na disku.\n" +"Jaká akce se má vykonat?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Znovu naÄÃst" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Znovu uložit" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nové zdÄ›dÄ›né" @@ -3357,7 +3361,7 @@ msgstr "VytvoÅ™it unikátnÃ" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Vložit" @@ -3915,19 +3919,16 @@ msgid "Searching..." msgstr "Hledám..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d shody." +msgstr "%d shoda v %d souboru." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d shody." +msgstr "%d shod v %d souboru." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d shody." +msgstr "%d shod v %d souborech." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5025,7 +5026,8 @@ msgid "Got:" msgstr "Staženo:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Neúspěšná kontrola sha256 hashe" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5158,10 +5160,10 @@ msgid "Assets ZIP File" msgstr "ZIP soubor asetů" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Nelze urÄit cestu uloženà pro svÄ›telnou mapu obrázku.\n" "Uložte scénu (obrázky se uložà do stejného adresáře) nebo vyberte cestu pro " @@ -5182,9 +5184,32 @@ msgstr "" "ÄtenÃ." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Nebylo možné urÄit velikost svÄ›telné mapy. Maximálnà velikost je pÅ™ÃliÅ¡ malá?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"NÄ›které sÃtÄ› jsou neplatné. UjistÄ›te se, že hodnoty kanálu UV2 jsou ve " +"Ätvercové oblasti [0.0, 1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Godot byl sestaven bez podpory ray tracingu, svÄ›telné mapy nelze zapéct." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Zapéct lightmapy" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Vybrat soubor pro zapeÄenà svÄ›telných map:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6277,6 +6302,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Bod lze vložit pouze do process materiálu ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "PÅ™evést na CPUParticles" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "ÄŒas generovánà (sec):" @@ -6337,10 +6367,6 @@ msgstr "Generovánà AABB" msgid "Generate Visibility AABB" msgstr "Generovat viditelnostnà AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Vygenerovat AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Odstranit bod z kÅ™ivky" @@ -6928,6 +6954,14 @@ msgstr "ZavÅ™Ãt dokumentaci" msgid "Run" msgstr "Spustit" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Hledat" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Vstoupit do" @@ -6981,16 +7015,6 @@ msgstr "" "NásledujÃcà soubory majà novÄ›jšà verzi na disku.\n" "Jaká akce se má vykonat?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Znovu naÄÃst" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Znovu uložit" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Ladicà program" @@ -7083,8 +7107,8 @@ msgstr "Breakpointy" msgid "Go To" msgstr "PÅ™ejÃt na" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Vyjmout" @@ -7307,6 +7331,11 @@ msgid "Yaw" msgstr "Náklon" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Velikost: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekty vykreslené" @@ -9977,6 +10006,11 @@ msgid "Projects" msgstr "Projekty" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "ZÃskávánà zrcadel, prosÃm Äekejte..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Datum modifikace" @@ -10595,6 +10629,16 @@ msgid "Instance Child Scene" msgstr "PÅ™idat instanci scény" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Nelze manipulovat s uzly z cizà scény!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Vložit uzly" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Odpojit skript" @@ -10721,6 +10765,11 @@ msgid "Attach Script" msgstr "PÅ™ipojit skript" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Vyjmout uzly" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Odstranit uzel/uzly" @@ -11525,6 +11574,39 @@ msgstr "Filtrovat meshe" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "PÅ™iÅ™aÄte uzlu GridMap zdroj MeshLibrary k použità jeho sÃtÄ›." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "Vygenerovat AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "SmÄ›ry" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Odsadit zprava" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Následné zpracovánÃ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Vykreslenà svÄ›tel:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Název tÅ™Ãdy nemůže být rezervované klÃÄové slovo" @@ -12030,12 +12112,17 @@ msgid "Select device from the list" msgstr "Vyberte zaÅ™Ãzenà ze seznamu" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Spustitelný ADB nenà nakonfigurovaný v Nastavenà Editoru." +#, fuzzy +msgid "Unable to find the 'apksigner' tool." +msgstr "Nelze najÃt nástroj zipalign." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner nenà nakonfigurovaný v Nastavenà Editoru." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Å ablona sestavenà Androidu nenà pro projekt nainstalována. Nainstalujte jej " +"z nabÃdky Projekt." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12049,13 +12136,13 @@ msgstr "" "ÚložiÅ¡tÄ› klÃÄů pro vydánà je nakonfigurováno nesprávnÄ› v profilu exportu." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "" -"Vlastnà sestavenà vyžaduje správnou cestu k sadÄ› Android SDK v nastavenà " -"editoru." +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "Nesprávná cesta Android SDK pro vlastnà sestavenà v Nastavenà editoru." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "Nesprávná cesta Android SDK pro vlastnà sestavenà v Nastavenà editoru." #: platform/android/export/export.cpp @@ -12063,12 +12150,21 @@ msgid "Missing 'platform-tools' directory!" msgstr "Chybà složka \"platform-tools\"!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "Nesprávná cesta Android SDK pro vlastnà sestavenà v Nastavenà editoru." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Chybà složka \"build-tools\"!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"Å ablona sestavenà Androidu nenà pro projekt nainstalována. Nainstalujte jej " -"z nabÃdky Projekt." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12528,28 +12624,32 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin musà mÃt uzel ARVRCamera jako potomka." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(ZbývajÃcà Äas: %d:%02d s)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Parsuji geometrii..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Vykreslenà mřÞek: " +#, fuzzy +msgid "Preparing environment" +msgstr "Zobrazit prostÅ™edÃ" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Vykreslenà svÄ›tel:" +#, fuzzy +msgid "Generating capture" +msgstr "Generovánà svÄ›telné mapy" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "DokonÄovánà vykreslenÃ" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Generovánà svÄ›telné mapy" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "OsvÄ›tlenà sÃtÃ: " +msgid "Done" +msgstr "Hotovo" #: scene/3d/collision_object.cpp msgid "" @@ -12624,6 +12724,10 @@ msgid "Plotting Meshes" msgstr "Vykreslenà sÃtÃ" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "DokonÄovánà vykreslenÃ" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12877,10 +12981,13 @@ msgstr "Pozor!" msgid "Please Confirm..." msgstr "PotvrÄte prosÃm..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Je nutné použÃt platnou pÅ™Ãponu." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Povolit pÅ™ichytávánÃ" +msgstr "Povolit minimapu mřÞky." #: scene/gui/popup.cpp msgid "" @@ -12937,6 +13044,12 @@ msgstr "" "Velikost pohledu musà být vÄ›tšà než 0, aby bylo možné cokoliv renderovat." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Neplatný zdroj pro náhled." @@ -12964,6 +13077,35 @@ msgstr "OdliÅ¡nosti mohou být pÅ™iÅ™azeny pouze ve vertex funkci." msgid "Constants cannot be modified." msgstr "Konstanty nenà možné upravovat." +#~ msgid "No" +#~ msgstr "Ne" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Tato scéna nebyla nikdy uložena. Uložit pÅ™ed spuÅ¡tÄ›nÃm?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Spustitelný ADB nenà nakonfigurovaný v Nastavenà Editoru." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner nenà nakonfigurovaný v Nastavenà Editoru." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Vlastnà sestavenà vyžaduje správnou cestu k sadÄ› Android SDK v nastavenà " +#~ "editoru." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(ZbývajÃcà Äas: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Vykreslenà mřÞek: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "OsvÄ›tlenà sÃtÃ: " + #~ msgid "Search complete" #~ msgstr "Vyhledávánà dokonÄeno" @@ -12976,12 +13118,6 @@ msgstr "Konstanty nenà možné upravovat." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "Soubor nebo složka se stejným názvem již na tomto mÃstÄ› existuje." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Chybà složka \"build-tools\"!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Nelze najÃt nástroj zipalign." - #~ msgid "Aligning APK..." #~ msgstr "Zarovnávánà APK..." @@ -13266,9 +13402,6 @@ msgstr "Konstanty nenà možné upravovat." #~ msgid "Failed to save solution." #~ msgstr "NepodaÅ™ilo se uložit Å™eÅ¡enÃ." -#~ msgid "Done" -#~ msgstr "Hotovo" - #~ msgid "Failed to create C# project." #~ msgstr "VytvoÅ™enà C# projektu selhalo." diff --git a/editor/translations/da.po b/editor/translations/da.po index 5de9c37510..0f677c6f96 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -15,14 +15,15 @@ # Mads K. Bredager <mbredager@gmail.com>, 2019. # Kristoffer Andersen <kjaa@google.com>, 2019. # Joe Osborne <reachjoe.o@gmail.com>, 2020. -# Autowinto <happymansi@hotmail.com>, 2020. -# Mikkel Mouridsen <mikkelmouridsen@me.com>, 2020. +# Autowinto <happymansi@hotmail.com>, 2020, 2021. +# Mikkel Mouridsen <mikkelmouridsen@me.com>, 2020, 2021. +# snakatk <snaqii@live.dk>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-06-22 06:40+0000\n" -"Last-Translator: Mikkel Mouridsen <mikkelmouridsen@me.com>\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" +"Last-Translator: snakatk <snaqii@live.dk>\n" "Language-Team: Danish <https://hosted.weblate.org/projects/godot-engine/" "godot/da/>\n" "Language: da\n" @@ -30,7 +31,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -141,7 +142,7 @@ msgstr "Tilføj Bezier-punkt" #: editor/animation_bezier_editor.cpp msgid "Move Bezier Points" -msgstr "Flyt punkt" +msgstr "Flyt Bezier-punkter" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" @@ -197,9 +198,8 @@ msgid "Anim Multi Change Call" msgstr "Anim Skift Call" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Length" -msgstr "Ændre Animation Navn:" +msgstr "Ændre Animationslængde" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -334,7 +334,7 @@ msgstr "Vikle Løkke Interpolation" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" -msgstr "Indsæt nøgle" +msgstr "Indsæt Nøgle" #: editor/animation_track_editor.cpp msgid "Duplicate Key(s)" @@ -680,7 +680,7 @@ msgstr "Vælg spor til kopiering:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopier" @@ -762,8 +762,9 @@ msgid "Standard" msgstr "Standard" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Toggle Scripts Panel" -msgstr "" +msgstr "SlÃ¥ til/fra Scripts Panel" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -825,7 +826,7 @@ msgstr "Fra signal:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "" +msgstr "Scenen indeholder ikke noget script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -867,22 +868,23 @@ msgid "Deferred" msgstr "Udskudt" #: editor/connections_dialog.cpp +#, fuzzy msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." -msgstr "" +msgstr "Udskyder signalet, gemmer det i en kø og anvender det ved spildtid." #: editor/connections_dialog.cpp msgid "Oneshot" msgstr "OneShot" #: editor/connections_dialog.cpp +#, fuzzy msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Frakobler signalet efter dets første aktivering." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Forbind Signal: " +msgstr "Kan ikke forbinde signal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -1429,12 +1431,14 @@ msgid "Open Audio Bus Layout" msgstr "Ã…ben Audio Bus Layout" #: editor/editor_audio_buses.cpp +#, fuzzy msgid "There is no '%s' file." -msgstr "" +msgstr "Der er ingen '%s' fil." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Layout" -msgstr "" +msgstr "Layout" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -1513,8 +1517,9 @@ msgstr "" "Ugyldigt navn. MÃ¥ ikke være i konflikt med eksisterende global constant navn." #: editor/editor_autoload_settings.cpp +#, fuzzy msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "Nøgleord kan ikke bruges som autoload navn." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1545,8 +1550,9 @@ msgid "Rearrange Autoloads" msgstr "Flytte om pÃ¥ Autoloads" #: editor/editor_autoload_settings.cpp +#, fuzzy msgid "Can't add autoload:" -msgstr "" +msgstr "Kan ikke tilføje autoload:" #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" @@ -1633,8 +1639,9 @@ msgid "Storing File:" msgstr "Lagrings Fil:" #: editor/editor_export.cpp +#, fuzzy msgid "No export template found at the expected path:" -msgstr "" +msgstr "Ingen eksporterings-skabelon fundet ved den forventede sti:" #: editor/editor_export.cpp msgid "Packing" @@ -2031,10 +2038,6 @@ msgstr "ForhÃ¥ndsvisning:" msgid "File:" msgstr "Fil:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Du skal bruge en gyldig udvidelse." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Skan Kilder" @@ -2475,6 +2478,10 @@ msgid "There is no defined scene to run." msgstr "Der er ingen defineret scene at køre." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Kunne ikke starte underproces!" @@ -2520,18 +2527,6 @@ msgstr "" msgid "Save Scene As..." msgstr "Gem Scene Som..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nej" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ja" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Denne scene er aldrig blevet gemt. Gem før kørsel?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Denne handling kan ikke udføres uden en scene." @@ -2580,6 +2575,10 @@ msgid "Quit" msgstr "Afslut" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ja" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Forlad editor?" @@ -2627,7 +2626,8 @@ msgstr "" "mislykkedes." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Kan ikke finde scriptfelt for addon plugin pÃ¥: 'res://addons/%s'." #: editor/editor_node.cpp @@ -3073,14 +3073,6 @@ msgid "Help" msgstr "Hjælp" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Søg" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online Dokumentation" @@ -3241,6 +3233,23 @@ msgid "Open & Run a Script" msgstr "Ã…ben & Kør et Script" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "De følgende filer kunne ikke trækkes ud af pakken:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Ny Arved" @@ -3449,7 +3458,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Indsæt" @@ -4784,17 +4793,18 @@ msgid "Scale animation playback globally for the node." msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Animation Tools" -msgstr "" +msgstr "Animation Værktøjer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "Animation" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy msgid "Edit Transitions..." -msgstr "Overgange" +msgstr "Rediger Overgange..." #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -4832,20 +4842,21 @@ msgid "Future" msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Depth" -msgstr "" +msgstr "Dybde" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "" +msgstr "1 trin" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" -msgstr "" +msgstr "2 trin" #: editor/plugins/animation_player_editor_plugin.cpp msgid "3 steps" -msgstr "" +msgstr "3 trin" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" @@ -4862,30 +4873,31 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy msgid "Pin AnimationPlayer" -msgstr "Ændre Animation Navn:" +msgstr "Fastgør AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Opret Ny Animation" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Animation Navn:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp msgid "Error!" -msgstr "" +msgstr "Fejl!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Next (Auto Queue):" -msgstr "" +msgstr "Næste (Auto Kø):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" @@ -4897,14 +4909,12 @@ msgid "Move Node" msgstr "Flyt Node(s)" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition exists!" -msgstr "Overgang" +msgstr "Overgang eksisterer!" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Add Transition" -msgstr "Overgang" +msgstr "Tilføj Overgang" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -4941,14 +4951,12 @@ msgid "No playback resource set at path: %s." msgstr "Ikke i stien for ressource." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Node Removed" -msgstr "Fjern" +msgstr "Node Fjernet" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition Removed" -msgstr "Overgang" +msgstr "Overgang Fjernet" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set Start Node (Autoplay)" @@ -4985,9 +4993,8 @@ msgid "Set the end animation. This is useful for sub-transitions." msgstr "" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition: " -msgstr "Overgang" +msgstr "Overgang: " #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -5002,7 +5009,7 @@ msgstr "Animation Zoom." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" -msgstr "" +msgstr "Nyt navn:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp @@ -5026,8 +5033,9 @@ msgid "Mix" msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp +#, fuzzy msgid "Auto Restart:" -msgstr "" +msgstr "Auto Genstart:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Restart (s):" @@ -5043,8 +5051,9 @@ msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp +#, fuzzy msgid "Amount:" -msgstr "" +msgstr "Mængde:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend 0:" @@ -5060,13 +5069,14 @@ msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Current:" -msgstr "" +msgstr "Nuværende:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp #: modules/visual_script/visual_script_editor.cpp +#, fuzzy msgid "Add Input" -msgstr "" +msgstr "Tilføj Input" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Clear Auto-Advance" @@ -5077,8 +5087,9 @@ msgid "Set Auto-Advance" msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp +#, fuzzy msgid "Delete Input" -msgstr "" +msgstr "Fjern Input" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation tree is valid." @@ -5125,16 +5136,19 @@ msgid "Transition Node" msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp +#, fuzzy msgid "Import Animations..." -msgstr "" +msgstr "Importer Animationer..." #: editor/plugins/animation_tree_player_editor_plugin.cpp +#, fuzzy msgid "Edit Node Filters" -msgstr "" +msgstr "Rediger Node Filtre" #: editor/plugins/animation_tree_player_editor_plugin.cpp +#, fuzzy msgid "Filters..." -msgstr "" +msgstr "Filtre..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" @@ -5145,8 +5159,9 @@ msgid "View Files" msgstr "Vis filer" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Connection error, please try again." -msgstr "" +msgstr "Forbindelsesfejl, prøv venligst igen." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect to host:" @@ -5154,15 +5169,16 @@ msgstr "Kan ikke forbinde til host:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response from host:" -msgstr "" +msgstr "Ingen respons fra host:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve hostname:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Request failed, return code:" -msgstr "" +msgstr "Forespørgsel mislykkedes, returkode:" #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -5172,11 +5188,12 @@ msgstr "Forespørgsel mislykkedes." #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy msgid "Cannot save response to:" -msgstr "Kan ikke fjerne:" +msgstr "Kan ikke gemme respons i:" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Write error." -msgstr "" +msgstr "Skrivefejl." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" @@ -5190,12 +5207,12 @@ msgstr "Omdiriger Løkke." #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy msgid "Request failed, timeout" -msgstr "Forespørgsel mislykkedes." +msgstr "Forespørgsel mislykkedes, tiden udløb." #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy msgid "Timeout." -msgstr "Tid" +msgstr "Tiden udløb." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." @@ -5210,7 +5227,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5218,14 +5235,12 @@ msgid "Asset Download Error:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Downloading (%s / %s)..." -msgstr "Indlæser" +msgstr "Downloader (%s / %s)..." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Downloading..." -msgstr "Indlæser" +msgstr "Downloader..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Resolving..." @@ -5242,11 +5257,12 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy msgid "Install..." -msgstr "Installér" +msgstr "Installér..." #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Retry" -msgstr "" +msgstr "Prøv igen" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" @@ -5266,25 +5282,23 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Name (A-Z)" -msgstr "" +msgstr "Navn (A-Z)" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Name (Z-A)" -msgstr "" +msgstr "Navn (Z-A)" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "License (A-Z)" -msgstr "Licens" +msgstr "Licens (A-Z)" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "License (Z-A)" -msgstr "Licens" +msgstr "Licens (Z-A)" #: editor/plugins/asset_library_editor_plugin.cpp msgid "First" -msgstr "" +msgstr "Første" #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -5297,7 +5311,7 @@ msgstr "Næste" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Last" -msgstr "" +msgstr "Sidste" #: editor/plugins/asset_library_editor_plugin.cpp msgid "All" @@ -5308,9 +5322,8 @@ msgid "No results for \"%s\"." msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Import..." -msgstr "Importer" +msgstr "Importer..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Plugins..." @@ -5330,9 +5343,8 @@ msgid "Site:" msgstr "Websted:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Support" -msgstr "Støtte..." +msgstr "Support" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Official" @@ -5343,9 +5355,8 @@ msgid "Testing" msgstr "Tester" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Loading..." -msgstr "Indlæs" +msgstr "Indlæser..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -5354,8 +5365,7 @@ msgstr "Assets zipfil" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5369,9 +5379,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Vælg template fil" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -5395,7 +5425,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "steps" -msgstr "" +msgstr "trin" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" @@ -6477,6 +6507,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Konverter Til %s" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6537,10 +6572,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -7159,6 +7190,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Søg" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7212,16 +7251,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7322,8 +7351,8 @@ msgstr "Slet points" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Cut" @@ -7562,6 +7591,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10228,6 +10261,11 @@ msgid "Projects" msgstr "Projekt" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Henter spejle, vent venligst ..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10855,6 +10893,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Indsæt Node" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Ryd Script" @@ -10985,6 +11032,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Indsæt Node" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11826,6 +11878,37 @@ msgstr "Filter mode:" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Beskrivelse" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Skift udtryk" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Generering af lightmaps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12356,11 +12439,13 @@ msgid "Select device from the list" msgstr "Vælg enhed fra listen" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12372,11 +12457,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12384,9 +12469,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12824,27 +12919,29 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Generering af lightmaps" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Generering af lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12913,6 +13010,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13143,6 +13244,10 @@ msgstr "Advarsel!" msgid "Please Confirm..." msgstr "Bekræft venligst..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Du skal bruge en gyldig udvidelse." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -13196,6 +13301,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Ugyldig skriftstørrelse." @@ -13226,6 +13337,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstanter kan ikke ændres." +#~ msgid "No" +#~ msgstr "Nej" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Denne scene er aldrig blevet gemt. Gem før kørsel?" + #, fuzzy #~ msgid "Search complete" #~ msgstr "Søg Tekst" @@ -13464,10 +13581,6 @@ msgstr "Konstanter kan ikke ændres." #~ msgid "Create folder" #~ msgstr "Opret mappe" -#, fuzzy -#~ msgid "Custom Node" -#~ msgstr "Indsæt Node" - #~ msgid "Invalid Path" #~ msgstr "Ugyldig sti" diff --git a/editor/translations/de.po b/editor/translations/de.po index 016d676ee4..0c8ab619c5 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -23,7 +23,7 @@ # Peter Friedland <peter_friedland@gmx.de>, 2016. # No need for a name <endoplasmatik@gmx.net>, 2016. # Sönke <me@eknoes.de>, 2018. -# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020. +# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020, 2021. # Tim Schellenberg <smwleod@gmail.com>, 2017. # Timo Schwarzer <account@timoschwarzer.com>, 2016-2018. # viernullvier <hannes.breul+github@gmail.com>, 2016. @@ -36,7 +36,7 @@ # asyncial <mahlburg@posteo.de>, 2018. # ssantos <ssantos@web.de>, 2018. # Rémi Verschelde <akien@godotengine.org>, 2019. -# Martin <martinreininger@gmx.net>, 2019. +# Martin <martinreininger@gmx.net>, 2019, 2021. # Andreas During <anduring@web.de>, 2019. # Arthur S. Muszynski <artism90@gmail.com>, 2019. # Andreas Binczyk <andreas.binczyk@gmail.com>, 2019. @@ -62,11 +62,12 @@ # Patric Wust <patric.wust@gmx.de>, 2020. # Jonathan Hassel <jonathan.hassel@icloud.com>, 2020. # Artur Schönfeld <schoenfeld.artur@ymail.com>, 2020. +# kidinashell <kidinashell@protonmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-02-21 10:50+0000\n" "Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" @@ -75,7 +76,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -707,7 +708,7 @@ msgstr "Zu kopierende Spuren auswählen" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopieren" @@ -2012,10 +2013,6 @@ msgstr "Vorschau:" msgid "File:" msgstr "Datei:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Eine gültige Datei-Endung muss verwendet werden." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Lese Quellen" @@ -2455,6 +2452,10 @@ msgid "There is no defined scene to run." msgstr "Es ist keine abzuspielende Szene definiert." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Szene vor dem Abspielen speichern..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Unterprozess konnte nicht gestartet werden!" @@ -2498,18 +2499,6 @@ msgstr "Ein Wurzel-Node wird benötigt um diese Szene zu speichern." msgid "Save Scene As..." msgstr "Szene speichern als..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nein" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ja" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Diese Szene wurde nie gespeichert. Speichern vorm Starten?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Diese Aktion kann nicht ohne eine Szene ausgeführt werden." @@ -2561,6 +2550,10 @@ msgid "Quit" msgstr "Verlassen" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ja" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Editor verlassen?" @@ -2609,7 +2602,8 @@ msgstr "" "fehlgeschlagen." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Skript-Feld für Erweiterung in ‚res://addons/%s‘ konnte nicht gefunden " "werden." @@ -3050,14 +3044,6 @@ msgid "Help" msgstr "Hilfe" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Suchen" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Internetdokumentation" @@ -3223,6 +3209,24 @@ msgid "Open & Run a Script" msgstr "Skript öffnen und ausführen" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Die folgenden Dateien wurden im Dateisystem verändert.\n" +"Wie soll weiter vorgegangen werden?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Neu laden" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Erneut speichern" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Neu Geerbte" @@ -3434,7 +3438,7 @@ msgstr "Einzigartig machen" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Einfügen" @@ -3993,19 +3997,16 @@ msgid "Searching..." msgstr "Am suchen..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d Übereinstimmungen gefunden." +msgstr "%d Übereinstimmung in %d Datei gefunden." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d Übereinstimmungen gefunden." +msgstr "%d Übereinstimmungen in %d Datei gefunden." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d Übereinstimmungen gefunden." +msgstr "%d Übereinstimmungen in %d Dateien gefunden." #: editor/groups_editor.cpp msgid "Add to Group" @@ -4773,7 +4774,7 @@ msgstr "Weißmodulation erzwingen" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" -msgstr "Griffe (3D) einbeziehen" +msgstr "3D-Manipulator einbeziehen" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pin AnimationPlayer" @@ -5113,7 +5114,8 @@ msgid "Got:" msgstr "Erhalten:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Sha256-Prüfung fehlgeschlagen" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5248,12 +5250,10 @@ msgstr "Nutzerinhalte als ZIP-Datei" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"Der Speicherpfad für Lightmap-Bilder kann nicht bestimmt werden.\n" -"Speichern Sie die Szene (Bilder werden im gleichen Ordner gespeichert) oder " -"legen Sie den Speicherpfad in den BakedLightmap-Eigenschaften fest." +"Ein Speicherpfad für Lightmap-Bilder kann nicht bestimmt werden.\n" +"Ein Speichern der Szene sollte dieses Problem beheben." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5271,9 +5271,34 @@ msgstr "" "Speicherpfad beschreibbar ist." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Die Größe des Lightmaps kann nicht bestimmt werden. Möglicherweise ist die " +"maximale Lightmap-Größe zu klein." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Ein Mesh ist ungültig. Es muss sichergestellt sein dass alle Werte das UV2-" +"Kanals im Bereich von 0.0 bis 1.0 liegen." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Diese Godot-Version wurde ohne Raytracing-Unterstützung erstellt, Lightmaps " +"können damit nicht gebacken werden." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Lightmaps vorrendern" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Lightmap-Bake-Datei auswählen:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6375,6 +6400,10 @@ msgstr "" "werden" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Zu CPUParticles2D konvertieren" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Erzeugungszeit (s):" @@ -6435,10 +6464,6 @@ msgstr "Erzeuge AABB" msgid "Generate Visibility AABB" msgstr "Erzeuge Sichtbarkeits-AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Erzeuge AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Punkt von Kurve entfernen" @@ -7030,6 +7055,14 @@ msgstr "Dokumentation schließen" msgid "Run" msgstr "Ausführen" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Suchen" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Hineinspringen" @@ -7083,16 +7116,6 @@ msgstr "" "Die folgenden Dateien wurden im Dateisystem verändert.\n" "Wie soll weiter vorgegangen werden?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Neu laden" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Erneut speichern" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Debugger" @@ -7188,8 +7211,8 @@ msgstr "Haltepunkte" msgid "Go To" msgstr "Springe zu" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Ausschneiden" @@ -7414,6 +7437,10 @@ msgid "Yaw" msgstr "Gieren" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Größe" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Gezeichnete Objekte" @@ -7528,7 +7555,7 @@ msgstr "Umgebung anzeigen" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Gizmos" -msgstr "Griffe anzeigen" +msgstr "Manipulator anzeigen" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Information" @@ -7616,9 +7643,9 @@ msgid "" msgstr "" "Klicken um zwischen Sichtbarkeitsmodi umzuschalten.\n" "\n" -"Offenes Auge: Griffe sind sichtbar.\n" -"Geschlossenes Auge: Griffe sind unsichtbar.\n" -"Halb offenes Auge: Griffe sind auch durch deckende Oberflächen sichtbar " +"Offenes Auge: Manipulator ist sichtbar.\n" +"Geschlossenes Auge: Manipulator ist unsichtbar.\n" +"Halb offenes Auge: Manipulator ist auch durch deckende Oberflächen sichtbar " "(\"Röntgenblick\")." #: editor/plugins/spatial_editor_plugin.cpp @@ -7732,7 +7759,7 @@ msgstr "Vier Ansichten" #: editor/plugins/spatial_editor_plugin.cpp msgid "Gizmos" -msgstr "Griffe" +msgstr "Manipulator" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Origin" @@ -7809,7 +7836,7 @@ msgstr "Nachher" #: editor/plugins/spatial_editor_plugin.cpp msgid "Nameless gizmo" -msgstr "Namenloser Anfasser" +msgstr "Namenloser Manipulator" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create Mesh2D" @@ -10111,6 +10138,10 @@ msgid "Projects" msgstr "Projekte" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Projekte werden geladen, bitte warten..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Zuletzt bearbeitet" @@ -10280,7 +10311,7 @@ msgstr "Ereignis hinzufügen" #: editor/project_settings_editor.cpp msgid "Button" -msgstr "Schaltfläche (Button)" +msgstr "Knopf" #: editor/project_settings_editor.cpp msgid "Left Button." @@ -10734,6 +10765,16 @@ msgid "Instance Child Scene" msgstr "Szene hier instantiieren" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Bearbeiten von Nodes einer fremden Szene ist nicht möglich!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Nodes einfügen" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Skript loslösen" @@ -10861,6 +10902,11 @@ msgid "Attach Script" msgstr "Skript hinzufügen" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Nodes trennen" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Entferne Node(s)" @@ -11668,6 +11714,34 @@ msgstr "Meshes filtern" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "GridMap zu MeshLibrary hinzufügen um ihre Meshes benutzen zu können." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Backen beginnen" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Datenstrukturen werden vorbereitet" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Puffer generieren" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Direct-Lighting" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Indirect-Lighting" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Nachbearbeitung" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Lightmaps auftragen" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Der Klassenname kann nicht ein reserviertes Schlüsselwort sein" @@ -12186,12 +12260,16 @@ msgid "Select device from the list" msgstr "Gerät aus Liste auswählen" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Das ADB-Programm wurde nicht in den Editoreinstellungen konfiguriert." +msgid "Unable to find the 'apksigner' tool." +msgstr "Das ‚apksigner‘-Hilfswerkzeug konnte nicht gefunden werden." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK-Jarsigner wurde nicht in den Editoreinstellungen konfiguriert." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Es wurde keine Android-Buildvorlage für dieses Projekt installiert. Es kann " +"im Projektmenü installiert werden." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12205,26 +12283,38 @@ msgstr "" "Release-Keystore wurde nicht korrekt konfiguriert in den Exporteinstellungen." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Eigene Builds erfordern gültigen Android-SDK-Pfad in den Editoreinstellungen." +"Es wird ein gültiger Android-SDK-Pfad in den Editoreinstellungen benötigt." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Ungültiger Android-SDK-Pfad für eigene Builds in den Editoreinstellungen." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Ungültiger Android-SDK-Pfad in den Editoreinstellungen." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "‚platform-tools‘-Verzeichnis fehlt!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" -"Es wurde keine Android-Buildvorlage für dieses Projekt installiert. Es kann " -"im Projektmenü installiert werden." +"‚adb‘-Anwendung der Android-SDK-Platform-Tools konnte nicht gefunden werden." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Schauen Sie im Android-SDK-Verzeichnis das in den Editoreinstellungen " +"angegeben wurde nach." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "‚build-tools‘-Verzeichnis fehlt!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" +"‚apksigner‘-Anwendung der Android-SDK-Build-Tools konnte nicht gefunden " +"werden." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12707,28 +12797,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin benötigt ein ARVRCamera-Unterobjekt." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Am Suchen nach Meshes und Lichtern" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Verbleibende Zeit: %d:%20d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Am Vorbereiten der Geometrie (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Plotte Meshe: " +msgid "Preparing environment" +msgstr "Am Vorbereiten der Umgebung" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Plotte Lichter:" +msgid "Generating capture" +msgstr "Am Generieren eines Schnappschusses" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Stelle Plot fertig" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Am Speichern der Lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Beleuchte Meshe: " +msgid "Done" +msgstr "Fertig" #: scene/3d/collision_object.cpp msgid "" @@ -12805,6 +12895,10 @@ msgid "Plotting Meshes" msgstr "Plotte Mesh" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Stelle Plot fertig" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13074,10 +13168,13 @@ msgstr "Warnung!" msgid "Please Confirm..." msgstr "Bitte bestätigen..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Eine gültige Datei-Endung muss verwendet werden." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Einrasten aktivieren" +msgstr "Gitterübersichtskarte aktivieren." #: scene/gui/popup.cpp msgid "" @@ -13137,6 +13234,14 @@ msgstr "" "Die Größe des Viewports muss größer als 0 sein um etwas rendern zu können." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Der Sampler-Port ist verbunden wird aber nicht benutzt. Die Quelle sollte " +"möglicherweise auf ‚SamplerPort‘ gestellt werden." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ungültige Quelle für Vorschau." @@ -13164,6 +13269,37 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden." msgid "Constants cannot be modified." msgstr "Konstanten können nicht verändert werden." +#~ msgid "No" +#~ msgstr "Nein" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Diese Szene wurde nie gespeichert. Speichern vorm Starten?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "" +#~ "Das ADB-Programm wurde nicht in den Editoreinstellungen konfiguriert." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "" +#~ "OpenJDK-Jarsigner wurde nicht in den Editoreinstellungen konfiguriert." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Eigene Builds erfordern gültigen Android-SDK-Pfad in den " +#~ "Editoreinstellungen." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Verbleibende Zeit: %d:%20d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Plotte Meshe: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Beleuchte Meshe: " + #~ msgid "Search complete" #~ msgstr "Suche abgeschlossen" @@ -13178,12 +13314,6 @@ msgstr "Konstanten können nicht verändert werden." #~ "Es existiert bereits eine Datei oder ein Ordner an diesem Pfad mit dem " #~ "angegebenen Namen." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "‚build-tools‘-Verzeichnis fehlt!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Das zipalign Hilfswerkzeug konnte nicht gefunden werden." - #~ msgid "Aligning APK..." #~ msgstr "Richte APK aus..." @@ -13533,9 +13663,6 @@ msgstr "Konstanten können nicht verändert werden." #~ msgid "Failed to save solution." #~ msgstr "Fehler beim Speichern der Lösung." -#~ msgid "Done" -#~ msgstr "Fertig" - #~ msgid "Failed to create C# project." #~ msgstr "C#-Projekt-Erzeugen fehlgeschlagen." diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 900a74d158..21d516e8ee 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -1,4 +1,4 @@ -# LANGUAGE translation of the Godot Engine editor +# LANGUAGE translation of the Godot Engine editor. # Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. @@ -621,7 +621,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1882,10 +1882,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2289,6 +2285,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2332,18 +2332,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2391,6 +2379,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2433,7 +2425,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2823,14 +2815,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2984,6 +2968,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3186,7 +3186,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4814,7 +4814,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4949,8 +4949,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4964,9 +4963,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6022,6 +6040,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6082,10 +6104,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6667,6 +6685,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6718,16 +6744,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6820,8 +6836,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7042,6 +7058,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9562,6 +9582,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10165,6 +10189,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10285,6 +10317,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11069,6 +11105,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11564,11 +11628,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11580,11 +11646,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11592,9 +11658,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11985,27 +12061,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12065,6 +12141,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12278,6 +12358,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12323,6 +12407,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index b49fd28cbf..f6205b3b50 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -10,12 +10,13 @@ # pandektis <pandektis@gmail.com>, 2020. # KostasMSC <kargyris@athtech.gr>, 2020. # lawfulRobot <czavantias@gmail.com>, 2020. +# Michalis <michalisntovas@yahoo.gr>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-30 12:32+0000\n" -"Last-Translator: lawfulRobot <czavantias@gmail.com>\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" +"Last-Translator: Michalis <michalisntovas@yahoo.gr>\n" "Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/" "el/>\n" "Language: el\n" @@ -23,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -656,7 +657,7 @@ msgstr "Επιλογή Κομματιών για ΑντιγÏαφή" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "ΑντιγÏαφή" @@ -1878,7 +1879,7 @@ msgstr "Αποθήκευση αÏχείου" #: editor/editor_file_dialog.cpp msgid "Go Back" -msgstr "Πήγαινε πίσω" +msgstr "ΕπιστÏοφή" #: editor/editor_file_dialog.cpp msgid "Go Forward" @@ -1958,10 +1959,6 @@ msgstr "Î Ïοεπισκόπηση:" msgid "File:" msgstr "ΑÏχείο:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Απαιτείται η χÏήση ÎγκυÏης επÎκτασης." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "ΣάÏωση πηγών" @@ -2396,6 +2393,10 @@ msgid "There is no defined scene to run." msgstr "Δεν υπάÏχει καθοÏισμÎνη σκηνή για εκτελÎση." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "ΑδÏνατη η εκκίνηση της υπό-εÏγασίας!" @@ -2439,18 +2440,6 @@ msgstr "Απαιτείται Ïιζικός κόμβος για την αποθΠmsgid "Save Scene As..." msgstr "Αποθήκευση σκηνή ως..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Όχι" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Îαι" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Αυτή η σκηνή δεν Îχει αποθηκευτεί. Αποθήκευση Ï€Ïιν από την εκτÎλεση;" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Αυτή η λειτουÏγία δεν μποÏεί να γίνει χωÏίς σκηνή." @@ -2502,6 +2491,10 @@ msgid "Quit" msgstr "Έξοδος" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Îαι" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "ΤεÏματισμός του Ï€ÏογÏάμματος επεξεÏγασίας;" @@ -2550,7 +2543,8 @@ msgstr "" "αÏχείου ÏÏθμισης." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "ΑδÏνατη η ÎÏ…Ïεση του πεδίου 'script' για την Ï€Ïόσθετη επÎκταση στο: 'res://" "addons/%s'." @@ -2991,14 +2985,6 @@ msgid "Help" msgstr "Βοήθεια" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Αναζήτηση" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "ΗλεκτÏονική τεκμηÏίωση" @@ -3166,6 +3152,25 @@ msgid "Open & Run a Script" msgstr "Άνοιξε & ΤÏÎξε μία δÎσμη ενεÏγειών" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Τα ακόλουθα αÏχεία είναι νεότεÏα στον δίσκο.\n" +"Τι δÏάση να ληφθεί;:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "ΕπαναφόÏτωση" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Επαναποθήκευση" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "ÎÎα κληÏονομημÎνη" @@ -3376,7 +3381,7 @@ msgstr "Κάνε μοναδικό" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Επικόλληση" @@ -3913,7 +3918,7 @@ msgstr "Αντικατάσταση..." #: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" -msgstr "ΑκÏÏωση" +msgstr "ΆκυÏο" #: editor/find_in_files.cpp msgid "Find: " @@ -5053,7 +5058,8 @@ msgid "Got:" msgstr "ΔοσμÎνο:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Η δοκιμή κατακεÏÎ¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï sha256 απÎτυχε" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5186,10 +5192,10 @@ msgid "Assets ZIP File" msgstr "ΑÏχείο ZIP των Στοιχείων" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Δεν ήταν δυνατός ο Ï€ÏοσδιοÏισμός διαδÏομής αποθήκευσης για εικόνες " "lightmap.\n" @@ -5212,9 +5218,29 @@ msgstr "" "είναι εγγÏάψιμη." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Î Ïοετοιμασία Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Επιλογή ΑÏχείου Î ÏοτÏπων" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6324,6 +6350,11 @@ msgstr "" "ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "ΜετατÏοπή σε σωματίδια CPU" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "ΧÏόνος ΠαÏαγωγής (sec):" @@ -6384,10 +6415,6 @@ msgstr "ΔημιουÏία AABB" msgid "Generate Visibility AABB" msgstr "ΔημιουÏία AABB οÏατότητας" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "ΔημιουÏία AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "ΑφαίÏεση σημείου από την καμπÏλη" @@ -6987,6 +7014,14 @@ msgstr "Κλείσιμο ΤεκμηÏίωσης" msgid "Run" msgstr "ΕκτÎλεση" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Αναζήτηση" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Βήμα μÎσα" @@ -7002,7 +7037,7 @@ msgstr "Διακοπή" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp msgid "Continue" -msgstr "ΣυνÎχιση" +msgstr "ΣυνÎχεια" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" @@ -7040,16 +7075,6 @@ msgstr "" "Τα ακόλουθα αÏχεία είναι νεότεÏα στον δίσκο.\n" "Τι δÏάση να ληφθεί;:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "ΕπαναφόÏτωση" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Επαναποθήκευση" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Αποσφαλματωτής" @@ -7146,8 +7171,8 @@ msgstr "Σημεία Διακοπής" msgid "Go To" msgstr "Πήγαινε Σε" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Αποκοπή" @@ -7372,6 +7397,11 @@ msgid "Yaw" msgstr "ΠαÏÎκκλιση" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "ΜÎγεθος: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ΖωγÏαφισμÎνα αντικείμενα" @@ -10068,6 +10098,11 @@ msgid "Projects" msgstr "ΈÏγα" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Ανάκτηση δεδοÎνων κατοπτÏισμοÏ, παÏακαλώ πεÏιμÎνετε..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Τελευταία ΤÏοποποιημÎνα" @@ -10687,6 +10722,16 @@ msgid "Instance Child Scene" msgstr "ΑÏχικοποίηση σκηνής ως παιδί" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Δεν είναι δυνατή η λειτουÏγία σε κόμβους από ξÎνη σκηνή!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Επικόλληση κόμβων" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "ΑποσÏνδεση ΔÎσμης ΕνεÏγειών" @@ -10819,6 +10864,11 @@ msgid "Attach Script" msgstr "ΣÏνδεση ΔÎσμης ΕνεÏγειών" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Αποκοπή κόμβων" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "ΑφαίÏεση κόμβων" @@ -11628,6 +11678,39 @@ msgstr "ΦιλτÏάÏισμα πλεγμάτων" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "ΟÏίστε Îναν πόÏο MeshLibrary στο GridMap για χÏήση των πλεγμάτων του." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "ΔημιουÏία AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Κατευθήνσεις" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "ΣτοιχειοθÎτηση Δεξιά" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "ΜετεπεξεÏγασία" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "ΤοποθÎτηση φώτων:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Το όνομα της κλάσης δεν μποÏεί να είναι λÎξη-κλειδί" @@ -12149,13 +12232,16 @@ msgid "Select device from the list" msgstr "ΕπιλÎξτε συσκευή από την λίστα" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" -"Το εκτελÎσιμο αÏχείο ADB δεν Îχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "Το OpenJDK jarsigner δεν Îχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Λείπει το Ï€Ïότυπο δόμησης Android από το ÎÏγο. Εγκαταστήστε το από το Î¼ÎµÎ½Î¿Ï " +"«ΈÏγο»." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12169,13 +12255,15 @@ msgstr "" "ΕσφαλμÎνη ÏÏθμιση αποθετηÏίου κλειδιών διανομής στην διαμόÏφωση εξαγωγής." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Η Ï€ÏοσαÏμοσμÎνη δόμηση απαιτεί μια ÎγκυÏη διαδÏομή για το Android SDK στις " -"Ρυθμίσεις ΕπεξεÏγαστή." +"Μη ÎγκυÏη διαδÏομή Android SDK για Ï€ÏοσαÏμοσμÎνη δόμηση στις Ρυθμίσεις " +"ΕπεξεÏγαστή." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "" "Μη ÎγκυÏη διαδÏομή Android SDK για Ï€ÏοσαÏμοσμÎνη δόμηση στις Ρυθμίσεις " "ΕπεξεÏγαστή." @@ -12185,12 +12273,23 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Μη ÎγκυÏη διαδÏομή Android SDK για Ï€ÏοσαÏμοσμÎνη δόμηση στις Ρυθμίσεις " +"ΕπεξεÏγαστή." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"Λείπει το Ï€Ïότυπο δόμησης Android από το ÎÏγο. Εγκαταστήστε το από το Î¼ÎµÎ½Î¿Ï " -"«ΈÏγο»." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12660,28 +12759,32 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "Το ARVROrigin απαιτεί γονικό κόμβο ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(ΟλοκλήÏωση σε: %d:%02d s)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Ανάλυση γεωμετÏίας..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "ΤοποθÎτηση πλεγμάτων: " +#, fuzzy +msgid "Preparing environment" +msgstr "Εμφάνιση πεÏιβάλλοντος" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "ΤοποθÎτηση φώτων:" +#, fuzzy +msgid "Generating capture" +msgstr "ΔημιουÏγία χαÏτών φωτός" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "ΟλοκλήÏωση σχεδιαγÏάμματος" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "ΔημιουÏγία χαÏτών φωτός" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Φώτηση πλεγμάτων: " +msgid "Done" +msgstr "ΤÎλος" #: scene/3d/collision_object.cpp msgid "" @@ -12760,6 +12863,10 @@ msgid "Plotting Meshes" msgstr "ΤοποθÎτηση πλεγμάτων" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "ΟλοκλήÏωση σχεδιαγÏάμματος" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13019,6 +13126,10 @@ msgstr "Ειδοποίηση!" msgid "Please Confirm..." msgstr "ΠαÏακαλώ επιβεβαιώστε..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Απαιτείται η χÏήση ÎγκυÏης επÎκτασης." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -13082,6 +13193,12 @@ msgstr "" "απόδοση." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "ΆκυÏη πηγή για Ï€Ïοεπισκόπηση." @@ -13109,6 +13226,37 @@ msgstr "Τα «varying» μποÏοÏν να ανατεθοÏν μόνο στηΠmsgid "Constants cannot be modified." msgstr "Οι σταθεÏÎÏ‚ δεν μποÏοÏν να Ï„ÏοποποιηθοÏν." +#~ msgid "No" +#~ msgstr "Όχι" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Αυτή η σκηνή δεν Îχει αποθηκευτεί. Αποθήκευση Ï€Ïιν από την εκτÎλεση;" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "" +#~ "Το εκτελÎσιμο αÏχείο ADB δεν Îχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "Το OpenJDK jarsigner δεν Îχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Η Ï€ÏοσαÏμοσμÎνη δόμηση απαιτεί μια ÎγκυÏη διαδÏομή για το Android SDK " +#~ "στις Ρυθμίσεις ΕπεξεÏγαστή." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(ΟλοκλήÏωση σε: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "ΤοποθÎτηση πλεγμάτων: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Φώτηση πλεγμάτων: " + #~ msgid "Search complete" #~ msgstr "ΟλοκλήÏωση αναζήτησης" @@ -13462,9 +13610,6 @@ msgstr "Οι σταθεÏÎÏ‚ δεν μποÏοÏν να Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î·Î¸Î¿Ï #~ msgid "Failed to save solution." #~ msgstr "ΑπÎτυχε η αποθήκευση της λÏσης." -#~ msgid "Done" -#~ msgstr "ΤÎλος" - #~ msgid "Failed to create C# project." #~ msgstr "ΑπÎτυχε η δημιουÏγία ÎÏγου C#." diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 8f17041a39..bbc0d13358 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -10,18 +10,19 @@ # Sr Half <flavio05@outlook.com>, 2020. # Cristian Yepez <cristianyepez@gmail.com>, 2020. # BinotaLIU <me@binota.org>, 2020. +# Jakub Fabijan <animatorzPolski@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2020-11-20 23:08+0000\n" -"Last-Translator: BinotaLIU <me@binota.org>\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" +"Last-Translator: Jakub Fabijan <animatorzPolski@gmail.com>\n" "Language-Team: Esperanto <https://hosted.weblate.org/projects/godot-engine/" "godot/eo/>\n" "Language: eo\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -646,14 +647,13 @@ msgstr "Elekti vojetojn por duplikati" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Duplikati" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select All/None" -msgstr "Elektaro nur" +msgstr "Elekti Ĉiuj/Neniuj" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" @@ -1930,10 +1930,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2350,6 +2346,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2393,19 +2393,6 @@ msgstr "Radika nodo estas necesita por konservi la scenon." msgid "Save Scene As..." msgstr "Konservi sceno kiel..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ne" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Jes" - -#: editor/editor_node.cpp -#, fuzzy -msgid "This scene has never been saved. Save before running?" -msgstr "Ĉi tiu sceno konservis neniam. Konservi antaÅ ruli?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp #, fuzzy msgid "This operation can't be done without a scene." @@ -2458,6 +2445,10 @@ msgid "Quit" msgstr "Foriri" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Jes" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Eliri la editilo?" @@ -2500,7 +2491,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2920,14 +2911,6 @@ msgid "Help" msgstr "Helpo" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Serĉo" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp #, fuzzy msgid "Online Docs" @@ -3084,6 +3067,22 @@ msgid "Open & Run a Script" msgstr "Malfermi & ruli skripto" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3288,7 +3287,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4933,7 +4932,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5068,8 +5067,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5083,9 +5081,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6150,6 +6167,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6211,10 +6232,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6797,6 +6814,14 @@ msgstr "" msgid "Run" msgstr "Ruli" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Serĉo" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6849,16 +6874,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6951,8 +6966,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7174,6 +7189,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9718,6 +9737,10 @@ msgid "Projects" msgstr "Projektoj" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp #, fuzzy msgid "Last Modified" msgstr "Modifita" @@ -10323,6 +10346,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Skali Elektaron" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Krei skripton" @@ -10447,6 +10479,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11239,6 +11275,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11744,11 +11808,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11760,11 +11826,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11772,9 +11838,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12166,27 +12242,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12246,6 +12322,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12459,6 +12539,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12504,6 +12588,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Nevalida fonto por ombrigilo." @@ -12533,6 +12623,13 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstantoj ne povas esti modifitaj." +#~ msgid "No" +#~ msgstr "Ne" + +#, fuzzy +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ĉi tiu sceno konservis neniam. Konservi antaÅ ruli?" + #~ msgid "Search complete" #~ msgstr "Serĉo finiÄis" diff --git a/editor/translations/es.po b/editor/translations/es.po index 38f16e8da7..20a252e6a4 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -14,11 +14,11 @@ # Diego López <diegodario21@gmail.com>, 2017. # eon-s <emanuel.segretin@gmail.com>, 2018, 2019, 2020. # Gustavo Leon <gleondiaz@gmail.com>, 2017-2018. -# Javier Ocampos <xavier.ocampos@gmail.com>, 2018, 2019, 2020. +# Javier Ocampos <xavier.ocampos@gmail.com>, 2018, 2019, 2020, 2021. # Jose Maria Martinez <josemar1992@hotmail.com>, 2018. # Juan Quiroga <juanquiroga9@gmail.com>, 2017. # Kiji Pixel <raccoon.fella@gmail.com>, 2017. -# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017, 2019, 2020. +# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017, 2019, 2020, 2021. # Lonsfor <lotharw@protonmail.com>, 2017-2018. # Mario Nachbaur <manachbaur@gmail.com>, 2018. # Oscar Carballal <oscar.carballal@protonmail.com>, 2017-2018. @@ -55,12 +55,16 @@ # Skarline <lihue-molina@hotmail.com>, 2020. # Oxixes <oxixes@protonmail.com>, 2020. # David Aroca Rojas <arocarojasdavid@gmail.com>, 2020. +# Ricardo Pérez <ricpelo@gmail.com>, 2021. +# A <kaieltroll@gmail.com>, 2021. +# Lucasdelpiero <lucasdelpiero98@gmail.com>, 2021. +# SteamGoblin <SteamGoblin860@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" -"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" +"Last-Translator: SteamGoblin <SteamGoblin860@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -68,7 +72,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -704,7 +708,7 @@ msgstr "Selecciona las Pistas a Copiar" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copiar" @@ -2009,10 +2013,6 @@ msgstr "Vista Previa:" msgid "File:" msgstr "Archivo:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Debe tener una extensión válida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Escanear Fuentes" @@ -2451,6 +2451,10 @@ msgid "There is no defined scene to run." msgstr "No hay escena definida para ejecutar." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Guarda escena antes de ejecutar..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "¡No se pudo comenzar el subproceso!" @@ -2494,19 +2498,6 @@ msgstr "Se necesita un nodo raÃz para guardar la escena." msgid "Save Scene As..." msgstr "Guardar Escena Como..." -#: editor/editor_node.cpp -msgid "No" -msgstr "No" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "SÃ" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" -"Esta escena nunca se ha guardado. ¿Quieres guardarla antes de ejecutarla?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Esta operación no puede realizarse sin una escena." @@ -2557,6 +2548,10 @@ msgid "Quit" msgstr "Salir" #: editor/editor_node.cpp +msgid "Yes" +msgstr "SÃ" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "¿Salir del editor?" @@ -2605,7 +2600,8 @@ msgstr "" "configuración de '%s'." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "No se pudo encontrar el campo del script para el plugin addon en: 'res://" "addons/%s'." @@ -3045,14 +3041,6 @@ msgid "Help" msgstr "Ayuda" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Buscar" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentación Online" @@ -3220,6 +3208,25 @@ msgid "Open & Run a Script" msgstr "Abrir y Ejecutar un Script" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Los siguientes archivos son nuevos en disco.\n" +"¿Qué es lo que quieres hacer?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Recargar" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Volver a Guardar" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nueva Escena Heredada" @@ -3431,7 +3438,7 @@ msgstr "Hacer Único" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Pegar" @@ -3994,19 +4001,16 @@ msgid "Searching..." msgstr "Buscando..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d coincidencias." +msgstr "%d coincidencias en el archivo %d." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d coincidencias." +msgstr "%d coincidencias en el archivo %d." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d coincidencias." +msgstr "%d coincidencias en %d archivos." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5115,7 +5119,8 @@ msgid "Got:" msgstr "Tiene:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Fallo en la comprobación del hash sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5250,12 +5255,11 @@ msgstr "Archivo ZIP de elementos" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"No se puede encontrar una ruta válida para las imágenes \"lightmap\".\n" -"Guarda la escena (para que las imágenes se guarden en el mismo directorio), " -"o selecciona otra ruta desde las propiedades del \"BackedLightmap\"." +"No se puede determinar una ruta de guardado para las imágenes de los " +"lightmaps.\n" +"Guarda tu escena e inténtalo de nuevo." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5272,9 +5276,34 @@ msgstr "" "escribir en la ruta." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Falló al determinar el tamaño del lightmap ¿El tamaño máximo del lightmap es " +"demasiado pequeño?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Alguna malla es inválida. Asegúrate de que los valores del canal de UV2 " +"están contenidos dentro de la región cuadrangular [0,0,1,0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"El editor de Godot se construyó sin soporte de trazado de rayos, los " +"lightmaps no pueden ser bakeados." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Bake Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Selecciona un archivo lightmap bakeado:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6377,6 +6406,10 @@ msgstr "" "Solo se puede asignar un punto a un material de procesado ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Convertir a CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Tiempo de Generación (seg):" @@ -6437,10 +6470,6 @@ msgstr "Generando AABB" msgid "Generate Visibility AABB" msgstr "Generar AABB de visibilidad" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Generar AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Borrar Punto de la Curva" @@ -7032,6 +7061,14 @@ msgstr "Cerrar Documentación" msgid "Run" msgstr "Ejecutar" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Buscar" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Entrar En" @@ -7085,16 +7122,6 @@ msgstr "" "Los siguientes archivos son nuevos en disco.\n" "¿Qué es lo que quieres hacer?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Recargar" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Volver a Guardar" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Depurador" @@ -7190,8 +7217,8 @@ msgstr "Breakpoints" msgid "Go To" msgstr "Ir A" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Cortar" @@ -7411,7 +7438,11 @@ msgstr "Altura" #: editor/plugins/spatial_editor_plugin.cpp msgid "Yaw" -msgstr "Yaw" +msgstr "Guiñada" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Tamaño" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" @@ -9747,7 +9778,7 @@ msgstr "Script" #: editor/project_export.cpp msgid "Script Export Mode:" -msgstr "Modo de Exportación de Scipts:" +msgstr "Modo de exportación de scripts:" #: editor/project_export.cpp msgid "Text" @@ -10106,6 +10137,11 @@ msgid "Projects" msgstr "Proyectos" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Obteniendo mirrors, por favor espera..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Ultima Modificación" @@ -10726,6 +10762,16 @@ msgid "Instance Child Scene" msgstr "Instanciar Escena Hija" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "¡No se puede operar sobre los nodos de una escena externa!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Pegar Nodos" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Sustraer Script" @@ -10853,6 +10899,11 @@ msgid "Attach Script" msgstr "Añadir Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Cortar Nodos" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Eliminar Nodo(s)" @@ -11664,6 +11715,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "Proporciona un recurso MeshLibrary a este GridMap para usar sus mallas." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Empezar a Bakear" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Preparar estructuras de datos" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Generar buffers" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Iluminación directa" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Iluminación indirecta" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Post procesado" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Trazar lightmaps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "El nombre de la clase no puede ser una palabra reservada" @@ -12182,12 +12261,16 @@ msgid "Select device from the list" msgstr "Seleccionar dispositivo de la lista" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Ejecutable ADB no configurado en Configuración del Editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "No se pudo encontrar la herramienta 'apksigner'." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner no configurado en Configuración del Editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"La plantilla de exportación de Android no esta instalada en el proyecto. " +"Instalala desde el menú de Proyecto." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12201,28 +12284,40 @@ msgstr "" "exportación." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"La compilación personalizada requiere una ruta de Android SDK válida en " -"Configuración del Editor." +"Se requiere una ruta válida del SDK de Android en la Configuración del " +"Editor." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Ruta del SDK de Android inválida para la compilación personalizada en " -"Configuración del Editor." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Ruta del SDK de Android inválida en la Configuración del Editor." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "¡No se encontró el directorio 'platform-tools'!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" -"La plantilla de exportación de Android no esta instalada en el proyecto. " -"Instalala desde el menú de Proyecto." +"No se pudo encontrar el comando adb de las herramientas de la plataforma SDK " +"de Android." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Por favor, comprueba el directorio del SDK de Android especificado en la " +"Configuración del Editor." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "¡No se encontró el directorio 'build-tools'!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" +"No se pudo encontrar el comando apksigner de las herramientas de " +"construcción del SDK de Android." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12707,28 +12802,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin requiere un nodo hijo ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Encontrando mallas y luces" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Tiempo restante: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Preparando geometrÃa (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Trazando Mallas: " +msgid "Preparing environment" +msgstr "Preparar entorno" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Trazando Iluminación:" +msgid "Generating capture" +msgstr "Generar captura" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Finalizar Trazado" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Guardar lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Iluminación de Mallas: " +msgid "Done" +msgstr "Hecho" #: scene/3d/collision_object.cpp msgid "" @@ -12804,6 +12899,10 @@ msgid "Plotting Meshes" msgstr "Trazando Mallas" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Finalizar Trazado" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13066,10 +13165,13 @@ msgstr "¡Alerta!" msgid "Please Confirm..." msgstr "Por favor, Confirma..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Debe tener una extensión válida." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Activar Snap" +msgstr "Activar minimapa de cuadrÃcula." #: scene/gui/popup.cpp msgid "" @@ -13127,6 +13229,14 @@ msgstr "" "cosa." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"El puerto de muestreo está conectado, pero no se utiliza. Considera la " +"posibilidad de cambiar la fuente a \"SamplerPort\"." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fuente inválida para la vista previa." @@ -13154,6 +13264,36 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice." msgid "Constants cannot be modified." msgstr "Las constantes no pueden modificarse." +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Esta escena nunca se ha guardado. ¿Quieres guardarla antes de ejecutarla?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Ejecutable ADB no configurado en Configuración del Editor." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner no configurado en Configuración del Editor." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "La compilación personalizada requiere una ruta de Android SDK válida en " +#~ "Configuración del Editor." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Tiempo restante: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Trazando Mallas: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Iluminación de Mallas: " + #~ msgid "Search complete" #~ msgstr "Búsqueda completa" @@ -13166,12 +13306,6 @@ msgstr "Las constantes no pueden modificarse." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "Ya hay un archivo o carpeta con el mismo nombre en esta ubicación." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "¡No se encontró el directorio 'build-tools'!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "No se pudo encontrar la herramienta zipalign." - #~ msgid "Aligning APK..." #~ msgstr "Alineando APK..." @@ -13516,9 +13650,6 @@ msgstr "Las constantes no pueden modificarse." #~ msgid "Failed to save solution." #~ msgstr "Fallo al guardar solución." -#~ msgid "Done" -#~ msgstr "Hecho" - #~ msgid "Failed to create C# project." #~ msgstr "Fallo al crear proyecto C#." diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 2a736acee0..a95f85e753 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -3,7 +3,7 @@ # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. # Diego López <diegodario21@gmail.com>, 2017. -# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018, 2019, 2020. +# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018, 2019, 2020, 2021. # Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018. # Sebastian Silva <sebastian@sugarlabs.org>, 2016. # Jose Luis Bossio <joseluisbossio@gmail.com>, 2018. @@ -21,8 +21,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-29 15:03+0000\n" -"Last-Translator: Skarline <lihue-molina@hotmail.com>\n" +"PO-Revision-Date: 2021-02-21 10:50+0000\n" +"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" "Language: es_AR\n" @@ -30,7 +30,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -664,7 +664,7 @@ msgstr "Elegir Pistas a Copiar" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copiar" @@ -1165,19 +1165,19 @@ msgstr "Autores" #: editor/editor_about.cpp msgid "Platinum Sponsors" -msgstr "Sponsor Platino" +msgstr "Sponsors Platino" #: editor/editor_about.cpp msgid "Gold Sponsors" -msgstr "Sponsor Oro" +msgstr "Sponsors Oro" #: editor/editor_about.cpp msgid "Silver Sponsors" -msgstr "Patrocinadores Nivel Plata" +msgstr "Sponsors Plata" #: editor/editor_about.cpp msgid "Bronze Sponsors" -msgstr "Patrocinadores Nivel Bronce" +msgstr "Sponsors Bronce" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -1632,7 +1632,8 @@ msgid "" "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" "La plataforma de destino requiere compresión de texturas 'ETC2' o 'PVRTC' " -"para GLES3. Activá 'Import Etc 2' o 'Import Pvrtc' en Ajustes del Proyecto." +"para GLES3. Activá 'Importar Etc 2' o 'Importar Pvrtc' en Ajustes del " +"Proyecto." #: editor/editor_export.cpp msgid "" @@ -1967,10 +1968,6 @@ msgstr "Vista Previa:" msgid "File:" msgstr "Archivo:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Debe ser una extensión válida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Escanear Fuentes" @@ -2228,7 +2225,7 @@ msgstr "OK" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" -msgstr "Error al guardar el recurso!" +msgstr "¡Error al guardar el recurso!" #: editor/editor_node.cpp msgid "" @@ -2261,7 +2258,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "Error parsear '%s'." +msgstr "Error al parsear '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." @@ -2410,6 +2407,10 @@ msgid "There is no defined scene to run." msgstr "No hay escena definida para ejecutar." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Guardar escena antes de ejecutar..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "No se pudo comenzar el subproceso!" @@ -2453,18 +2454,6 @@ msgstr "Se necesita un nodo raÃz para guardar la escena." msgid "Save Scene As..." msgstr "Guardar Escena Como..." -#: editor/editor_node.cpp -msgid "No" -msgstr "No" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Si" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Esta escena nunca ha sido guardada. Guardar antes de ejecutar?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Esta operación no puede hacerse sin una escena." @@ -2515,6 +2504,10 @@ msgid "Quit" msgstr "Salir" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Si" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Salir del editor?" @@ -2563,7 +2556,8 @@ msgstr "" "configuración." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "No se pudo encontrar el campo script para el plugin de addon en: 'res://" "addons/%s'." @@ -2890,7 +2884,7 @@ msgstr "" "El sistema de archivos será proporcionado desde el proyecto por el editor a " "través de la red.\n" "En Android, el deploy usará el cable USB para un rendimiento más rápido. " -"Esta opción acelera las pruebas de los proyectos con recursos grandes." +"Esta opción acelera el testeo de los proyectos con recursos grandes." #: editor/editor_node.cpp msgid "Visible Collision Shapes" @@ -3001,14 +2995,6 @@ msgid "Help" msgstr "Ayuda" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Buscar" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentación Online" @@ -3176,6 +3162,24 @@ msgid "Open & Run a Script" msgstr "Abrir y Correr un Script" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Los siguientes archivos son nuevos en disco.\n" +"¿Qué acción se deberÃa tomar?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Volver a Cargar" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Volver a Guardar" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nuevo Heredado" @@ -3386,7 +3390,7 @@ msgstr "Convertir en Unico" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Pegar" @@ -3949,19 +3953,16 @@ msgid "Searching..." msgstr "Buscando..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d coincidencias." +msgstr "%d coincidencia en %d archivo." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d coincidencias." +msgstr "%d coincidencias en %d archivo." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d coincidencias." +msgstr "%d coincidencias en %d archivos." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5070,7 +5071,8 @@ msgid "Got:" msgstr "Recibido:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Fallo el chequeo del hash sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5205,12 +5207,11 @@ msgstr "Archivo ZIP de Assets" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"No se pudo determinar una ruta de guardado para las imagenes de lightmap.\n" -"Guardá tu escena (para imagenes a ser guardadas en el mismo directorio), o " -"elegà una ruta de guardado desde las propiedades de BakedLightmap." +"No se puede determinar una ruta de guardado para las imágenes de los " +"lightmaps.\n" +"Guardá tu escena e inténtalo de nuevo." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5227,9 +5228,34 @@ msgstr "" "escritura." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Falló al determinar el tamaño del lightmap ¿El tamaño máximo de lightmap es " +"demasiado pequeño?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Alguna malla es inválida. Asegurate de que los valores del canal UV2 estén " +"contenidos dentro de la región cuadrada [0,0,1,0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"El editor de Godot se compiló sin soporte de ray tracing, los lightmaps no " +"pueden ser bakeados." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Bake Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Selecciona un archivo de lightmap bakeado:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6326,6 +6352,10 @@ msgstr "" "Solo se puede setear un punto en un material de proceso ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Convertir a CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Tiempo de Generación (seg):" @@ -6386,10 +6416,6 @@ msgstr "Generando AABB" msgid "Generate Visibility AABB" msgstr "Generar AABB de Visibilidad" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Generar AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Remover Punto de Curva" @@ -6981,6 +7007,14 @@ msgstr "Cerrar Docs" msgid "Run" msgstr "Ejecutar" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Buscar" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Step Into" @@ -7034,16 +7068,6 @@ msgstr "" "Los siguientes archivos son nuevos en disco.\n" "¿Qué acción se deberÃa tomar?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Volver a Cargar" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Volver a Guardar" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Depurador" @@ -7139,8 +7163,8 @@ msgstr "Puntos de interrupción" msgid "Go To" msgstr "Ir A" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Cortar" @@ -7363,6 +7387,10 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Tamaño" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Dibujados" @@ -10054,6 +10082,10 @@ msgid "Projects" msgstr "Proyectos" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Cargando, esperá, por favor..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Ultima Modificación" @@ -10674,6 +10706,16 @@ msgid "Instance Child Scene" msgstr "Instanciar Escena Hija" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "No se puede operar sobre los nodos de una escena externa!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Pegar Nodos" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Desasignar Script" @@ -10802,6 +10844,11 @@ msgid "Attach Script" msgstr "Adjuntar Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Cortar Nodos" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Quitar Nodo(s)" @@ -11611,6 +11658,34 @@ msgstr "Filtrar meshes" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Asignar un recurso MeshLibrary a este GridMap para usar sus meshes." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Iniciar Bake" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Preparando estructuras de datos" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Generar buffers" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Iluminación directa" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Iluminación indirecta" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Post procesado" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Trazando lightmatps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "El nombre de la clase no puede ser una palabra reservada" @@ -12128,12 +12203,16 @@ msgid "Select device from the list" msgstr "Seleccionar dispositivo de la lista" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Ejecutable ADB no configurado en Configuración del Editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "No se pudo encontrar la herramienta 'apksigner'." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner no configurado en Configuración del Editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"La plantilla de exportación de Android no esta instalada en el proyecto. " +"Instalala desde el menú de Proyecto." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12147,28 +12226,36 @@ msgstr "" "exportación." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"La compilación personalizada requiere una ruta de Android SDK válida en " -"Configuración del Editor." +"Se requiere una ruta válida al SDK de Android en la Configuración del Editor." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Ruta del SDK de Android inválida para la compilación personalizada en " -"Configuración del Editor." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Ruta del SDK de Android inválida en la Configuración del Editor." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "¡No se encontró el directorio 'platform-tools'!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "No se pudo encontrar el comando adb en las Android SDK platform-tools." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"La plantilla de exportación de Android no esta instalada en el proyecto. " -"Instalala desde el menú de Proyecto." +"Por favor, comprueba el directorio del SDK de Android especificado en la " +"Configuración del Editor." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "¡No se encontró el directorio 'build-tools'!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" +"No se pudo encontrar el comando apksigner en las Android SDK build-tools." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12650,28 +12737,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin requiere un nodo hijo ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Encontrar mallas y luces" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Tiempo Restante: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Preparando geometrÃa (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Trazando Meshes: " +msgid "Preparing environment" +msgstr "Preparando entorno" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Trazando Luces:" +msgid "Generating capture" +msgstr "Generando capturas" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Finalizar Trazado" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Guardando lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Iluminando Meshes: " +msgid "Done" +msgstr "Hecho" #: scene/3d/collision_object.cpp msgid "" @@ -12747,6 +12834,10 @@ msgid "Plotting Meshes" msgstr "Trazando Meshes" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Finalizar Trazado" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13007,10 +13098,13 @@ msgstr "Alerta!" msgid "Please Confirm..." msgstr "Confirmá, por favor..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Debe ser una extensión válida." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Activar Ajuste" +msgstr "Activar minimapa de grilla." #: scene/gui/popup.cpp msgid "" @@ -13065,6 +13159,14 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "El tamaño del viewport debe ser mayor a 0 para poder renderizar." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"El puerto de muestreo está conectado, pero no se utiliza. Considerá la " +"posibilidad de cambiar la fuente a \"SamplerPort\"." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fuente inválida para la vista previa." @@ -13092,6 +13194,35 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice." msgid "Constants cannot be modified." msgstr "Las constantes no pueden modificarse." +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Esta escena nunca ha sido guardada. Guardar antes de ejecutar?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Ejecutable ADB no configurado en Configuración del Editor." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner no configurado en Configuración del Editor." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "La compilación personalizada requiere una ruta de Android SDK válida en " +#~ "Configuración del Editor." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Tiempo Restante: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Trazando Meshes: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Iluminando Meshes: " + #~ msgid "Search complete" #~ msgstr "Búsqueda completa" @@ -13441,9 +13572,6 @@ msgstr "Las constantes no pueden modificarse." #~ msgid "Failed to save solution." #~ msgstr "No se pudo guardar la solución." -#~ msgid "Done" -#~ msgstr "Hecho" - #~ msgid "Failed to create C# project." #~ msgstr "No se pudo crear el proyecto en C#" diff --git a/editor/translations/et.po b/editor/translations/et.po index 0c8f6e7de6..e6f2c1aac4 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -4,20 +4,21 @@ # This file is distributed under the same license as the Godot source code. # Jens <arrkiin@gmail.com>, 2019. # Mattias Aabmets <mattias.aabmets@gmail.com>, 2019. -# StReef <streef.gtx@gmail.com>, 2020. +# StReef <streef.gtx@gmail.com>, 2020, 2021. # René <renepiik@gmail.com>, 2020. +# Kritzmensch <streef.gtx@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2020-12-02 09:52+0000\n" -"Last-Translator: StReef <streef.gtx@gmail.com>\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" +"Last-Translator: Kritzmensch <streef.gtx@gmail.com>\n" "Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/" "godot/et/>\n" "Language: et\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -634,7 +635,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopeeri" @@ -1126,14 +1127,12 @@ msgid "Gold Sponsors" msgstr "Kuldsponsorid" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "Hõbennetajad" +msgstr "Hõbesponsorid" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "Pronksannetajad" +msgstr "Pronkssponsorid" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -1278,11 +1277,11 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "Solo" -msgstr "" +msgstr "Soolo" #: editor/editor_audio_buses.cpp msgid "Mute" -msgstr "" +msgstr "Vaigista" #: editor/editor_audio_buses.cpp msgid "Bypass" @@ -1299,7 +1298,7 @@ msgstr "Duplikeeri" #: editor/editor_audio_buses.cpp msgid "Reset Volume" -msgstr "" +msgstr "Lähtesta valjus" #: editor/editor_audio_buses.cpp msgid "Delete Effect" @@ -1327,7 +1326,7 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "" +msgstr "Lähtesta siini valjus" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" @@ -1633,7 +1632,7 @@ msgstr "Skriptiredaktor" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "" +msgstr "Vadade kogum" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" @@ -1808,7 +1807,7 @@ msgstr "Värskenda" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" -msgstr "" +msgstr "Kõik tuvastatud" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" @@ -1895,11 +1894,11 @@ msgstr "Värskenda faile." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." -msgstr "" +msgstr "Lisa praegune kaust lemmikute sekka." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle the visibility of hidden files." -msgstr "" +msgstr "Näita peidetud faile." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1923,10 +1922,6 @@ msgstr "Eelvaade:" msgid "File:" msgstr "Fail:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Peab kasutama kehtivat laiendit." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2337,6 +2332,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2380,25 +2379,13 @@ msgstr "" msgid "Save Scene As..." msgstr "Salvesta stseen kui..." -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "Ekspordi võrgu kogum" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." @@ -2439,6 +2426,10 @@ msgid "Quit" msgstr "Välju" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Välju redaktorist?" @@ -2481,8 +2472,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." -msgstr "" +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "Lisa-skripti ei olnud võimalik laadida teelt: '%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." @@ -2745,7 +2737,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "" +msgstr "Välju ja kuva projektide loetelu" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp @@ -2801,9 +2793,8 @@ msgid "" msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Synchronize Scene Changes" -msgstr "Pinna muutused" +msgstr "Sünkroniseeri stseeni muudatused" #: editor/editor_node.cpp msgid "" @@ -2879,14 +2870,6 @@ msgid "Help" msgstr "Abi" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Otsi" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Veebidokumentatsioonid" @@ -3033,13 +3016,29 @@ msgstr "" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "" +msgstr "Liida olemasolevaga" #: editor/editor_node.cpp msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3242,7 +3241,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -3324,7 +3323,7 @@ msgstr "" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "Stseeni tee:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" @@ -4870,7 +4869,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4963,7 +4962,7 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Import..." -msgstr "" +msgstr "Impordi..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Plugins..." @@ -5005,8 +5004,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5020,9 +5018,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6078,6 +6095,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6138,10 +6159,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6723,13 +6740,21 @@ msgstr "" msgid "Run" msgstr "Käivita" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Otsi" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "" +msgstr "Trepi sissepoole" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" -msgstr "" +msgstr "Trepi üle" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" @@ -6774,16 +6799,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Siluja" @@ -6869,15 +6884,15 @@ msgstr "" #: editor/plugins/script_text_editor.cpp msgid "Breakpoints" -msgstr "" +msgstr "Katkepunktid" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -6977,19 +6992,19 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "" +msgstr "Lülita katkepunkt sisse/välja" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" -msgstr "" +msgstr "Eemalda kõik katkepunktid" #: editor/plugins/script_text_editor.cpp msgid "Go to Next Breakpoint" -msgstr "" +msgstr "Liigu järgmise katkepunkti juurde" #: editor/plugins/script_text_editor.cpp msgid "Go to Previous Breakpoint" -msgstr "" +msgstr "Naase eelmise katkepunkti juurde" #: editor/plugins/shader_editor_plugin.cpp msgid "" @@ -7098,6 +7113,10 @@ msgid "Yaw" msgstr "Sagitaal" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekte kuvatud" @@ -7187,7 +7206,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" -msgstr "" +msgstr "Lukusta vaateakna pöördenurk" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Normal" @@ -7275,7 +7294,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Rotation Locked" -msgstr "" +msgstr "Vaateakna pöördenurk on lukustatud" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -9571,12 +9590,17 @@ msgid "" "Please edit the project and set the main scene in the Project Settings under " "the \"Application\" category." msgstr "" +"Projekti ei saa käivitada: peastseeni ei ole määratud.\n" +"Redigeerige project.godot faili ja määrake projekti peastseen \"application" +"\" alajaotuses." #: editor/project_manager.cpp msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" +"Projekti ei saa käivitada: varad tuleb importida.\n" +"Redigeerige projekti käivitama algset importimise protsessi." #: editor/project_manager.cpp msgid "Are you sure to run %d projects at once?" @@ -9622,6 +9646,10 @@ msgid "Projects" msgstr "Projektid" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -9639,7 +9667,7 @@ msgstr "Uus projekt" #: editor/project_manager.cpp msgid "Remove Missing" -msgstr "" +msgstr "Eemalda puuduvad" #: editor/project_manager.cpp msgid "Templates" @@ -9651,7 +9679,7 @@ msgstr "" #: editor/project_manager.cpp msgid "Can't run project" -msgstr "" +msgstr "Projekti ei saa käivitada" #: editor/project_manager.cpp msgid "" @@ -10225,6 +10253,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Kustuta sõlm(ed)" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10346,6 +10383,11 @@ msgid "Attach Script" msgstr "Manusta skript" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Kustuta sõlm(ed)" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -10724,7 +10766,7 @@ msgstr "Videomälu" #: editor/script_editor_debugger.cpp msgid "Skip Breakpoints" -msgstr "" +msgstr "Jäta katkepunktid vahele" #: editor/script_editor_debugger.cpp msgid "Inspect Previous Instance" @@ -10740,11 +10782,11 @@ msgstr "Virnakaadrid" #: editor/script_editor_debugger.cpp msgid "Profiler" -msgstr "" +msgstr "Profileerija" #: editor/script_editor_debugger.cpp msgid "Network Profiler" -msgstr "" +msgstr "Võrgu profileerija" #: editor/script_editor_debugger.cpp msgid "Monitor" @@ -10780,7 +10822,7 @@ msgstr "Ressursi tee" #: editor/script_editor_debugger.cpp msgid "Type" -msgstr "" +msgstr "Tüüp" #: editor/script_editor_debugger.cpp msgid "Format" @@ -10813,7 +10855,7 @@ msgstr "" #: editor/script_editor_debugger.cpp #, fuzzy msgid "Export measures as CSV" -msgstr "Ekspordi mõõtmed/meetmed CSV-vormingus" +msgstr "Ekspordi mõõtmed CSV-vormingus" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -11131,6 +11173,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11626,11 +11696,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11642,11 +11714,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11654,9 +11726,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12047,27 +12129,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "" +#, fuzzy +msgid "Preparing environment" +msgstr "Kuva keskkond" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12127,6 +12210,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12340,6 +12427,10 @@ msgstr "" msgid "Please Confirm..." msgstr "Palun kinnita..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Peab kasutama kehtivat laiendit." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12385,6 +12476,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Vaateakne suurus peab olema suurem kui 0, et kuvada." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Vigane eelvaate lähe." diff --git a/editor/translations/eu.po b/editor/translations/eu.po index dff34d3f00..ef200e15d6 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -626,7 +626,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1896,10 +1896,6 @@ msgstr "Aurrebista:" msgid "File:" msgstr "Fitxategia:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Baliozko luzapena erabili behar du." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2303,6 +2299,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2346,18 +2346,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2406,6 +2394,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2448,7 +2440,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2838,14 +2830,6 @@ msgid "Help" msgstr "Laguntza" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Bilatu" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Lineako dokumentuak" @@ -2999,6 +2983,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3201,7 +3201,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4835,7 +4835,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4970,8 +4970,7 @@ msgstr "Aktiboen ZIP fitxategia" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4985,9 +4984,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Hautatu txantiloi fitxategia" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6043,6 +6062,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6103,10 +6126,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6688,6 +6707,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Bilatu" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6739,16 +6766,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6841,8 +6858,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7063,6 +7080,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9587,6 +9608,13 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "" +"Fitxategiak arakatzen,\n" +"Itxaron mesedez..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10193,6 +10221,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Scripta" @@ -10314,6 +10350,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11100,6 +11140,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11595,11 +11663,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11611,11 +11681,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11623,9 +11693,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12016,27 +12096,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12096,6 +12176,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12309,6 +12393,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Baliozko luzapena erabili behar du." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -12355,6 +12443,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index a97774e993..29d3139e9c 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -658,7 +658,7 @@ msgstr "انتخاب میسرها جهت تکثیر" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Ú©Ù¾ÛŒ" @@ -1938,10 +1938,6 @@ msgstr "" msgid "File:" msgstr "پرونده:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "باید یک پسوند معتبر بکار گیرید." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2345,6 +2341,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2388,18 +2388,6 @@ msgstr "" msgid "Save Scene As..." msgstr "ذخیره صØÙ†Ù‡ در ..." -#: editor/editor_node.cpp -msgid "No" -msgstr "نه" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "بله" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "این صØÙ†Ù‡ هرگز ذخیره نشده است. ذخیره قبل از اجرا؟" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "این عملیات بدون یک صØÙ†Ù‡ انجام نمی شود." @@ -2447,6 +2435,10 @@ msgid "Quit" msgstr "خروج" #: editor/editor_node.cpp +msgid "Yes" +msgstr "بله" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "خروج از ویرایشگر؟" @@ -2489,8 +2481,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." -msgstr "" +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "امکان بارگیری اسکریپت Ø§ÙØ²ÙˆÙ†Ù‡ از مسیر وجود ندارد: '%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." @@ -2887,14 +2880,6 @@ msgid "Help" msgstr "راهنما" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "جستجو" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3054,6 +3039,23 @@ msgid "Open & Run a Script" msgstr "گشودن Ùˆ اجرای یک اسکریپت" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "استخراج پرونده های زیر از بسته بندی انجام نشد:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "وارث جدید" @@ -3266,7 +3268,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "چسباندن" @@ -5011,7 +5013,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5156,8 +5158,7 @@ msgstr "ÙØ§ÛŒÙ„ های ZIP‌ منابع بازی" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5171,9 +5172,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "انتخاب پرونده قالب" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6280,6 +6301,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "اتصال به گره:" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6340,10 +6366,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6962,6 +6984,14 @@ msgstr "" msgid "Run" msgstr "اجرا" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "جستجو" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7016,16 +7046,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7126,8 +7146,8 @@ msgstr "ØØ°Ù Ú©Ù†" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "برش" @@ -7367,6 +7387,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10047,6 +10071,11 @@ msgid "Projects" msgstr "Ø·Ø±Ø Ù‡Ø§" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "بارگیری" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10683,6 +10712,15 @@ msgid "Instance Child Scene" msgstr "ارث‌بری صØÙ†Ù‡Ù” ÙØ±Ø²Ù†Ø¯" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "مسیر به سمت گره:" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "پیوست کردن اسکریپت" @@ -10814,6 +10852,11 @@ msgid "Attach Script" msgstr "پیوست کردن اسکریپت" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "ساختن گره" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "ØØ°Ù گره(ها)" @@ -11665,6 +11708,36 @@ msgstr "ØØ§Ù„ت صاÙÛŒ:" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "توضیØ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "انتقال را در انیمیشن تغییر بده" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12204,11 +12277,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12220,11 +12295,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12232,9 +12307,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12674,27 +12759,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12765,6 +12850,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12996,6 +13085,10 @@ msgstr "هشدار!" msgid "Please Confirm..." msgstr "Ù„Ø·ÙØ§Ù‹ تأیید کنید…" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "باید یک پسوند معتبر بکار گیرید." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -13049,6 +13142,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "اندازهٔ قلم نامعتبر." @@ -13079,6 +13178,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "ثوابت قابل تغییر نیستند." +#~ msgid "No" +#~ msgstr "نه" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "این صØÙ†Ù‡ هرگز ذخیره نشده است. ذخیره قبل از اجرا؟" + #, fuzzy #~ msgid "Search complete" #~ msgstr "جستجوی متن" @@ -13276,10 +13381,6 @@ msgstr "ثوابت قابل تغییر نیستند." #~ msgstr "ساختن پوشه" #, fuzzy -#~ msgid "Custom Node" -#~ msgstr "ساختن گره" - -#, fuzzy #~ msgid "Invalid Path" #~ msgstr "مسیر نامعتبر." diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 4ff9685447..16daaed9b0 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -8,14 +8,14 @@ # Jarmo Riikonen <amatrelan@gmail.com>, 2017. # Nuutti Varvikko <nvarvikko@gmail.com>, 2018. # Sami Lehtilä <sami.lehtila@gmail.com>, 2018. -# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020. +# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021. # Tuomas Lähteenmäki <lahtis@gmail.com>, 2019. # Matti Niskanen <matti.t.niskanen@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -24,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -648,7 +648,7 @@ msgstr "Valitse kopioitavat raidat" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopioi" @@ -1949,10 +1949,6 @@ msgstr "Esikatselu:" msgid "File:" msgstr "Tiedosto:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Käytä sopivaa tiedostopäätettä." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Selaa lähdetiedostoja" @@ -2387,6 +2383,10 @@ msgid "There is no defined scene to run." msgstr "Suoritettavaa skeneä ei ole määritetty." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Tallenna skene ennen ajamista..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Aliprosessia ei voitu käynnistää!" @@ -2430,18 +2430,6 @@ msgstr "Skenen tallentaminen edellyttää, että sillä on juurisolmu." msgid "Save Scene As..." msgstr "Tallenna skene nimellä..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ei" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Kyllä" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Tätä skeneä ei ole koskaan tallennettu. Tallenna ennen suorittamista?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Tätä toimintoa ei voi tehdä ilman skeneä." @@ -2492,6 +2480,10 @@ msgid "Quit" msgstr "Lopeta" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Kyllä" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Poistu editorista?" @@ -2538,7 +2530,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "Lisäosan '%s' aktivointi epäonnistui, virheellinen asetustiedosto." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Skriptikenttää ei löytynyt lisäosan tiedostosta: 'res://addons/%s'." #: editor/editor_node.cpp @@ -2965,14 +2958,6 @@ msgid "Help" msgstr "Ohje" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Hae" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Dokumentaatio" @@ -3137,6 +3122,24 @@ msgid "Open & Run a Script" msgstr "Avaa ja suorita skripti" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Seuraavat tiedostot ovat uudempia levyllä.\n" +"Mikä toimenpide tulisi suorittaa?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Lataa uudelleen" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Tallenna uudelleen" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Uusi peritty skene" @@ -3348,7 +3351,7 @@ msgstr "Tee yksilölliseksi" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Liitä" @@ -3906,19 +3909,16 @@ msgid "Searching..." msgstr "Haetaan..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d osumaa." +msgstr "%d osuma %d tiedostossa." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d osumaa." +msgstr "%d osumaa %d tiedostossa." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d osumaa." +msgstr "%d osumaa %d tiedostossa." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5025,7 +5025,8 @@ msgid "Got:" msgstr "Saatiin:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "sha256-hajautusarvon tarkistus epäonnistui" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5160,12 +5161,10 @@ msgstr "Assettien zip-tiedosto" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Lightmap-kuvien tallennuspolun määrittäminen ei onnistu.\n" -"Tallenna skenesi (jotta kuvat tallentuisivat samaan hakemistoon), tai " -"valitse tallennuspolku BakedLightmapin asetuksista." +"Tallenna skenesi ja yritä uudelleen." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5182,9 +5181,34 @@ msgstr "" "kirjoituskelpoinen." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Lightmapin koon määrittäminen epäonnistui. Suurin lightmapin koko liian " +"pieni?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Jokin mesh on virheellinen. Varmista, että UV2-kanavan arvot ovat [0.0, 1.0] " +"välisen neliön alueella." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Godot-editori on käännetty ilman ray tracing -tukea, joten lightmappeja ei " +"voi kehittää." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Kehitä Lightmapit" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Valitse lightmapin kehitystiedosto:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6279,6 +6303,10 @@ msgstr "" "Piste voidaan asettaa ainoastaan ParticlesMaterial käsittelyn materiaaliin" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Muunna CPUParticles2D solmuksi" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Luontiaika (s):" @@ -6339,10 +6367,6 @@ msgstr "Luodaan AABB" msgid "Generate Visibility AABB" msgstr "Kartoita näkyvä alue" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Luo AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Poista pisteet käyrästä" @@ -6934,6 +6958,14 @@ msgstr "Sulje dokumentaatio" msgid "Run" msgstr "Suorita" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Hae" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Siirry sisään" @@ -6987,16 +7019,6 @@ msgstr "" "Seuraavat tiedostot ovat uudempia levyllä.\n" "Mikä toimenpide tulisi suorittaa?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Lataa uudelleen" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Tallenna uudelleen" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Debuggeri" @@ -7091,8 +7113,8 @@ msgstr "Keskeytyskohdat" msgid "Go To" msgstr "Mene" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Leikkaa" @@ -7315,6 +7337,10 @@ msgid "Yaw" msgstr "Käännös (yaw)" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Koko" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekteja piirretty" @@ -9997,6 +10023,10 @@ msgid "Projects" msgstr "Projektit" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Ladataan, hetkinen..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Viimeksi muutettu" @@ -10615,6 +10645,16 @@ msgid "Instance Child Scene" msgstr "Luo aliskenen ilmentymä" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Ei voida suorittaa ulkopuolisen skenen solmuille!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Liitä solmut" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Irrota skripti" @@ -10744,6 +10784,11 @@ msgid "Attach Script" msgstr "Liitä skripti" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Leikkaa solmut" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Poista solmu(t)" @@ -11554,6 +11599,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "Anna MeshLibrary resurssi tälle GridMap solmulle käyttääksesi sen meshejä." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Aloita kehitys" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Valmistellaan tietorakenteita" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Luo puskurit" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Suora valaistus" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Epäsuora valaistus" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Jälkikäsittely" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Piirretään lightmappeja" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Luokan nimi ei voi olla varattu avainsana" @@ -12066,12 +12139,16 @@ msgid "Select device from the list" msgstr "Valitse laite listasta" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB käynnistystiedostoa ei ole määritetty editorin asetuksissa." +msgid "Unable to find the 'apksigner' tool." +msgstr "'apksigner' työkalua ei löydy." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner ei ole määritettynä editorin asetuksissa." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Android-käännösmallia ei ole asennettu projektiin. Asenna se Projekti-" +"valikosta." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12083,28 +12160,33 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "Release keystore on konfiguroitu väärin viennin esiasetuksissa." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "" -"Mukautettu käännös edellyttää kelvollista Android SDK -polkua editorin " -"asetuksissa." +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "Editorin asetuksiin tarvitaan kelvollinen Android SDK -polku." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Virheellinen Android SDK -polku mukautettu käännöstä varten editorin " -"asetuksissa." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Editorin asetuksissa on virheellinen Android SDK -polku." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "'platform-tools' hakemisto puuttuu!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "Android SDK platform-tools adb-komentoa ei löydy." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Android-käännösmallia ei ole asennettu projektiin. Asenna se Projekti-" -"valikosta." +"Ole hyvä ja tarkista editorin asetuksissa määritelty Android SDK -hakemisto." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "'build-tools' hakemisto puuttuu!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "Android SDK build-tools apksigner-komentoa ei löydy." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12577,28 +12659,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin solmu tarvitsee ARVRCamera alisolmun." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Etsitään meshejä ja valoja" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Aikaa jäljellä: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Valmistellaan geometriaa (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Piirretään meshejä: " +msgid "Preparing environment" +msgstr "Valmistellaan ympäristöä" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Piirretään valoja:" +msgid "Generating capture" +msgstr "Luodaan kaappausta" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Viimeistellään piirto" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Tallennetaan lightmappeja" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Valaistaan meshejä: " +msgid "Done" +msgstr "Valmis" #: scene/3d/collision_object.cpp msgid "" @@ -12674,6 +12756,10 @@ msgid "Plotting Meshes" msgstr "Piirretään meshejä" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Viimeistellään piirto" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12932,10 +13018,13 @@ msgstr "Huomio!" msgid "Please Confirm..." msgstr "Ole hyvä ja vahvista..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Käytä sopivaa tiedostopäätettä." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Käytä tarttumista" +msgstr "Käytä ruudukon pienoiskarttaa." #: scene/gui/popup.cpp msgid "" @@ -12991,6 +13080,14 @@ msgstr "" "Näyttöruudun koko on oltava suurempi kuin 0, jotta mitään renderöidään." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Näytteistysportti on yhdistetty mutta ei käytössä. Harkitse lähteen " +"vaihtamista 'SamplerPort' asetukseen." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Virheellinen lähde esikatselulle." @@ -13018,6 +13115,36 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa." msgid "Constants cannot be modified." msgstr "Vakioita ei voi muokata." +#~ msgid "No" +#~ msgstr "Ei" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Tätä skeneä ei ole koskaan tallennettu. Tallenna ennen suorittamista?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ADB käynnistystiedostoa ei ole määritetty editorin asetuksissa." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner ei ole määritettynä editorin asetuksissa." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Mukautettu käännös edellyttää kelvollista Android SDK -polkua editorin " +#~ "asetuksissa." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Aikaa jäljellä: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Piirretään meshejä: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Valaistaan meshejä: " + #~ msgid "Search complete" #~ msgstr "Haku valmis" @@ -13030,12 +13157,6 @@ msgstr "Vakioita ei voi muokata." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "Tästä sijainnista löytyy jo samanniminen tiedosto tai kansio." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "'build-tools' hakemisto puuttuu!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "zipalign työkalua ei löydy." - #~ msgid "Aligning APK..." #~ msgstr "Tasataan APK:ta..." @@ -13377,9 +13498,6 @@ msgstr "Vakioita ei voi muokata." #~ msgid "Failed to save solution." #~ msgstr "Ratkaisun tallennus epäonnistui." -#~ msgid "Done" -#~ msgstr "Valmis" - #~ msgid "Failed to create C# project." #~ msgstr "C# projektin luonti epäonnistui." diff --git a/editor/translations/fil.po b/editor/translations/fil.po index b024a86272..dc84dd744f 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -634,7 +634,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopya" @@ -1896,10 +1896,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2304,6 +2300,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2347,18 +2347,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "Hindi" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Oo" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2406,6 +2394,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Oo" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2448,7 +2440,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2838,14 +2830,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3000,6 +2984,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3203,7 +3203,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4832,7 +4832,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4967,8 +4967,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4982,9 +4981,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6043,6 +6061,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6103,10 +6125,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6689,6 +6707,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6740,16 +6766,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6842,8 +6858,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7064,6 +7080,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9588,6 +9608,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10192,6 +10216,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Burahin ang (mga) Napiling Key" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10312,6 +10345,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11098,6 +11135,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11596,11 +11661,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11612,11 +11679,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11624,9 +11691,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12017,27 +12094,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12097,6 +12174,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12310,6 +12391,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12355,6 +12440,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12381,3 +12472,6 @@ msgstr "" #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." msgstr "" + +#~ msgid "No" +#~ msgstr "Hindi" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 6b43079359..44002bf560 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -69,7 +69,7 @@ # Sofiane <Sofiane-77@caramail.fr>, 2019. # Camille Mohr-Daurat <pouleyketchoup@gmail.com>, 2019. # Pierre Stempin <pierre.stempin@gmail.com>, 2019. -# Pierre Caye <pierrecaye@laposte.net>, 2020. +# Pierre Caye <pierrecaye@laposte.net>, 2020, 2021. # Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020. # LaurentOngaro <laurent@gameamea.com>, 2020. # Julien Humbert <julroy67@gmail.com>, 2020. @@ -77,11 +77,12 @@ # Léo Vincent <l009.vincent@gmail.com>, 2020. # Joseph Boudou <joseph.boudou@matabio.net>, 2020. # Vincent Foulon <vincent.foulon80@gmail.com>, 2020. +# TechnoPorg <jonah.janzen@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-16 09:41+0000\n" +"PO-Revision-Date: 2021-01-22 10:21+0000\n" "Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" @@ -90,7 +91,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -727,7 +728,7 @@ msgstr "Sélectionner les pistes à copier" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copier" @@ -2029,10 +2030,6 @@ msgstr "Aperçu :" msgid "File:" msgstr "Fichier :" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Utilisez une extension valide." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Scanner les sources" @@ -2475,6 +2472,10 @@ msgid "There is no defined scene to run." msgstr "Il n'y a pas de scène définie pour être lancée." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Enregistrer la scène avant de l'exécuter..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Impossible de démarrer le sous-processus !" @@ -2518,19 +2519,6 @@ msgstr "Un nÅ“ud racine est nécessaire pour sauvegarder la scène." msgid "Save Scene As..." msgstr "Enregistrer la scène sous…" -#: editor/editor_node.cpp -msgid "No" -msgstr "Non" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Oui" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" -"Cette scène n'a jamais été enregistrée. L'enregistrer avant de la lancer ?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Cette opération ne peut être réalisée sans une scène." @@ -2580,6 +2568,10 @@ msgid "Quit" msgstr "Quitter" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Oui" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Quitter l'éditeur ?" @@ -2627,14 +2619,13 @@ msgstr "Réouvrir la scène fermée" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" -"Impossible d'activer le greffon depuis : « %s », l’analyse syntaxique de la " +"Impossible d'activer le plugin depuis : « %s », l’analyse syntaxique de la " "configuration a échoué." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" -"Impossible de trouver le champ de script pour le plugin dans : « res://" -"addons/%s »." +"Impossible de trouver le champ de script pour le plugin dans : « %s »." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." @@ -3073,14 +3064,6 @@ msgid "Help" msgstr "Aide" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Rechercher" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentation en ligne" @@ -3247,6 +3230,24 @@ msgid "Open & Run a Script" msgstr "Ouvrir et exécuter un script" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Les fichiers suivants sont plus récents sur le disque.\n" +"Quelle action doit être prise ?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Recharger" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Ré-enregistrer" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nouveau hérité" @@ -3458,7 +3459,7 @@ msgstr "Rendre unique" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Coller" @@ -4298,7 +4299,7 @@ msgstr "Modifier un plugin" #: editor/plugin_config_dialog.cpp msgid "Create a Plugin" -msgstr "Créer un Plugin" +msgstr "Créer un plugin" #: editor/plugin_config_dialog.cpp msgid "Plugin Name:" @@ -5142,8 +5143,8 @@ msgid "Got:" msgstr "A :" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" -msgstr "Vérification de brouillage sha256 échouée" +msgid "Failed SHA-256 hash check" +msgstr "Vérification du hachage SHA-256 échouée" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" @@ -5277,13 +5278,10 @@ msgstr "Fichier ZIP de données" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"Ne peut pas déterminer un chemin de sauvegarde pour les images lightmap.\n" -"Sauvegarder votre scène (pour que les images soient sauvegardées dans le " -"même répertoire), ou choisissez un répertoire de sauvegarde à partir des " -"propriétés BakedLightmap." +"Impossible de déterminer un chemin de sauvegarde pour les images lightmap.\n" +"Enregistrez votre scène et réessayez." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5300,9 +5298,34 @@ msgstr "" "accessible en écriture." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Échec de la détermination de la taille de la lightmap. Taille maximale de " +"lightmap trop petite ?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Un maillage n'est pas valide. Assurez-vous que les valeurs du canal UV2 sont " +"contenues dans la région carrée [0.0,1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"L'éditeur Godot a été compilé sans support du ray tracing, les lightmaps ne " +"peuvent pas être pré-calculées." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Précalculer les lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Sélectionnez le fichier de pré-calcul de lightmap :" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6411,6 +6434,10 @@ msgstr "" "Ne peut définir qu'un point dans un matériau de processus ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Convertir en CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Temps de Génération (sec) :" @@ -6471,10 +6498,6 @@ msgstr "Générer AABB" msgid "Generate Visibility AABB" msgstr "Générer AABB de Visibilité" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Générer AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Supprimer Point de la Courbe" @@ -7066,6 +7089,14 @@ msgstr "Fermer les documentations" msgid "Run" msgstr "Lancer" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Rechercher" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Rentrer" @@ -7119,16 +7150,6 @@ msgstr "" "Les fichiers suivants sont plus récents sur le disque.\n" "Quelle action doit être prise ? :" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Recharger" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Ré-enregistrer" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Débogueur" @@ -7225,8 +7246,8 @@ msgstr "Point d'arrêts" msgid "Go To" msgstr "Atteindre" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Couper" @@ -7449,6 +7470,10 @@ msgid "Yaw" msgstr "Lacet (hauteur)" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Taille" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objets dessinés" @@ -10152,6 +10177,10 @@ msgid "Projects" msgstr "Projets" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Chargement en cours, veuillez patienter..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Dernière modification" @@ -10771,6 +10800,14 @@ msgid "Instance Child Scene" msgstr "Instancier une scène enfant" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "Impossible de copier le nÅ“ud racine dans la même scène." + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "Coller le(s) nÅ“ud(s)" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Détacher le script" @@ -10897,6 +10934,10 @@ msgid "Attach Script" msgstr "Attacher un script" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "Couper le(s) nÅ“ud(s)" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Supprimer le(s) nÅ“ud(s)" @@ -11709,6 +11750,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "Donnez une ressource MeshLibrary à cette GridMap pour utiliser ses maillages." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Commencer le pré-calcul" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Préparation des structures de données" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Générer des tampons" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Éclairage direct" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Éclairage indirect" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Post-traitement" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Tracer des lightmaps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Le nom de classe ne peut pas être un mot-clé réservé" @@ -12230,13 +12299,16 @@ msgid "Select device from the list" msgstr "Sélectionner appareil depuis la liste" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "L'exécutable ADB n'est pas configuré dans les Paramètres de l'éditeur." +msgid "Unable to find the 'apksigner' tool." +msgstr "Impossible de trouver l'outil 'apksigner'." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" -"Le jarsigner OpenJDK n'est pas configuré dans les Paramètres de l'éditeur." +"Le modèle de compilation Android n'est pas installé dans le projet. " +"Installez-le à partir du menu Projet." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12251,28 +12323,38 @@ msgstr "" "d'exportation." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"La création d'une version personnalisée nécessite un chemin d'accès Android " -"SDK valide dans les paramètres de l'éditeur." +"Un chemin d'accès valide au SDK Android est requis dans les paramètres de " +"l'éditeur." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" -"Chemin d'accès invalide au SDK Android pour le build custom dans les " -"paramètres de l'éditeur." +"Chemin d'accès invalide au SDK Android dans les paramètres de l'éditeur." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Dossier « platform-tools » manquant !" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "Impossible de trouver la commande adb du SDK Android platform-tools." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Le modèle de compilation Android n'est pas installé dans le projet. " -"Installez-le à partir du menu Projet." +"Veuillez vérifier le répertoire du SDK Android spécifié dans les paramètres " +"de l'éditeur." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Dossier « build-tools » manquant !" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" +"Impossible de trouver la commande apksigner du SDK Android build-tools." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12766,28 +12848,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin requiert un nÅ“ud enfant ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Recherche de maillages et de lumières" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Temps restant : %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Préparation de la géométrie (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Tracer les maillages : " +msgid "Preparing environment" +msgstr "Préparation de l'environnement" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Tracer les lumières :" +msgid "Generating capture" +msgstr "Génération de capture" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Finalisation du tracer" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Enregistrement des lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Tracer les maillages : " +msgid "Done" +msgstr "Terminé" #: scene/3d/collision_object.cpp msgid "" @@ -12862,6 +12944,10 @@ msgid "Plotting Meshes" msgstr "Tracer les maillages" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Finalisation du tracer" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13127,10 +13213,13 @@ msgstr "Alerte !" msgid "Please Confirm..." msgstr "Veuillez confirmer…" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Utilisez une extension valide." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Activer l'alignement" +msgstr "Activer l'alignement." #: scene/gui/popup.cpp msgid "" @@ -13189,6 +13278,14 @@ msgstr "" "afficher quoi que ce soit." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Le port de l'échantillonneur est connecté mais n'est pas utilisé. Pensez à " +"changer la source en 'SamplerPort'." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Source invalide pour la prévisualisation." @@ -13216,6 +13313,38 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex." msgid "Constants cannot be modified." msgstr "Les constantes ne peuvent être modifiées." +#~ msgid "No" +#~ msgstr "Non" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Cette scène n'a jamais été enregistrée. L'enregistrer avant de la lancer ?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "" +#~ "L'exécutable ADB n'est pas configuré dans les Paramètres de l'éditeur." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "" +#~ "Le jarsigner OpenJDK n'est pas configuré dans les Paramètres de l'éditeur." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "La création d'une version personnalisée nécessite un chemin d'accès " +#~ "Android SDK valide dans les paramètres de l'éditeur." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Temps restant : %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Tracer les maillages : " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Tracer les maillages : " + #~ msgid "Search complete" #~ msgstr "Recherche terminée" @@ -13230,12 +13359,6 @@ msgstr "Les constantes ne peuvent être modifiées." #~ "Il existe déjà un fichier ou un dossier ayant le même nom à cet " #~ "emplacement." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Dossier « build-tools » manquant !" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Impossible de trouver l'outil zipalign." - #~ msgid "Aligning APK..." #~ msgstr "Alignement de l'APK…" @@ -13583,9 +13706,6 @@ msgstr "Les constantes ne peuvent être modifiées." #~ msgid "Failed to save solution." #~ msgstr "Impossible de sauvegarder la solution." -#~ msgid "Done" -#~ msgstr "Terminé" - #~ msgid "Failed to create C# project." #~ msgstr "Impossible de créer le projet C#." diff --git a/editor/translations/ga.po b/editor/translations/ga.po index f9fab95696..6bddf1e53c 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -627,7 +627,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1890,10 +1890,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2298,6 +2294,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2341,18 +2341,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2401,6 +2389,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2443,7 +2435,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2833,14 +2825,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2994,6 +2978,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3196,7 +3196,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4829,7 +4829,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4964,8 +4964,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4979,9 +4978,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6038,6 +6056,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6098,10 +6120,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6683,6 +6701,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6734,16 +6760,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6836,8 +6852,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7058,6 +7074,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9583,6 +9603,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10186,6 +10210,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10306,6 +10338,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11093,6 +11129,34 @@ msgstr "ScagairÃ..." msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11592,11 +11656,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11608,11 +11674,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11620,9 +11686,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12013,27 +12089,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12093,6 +12169,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12306,6 +12386,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12351,6 +12435,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/gl.po b/editor/translations/gl.po new file mode 100644 index 0000000000..323fc16ec4 --- /dev/null +++ b/editor/translations/gl.po @@ -0,0 +1,12839 @@ +# Galician translation of the Godot Engine editor. +# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. +# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). +# This file is distributed under the same license as the Godot source code. +# +# Andy Barcia <andybarcia4@gmail.com>, 2021. +# PokeGalaico <abloodyfreaks@gmail.com>, 2021. +msgid "" +msgstr "" +"Project-Id-Version: Godot Engine editor\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" +"Last-Translator: Andy Barcia <andybarcia4@gmail.com>\n" +"Language-Team: Galician <https://hosted.weblate.org/projects/godot-engine/" +"godot/gl/>\n" +"Language: gl\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.5-dev\n" + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Invalid type argument to convert(), use TYPE_* constants." +msgstr "Tipo de argumento inválido para convert(), utiliza constantes TYPE_*." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +msgid "Expected a string of length 1 (a character)." +msgstr "Esperábase un string de lonxitude 1 (un carácter)." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/mono/glue/gd_glue.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Not enough bytes for decoding bytes, or invalid format." +msgstr "" +"Non hai insuficientes \"bytes\" para descodificar, ou o formato é inválido." + +#: core/math/expression.cpp +msgid "Invalid input %i (not passed) in expression" +msgstr "Entrada inválida %i (non recibida) na expresión" + +#: core/math/expression.cpp +msgid "self can't be used because instance is null (not passed)" +msgstr "Non se pode usar \"self\" porque a instancia é nula (non recibida)" + +#: core/math/expression.cpp +msgid "Invalid operands to operator %s, %s and %s." +msgstr "Operandos inválidos para o operador %s, %s e %s." + +#: core/math/expression.cpp +msgid "Invalid index of type %s for base type %s" +msgstr "Ãndice de tipo %s inválido para tipo base %s" + +#: core/math/expression.cpp +msgid "Invalid named index '%s' for base type %s" +msgstr "O Ãndice do nome '%s' non é válido para o tipo de base %s" + +#: core/math/expression.cpp +msgid "Invalid arguments to construct '%s'" +msgstr "Argumentos inválidos para construir '%s'" + +#: core/math/expression.cpp +msgid "On call to '%s':" +msgstr "En chamada a '%s':" + +#: core/ustring.cpp +msgid "B" +msgstr "B" + +#: core/ustring.cpp +msgid "KiB" +msgstr "KiB" + +#: core/ustring.cpp +msgid "MiB" +msgstr "MiB" + +#: core/ustring.cpp +msgid "GiB" +msgstr "GiB" + +#: core/ustring.cpp +msgid "TiB" +msgstr "TiB" + +#: core/ustring.cpp +msgid "PiB" +msgstr "PiB" + +#: core/ustring.cpp +msgid "EiB" +msgstr "EiB" + +#: editor/animation_bezier_editor.cpp +msgid "Free" +msgstr "Libre" + +#: editor/animation_bezier_editor.cpp +msgid "Balanced" +msgstr "Balanceado" + +#: editor/animation_bezier_editor.cpp +msgid "Mirror" +msgstr "Espello" + +#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp +msgid "Time:" +msgstr "Tempo:" + +#: editor/animation_bezier_editor.cpp +msgid "Value:" +msgstr "Valor:" + +#: editor/animation_bezier_editor.cpp +msgid "Insert Key Here" +msgstr "Introducir Clave AquÃ" + +#: editor/animation_bezier_editor.cpp +msgid "Duplicate Selected Key(s)" +msgstr "Duplicar Clave(s) Seleccionadas(s)" + +#: editor/animation_bezier_editor.cpp +msgid "Delete Selected Key(s)" +msgstr "Eliminar Clave(s) Seleccionada(s)" + +#: editor/animation_bezier_editor.cpp +msgid "Add Bezier Point" +msgstr "Engadir Punto Bezier" + +#: editor/animation_bezier_editor.cpp +msgid "Move Bezier Points" +msgstr "Mover Punto Bezier" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Duplicate Keys" +msgstr "Duplicar Claves de Animación" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Delete Keys" +msgstr "Eliminar Claves de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Time" +msgstr "Cambiar Tempo do Fotograma Clave" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transition" +msgstr "Cambiar Transición de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transform" +msgstr "Cambiar Transformación da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Value" +msgstr "Cambiar Valor do Fotograma Clave da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Call" +msgstr "Cambiar Chamada da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Time" +msgstr "Cambiar Tempo de Múltiples Fotogramas Claves de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transition" +msgstr "Cambiar Múltiples Transicións da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transform" +msgstr "Cambiar Múltiples Transformacións da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Value" +msgstr "Cambiar Múltiples Valores do Fotograma Clave da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Call" +msgstr "Cambiar Múltiples Chamadas da Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Length" +msgstr "Cambiar Lonxitude da Animación" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation Loop" +msgstr "Cambiar Ciclo da Animación" + +#: editor/animation_track_editor.cpp +msgid "Property Track" +msgstr "Pista de Propiedades" + +#: editor/animation_track_editor.cpp +msgid "3D Transform Track" +msgstr "Pista de Transformación 3D" + +#: editor/animation_track_editor.cpp +msgid "Call Method Track" +msgstr "Pista de Chamadas de Métodos" + +#: editor/animation_track_editor.cpp +msgid "Bezier Curve Track" +msgstr "Pista de Curva Bezier" + +#: editor/animation_track_editor.cpp +msgid "Audio Playback Track" +msgstr "Pista de Reprodución de Audio" + +#: editor/animation_track_editor.cpp +msgid "Animation Playback Track" +msgstr "Pista de Reprodución de Animación" + +#: editor/animation_track_editor.cpp +msgid "Animation length (frames)" +msgstr "Lonxitude da Animacion (en fotogramas)" + +#: editor/animation_track_editor.cpp +msgid "Animation length (seconds)" +msgstr "Lonxitude da Animación (en segundos)" + +#: editor/animation_track_editor.cpp +msgid "Add Track" +msgstr "Engadir Pista" + +#: editor/animation_track_editor.cpp +msgid "Animation Looping" +msgstr "Animación en Bucle" + +#: editor/animation_track_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Functions:" +msgstr "Funciones:" + +#: editor/animation_track_editor.cpp +msgid "Audio Clips:" +msgstr "Clips de Audio:" + +#: editor/animation_track_editor.cpp +msgid "Anim Clips:" +msgstr "Clips de Animación:" + +#: editor/animation_track_editor.cpp +msgid "Change Track Path" +msgstr "Cambiar Ruta da Pista" + +#: editor/animation_track_editor.cpp +msgid "Toggle this track on/off." +msgstr "Act./Desact. esta pista." + +#: editor/animation_track_editor.cpp +msgid "Update Mode (How this property is set)" +msgstr "Modo de Actualización (cómo se establece esta propiedade)" + +#: editor/animation_track_editor.cpp +msgid "Interpolation Mode" +msgstr "Modo de Interpolación" + +#: editor/animation_track_editor.cpp +msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" +msgstr "Modo de Bucle Envolvente (interpola o final co comezo do bucle)" + +#: editor/animation_track_editor.cpp +msgid "Remove this track." +msgstr "Eliminar esta pista." + +#: editor/animation_track_editor.cpp +msgid "Time (s): " +msgstr "Tempo (s): " + +#: editor/animation_track_editor.cpp +msgid "Toggle Track Enabled" +msgstr "Act./Desact. Pista" + +#: editor/animation_track_editor.cpp +msgid "Continuous" +msgstr "Continuo" + +#: editor/animation_track_editor.cpp +msgid "Discrete" +msgstr "Discreto" + +#: editor/animation_track_editor.cpp +msgid "Trigger" +msgstr "Detonante (Trigger)" + +#: editor/animation_track_editor.cpp +msgid "Capture" +msgstr "Captura" + +#: editor/animation_track_editor.cpp +msgid "Nearest" +msgstr "Máis Cercano" + +#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp +#: editor/property_editor.cpp +msgid "Linear" +msgstr "Lineal" + +#: editor/animation_track_editor.cpp +msgid "Cubic" +msgstr "Cúbica" + +#: editor/animation_track_editor.cpp +msgid "Clamp Loop Interp" +msgstr "Interpolación de Bucle Recortado" + +#: editor/animation_track_editor.cpp +msgid "Wrap Loop Interp" +msgstr "Interpolación de Bucle Envolvente" + +#: editor/animation_track_editor.cpp +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key" +msgstr "Engadir Chave" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Key(s)" +msgstr "Duplicar Chave(s)" + +#: editor/animation_track_editor.cpp +msgid "Delete Key(s)" +msgstr "Eliminar Chave(s)" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Update Mode" +msgstr "Cambiar Modo de Actualización da Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Interpolation Mode" +msgstr "Cambiar Modo de Interpolación da Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Loop Mode" +msgstr "Cambiar Modo de Bucle da Animación" + +#: editor/animation_track_editor.cpp +msgid "Remove Anim Track" +msgstr "Eliminar Pista de Animación" + +#: editor/animation_track_editor.cpp +msgid "Create NEW track for %s and insert key?" +msgstr "Crear nova pista para %s e engadir chave?" + +#: editor/animation_track_editor.cpp +msgid "Create %d NEW tracks and insert keys?" +msgstr "Crear %d novas pistas e engadir chaves?" + +#: editor/animation_track_editor.cpp editor/create_dialog.cpp +#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/mesh_instance_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Create" +msgstr "Crear" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert" +msgstr "Engadir Animación" + +#: editor/animation_track_editor.cpp +msgid "AnimationPlayer can't animate itself, only other players." +msgstr "Un AnimationPlayer non pode animarse a si mesmo, só a outros players." + +#: editor/animation_track_editor.cpp +msgid "Anim Create & Insert" +msgstr "Crear e Engadir Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Track & Key" +msgstr "Engadir Pista e Chave de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Key" +msgstr "Engadir Chave de Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Step" +msgstr "Cambiar Paso de Animación" + +#: editor/animation_track_editor.cpp +msgid "Rearrange Tracks" +msgstr "Reordenar Pistas" + +#: editor/animation_track_editor.cpp +msgid "Transform tracks only apply to Spatial-based nodes." +msgstr "As pistas de transformación só aplÃcanse a nodos basados en Spatial." + +#: editor/animation_track_editor.cpp +msgid "" +"Audio tracks can only point to nodes of type:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" +msgstr "" +"As pistas de audio só poden apuntar a nodos de tipo:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" + +#: editor/animation_track_editor.cpp +msgid "Animation tracks can only point to AnimationPlayer nodes." +msgstr "As pistas de animación só poden apuntar a nodos AnimationPlayer." + +#: editor/animation_track_editor.cpp +msgid "An animation player can't animate itself, only other players." +msgstr "" +"Un reproductor de animacións non pode animarse a si mesmo, só a outros " +"reproductores." + +#: editor/animation_track_editor.cpp +msgid "Not possible to add a new track without a root" +msgstr "Non é posible engadir unha nova pista sen unha raÃz" + +#: editor/animation_track_editor.cpp +msgid "Invalid track for Bezier (no suitable sub-properties)" +msgstr "Pista inválida para Bezier (non hai sub-propiedades axeitadas)" + +#: editor/animation_track_editor.cpp +msgid "Add Bezier Track" +msgstr "Engadir Pista Bezier" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a key." +msgstr "A ruta á pista é inválida, polo que non se poden engadir chaves." + +#: editor/animation_track_editor.cpp +msgid "Track is not of type Spatial, can't insert key" +msgstr "A pista non é de tipo Spatial, e non se pode engadir chave" + +#: editor/animation_track_editor.cpp +msgid "Add Transform Track Key" +msgstr "Engadir Chave de Pista de Transformación" + +#: editor/animation_track_editor.cpp +msgid "Add Track Key" +msgstr "Engadir Chave de Pista" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a method key." +msgstr "" +"A ruta á pista é inválida, polo que non se pode engadir unha clave de método." + +#: editor/animation_track_editor.cpp +msgid "Add Method Track Key" +msgstr "Engadir Chave de Pista de Método" + +#: editor/animation_track_editor.cpp +msgid "Method not found in object: " +msgstr "Método non encontrado no obxecto: " + +#: editor/animation_track_editor.cpp +msgid "Anim Move Keys" +msgstr "Mover Claves de Animación" + +#: editor/animation_track_editor.cpp +msgid "Clipboard is empty" +msgstr "O portapapeis está baleiro" + +#: editor/animation_track_editor.cpp +msgid "Paste Tracks" +msgstr "Pegar Pistas" + +#: editor/animation_track_editor.cpp +msgid "Anim Scale Keys" +msgstr "Escalar Chaves de Animación" + +#: editor/animation_track_editor.cpp +msgid "" +"This option does not work for Bezier editing, as it's only a single track." +msgstr "" +"Esta opción non funciona con edición Bezier, xa que é unha única pista." + +#: editor/animation_track_editor.cpp +msgid "" +"This animation belongs to an imported scene, so changes to imported tracks " +"will not be saved.\n" +"\n" +"To enable the ability to add custom tracks, navigate to the scene's import " +"settings and set\n" +"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks" +"\", then re-import.\n" +"Alternatively, use an import preset that imports animations to separate " +"files." +msgstr "" +"Esta animación pertence a unha escena importada, polo que os cambios nas " +"pistas importadas non quedaran gardados.\n" +"\n" +"Para habilitar a capacidade de engadir pistas personalizadas, vai á " +"configuración de importación da escena e establece\n" +"\"Animación > Almacenamento\" a \"Arquivos\", activa \"Animación > Manter " +"Pistas Personalizadas\", e logo reimportaa.\n" +"Tamén poder usar un preset de importación que importa animacións para " +"separar arquivos." + +#: editor/animation_track_editor.cpp +msgid "Warning: Editing imported animation" +msgstr "Advertencia: Estase editando unha animación importada" + +#: editor/animation_track_editor.cpp +msgid "Select an AnimationPlayer node to create and edit animations." +msgstr "Selecciona un nodo AnimationPlayer para crear e editar animacións." + +#: editor/animation_track_editor.cpp +msgid "Only show tracks from nodes selected in tree." +msgstr "Só mostrar pistas de nodos seleccionados na árbore." + +#: editor/animation_track_editor.cpp +msgid "Group tracks by node or display them as plain list." +msgstr "Agrupar pistas por nodo ou mostralas coma unha simple lista." + +#: editor/animation_track_editor.cpp +msgid "Snap:" +msgstr "Axuste de CuadrÃcula:" + +#: editor/animation_track_editor.cpp +msgid "Animation step value." +msgstr "Valor de paso de animación." + +#: editor/animation_track_editor.cpp +msgid "Seconds" +msgstr "Segundos" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "FPS" +msgstr "FPS" + +#: editor/animation_track_editor.cpp editor/editor_properties.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit" +msgstr "Editar" + +#: editor/animation_track_editor.cpp +msgid "Animation properties." +msgstr "Propiedades de Animación." + +#: editor/animation_track_editor.cpp +msgid "Copy Tracks" +msgstr "Copiar Pistas" + +#: editor/animation_track_editor.cpp +msgid "Scale Selection" +msgstr "Escalar Selección" + +#: editor/animation_track_editor.cpp +msgid "Scale From Cursor" +msgstr "Escalar desde o Cursor" + +#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp +msgid "Duplicate Selection" +msgstr "Duplicar Selección" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Transposed" +msgstr "Duplicar Transposto" + +#: editor/animation_track_editor.cpp +msgid "Delete Selection" +msgstr "Eliminar Selección" + +#: editor/animation_track_editor.cpp +msgid "Go to Next Step" +msgstr "Ir ao Seguinte Paso" + +#: editor/animation_track_editor.cpp +msgid "Go to Previous Step" +msgstr "Ir ao Anterior Paso" + +#: editor/animation_track_editor.cpp +msgid "Optimize Animation" +msgstr "Optimizar Animación" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation" +msgstr "Limpiar Animación" + +#: editor/animation_track_editor.cpp +msgid "Pick the node that will be animated:" +msgstr "Elixe o nodo que será animado:" + +#: editor/animation_track_editor.cpp +msgid "Use Bezier Curves" +msgstr "Usar Curvas Bezier" + +#: editor/animation_track_editor.cpp +msgid "Anim. Optimizer" +msgstr "Optimizador de Animación" + +#: editor/animation_track_editor.cpp +msgid "Max. Linear Error:" +msgstr "Erro Lineal Máximo:" + +#: editor/animation_track_editor.cpp +msgid "Max. Angular Error:" +msgstr "Erro Angular Máximo:" + +#: editor/animation_track_editor.cpp +msgid "Max Optimizable Angle:" +msgstr "Ãngulo Optimizable Máximo:" + +#: editor/animation_track_editor.cpp +msgid "Optimize" +msgstr "Optimizar" + +#: editor/animation_track_editor.cpp +msgid "Remove invalid keys" +msgstr "Eliminar chaves inválidas" + +#: editor/animation_track_editor.cpp +msgid "Remove unresolved and empty tracks" +msgstr "Eliminar pistas baleiras e sen resolver" + +#: editor/animation_track_editor.cpp +msgid "Clean-up all animations" +msgstr "Limpiar tódolas animacións" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation(s) (NO UNDO!)" +msgstr "Limpiar Animación(s) (NON HAI VOLTA ATRÃS!)" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up" +msgstr "Limpiar" + +#: editor/animation_track_editor.cpp +msgid "Scale Ratio:" +msgstr "Relación de Escalado:" + +#: editor/animation_track_editor.cpp +msgid "Select Tracks to Copy" +msgstr "Selecciona as Pistas a Copiar" + +#: editor/animation_track_editor.cpp editor/editor_log.cpp +#: editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Copy" +msgstr "Copiar" + +#: editor/animation_track_editor.cpp +msgid "Select All/None" +msgstr "Seleccionar Todas/Ningunha" + +#: editor/animation_track_editor_plugins.cpp +msgid "Add Audio Track Clip" +msgstr "Engadir Clip de Pista de Audio" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip Start Offset" +msgstr "Cambiar Inicio do Clip na Pista de Audio" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip End Offset" +msgstr "Cambiar Final do Clip na Pista de Audio" + +#: editor/array_property_edit.cpp +msgid "Resize Array" +msgstr "Redimensionar Array" + +#: editor/array_property_edit.cpp +msgid "Change Array Value Type" +msgstr "Cambiar Tipo do Valor do Array" + +#: editor/array_property_edit.cpp +msgid "Change Array Value" +msgstr "Cambiar Valor do Array" + +#: editor/code_editor.cpp +msgid "Go to Line" +msgstr "Ir a Liña" + +#: editor/code_editor.cpp +msgid "Line Number:" +msgstr "Número de Liña:" + +#: editor/code_editor.cpp +msgid "%d replaced." +msgstr "%d substituÃdo." + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d match." +msgstr "%d coincidencia." + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d matches." +msgstr "%d coincidencias." + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Match Case" +msgstr "Coincidir Maiús./Minús." + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Whole Words" +msgstr "Palabras Completas" + +#: editor/code_editor.cpp +msgid "Replace" +msgstr "SubstituÃr" + +#: editor/code_editor.cpp +msgid "Replace All" +msgstr "SubstituÃr Todo" + +#: editor/code_editor.cpp +msgid "Selection Only" +msgstr "Só a Selección" + +#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp +#: editor/plugins/text_editor.cpp +msgid "Standard" +msgstr "Estándar" + +#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp +msgid "Toggle Scripts Panel" +msgstr "Act./Desact. Panel de Scripts" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom In" +msgstr "Aumentar Zoom" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Out" +msgstr "DiminuÃr Zoom" + +#: editor/code_editor.cpp +msgid "Reset Zoom" +msgstr "Reiniciar Zoom" + +#: editor/code_editor.cpp +msgid "Warnings" +msgstr "Avisos" + +#: editor/code_editor.cpp +msgid "Line and column numbers." +msgstr "Números de liña e columna." + +#: editor/connections_dialog.cpp +msgid "Method in target node must be specified." +msgstr "Debe especificarse o método no nodo receptor." + +#: editor/connections_dialog.cpp +msgid "Method name must be a valid identifier." +msgstr "O nome do método debe ser un identificador válido." + +#: editor/connections_dialog.cpp +msgid "" +"Target method not found. Specify a valid method or attach a script to the " +"target node." +msgstr "" +"Non se encontrou o método receptor. Especifique un método válido ou engada " +"un script ao nodo receptor." + +#: editor/connections_dialog.cpp +msgid "Connect to Node:" +msgstr "Conectar ao Nodo:" + +#: editor/connections_dialog.cpp +msgid "Connect to Script:" +msgstr "Conectar ao Script:" + +#: editor/connections_dialog.cpp +msgid "From Signal:" +msgstr "Desde a Sinal:" + +#: editor/connections_dialog.cpp +msgid "Scene does not contain any script." +msgstr "A escena non conteñe ningún script." + +#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp +#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +msgid "Add" +msgstr "Engadir" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/editor_feature_profile.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp +msgid "Remove" +msgstr "Eliminar" + +#: editor/connections_dialog.cpp +msgid "Add Extra Call Argument:" +msgstr "Engadir Argumento Extra á Chamada:" + +#: editor/connections_dialog.cpp +msgid "Extra Call Arguments:" +msgstr "Argumentos Extra da Chamada:" + +#: editor/connections_dialog.cpp +msgid "Receiver Method:" +msgstr "Método Receptor:" + +#: editor/connections_dialog.cpp +msgid "Advanced" +msgstr "Avanzado" + +#: editor/connections_dialog.cpp +msgid "Deferred" +msgstr "Diferido" + +#: editor/connections_dialog.cpp +msgid "" +"Defers the signal, storing it in a queue and only firing it at idle time." +msgstr "" +"Difire a sinal, almacenándoa nunha cola é só executándoa en tempo de " +"inactividade." + +#: editor/connections_dialog.cpp +msgid "Oneshot" +msgstr "Execución Única (Oneshot)" + +#: editor/connections_dialog.cpp +msgid "Disconnects the signal after its first emission." +msgstr "Desconecta a sinal unha vez foi emitida por primeira vez." + +#: editor/connections_dialog.cpp +msgid "Cannot connect signal" +msgstr "No se pode conectar a sinal" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/export_template_manager.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Close" +msgstr "Pechar" + +#: editor/connections_dialog.cpp +msgid "Connect" +msgstr "Conectar" + +#: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "Sinal:" + +#: editor/connections_dialog.cpp +msgid "Connect '%s' to '%s'" +msgstr "Conectar '%s' con '%s'" + +#: editor/connections_dialog.cpp +msgid "Disconnect '%s' from '%s'" +msgstr "Desconectar '%s' de '%s'" + +#: editor/connections_dialog.cpp +msgid "Disconnect all from signal: '%s'" +msgstr "Desconectar todo da sinal: '%s'" + +#: editor/connections_dialog.cpp +msgid "Connect..." +msgstr "Conectar..." + +#: editor/connections_dialog.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Disconnect" +msgstr "Desconectar" + +#: editor/connections_dialog.cpp +msgid "Connect a Signal to a Method" +msgstr "Conectar unha Sinal a un Método" + +#: editor/connections_dialog.cpp +msgid "Edit Connection:" +msgstr "Editar Conexión:" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from the \"%s\" signal?" +msgstr "Está seguro de que quere eliminar tódalas conexións da sinal '%s'?" + +#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp +msgid "Signals" +msgstr "Sinais" + +#: editor/connections_dialog.cpp +msgid "Filter signals" +msgstr "Filtrar sinais" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from this signal?" +msgstr "Está seguro de que quere eliminar tódalas conexións desta sinal?" + +#: editor/connections_dialog.cpp +msgid "Disconnect All" +msgstr "Desconectar Todas" + +#: editor/connections_dialog.cpp +msgid "Edit..." +msgstr "Editar..." + +#: editor/connections_dialog.cpp +msgid "Go To Method" +msgstr "Ir ao Método" + +#: editor/create_dialog.cpp +msgid "Change %s Type" +msgstr "Cambiar o Tipo de %s" + +#: editor/create_dialog.cpp editor/project_settings_editor.cpp +msgid "Change" +msgstr "Cambiar" + +#: editor/create_dialog.cpp +msgid "Create New %s" +msgstr "Crear Novo %s" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp +msgid "Favorites:" +msgstr "Favoritos:" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +msgid "Recent:" +msgstr "Recente:" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search:" +msgstr "Buscar:" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Matches:" +msgstr "Coincidencias:" + +#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp +#: editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Description:" +msgstr "Descrición:" + +#: editor/dependency_editor.cpp +msgid "Search Replacement For:" +msgstr "Buscar Substitución Para:" + +#: editor/dependency_editor.cpp +msgid "Dependencies For:" +msgstr "Dependencias De:" + +#: editor/dependency_editor.cpp +msgid "" +"Scene '%s' is currently being edited.\n" +"Changes will only take effect when reloaded." +msgstr "" +"A escena '%s' agora mesmo está sendo editada.\n" +"Os cambios só terán efecto cando sexa recargada." + +#: editor/dependency_editor.cpp +msgid "" +"Resource '%s' is in use.\n" +"Changes will only take effect when reloaded." +msgstr "" +"O recurso '%s' agora mesmo está sendo usado.\n" +"Os cambios só terán efecto cando sexa recargado." + +#: editor/dependency_editor.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dependencies" +msgstr "Dependencias" + +#: editor/dependency_editor.cpp +msgid "Resource" +msgstr "Recurso" + +#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp +#: editor/project_manager.cpp editor/project_settings_editor.cpp +msgid "Path" +msgstr "Ruta" + +#: editor/dependency_editor.cpp +msgid "Dependencies:" +msgstr "Dependencias:" + +#: editor/dependency_editor.cpp +msgid "Fix Broken" +msgstr "Corrixir Erros" + +#: editor/dependency_editor.cpp +msgid "Dependency Editor" +msgstr "Editor de Dependencias" + +#: editor/dependency_editor.cpp +msgid "Search Replacement Resource:" +msgstr "Buscar Recurso de Substitución:" + +#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +#: scene/gui/file_dialog.cpp +msgid "Open" +msgstr "Abrir" + +#: editor/dependency_editor.cpp +msgid "Owners Of:" +msgstr "Dono De:" + +#: editor/dependency_editor.cpp +msgid "" +"Remove selected files from the project? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" +"Eliminar do proxecto os arquivos seleccionados? (non se pode reverter)\n" +"Podes encontrar os arquivos eliminados na papeleira de reciclaxe do sistema " +"para restaurarlos." + +#: editor/dependency_editor.cpp +msgid "" +"The files being removed are required by other resources in order for them to " +"work.\n" +"Remove them anyway? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" +"Os arquivos sendo eliminados están requeridos por outros recursos para poder " +"funcionar.\n" +"Eliminalos de todas formas? (non se pode reverter)\n" +"Podes encontrar os arquivos eliminados na papeleira de reciclaxe do sistema " +"para restaurarlos." + +#: editor/dependency_editor.cpp +msgid "Cannot remove:" +msgstr "Non se pode eliminar:" + +#: editor/dependency_editor.cpp +msgid "Error loading:" +msgstr "Erro cargando:" + +#: editor/dependency_editor.cpp +msgid "Load failed due to missing dependencies:" +msgstr "Fallou a carga debido a dependencias ausentes:" + +#: editor/dependency_editor.cpp editor/editor_node.cpp +msgid "Open Anyway" +msgstr "Abrir de Todos Modos" + +#: editor/dependency_editor.cpp +msgid "Which action should be taken?" +msgstr "Que acción deberÃa de tomarse?" + +#: editor/dependency_editor.cpp +msgid "Fix Dependencies" +msgstr "Corrixir Dependencias" + +#: editor/dependency_editor.cpp +msgid "Errors loading!" +msgstr "Erros na carga!" + +#: editor/dependency_editor.cpp +msgid "Permanently delete %d item(s)? (No undo!)" +msgstr "Eliminar permanentemente %d obxectos? (Non se pode reverter!)" + +#: editor/dependency_editor.cpp +msgid "Show Dependencies" +msgstr "Amosar Dependencias" + +#: editor/dependency_editor.cpp +msgid "Orphan Resource Explorer" +msgstr "Explorador de Recursos Orfos" + +#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp +msgid "Delete" +msgstr "Eliminar" + +#: editor/dependency_editor.cpp +msgid "Owns" +msgstr "É Dono de" + +#: editor/dependency_editor.cpp +msgid "Resources Without Explicit Ownership:" +msgstr "Recursos Sen Dono ExplÃcito:" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Key" +msgstr "Cambiar Chave do Dicionario" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Value" +msgstr "Cambiar Valor do Dicionario" + +#: editor/editor_about.cpp +msgid "Thanks from the Godot community!" +msgstr "Moitas grazas de parte da comunidade de Godot!" + +#: editor/editor_about.cpp +msgid "Godot Engine contributors" +msgstr "Colaboradores de Godot Engine" + +#: editor/editor_about.cpp +msgid "Project Founders" +msgstr "Fundadores do Proxecto" + +#: editor/editor_about.cpp +msgid "Lead Developer" +msgstr "Desenvolvedor LÃder" + +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. +#: editor/editor_about.cpp +msgid "Project Manager " +msgstr "Xestor do Proxecto " + +#: editor/editor_about.cpp +msgid "Developers" +msgstr "Desenvolvedores" + +#: editor/editor_about.cpp +msgid "Authors" +msgstr "Autores" + +#: editor/editor_about.cpp +msgid "Platinum Sponsors" +msgstr "Patrocinadores Platino" + +#: editor/editor_about.cpp +msgid "Gold Sponsors" +msgstr "Patrocinadores Ouro" + +#: editor/editor_about.cpp +msgid "Silver Sponsors" +msgstr "Patrocinadores Prata" + +#: editor/editor_about.cpp +msgid "Bronze Sponsors" +msgstr "Patrocinadores Bronce" + +#: editor/editor_about.cpp +msgid "Mini Sponsors" +msgstr "Patrocinadores Mini" + +#: editor/editor_about.cpp +msgid "Gold Donors" +msgstr "Doadores Ouro" + +#: editor/editor_about.cpp +msgid "Silver Donors" +msgstr "Doadores Prata" + +#: editor/editor_about.cpp +msgid "Bronze Donors" +msgstr "Doadores Bronce" + +#: editor/editor_about.cpp +msgid "Donors" +msgstr "Doadores" + +#: editor/editor_about.cpp +msgid "License" +msgstr "Licenza" + +#: editor/editor_about.cpp +msgid "Third-party Licenses" +msgstr "Licenzas de Terceiros" + +#: editor/editor_about.cpp +msgid "" +"Godot Engine relies on a number of third-party free and open source " +"libraries, all compatible with the terms of its MIT license. The following " +"is an exhaustive list of all such third-party components with their " +"respective copyright statements and license terms." +msgstr "" +"Godot Engine depende dun número de bibliotecas de terceiros, gratis e open " +"source; todas compatibles cos termos da licenza MIT. A seguinte e unha lista " +"exhaustiva dos devanditos compoñentes de terceiros, coas suas respectivas " +"declaracións de copyright e termos de licenza." + +#: editor/editor_about.cpp +msgid "All Components" +msgstr "Todos os Compoñentes" + +#: editor/editor_about.cpp +msgid "Components" +msgstr "Compoñentes" + +#: editor/editor_about.cpp +msgid "Licenses" +msgstr "Licenzas" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Error opening package file, not in ZIP format." +msgstr "Erro ao abrir o arquivo comprimido, non está en formato ZIP." + +#: editor/editor_asset_installer.cpp +msgid "%s (Already Exists)" +msgstr "%s (Xa Existe)" + +#: editor/editor_asset_installer.cpp +msgid "Uncompressing Assets" +msgstr "Descomprimindo Assets" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "The following files failed extraction from package:" +msgstr "Os seguintes arquivos non se poideron extraer do paquete:" + +#: editor/editor_asset_installer.cpp +msgid "And %s more files." +msgstr "E %s arquivos máis." + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Package installed successfully!" +msgstr "Paquete instalado correctamente!" + +#: editor/editor_asset_installer.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Success!" +msgstr "Éxito!" + +#: editor/editor_asset_installer.cpp +msgid "Package Contents:" +msgstr "Contenido do Paquete:" + +#: editor/editor_asset_installer.cpp editor/editor_node.cpp +msgid "Install" +msgstr "Instalar" + +#: editor/editor_asset_installer.cpp +msgid "Package Installer" +msgstr "Instalador de Paquetes" + +#: editor/editor_audio_buses.cpp +msgid "Speakers" +msgstr "Altofalantes" + +#: editor/editor_audio_buses.cpp +msgid "Add Effect" +msgstr "Engadir Efecto" + +#: editor/editor_audio_buses.cpp +msgid "Rename Audio Bus" +msgstr "Renomear Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Change Audio Bus Volume" +msgstr "Cambiar Volume do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Solo" +msgstr "Act./Desact. Solo do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Mute" +msgstr "Act./Desact. Silencio do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Bypass Effects" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Select Audio Bus Send" +msgstr "Seleccionar EnvÃo do Bus de Audio" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus Effect" +msgstr "Engadir Efecto ao Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Move Bus Effect" +msgstr "Mover Efecto do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Delete Bus Effect" +msgstr "Eliminar Efecto do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Drag & drop to rearrange." +msgstr "Arrastrar e soltar para reordenar." + +#: editor/editor_audio_buses.cpp +msgid "Solo" +msgstr "Solo" + +#: editor/editor_audio_buses.cpp +msgid "Mute" +msgstr "Silenciar" + +#: editor/editor_audio_buses.cpp +msgid "Bypass" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Bus options" +msgstr "Opcións de Bus" + +#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Duplicate" +msgstr "Duplicar" + +#: editor/editor_audio_buses.cpp +msgid "Reset Volume" +msgstr "Restablecer Volume" + +#: editor/editor_audio_buses.cpp +msgid "Delete Effect" +msgstr "Eliminar Efecto" + +#: editor/editor_audio_buses.cpp +msgid "Audio" +msgstr "Son" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus" +msgstr "Engadir Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Master bus can't be deleted!" +msgstr "Non se pode eliminar o Bus mestre!" + +#: editor/editor_audio_buses.cpp +msgid "Delete Audio Bus" +msgstr "Eliminar Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Duplicate Audio Bus" +msgstr "Duplicar Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Reset Bus Volume" +msgstr "Restablecer Volume do Bus" + +#: editor/editor_audio_buses.cpp +msgid "Move Audio Bus" +msgstr "Mover Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Save Audio Bus Layout As..." +msgstr "Gardar Disposición do Bus de Son Como..." + +#: editor/editor_audio_buses.cpp +msgid "Location for New Layout..." +msgstr "Localización para a Nova Disposición..." + +#: editor/editor_audio_buses.cpp +msgid "Open Audio Bus Layout" +msgstr "Abrir Disposición do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "There is no '%s' file." +msgstr "Non hai ningún arquivo '%s'." + +#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp +msgid "Layout" +msgstr "Disposición" + +#: editor/editor_audio_buses.cpp +msgid "Invalid file, not an audio bus layout." +msgstr "Arquivo invalido; non é unha disposición dun Bus de son." + +#: editor/editor_audio_buses.cpp +msgid "Error saving file: %s" +msgstr "Erro gardando o arquivo: %s" + +#: editor/editor_audio_buses.cpp +msgid "Add Bus" +msgstr "Engadir Bus" + +#: editor/editor_audio_buses.cpp +msgid "Add a new Audio Bus to this layout." +msgstr "Engadir un novo Bus de Son a esta disposición." + +#: editor/editor_audio_buses.cpp editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Load" +msgstr "Cargar" + +#: editor/editor_audio_buses.cpp +msgid "Load an existing Bus Layout." +msgstr "Cargar unha disposición de Bus xa existente." + +#: editor/editor_audio_buses.cpp +msgid "Save As" +msgstr "Gardar Como" + +#: editor/editor_audio_buses.cpp +msgid "Save this Bus Layout to a file." +msgstr "Gardar esta disposición de Bus a un arquivo." + +#: editor/editor_audio_buses.cpp editor/import_dock.cpp +msgid "Load Default" +msgstr "Cargar Valores por Defecto" + +#: editor/editor_audio_buses.cpp +msgid "Load the default Bus Layout." +msgstr "Cargar a disposición de Bus por defecto." + +#: editor/editor_audio_buses.cpp +msgid "Create a new Bus Layout." +msgstr "Crear unha nova Disposición de Bus." + +#: editor/editor_autoload_settings.cpp +msgid "Invalid name." +msgstr "Nome inválido." + +#: editor/editor_autoload_settings.cpp +msgid "Valid characters:" +msgstr "Caracteres válidos:" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing engine class name." +msgstr "Non debe coincidir co nome dunha clase xa existente no engine." + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing built-in type name." +msgstr "Non debe coincidir co nome dun tipo xa existente no engine." + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing global constant name." +msgstr "Non debe coincidir co nome dunha constante global xa existente." + +#: editor/editor_autoload_settings.cpp +msgid "Keyword cannot be used as an autoload name." +msgstr "Unha palabra clave non pode usarse como nome dun AutoCargador." + +#: editor/editor_autoload_settings.cpp +msgid "Autoload '%s' already exists!" +msgstr "Xa existe un AutoCargador nomeado '%s'!" + +#: editor/editor_autoload_settings.cpp +msgid "Rename Autoload" +msgstr "Renomear AutoCargador" + +#: editor/editor_autoload_settings.cpp +msgid "Toggle AutoLoad Globals" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Move Autoload" +msgstr "Mover AutoCargador" + +#: editor/editor_autoload_settings.cpp +msgid "Remove Autoload" +msgstr "Eliminar AutoCargador" + +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp +msgid "Enable" +msgstr "Activar" + +#: editor/editor_autoload_settings.cpp +msgid "Rearrange Autoloads" +msgstr "Reordenar AutoCargadores" + +#: editor/editor_autoload_settings.cpp +msgid "Can't add autoload:" +msgstr "Non se puido engadir AutoCargador:" + +#: editor/editor_autoload_settings.cpp +msgid "Add AutoLoad" +msgstr "Engadir AutoCargador" + +#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp +msgid "Path:" +msgstr "Ruta:" + +#: editor/editor_autoload_settings.cpp +msgid "Node Name:" +msgstr "Nome do Nodo:" + +#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp +#: editor/editor_profiler.cpp editor/project_manager.cpp +#: editor/settings_config_dialog.cpp +msgid "Name" +msgstr "Nome" + +#: editor/editor_autoload_settings.cpp +msgid "Singleton" +msgstr "" + +#: editor/editor_data.cpp editor/inspector_dock.cpp +msgid "Paste Params" +msgstr "Pegar Parámetros" + +#: editor/editor_data.cpp +msgid "Updating Scene" +msgstr "Actualizando Escena" + +#: editor/editor_data.cpp +msgid "Storing local changes..." +msgstr "Gardando cambios locales..." + +#: editor/editor_data.cpp +msgid "Updating scene..." +msgstr "Actualizando escena..." + +#: editor/editor_data.cpp editor/editor_properties.cpp +msgid "[empty]" +msgstr "[baleiro]" + +#: editor/editor_data.cpp +msgid "[unsaved]" +msgstr "[non gardado]" + +#: editor/editor_dir_dialog.cpp +msgid "Please select a base directory first." +msgstr "Por favor, seleccione primeiro un directorio base." + +#: editor/editor_dir_dialog.cpp +msgid "Choose a Directory" +msgstr "Elixir un Directorio" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +#: scene/gui/file_dialog.cpp +msgid "Create Folder" +msgstr "Crear Cartafol" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp +#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp +msgid "Name:" +msgstr "Nome:" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp +msgid "Could not create folder." +msgstr "Non se puido crear cartafol." + +#: editor/editor_dir_dialog.cpp +msgid "Choose" +msgstr "Elixir" + +#: editor/editor_export.cpp +msgid "Storing File:" +msgstr "Gardando Arquivo:" + +#: editor/editor_export.cpp +msgid "No export template found at the expected path:" +msgstr "Non se encontrou ningún modelo de exportación na ruta esperada:" + +#: editor/editor_export.cpp +msgid "Packing" +msgstr "Empaquetando" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " +"Etc' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'ETC' para GLES2. Active " +"'Importar Etc' na 'Configuración do Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' texture compression for GLES3. Enable " +"'Import Etc 2' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'ETC2' para GLES3. Active " +"'Importar Etc 2' na 'Configuración do Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" +"A plataforma actual require unha compresión de texturas 'ETC' para o " +"controlador de respaldo a GLES2.\n" +"Active 'Importar Etc' na 'Configuración do Proxecto' ou desactive " +"'Controlador de Respaldo Activado'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for GLES2. Enable " +"'Import Pvrtc' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'PVRTC' para GLES2. " +"Active 'Importar Pvrtc' na 'Configuración do Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " +"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'ETC2' ou 'PVRTC' para " +"GLES3. Active 'Importar Etc 2' ou 'Importar Pvrtc' na 'Configuración do " +"Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" +"A plataforma actual require unha compresión de texturas 'PVRTC' para o " +"controlador de respaldo a GLES2.\n" +"Active 'Importar Pvrtc' na 'Configuración do Proxecto' ou desactive " +"'Controlador de Respaldo Activado'." + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom debug template not found." +msgstr "Non se encontrou un modelo de depuración personalizado." + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom release template not found." +msgstr "" + +#: editor/editor_export.cpp platform/javascript/export/export.cpp +msgid "Template file not found:" +msgstr "Non se encontrou o arquivo do modelo:" + +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "Na exportación de 32 bits o PCK integrado non pode ser maior de 4 GiB." + +#: editor/editor_feature_profile.cpp +msgid "3D Editor" +msgstr "Editor 3D" + +#: editor/editor_feature_profile.cpp +msgid "Script Editor" +msgstr "Editor de Scripts" + +#: editor/editor_feature_profile.cpp +msgid "Asset Library" +msgstr "Biblioteca de Assets" + +#: editor/editor_feature_profile.cpp +msgid "Scene Tree Editing" +msgstr "Edición de Ãrbore de Escenas" + +#: editor/editor_feature_profile.cpp +msgid "Node Dock" +msgstr "Panel de Nodos" + +#: editor/editor_feature_profile.cpp +msgid "FileSystem Dock" +msgstr "Panel de Sistema de Arquivos" + +#: editor/editor_feature_profile.cpp +msgid "Import Dock" +msgstr "Panel de Importación" + +#: editor/editor_feature_profile.cpp +msgid "Erase profile '%s'? (no undo)" +msgstr "Eliminar perfil '%s'? (non se pode deshacer)" + +#: editor/editor_feature_profile.cpp +msgid "Profile must be a valid filename and must not contain '.'" +msgstr "Un perfil debe ter un nome de arquivo válido, e non pode conter '.'" + +#: editor/editor_feature_profile.cpp +msgid "Profile with this name already exists." +msgstr "Un perfil con este nome xa existe." + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled, Properties Disabled)" +msgstr "(Editor Desactivado, Propiedades Desactivadas)" + +#: editor/editor_feature_profile.cpp +msgid "(Properties Disabled)" +msgstr "(Propiedades Desactivadas)" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled)" +msgstr "(Editor Desactivado)" + +#: editor/editor_feature_profile.cpp +msgid "Class Options:" +msgstr "Opcións de Clase:" + +#: editor/editor_feature_profile.cpp +msgid "Enable Contextual Editor" +msgstr "Activar o Editor Contextual" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Properties:" +msgstr "Propiedades Activadas:" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Features:" +msgstr "CaracterÃsticas Activadas:" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Classes:" +msgstr "Clases Activadas:" + +#: editor/editor_feature_profile.cpp +msgid "File '%s' format is invalid, import aborted." +msgstr "O formato '%s' do arquivo non é válido, a importación foi cancelada." + +#: editor/editor_feature_profile.cpp +msgid "" +"Profile '%s' already exists. Remove it first before importing, import " +"aborted." +msgstr "" +"O perfil '%s' xa existe. ElimÃnao antes de importar; importación abortada." + +#: editor/editor_feature_profile.cpp +msgid "Error saving profile to path: '%s'." +msgstr "Erro gardando o perfil á ruta: '%s'." + +#: editor/editor_feature_profile.cpp +msgid "Unset" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Current Profile:" +msgstr "Perfil Actual:" + +#: editor/editor_feature_profile.cpp +msgid "Make Current" +msgstr "Convertelo no Actual" + +#: editor/editor_feature_profile.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "New" +msgstr "Novo" + +#: editor/editor_feature_profile.cpp editor/editor_node.cpp +#: editor/project_manager.cpp +msgid "Import" +msgstr "Importación" + +#: editor/editor_feature_profile.cpp editor/project_export.cpp +msgid "Export" +msgstr "Exportación" + +#: editor/editor_feature_profile.cpp +msgid "Available Profiles:" +msgstr "Perfils Dispoñibles:" + +#: editor/editor_feature_profile.cpp +msgid "Class Options" +msgstr "Opcións de Clase" + +#: editor/editor_feature_profile.cpp +msgid "New profile name:" +msgstr "Nome do novo perfil:" + +#: editor/editor_feature_profile.cpp +msgid "Erase Profile" +msgstr "Eliminar Perfil" + +#: editor/editor_feature_profile.cpp +msgid "Godot Feature Profile" +msgstr "Perfil de CaracterÃsticas de Godot" + +#: editor/editor_feature_profile.cpp +msgid "Import Profile(s)" +msgstr "Importar Perfil(s)" + +#: editor/editor_feature_profile.cpp +msgid "Export Profile" +msgstr "Exportar Perfil" + +#: editor/editor_feature_profile.cpp +msgid "Manage Editor Feature Profiles" +msgstr "Administrar Perfils de CaracterÃsticas de Godot" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select Current Folder" +msgstr "Seleccionar Cartafol Actual" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File Exists, Overwrite?" +msgstr "O arquivo xa existe ¿Queres sobreescribilo?" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select This Folder" +msgstr "Seleccionar Este Cartafol" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Copy Path" +msgstr "Copiar Ruta" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Open in File Manager" +msgstr "Abrir no Explorador de Arquivos" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +msgid "Show in File Manager" +msgstr "Amosar no Explorador de Arquivos" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "New Folder..." +msgstr "Novo Cartafol..." + +#: editor/editor_file_dialog.cpp editor/find_in_files.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Refresh" +msgstr "Actualizar" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Recognized" +msgstr "Todos Recoñecidos" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Files (*)" +msgstr "Todos os Arquivos (*)" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File" +msgstr "Abrir un Arquivo" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open File(s)" +msgstr "Abrir Arquivo(s)" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a Directory" +msgstr "Abrir un Directorio" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File or Directory" +msgstr "Abrir un Arquivo ou Directorio" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/editor_properties.cpp editor/inspector_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp +msgid "Save" +msgstr "Gardar" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Save a File" +msgstr "Gardar un Arquivo" + +#: editor/editor_file_dialog.cpp +msgid "Go Back" +msgstr "Retroceder" + +#: editor/editor_file_dialog.cpp +msgid "Go Forward" +msgstr "Avanzar" + +#: editor/editor_file_dialog.cpp +msgid "Go Up" +msgstr "Subir" + +#: editor/editor_file_dialog.cpp +#, fuzzy +msgid "Toggle Hidden Files" +msgstr "Amosar/Ocultar Arquivos Ocultos" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Favorite" +msgstr "Act./Desact. Favorito" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Mode" +msgstr "Act./Desact. Modo" + +#: editor/editor_file_dialog.cpp +msgid "Focus Path" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Up" +msgstr "Subir Favorito" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Down" +msgstr "Baixar Favorito" + +#: editor/editor_file_dialog.cpp +msgid "Go to previous folder." +msgstr "Ir ao cartafol anterior." + +#: editor/editor_file_dialog.cpp +msgid "Go to next folder." +msgstr "Ir ao cartafol seguinte." + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Go to parent folder." +msgstr "Ir ao cartafol padre." + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Refresh files." +msgstr "Actualizar Arquivos." + +#: editor/editor_file_dialog.cpp +msgid "(Un)favorite current folder." +msgstr "Quitar cartafol actual de favoritos." + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Toggle the visibility of hidden files." +msgstr "Amosar/Ocultar arquivos ocultos." + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a grid of thumbnails." +msgstr "Ver elementos coma unha cuadrÃcula de miniaturas." + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a list." +msgstr "Ver elementos coma unha lista." + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Directories & Files:" +msgstr "Directorios e Arquivos:" + +#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp +#: editor/plugins/style_box_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Preview:" +msgstr "Vista Previa:" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File:" +msgstr "Arquivo:" + +#: editor/editor_file_system.cpp +msgid "ScanSources" +msgstr "Escanear Fontes" + +#: editor/editor_file_system.cpp +msgid "" +"There are multiple importers for different types pointing to file %s, import " +"aborted" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "(Re)Importing Assets" +msgstr "(Re)Importando Assets" + +#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp +msgid "Top" +msgstr "Superior" + +#: editor/editor_help.cpp +msgid "Class:" +msgstr "Clase:" + +#: editor/editor_help.cpp editor/scene_tree_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Inherits:" +msgstr "Herda de:" + +#: editor/editor_help.cpp +msgid "Inherited by:" +msgstr "Herdado de:" + +#: editor/editor_help.cpp +msgid "Description" +msgstr "Descrición" + +#: editor/editor_help.cpp +msgid "Online Tutorials" +msgstr "Tutoriales en liña" + +#: editor/editor_help.cpp +msgid "Properties" +msgstr "Propiedades" + +#: editor/editor_help.cpp +msgid "override:" +msgstr "sobrescribir:" + +#: editor/editor_help.cpp +msgid "default:" +msgstr "por defecto:" + +#: editor/editor_help.cpp +msgid "Methods" +msgstr "Métodos" + +#: editor/editor_help.cpp +#, fuzzy +msgid "Theme Properties" +msgstr "Propiedades do Tema" + +#: editor/editor_help.cpp +msgid "Enumerations" +msgstr "" + +#: editor/editor_help.cpp +msgid "Constants" +msgstr "Constantes" + +#: editor/editor_help.cpp +msgid "Property Descriptions" +msgstr "Descrición de Propiedades" + +#: editor/editor_help.cpp +msgid "(value)" +msgstr "(valor)" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this property. Please help us by " +"[color=$color][url=$url]contributing one[/url][/color]!" +msgstr "" +"Actualmente non hai unha descripción desta propiedade. Axúdanos [color=" +"$color][url=$url]contribuÃndo cunha descripción[/url][/color]!" + +#: editor/editor_help.cpp +msgid "Method Descriptions" +msgstr "Descrición de Métodos" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this method. Please help us by [color=" +"$color][url=$url]contributing one[/url][/color]!" +msgstr "" +"Actualmente non hai unha descripción deste método. Axúdanos [color=$color]" +"[url=$url]contribuÃndo cunha descripción[/url][/color]!" + +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Help" +msgstr "Buscar na Axuda" + +#: editor/editor_help_search.cpp +msgid "Case Sensitive" +msgstr "Distinguir MaÃusculas e Minúsculas" + +#: editor/editor_help_search.cpp +msgid "Show Hierarchy" +msgstr "Amosar XerarquÃa" + +#: editor/editor_help_search.cpp +msgid "Display All" +msgstr "Amosar Todo" + +#: editor/editor_help_search.cpp +msgid "Classes Only" +msgstr "Só Clases" + +#: editor/editor_help_search.cpp +msgid "Methods Only" +msgstr "Só Métodos" + +#: editor/editor_help_search.cpp +msgid "Signals Only" +msgstr "Só Sinais" + +#: editor/editor_help_search.cpp +msgid "Constants Only" +msgstr "Só Constantes" + +#: editor/editor_help_search.cpp +msgid "Properties Only" +msgstr "Só Propiedades" + +#: editor/editor_help_search.cpp +msgid "Theme Properties Only" +msgstr "Só Propiedades de Temas" + +#: editor/editor_help_search.cpp +msgid "Member Type" +msgstr "Tipo do Membro" + +#: editor/editor_help_search.cpp +msgid "Class" +msgstr "Clase" + +#: editor/editor_help_search.cpp +msgid "Method" +msgstr "Método" + +#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp +msgid "Signal" +msgstr "Sinal" + +#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp +msgid "Constant" +msgstr "Constante" + +#: editor/editor_help_search.cpp +msgid "Property" +msgstr "Propiedade" + +#: editor/editor_help_search.cpp +msgid "Theme Property" +msgstr "Propiedade de Temas" + +#: editor/editor_inspector.cpp editor/project_settings_editor.cpp +msgid "Property:" +msgstr "Propiedade:" + +#: editor/editor_inspector.cpp +msgid "Set" +msgstr "Establecer" + +#: editor/editor_inspector.cpp +msgid "Set Multiple:" +msgstr "Establecer Varios:" + +#: editor/editor_log.cpp +msgid "Output:" +msgstr "SaÃda:" + +#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Copy Selection" +msgstr "Copiar Selección" + +#: editor/editor_log.cpp editor/editor_network_profiler.cpp +#: editor/editor_profiler.cpp editor/editor_properties.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/property_editor.cpp editor/scene_tree_dock.cpp +#: editor/script_editor_debugger.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Clear" +msgstr "Limpar" + +#: editor/editor_log.cpp +msgid "Clear Output" +msgstr "Limpar SaÃda" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +#: editor/editor_profiler.cpp +msgid "Stop" +msgstr "Deter" + +#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp +#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp +msgid "Start" +msgstr "Iniciar" + +#: editor/editor_network_profiler.cpp +msgid "%s/s" +msgstr "%s/s" + +#: editor/editor_network_profiler.cpp +msgid "Down" +msgstr "Baixada" + +#: editor/editor_network_profiler.cpp +msgid "Up" +msgstr "Subida" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +msgid "Node" +msgstr "Nodo" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RPC" +msgstr "RPC Entrante" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RSET" +msgstr "RSET Entrante" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RPC" +msgstr "RPC SaÃnte" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RSET" +msgstr "RSET SaÃnte" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "New Window" +msgstr "Nova Xanela" + +#: editor/editor_node.cpp +msgid "Imported resources can't be saved." +msgstr "Os recursos importados non se poden gardar." + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: scene/gui/dialogs.cpp +msgid "OK" +msgstr "Vale" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Error saving resource!" +msgstr "Erro gardando o recurso!" + +#: editor/editor_node.cpp +msgid "" +"This resource can't be saved because it does not belong to the edited scene. " +"Make it unique first." +msgstr "" +"Este recurso non pode gardarse porque non pertence á escena actual. Primero " +"fágao único." + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Save Resource As..." +msgstr "Gardar Recurso Como..." + +#: editor/editor_node.cpp +msgid "Can't open file for writing:" +msgstr "Non se puido abrir o arquivo para escritura:" + +#: editor/editor_node.cpp +msgid "Requested file format unknown:" +msgstr "O formato do arquivo solicitado é descoñecido:" + +#: editor/editor_node.cpp +msgid "Error while saving." +msgstr "Erro ao gardar." + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Can't open '%s'. The file could have been moved or deleted." +msgstr "" +"Non se puido abrir '%s'. Pode ser que o arquivo fose movido ou eliminado." + +#: editor/editor_node.cpp +msgid "Error while parsing '%s'." +msgstr "Erro ao analizar sintacticamente '%s'." + +#: editor/editor_node.cpp +msgid "Unexpected end of file '%s'." +msgstr "Fin de arquivo inesperado en '%s'." + +#: editor/editor_node.cpp +msgid "Missing '%s' or its dependencies." +msgstr "Non se encontrou '%s' ou as súas dependencias." + +#: editor/editor_node.cpp +msgid "Error while loading '%s'." +msgstr "Erro ao cargar '%s'." + +#: editor/editor_node.cpp +msgid "Saving Scene" +msgstr "Gardando Escena" + +#: editor/editor_node.cpp +msgid "Analyzing" +msgstr "Analizando" + +#: editor/editor_node.cpp +msgid "Creating Thumbnail" +msgstr "Creando Miniatura" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a tree root." +msgstr "Esta operación non pode realizarse sen un nodo raÃz." + +#: editor/editor_node.cpp +msgid "" +"This scene can't be saved because there is a cyclic instancing inclusion.\n" +"Please resolve it and then attempt to save again." +msgstr "" +"Esta escena non pode gardarse porque hai unha relación de instanciación " +"cÃclica con outra escena.\n" +"Por favor, solucione o problema e inténteo de novo." + +#: editor/editor_node.cpp +msgid "" +"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " +"be satisfied." +msgstr "" +"Non se puido gardar a escena. Posiblemente as dependencias (instancias ou " +"herenzas) non puideron satisfacerse." + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "Can't overwrite scene that is still open!" +msgstr "Non se pode sobreescribir escena que sigue aberta!" + +#: editor/editor_node.cpp +msgid "Can't load MeshLibrary for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving MeshLibrary!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load TileSet for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving TileSet!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"An error occurred while trying to save the editor layout.\n" +"Make sure the editor's user data path is writable." +msgstr "" +"Produciuse un erro mentres se trataba de gardar a disposición das ventás do " +"editor.\n" +"Asegúrese de que o cartafol do editor ten dereitos de escritura." + +#: editor/editor_node.cpp +msgid "" +"Default editor layout overridden.\n" +"To restore the Default layout to its base settings, use the Delete Layout " +"option and delete the Default layout." +msgstr "" +"A disposición por defecto do editor foi sobreescrita.\n" +"Para devolver a disposición por defecto a súa configuración orixinal, usa a " +"opción 'Eliminar Disposición' e elimina a Disposición por defecto." + +#: editor/editor_node.cpp +msgid "Layout name not found!" +msgstr "Nome de disposición non encontrada!" + +#: editor/editor_node.cpp +msgid "Restored the Default layout to its base settings." +msgstr "Restableceuse a disposición por defecto aos seus valores orixinais." + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was imported, so it's not editable.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" +"Este recurso pertence a unha escena importada, polo que non é editable.\n" +"Por favor; lea a documentación referente a importación de escenas para " +"entender o fluxo de traballo." + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was instanced or inherited.\n" +"Changes to it won't be kept when saving the current scene." +msgstr "" +"Este recurso pertence a unha escena instanciada ou herdada.\n" +"Os cambios que lle faga non se gardarán cando garde a escena actual." + +#: editor/editor_node.cpp +msgid "" +"This resource was imported, so it's not editable. Change its settings in the " +"import panel and then re-import." +msgstr "" +"Este recurso foi importado, polo que non é editable. Cambia a súa " +"configuración no panel de importación, e reimportao." + +#: editor/editor_node.cpp +msgid "" +"This scene was imported, so changes to it won't be kept.\n" +"Instancing it or inheriting will allow making changes to it.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" +"Esta escena foi importada, polo que cambios na escena non serán gardados.\n" +"Instanciala ou herdala permitirá facerlle cambios permanentes.\n" +"Por favor, lea a documentación referente a importación de escenas para " +"entender o fluxo de traballo." + +#: editor/editor_node.cpp +msgid "" +"This is a remote object, so changes to it won't be kept.\n" +"Please read the documentation relevant to debugging to better understand " +"this workflow." +msgstr "" +"Este é un obxecto remoto, polo que os cambios que lle faga non serán " +"permanentes.\n" +"Por favor; lea a documentación referente a depuración para entender o fluxo " +"de traballo." + +#: editor/editor_node.cpp +msgid "There is no defined scene to run." +msgstr "Non hai unha escena definida para executar." + +#: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Garda a escena antes de executala..." + +#: editor/editor_node.cpp +msgid "Could not start subprocess!" +msgstr "Non se puido iniciar subproceso!" + +#: editor/editor_node.cpp editor/filesystem_dock.cpp +msgid "Open Scene" +msgstr "Abrir Escena" + +#: editor/editor_node.cpp +msgid "Open Base Scene" +msgstr "Abrir Escena Base" + +#: editor/editor_node.cpp +msgid "Quick Open..." +msgstr "Apertura Rápida..." + +#: editor/editor_node.cpp +msgid "Quick Open Scene..." +msgstr "Apertura Rápida de Escena..." + +#: editor/editor_node.cpp +msgid "Quick Open Script..." +msgstr "Apertura Rápida de Script..." + +#: editor/editor_node.cpp +msgid "Save & Close" +msgstr "Gardar e Pechar" + +#: editor/editor_node.cpp +msgid "Save changes to '%s' before closing?" +msgstr "Gardar os cambios de '%s' antes de pechar?" + +#: editor/editor_node.cpp +msgid "Saved %s modified resource(s)." +msgstr "Gardado(s) %s recurso(s) modificado(s)." + +#: editor/editor_node.cpp +msgid "A root node is required to save the scene." +msgstr "NecesÃtase un nodo raÃz para gardar a escena." + +#: editor/editor_node.cpp +msgid "Save Scene As..." +msgstr "Gardar Escena Como..." + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "This operation can't be done without a scene." +msgstr "Esta operación non pode realizarse se unha escena." + +#: editor/editor_node.cpp +msgid "Export Mesh Library" +msgstr "Exportar Biblioteca de Mallas" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a root node." +msgstr "Esta operación non pode realizarse sen un nodo raÃz." + +#: editor/editor_node.cpp +msgid "Export Tile Set" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a selected node." +msgstr "Esta operación non pode realizarse sen un nodo seleccionado." + +#: editor/editor_node.cpp +msgid "Current scene not saved. Open anyway?" +msgstr "Escena actual non gardada ¿Abrir de todos os modos?" + +#: editor/editor_node.cpp +msgid "Can't reload a scene that was never saved." +msgstr "Non se pode volver a cargar unha escena que nunca foi gardada." + +#: editor/editor_node.cpp +msgid "Reload Saved Scene" +msgstr "Recargar Escena Gardada" + +#: editor/editor_node.cpp +msgid "" +"The current scene has unsaved changes.\n" +"Reload the saved scene anyway? This action cannot be undone." +msgstr "" +"A escena actual ten cambios non gardados.\n" +"Quere volver a cargar a escena cargada de todos os modos? Esta acción non se " +"pode deshacer." + +#: editor/editor_node.cpp +msgid "Quick Run Scene..." +msgstr "Execución Rápida de Escena..." + +#: editor/editor_node.cpp +msgid "Quit" +msgstr "SaÃr" + +#: editor/editor_node.cpp +msgid "Yes" +msgstr "Si" + +#: editor/editor_node.cpp +msgid "Exit the editor?" +msgstr "SaÃr do editor?" + +#: editor/editor_node.cpp +msgid "Open Project Manager?" +msgstr "Abrir o Administrador de Proxectos?" + +#: editor/editor_node.cpp +msgid "Save & Quit" +msgstr "Gardar e SaÃr" + +#: editor/editor_node.cpp +msgid "Save changes to the following scene(s) before quitting?" +msgstr "Gardar os cambios nas seguintes escenas antes de saÃr?" + +#: editor/editor_node.cpp +msgid "Save changes the following scene(s) before opening Project Manager?" +msgstr "" +"Gardar os cambios nas seguintes escenas antes de abrir o Administrador de " +"Proxectos?" + +#: editor/editor_node.cpp +msgid "" +"This option is deprecated. Situations where refresh must be forced are now " +"considered a bug. Please report." +msgstr "" +"Esta opción está anticuada. As situacións nas que a actualización debe ser " +"forzada agora considéranse un erro. Por favor, repórtao." + +#: editor/editor_node.cpp +msgid "Pick a Main Scene" +msgstr "Elexir unha Escena Principal" + +#: editor/editor_node.cpp +msgid "Close Scene" +msgstr "Pechar Escena" + +#: editor/editor_node.cpp +msgid "Reopen Closed Scene" +msgstr "Reabrir Escena Pechada" + +#: editor/editor_node.cpp +msgid "Unable to enable addon plugin at: '%s' parsing of config failed." +msgstr "" +"Non se puido activar a caracterÃstica adicional (Plugin): Fallou a análise " +"sintáctica da configuración de '%s'." + +#: editor/editor_node.cpp +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "" +"Non se puido encontrar o campo do Script na caracterÃstica adicional " +"(Plugin) en 'res://addons/%s'." + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s'." +msgstr "" +"Non se puido cargar Script de caracterÃstica adicional (Addon) na ruta: '%s'." + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' There seems to be an error in " +"the code, please check the syntax." +msgstr "" +"Non se puido cargar Script de caracterÃstica adicional (Addon) na ruta: " +"'%s'. Parece que hai un erro no código; por favor, comproba a sintaxe." + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' Base type is not EditorPlugin." +msgstr "" +"Non se puido cargar o Script da caracterÃstica adicional (Plugin): O tipo " +"base de %s non é EditorPlugin." + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s' Script is not in tool mode." +msgstr "" +"Non se puido cargar Script de caracterÃstica adicional (Addon) na ruta: " +"'%s'. O script non está en modo ferramenta (tool)." + +#: editor/editor_node.cpp +msgid "" +"Scene '%s' was automatically imported, so it can't be modified.\n" +"To make changes to it, a new inherited scene can be created." +msgstr "" +"A escena '%s' foi automáticamente importada, polo que non pode modificarse.\n" +"Para facerlle cambios pódese crear unha nova escena herdada." + +#: editor/editor_node.cpp +msgid "" +"Error loading scene, it must be inside the project path. Use 'Import' to " +"open the scene, then save it inside the project path." +msgstr "" +"Erro cargando a escena: debe estar dentro da ruta do proxecto. Usa \"Importar" +"\" para abrir a escena, e despois gardala dentro da ruta do proxecto." + +#: editor/editor_node.cpp +msgid "Scene '%s' has broken dependencies:" +msgstr "A escena '%s' ten dependencias rotas:" + +#: editor/editor_node.cpp +msgid "Clear Recent Scenes" +msgstr "Limpar Escenas Recentes" + +#: editor/editor_node.cpp +msgid "" +"No main scene has ever been defined, select one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" +"Nunca se definiu unha escena principal. Seleccionar unha?\n" +"Podes cambialo despois na \"Configuración do Proxecto\", na categorÃa " +"\"Aplicación\"." + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' does not exist, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" +"A escena seleccionada '%s' non existe. Seleccionar unha válida?\n" +"Podes cambiala despois en \"Configuración do Proxecto\" na categorÃa " +"\"aplicación\"." + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' is not a scene file, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" +"A escena seleccionada '%s' non é un arquivo de escenas. Seleccionar un " +"arquivo válido?\n" +"Podes cambialo despois en \"Configuración do Proxecto\" na categorÃa " +"\"aplicación\"." + +#: editor/editor_node.cpp +msgid "Save Layout" +msgstr "Gardar Disposición" + +#: editor/editor_node.cpp +msgid "Delete Layout" +msgstr "Eliminar Dispoción" + +#: editor/editor_node.cpp editor/import_dock.cpp +#: editor/script_create_dialog.cpp +msgid "Default" +msgstr "Por Defecto" + +#: editor/editor_node.cpp editor/editor_properties.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp +msgid "Show in FileSystem" +msgstr "Amosar no Sistema de Arquivos" + +#: editor/editor_node.cpp +msgid "Play This Scene" +msgstr "Reproducir Esta Escena" + +#: editor/editor_node.cpp +msgid "Close Tab" +msgstr "Pechar Pestana" + +#: editor/editor_node.cpp +msgid "Undo Close Tab" +msgstr "Desfacer Pechar Pestana" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Close Other Tabs" +msgstr "Pechar Outras Pestanas" + +#: editor/editor_node.cpp +msgid "Close Tabs to the Right" +msgstr "Pechar Pestanas á Dereita" + +#: editor/editor_node.cpp +msgid "Close All Tabs" +msgstr "Pechar Todas as Pestanas" + +#: editor/editor_node.cpp +msgid "Switch Scene Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files or folders" +msgstr "%d arquivos ou cartafois máis" + +#: editor/editor_node.cpp +msgid "%d more folders" +msgstr "%d cartafois máis" + +#: editor/editor_node.cpp +msgid "%d more files" +msgstr "%d arquivos máis" + +#: editor/editor_node.cpp +msgid "Dock Position" +msgstr "Posición do Panel" + +#: editor/editor_node.cpp +msgid "Distraction Free Mode" +msgstr "Modo Sen Distraccións" + +#: editor/editor_node.cpp +msgid "Toggle distraction-free mode." +msgstr "Act./Desact. modo sen distraccións." + +#: editor/editor_node.cpp +msgid "Add a new scene." +msgstr "Engadir unha nova escena." + +#: editor/editor_node.cpp +msgid "Scene" +msgstr "Escena" + +#: editor/editor_node.cpp +msgid "Go to previously opened scene." +msgstr "Ir á escena aberta previamente." + +#: editor/editor_node.cpp +msgid "Copy Text" +msgstr "Copiar Texto" + +#: editor/editor_node.cpp +msgid "Next tab" +msgstr "Seguinte pestana" + +#: editor/editor_node.cpp +msgid "Previous tab" +msgstr "Anterior Pestana" + +#: editor/editor_node.cpp +msgid "Filter Files..." +msgstr "Filtrar Arquivos..." + +#: editor/editor_node.cpp +msgid "Operations with scene files." +msgstr "Operacións con arquivos de escenas." + +#: editor/editor_node.cpp +msgid "New Scene" +msgstr "Nova Escena" + +#: editor/editor_node.cpp +msgid "New Inherited Scene..." +msgstr "Nova Escena Herdada..." + +#: editor/editor_node.cpp +msgid "Open Scene..." +msgstr "Abrir Escena..." + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Open Recent" +msgstr "Abrir Recente" + +#: editor/editor_node.cpp +msgid "Save Scene" +msgstr "Gardar Escena" + +#: editor/editor_node.cpp +msgid "Save All Scenes" +msgstr "Gardar Todas as Escenas" + +#: editor/editor_node.cpp +msgid "Convert To..." +msgstr "Converter a..." + +#: editor/editor_node.cpp +msgid "MeshLibrary..." +msgstr "" + +#: editor/editor_node.cpp +msgid "TileSet..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Undo" +msgstr "Desfacer" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Redo" +msgstr "Refacer" + +#: editor/editor_node.cpp +msgid "Miscellaneous project or scene-wide tools." +msgstr "Ferramentas varias do proxecto ou escena." + +#: editor/editor_node.cpp editor/project_manager.cpp +#: editor/script_create_dialog.cpp +msgid "Project" +msgstr "Proxecto" + +#: editor/editor_node.cpp +msgid "Project Settings..." +msgstr "Axustes do Proxecto..." + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control" +msgstr "Control de Versións" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Set Up Version Control" +msgstr "Configurar Control de Versións" + +#: editor/editor_node.cpp +msgid "Shut Down Version Control" +msgstr "Desactivar Control de Versións" + +#: editor/editor_node.cpp +msgid "Export..." +msgstr "Exportar..." + +#: editor/editor_node.cpp +msgid "Install Android Build Template..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Data Folder" +msgstr "Abrir Cartafol de Datos do Proxecto" + +#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp +msgid "Tools" +msgstr "Ferramentas" + +#: editor/editor_node.cpp +msgid "Orphan Resource Explorer..." +msgstr "Explorador de Recursos Orfos..." + +#: editor/editor_node.cpp +msgid "Quit to Project List" +msgstr "SaÃr á Lista de Proxectos" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/project_export.cpp +msgid "Debug" +msgstr "Depuración" + +#: editor/editor_node.cpp +msgid "Deploy with Remote Debug" +msgstr "Exportar con Depuración Remota" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy will make the executable " +"attempt to connect to this computer's IP so the running project can be " +"debugged.\n" +"This option is intended to be used for remote debugging (typically with a " +"mobile device).\n" +"You don't need to enable it to use the GDScript debugger locally." +msgstr "" +"Cando esta opción está activada, usar o despregue dun só clic fará que o " +"executable intente conectarse a IP deste computador, para poder depurar o " +"proxecto mentres este está executandose no dispositivo.\n" +"Esta opción está pensada para ser utilizada coa depuración remota " +"(normalmente nun dispositivo móbil).\n" +"Non necesita activar esta opción para utilizar o depurador de GDScript de " +"forma local." + +#: editor/editor_node.cpp +msgid "Small Deploy with Network Filesystem" +msgstr "Exportación Reducida co Sistema de Arquivos en Rede" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy for Android will only " +"export an executable without the project data.\n" +"The filesystem will be provided from the project by the editor over the " +"network.\n" +"On Android, deploying will use the USB cable for faster performance. This " +"option speeds up testing for projects with large assets." +msgstr "" +"Cando esta opción está activada, usar o despregue don só clic para Android " +"exportará só o executable, sen os datos do proxecto.\n" +"O sistema de arquivos proporcionarase por o editor na rede.\n" +"En Android ao despregar a aplicación usarase o USB para obter maior " +"rendemento. Esta opción acelera o proceso de proba en proxectos con gran " +"cantidade de Assets." + +#: editor/editor_node.cpp +msgid "Visible Collision Shapes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, collision shapes and raycast nodes (for 2D and " +"3D) will be visible in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Navigation" +msgstr "Navegación Visible" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, navigation meshes and polygons will be visible " +"in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Scene Changes" +msgstr "Sincronizar Cambios na Escena" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any changes made to the scene in the editor " +"will be replicated in the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" +"Cando esta opción está activada, calquera cambio na escena no editor verase " +"reflectido no proxecto en execución.\n" +"Cando é usado remotamente nun dispositivo, é máis eficiente cando o sistema " +"de arquivos en rede está activado." + +#: editor/editor_node.cpp +msgid "Synchronize Script Changes" +msgstr "Sincronizar Cambios nos Scripts" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any script that is saved will be reloaded in " +"the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" +"Cando esta opción está activada, calquera script gardada será recargada no " +"proxecto mentras este está en execución.\n" +"Cando é usado remotamente nun dispositivo, é máis eficiente cando o sistema " +"de arquivos en rede está activado." + +#: editor/editor_node.cpp editor/script_create_dialog.cpp +msgid "Editor" +msgstr "Editor" + +#: editor/editor_node.cpp +msgid "Editor Settings..." +msgstr "Configuración do Editor..." + +#: editor/editor_node.cpp +msgid "Editor Layout" +msgstr "Disposición das Ventás do Editor" + +#: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Captura de Pantalla" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" +"As capturas de pantalla gárdanse no cartafol de Datos/Configuración do " +"Editor." + +#: editor/editor_node.cpp +msgid "Toggle Fullscreen" +msgstr "Act./Desact. Pantalla Completa" + +#: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Act./Desact. Consola do Sistema" + +#: editor/editor_node.cpp +msgid "Open Editor Data/Settings Folder" +msgstr "Abrir Cartafol de Datos/Configuración do Editor" + +#: editor/editor_node.cpp +msgid "Open Editor Data Folder" +msgstr "Abrir Cartafol de Datos do Editor" + +#: editor/editor_node.cpp +msgid "Open Editor Settings Folder" +msgstr "Abrir Cartafol de Configuración do Editor" + +#: editor/editor_node.cpp +msgid "Manage Editor Features..." +msgstr "Administrar CaracterÃsticas do Editor..." + +#: editor/editor_node.cpp +msgid "Manage Export Templates..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp +msgid "Help" +msgstr "Axuda" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Online Docs" +msgstr "Documentación En Liña" + +#: editor/editor_node.cpp +msgid "Q&A" +msgstr "Preguntas e Respostas" + +#: editor/editor_node.cpp +msgid "Report a Bug" +msgstr "Reportar un Erro" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "Reportar Problema ca Documentación" + +#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp +msgid "Community" +msgstr "Comunidade" + +#: editor/editor_node.cpp +msgid "About" +msgstr "Acerca De" + +#: editor/editor_node.cpp +msgid "Play the project." +msgstr "Reproduce o proxecto." + +#: editor/editor_node.cpp +msgid "Play" +msgstr "Executar" + +#: editor/editor_node.cpp +msgid "Pause the scene execution for debugging." +msgstr "Pausa a execución da escena para a depuración." + +#: editor/editor_node.cpp +msgid "Pause Scene" +msgstr "Pausar Escena" + +#: editor/editor_node.cpp +msgid "Stop the scene." +msgstr "Detén a escena." + +#: editor/editor_node.cpp +msgid "Play the edited scene." +msgstr "Reproduce a escena actual." + +#: editor/editor_node.cpp +msgid "Play Scene" +msgstr "Executar Escena" + +#: editor/editor_node.cpp +msgid "Play custom scene" +msgstr "Executar escena a elixir" + +#: editor/editor_node.cpp +msgid "Play Custom Scene" +msgstr "Executar Escena a Elixir" + +#: editor/editor_node.cpp +msgid "Changing the video driver requires restarting the editor." +msgstr "Cambiar o controlador de vÃdeo require reiniciar o editor." + +#: editor/editor_node.cpp editor/project_settings_editor.cpp +#: editor/settings_config_dialog.cpp +msgid "Save & Restart" +msgstr "Gardar e Reinicar" + +#: editor/editor_node.cpp +msgid "Spins when the editor window redraws." +msgstr "Xira cando o editor actualiza a pantalla." + +#: editor/editor_node.cpp +msgid "Update Continuously" +msgstr "Actualizar de Maneira Continua" + +#: editor/editor_node.cpp +msgid "Update When Changed" +msgstr "Actualizar Cando Sexa Necesario" + +#: editor/editor_node.cpp +msgid "Hide Update Spinner" +msgstr "" + +#: editor/editor_node.cpp +msgid "FileSystem" +msgstr "Sistema de Arquivos" + +#: editor/editor_node.cpp +msgid "Inspector" +msgstr "Inspector" + +#: editor/editor_node.cpp +msgid "Expand Bottom Panel" +msgstr "Estender Panel Inferior" + +#: editor/editor_node.cpp +msgid "Output" +msgstr "SaÃda" + +#: editor/editor_node.cpp +msgid "Don't Save" +msgstr "Non Gardar" + +#: editor/editor_node.cpp +msgid "Android build template is missing, please install relevant templates." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Templates" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This will set up your project for custom Android builds by installing the " +"source template to \"res://android/build\".\n" +"You can then apply modifications and build your own custom APK on export " +"(adding modules, changing the AndroidManifest.xml, etc.).\n" +"Note that in order to make custom builds instead of using pre-built APKs, " +"the \"Use Custom Build\" option should be enabled in the Android export " +"preset." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The Android build template is already installed in this project and it won't " +"be overwritten.\n" +"Remove the \"res://android/build\" directory manually before attempting this " +"operation again." +msgstr "" + +#: editor/editor_node.cpp +msgid "Import Templates From ZIP File" +msgstr "" + +#: editor/editor_node.cpp +msgid "Template Package" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Library" +msgstr "Biblioteca de Exportación" + +#: editor/editor_node.cpp +msgid "Merge With Existing" +msgstr "Combinar Con Existentes" + +#: editor/editor_node.cpp +msgid "Open & Run a Script" +msgstr "Abrir e Executar un Script" + +#: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Este shader foi modificado en disco.\n" +"Que acción deberÃan de tomarse?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Recargar" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Volver a Gardar" + +#: editor/editor_node.cpp +msgid "New Inherited" +msgstr "Nova Escena Herdada" + +#: editor/editor_node.cpp +msgid "Load Errors" +msgstr "Erros durante a Carga" + +#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Select" +msgstr "Elixir" + +#: editor/editor_node.cpp +msgid "Open 2D Editor" +msgstr "Abrir Editor 2D" + +#: editor/editor_node.cpp +msgid "Open 3D Editor" +msgstr "Abrir Editor 3D" + +#: editor/editor_node.cpp +msgid "Open Script Editor" +msgstr "Abrir Editor de Scripts" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "Open Asset Library" +msgstr "Abrir Biblioteca de Assets" + +#: editor/editor_node.cpp +msgid "Open the next Editor" +msgstr "Abrir o seguinte editor" + +#: editor/editor_node.cpp +msgid "Open the previous Editor" +msgstr "Abrir o anterior editor" + +#: editor/editor_node.h +msgid "Warning!" +msgstr "Aviso!" + +#: editor/editor_path.cpp +msgid "No sub-resources found." +msgstr "Non se atopou ningún sub-recurso." + +#: editor/editor_plugin.cpp +msgid "Creating Mesh Previews" +msgstr "Creando Previsualización de Mallas" + +#: editor/editor_plugin.cpp +msgid "Thumbnail..." +msgstr "Miniatura..." + +#: editor/editor_plugin_settings.cpp +msgid "Main Script:" +msgstr "Script Principal:" + +#: editor/editor_plugin_settings.cpp +msgid "Edit Plugin" +msgstr "Editar CaracterÃstica Adicional (Plugin)" + +#: editor/editor_plugin_settings.cpp +msgid "Installed Plugins:" +msgstr "CaracterÃsticas Adicionais (Plugins) Instalados:" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Update" +msgstr "Actualizar" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Version:" +msgstr "Versión:" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Author:" +msgstr "Autor:" + +#: editor/editor_plugin_settings.cpp +msgid "Status:" +msgstr "Estado:" + +#: editor/editor_plugin_settings.cpp +msgid "Edit:" +msgstr "Editar:" + +#: editor/editor_profiler.cpp +msgid "Measure:" +msgstr "Medida:" + +#: editor/editor_profiler.cpp +msgid "Frame Time (sec)" +msgstr "Duración de Fotograma (seg)" + +#: editor/editor_profiler.cpp +msgid "Average Time (sec)" +msgstr "Tempo Medio (seg)" + +#: editor/editor_profiler.cpp +msgid "Frame %" +msgstr "Fotograma %" + +#: editor/editor_profiler.cpp +msgid "Physics Frame %" +msgstr "Fotograma de FÃsica %" + +#: editor/editor_profiler.cpp +msgid "Inclusive" +msgstr "Inclusivo" + +#: editor/editor_profiler.cpp +msgid "Self" +msgstr "Propio" + +#: editor/editor_profiler.cpp +msgid "Frame #:" +msgstr "Fotograma #:" + +#: editor/editor_profiler.cpp +msgid "Time" +msgstr "Tempo" + +#: editor/editor_profiler.cpp +msgid "Calls" +msgstr "Chamadas" + +#: editor/editor_properties.cpp +msgid "Edit Text:" +msgstr "Editar Texto:" + +#: editor/editor_properties.cpp editor/script_create_dialog.cpp +msgid "On" +msgstr "Activado" + +#: editor/editor_properties.cpp +msgid "Layer" +msgstr "Capa" + +#: editor/editor_properties.cpp +msgid "Bit %d, value %d" +msgstr "Bit %d, valor %d" + +#: editor/editor_properties.cpp +msgid "[Empty]" +msgstr "[Baleiro]" + +#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp +msgid "Assign..." +msgstr "Asignar..." + +#: editor/editor_properties.cpp +msgid "Invalid RID" +msgstr "Identificador de Recurso (RID) inválido" + +#: editor/editor_properties.cpp +msgid "" +"The selected resource (%s) does not match any type expected for this " +"property (%s)." +msgstr "" +"O recurso seleccionado (%s) non coincide con ningún tipo esperado para esta " +"propiedade (%s)." + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on resources saved as a file.\n" +"Resource needs to belong to a scene." +msgstr "" +"Non se pode crear un ViewportTexture nun recurso gardado coma un arquivo.\n" +"O recurso ten que pertencer a unha escena." + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on this resource because it's not set as " +"local to scene.\n" +"Please switch on the 'local to scene' property on it (and all resources " +"containing it up to a node)." +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Pick a Viewport" +msgstr "Selecciona unha Mini-Ventá (Viewport)" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New Script" +msgstr "Novo Script" + +#: editor/editor_properties.cpp editor/scene_tree_dock.cpp +msgid "Extend Script" +msgstr "Estender Script" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New %s" +msgstr "Novo %s" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Make Unique" +msgstr "Facer Único" + +#: editor/editor_properties.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Paste" +msgstr "Pegar" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Convert To %s" +msgstr "Converter a %s" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Selected node is not a Viewport!" +msgstr "O nodo seleccionado non é unha Mini-Ventá (Viewport)!" + +#: editor/editor_properties_array_dict.cpp +msgid "Size: " +msgstr "Tamaño: " + +#: editor/editor_properties_array_dict.cpp +msgid "Page: " +msgstr "Páxina: " + +#: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Eliminar Elemento" + +#: editor/editor_properties_array_dict.cpp +msgid "New Key:" +msgstr "Nova Chave:" + +#: editor/editor_properties_array_dict.cpp +msgid "New Value:" +msgstr "Novo Valor:" + +#: editor/editor_properties_array_dict.cpp +msgid "Add Key/Value Pair" +msgstr "Engadir Parella Chave/Valor" + +#: editor/editor_run_native.cpp +msgid "" +"No runnable export preset found for this platform.\n" +"Please add a runnable preset in the Export menu or define an existing preset " +"as runnable." +msgstr "" +"Non se encontraron axustes de exportación executables para esta plataforma.\n" +"Engade uns axustes de exportación executables, ou define algún xa existente " +"como executable." + +#: editor/editor_run_script.cpp +msgid "Write your logic in the _run() method." +msgstr "Escribe a túa lóxica no método '_run()'." + +#: editor/editor_run_script.cpp +msgid "There is an edited scene already." +msgstr "Xa hai unha escena editada." + +#: editor/editor_run_script.cpp +msgid "Couldn't instance script:" +msgstr "Non se puido instanciar o script:" + +#: editor/editor_run_script.cpp +msgid "Did you forget the 'tool' keyword?" +msgstr "Olvidaches a palabra clave 'tool'?" + +#: editor/editor_run_script.cpp +msgid "Couldn't run script:" +msgstr "Non se puido executar o script:" + +#: editor/editor_run_script.cpp +msgid "Did you forget the '_run' method?" +msgstr "Olvidaches o método '_run'?" + +#: editor/editor_spin_slider.cpp +msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." +msgstr "" +"Mantén pulsado Ctrl para redondear a enteiros. Mantén pulsado Shift para " +"cambios máis precisos." + +#: editor/editor_sub_scene.cpp +msgid "Select Node(s) to Import" +msgstr "Selecciona o(s) Nodo(s) a Importar" + +#: editor/editor_sub_scene.cpp editor/project_manager.cpp +msgid "Browse" +msgstr "Examinar" + +#: editor/editor_sub_scene.cpp +msgid "Scene Path:" +msgstr "Ruta da Escena:" + +#: editor/editor_sub_scene.cpp +msgid "Import From Node:" +msgstr "Importar Desde Nodo:" + +#: editor/export_template_manager.cpp +msgid "Redownload" +msgstr "Volver a Descargar" + +#: editor/export_template_manager.cpp +msgid "Uninstall" +msgstr "Desinstalar" + +#: editor/export_template_manager.cpp +msgid "(Installed)" +msgstr "(Instalado)" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download" +msgstr "Descargar" + +#: editor/export_template_manager.cpp +msgid "Official export templates aren't available for development builds." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Missing)" +msgstr "(Non encontrado)" + +#: editor/export_template_manager.cpp +msgid "(Current)" +msgstr "(Actual)" + +#: editor/export_template_manager.cpp +msgid "Retrieving mirrors, please wait..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove template version '%s'?" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't open export templates zip." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Invalid version.txt format inside templates: %s." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "No version.txt found inside templates." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error creating path for templates:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Extracting Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Importing:" +msgstr "Importando:" + +#: editor/export_template_manager.cpp +msgid "Error getting the list of mirrors." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error parsing JSON of mirror list. Please report this issue!" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"No download links found for this version. Direct download is only available " +"for official releases." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect." +msgstr "Non se pode conectar." + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response." +msgstr "Sen resposta." + +#: editor/export_template_manager.cpp +msgid "Request Failed." +msgstr "A Petición Fracasou." + +#: editor/export_template_manager.cpp +msgid "Redirect Loop." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed:" +msgstr "Fracasado:" + +#: editor/export_template_manager.cpp +msgid "Download Complete." +msgstr "Descarga Completa." + +#: editor/export_template_manager.cpp +msgid "Cannot remove temporary file:" +msgstr "Non se pode eliminar o arquivo temporal:" + +#: editor/export_template_manager.cpp +msgid "" +"Templates installation failed.\n" +"The problematic templates archives can be found at '%s'." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error requesting URL:" +msgstr "Erro ao solicitar a URL:" + +#: editor/export_template_manager.cpp +msgid "Connecting to Mirror..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Disconnected" +msgstr "Desconectado" + +#: editor/export_template_manager.cpp +msgid "Resolving" +msgstr "Resolvendo" + +#: editor/export_template_manager.cpp +msgid "Can't Resolve" +msgstr "Non se puido Resolver" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connecting..." +msgstr "Conectando..." + +#: editor/export_template_manager.cpp +msgid "Can't Connect" +msgstr "Non se Pode Conectar" + +#: editor/export_template_manager.cpp +msgid "Connected" +msgstr "Conectado" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Requesting..." +msgstr "Solicitando..." + +#: editor/export_template_manager.cpp +msgid "Downloading" +msgstr "Descargando" + +#: editor/export_template_manager.cpp +msgid "Connection Error" +msgstr "Erro de Conexión" + +#: editor/export_template_manager.cpp +msgid "SSL Handshake Error" +msgstr "Erro SSL Handshake" + +#: editor/export_template_manager.cpp +msgid "Uncompressing Android Build Sources" +msgstr "Descomprimindo Recursos de Compilación de Android" + +#: editor/export_template_manager.cpp +msgid "Current Version:" +msgstr "Versión Actual:" + +#: editor/export_template_manager.cpp +msgid "Installed Versions:" +msgstr "Versións Instaladas:" + +#: editor/export_template_manager.cpp +msgid "Install From File" +msgstr "Instalar Dende Arquivo" + +#: editor/export_template_manager.cpp +msgid "Remove Template" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select Template File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Godot Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Export Template Manager" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select mirror from list: (Shift+Click: Open in Browser)" +msgstr "Seleccione un mirror da lista: (Shift+Clic: Abrir no Navegador)" + +#: editor/filesystem_dock.cpp +msgid "Favorites" +msgstr "Favoritos" + +#: editor/filesystem_dock.cpp +msgid "Status: Import of file failed. Please fix file and reimport manually." +msgstr "" +"Estado: Fallou a importación do arquivo. Por favor, amaña o arquivo e " +"impórtao manualmente." + +#: editor/filesystem_dock.cpp +msgid "Cannot move/rename resources root." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move a folder into itself." +msgstr "Non se pode mover un cartafol dentro de sà mesmo." + +#: editor/filesystem_dock.cpp +msgid "Error moving:" +msgstr "Erro ao mover:" + +#: editor/filesystem_dock.cpp +msgid "Error duplicating:" +msgstr "Erro ao duplicar:" + +#: editor/filesystem_dock.cpp +msgid "Unable to update dependencies:" +msgstr "Incapaz de actualizar dependencias:" + +#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp +msgid "No name provided." +msgstr "Nome non proporcionado." + +#: editor/filesystem_dock.cpp +msgid "Provided name contains invalid characters." +msgstr "O nome proporcionado contén caracteres inválidos." + +#: editor/filesystem_dock.cpp +msgid "A file or folder with this name already exists." +msgstr "Xa existe un arquivo ou cartafol con este nome." + +#: editor/filesystem_dock.cpp +msgid "Name contains invalid characters." +msgstr "O nome contén caracteres inválidos." + +#: editor/filesystem_dock.cpp +msgid "" +"The following files or folders conflict with items in the target location " +"'%s':\n" +"\n" +"%s\n" +"\n" +"Do you wish to overwrite them?" +msgstr "" +"Os seguintes arquivos ou cartafois entran en conflicto con elementos da " +"ubicación de destino '%s':\n" +"\n" +"%s\n" +"\n" +"Queres sobreescribilos?" + +#: editor/filesystem_dock.cpp +msgid "Renaming file:" +msgstr "Renomeando Arquivo:" + +#: editor/filesystem_dock.cpp +msgid "Renaming folder:" +msgstr "Renomeando Cartafol:" + +#: editor/filesystem_dock.cpp +msgid "Duplicating file:" +msgstr "Duplicando Arquivo:" + +#: editor/filesystem_dock.cpp +msgid "Duplicating folder:" +msgstr "Duplicando Cartafol:" + +#: editor/filesystem_dock.cpp +msgid "New Inherited Scene" +msgstr "Nova Escena Herdada" + +#: editor/filesystem_dock.cpp +msgid "Set As Main Scene" +msgstr "Establecer coma Escena Principal" + +#: editor/filesystem_dock.cpp +msgid "Open Scenes" +msgstr "Abrir Escenas" + +#: editor/filesystem_dock.cpp +msgid "Instance" +msgstr "Instanciar" + +#: editor/filesystem_dock.cpp +msgid "Add to Favorites" +msgstr "Engadir a Favoritos" + +#: editor/filesystem_dock.cpp +msgid "Remove from Favorites" +msgstr "Eliminar de Favoritos" + +#: editor/filesystem_dock.cpp +msgid "Edit Dependencies..." +msgstr "Editar Dependencias..." + +#: editor/filesystem_dock.cpp +msgid "View Owners..." +msgstr "Ver Donos..." + +#: editor/filesystem_dock.cpp +msgid "Move To..." +msgstr "Mover a..." + +#: editor/filesystem_dock.cpp +msgid "New Scene..." +msgstr "Nova Escena..." + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "New Script..." +msgstr "Novo Script..." + +#: editor/filesystem_dock.cpp +msgid "New Resource..." +msgstr "Novo Recurso..." + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Expand All" +msgstr "Expandir Todo" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Collapse All" +msgstr "Colapsar Todo" + +#: editor/filesystem_dock.cpp +msgid "Duplicate..." +msgstr "Duplicar..." + +#: editor/filesystem_dock.cpp +msgid "Move to Trash" +msgstr "Mover á Papeleira" + +#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Rename..." +msgstr "Renomear..." + +#: editor/filesystem_dock.cpp +msgid "Previous Folder/File" +msgstr "Anterior Cartafol/Arquivo" + +#: editor/filesystem_dock.cpp +msgid "Next Folder/File" +msgstr "Seguinte Cartafol/Arquivo" + +#: editor/filesystem_dock.cpp +msgid "Re-Scan Filesystem" +msgstr "Reexaminar Sistema de Arquivos" + +#: editor/filesystem_dock.cpp +msgid "Toggle Split Mode" +msgstr "Act./Desact. Modo Dividido" + +#: editor/filesystem_dock.cpp +msgid "Search files" +msgstr "Buscar arquivos" + +#: editor/filesystem_dock.cpp +msgid "" +"Scanning Files,\n" +"Please Wait..." +msgstr "" +"Examinando arquivos,\n" +"Por favor, espere..." + +#: editor/filesystem_dock.cpp +msgid "Move" +msgstr "Mover" + +#: editor/filesystem_dock.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/project_manager.cpp editor/rename_dialog.cpp +#: editor/scene_tree_dock.cpp +msgid "Rename" +msgstr "Renomear" + +#: editor/filesystem_dock.cpp +msgid "Overwrite" +msgstr "Sobreescribir" + +#: editor/filesystem_dock.cpp +msgid "Create Scene" +msgstr "Crear Escena" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "Create Script" +msgstr "Crear Script" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +msgid "Find in Files" +msgstr "Buscar en Arquivos" + +#: editor/find_in_files.cpp +msgid "Find:" +msgstr "Buscar:" + +#: editor/find_in_files.cpp +msgid "Folder:" +msgstr "Cartafol:" + +#: editor/find_in_files.cpp +msgid "Filters:" +msgstr "Filtros:" + +#: editor/find_in_files.cpp +msgid "" +"Include the files with the following extensions. Add or remove them in " +"ProjectSettings." +msgstr "" +"Inclúe os arquivos coas seguintes extensións. Engádeos ou elimÃnaos na " +"Configuración do proxecto." + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find..." +msgstr "Buscar..." + +#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp +msgid "Replace..." +msgstr "SubstituÃr..." + +#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp +msgid "Cancel" +msgstr "Cancelar" + +#: editor/find_in_files.cpp +msgid "Find: " +msgstr "Buscar: " + +#: editor/find_in_files.cpp +msgid "Replace: " +msgstr "SubstituÃr: " + +#: editor/find_in_files.cpp +msgid "Replace all (no undo)" +msgstr "SubstituÃr todo (non se pode defacer)" + +#: editor/find_in_files.cpp +msgid "Searching..." +msgstr "Procurando..." + +#: editor/find_in_files.cpp +msgid "%d match in %d file." +msgstr "%d coincidencia en %d arquivo." + +#: editor/find_in_files.cpp +msgid "%d matches in %d file." +msgstr "%d coincidencias en %d arquivo." + +#: editor/find_in_files.cpp +msgid "%d matches in %d files." +msgstr "%d coincidencias en %d arquivos." + +#: editor/groups_editor.cpp +msgid "Add to Group" +msgstr "Engadir ao Grupo" + +#: editor/groups_editor.cpp +msgid "Remove from Group" +msgstr "Eliminar do Grupo" + +#: editor/groups_editor.cpp +msgid "Group name already exists." +msgstr "Este nome de grupo xa existe." + +#: editor/groups_editor.cpp +msgid "Invalid group name." +msgstr "Nome de grupo inválido." + +#: editor/groups_editor.cpp +msgid "Rename Group" +msgstr "Renomear Grupo" + +#: editor/groups_editor.cpp +msgid "Delete Group" +msgstr "Eliminar Grupo" + +#: editor/groups_editor.cpp editor/node_dock.cpp +msgid "Groups" +msgstr "Grupos" + +#: editor/groups_editor.cpp +msgid "Nodes Not in Group" +msgstr "Nodos Fora do Grupo" + +#: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp +msgid "Filter nodes" +msgstr "Filtrar nodos" + +#: editor/groups_editor.cpp +msgid "Nodes in Group" +msgstr "Nodos no Grupo" + +#: editor/groups_editor.cpp +msgid "Empty groups will be automatically removed." +msgstr "Os grupos baleiros serán automaticamente eliminados." + +#: editor/groups_editor.cpp +msgid "Group Editor" +msgstr "Editor de Grupos" + +#: editor/groups_editor.cpp +msgid "Manage Groups" +msgstr "Administrar Grupos" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Single Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Animations" +msgstr "Importar con Animacións Separadas" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials" +msgstr "Importar con Materiais Separados" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects" +msgstr "Importar con Obxectos Separados" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials" +msgstr "Importar con Obxectos e Materiais Separados" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Animations" +msgstr "Importar con Obxectos e Animacións Separadas" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials+Animations" +msgstr "Importar con Materiais e Animacións Separadas" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials+Animations" +msgstr "Importar con Obxectos, Materiais, e Animacións Separados" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes+Materials" +msgstr "Importar como Escenas e Materiales Múltiples" + +#: editor/import/resource_importer_scene.cpp +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import Scene" +msgstr "Importar Escena" + +#: editor/import/resource_importer_scene.cpp +msgid "Importing Scene..." +msgstr "Importando Escena..." + +#: editor/import/resource_importer_scene.cpp +msgid "Generating Lightmaps" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating for Mesh: " +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Running Custom Script..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Couldn't load post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Invalid/broken script for post-import (check console):" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Error running post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Did you return a Node-derived object in the `post_import()` method?" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Saving..." +msgstr "Gardando..." + +#: editor/import_dock.cpp +msgid "%d Files" +msgstr "%d Arquivos" + +#: editor/import_dock.cpp +msgid "Set as Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Clear Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Import As:" +msgstr "Importar Como:" + +#: editor/import_dock.cpp +msgid "Preset" +msgstr "Axustes de Importación" + +#: editor/import_dock.cpp +msgid "Reimport" +msgstr "Reimportar" + +#: editor/import_dock.cpp +msgid "Save Scenes, Re-Import, and Restart" +msgstr "" + +#: editor/import_dock.cpp +msgid "Changing the type of an imported file requires editor restart." +msgstr "" + +#: editor/import_dock.cpp +msgid "" +"WARNING: Assets exist that use this resource, they may stop loading properly." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Failed to load resource." +msgstr "Fallou a carga do Recurso." + +#: editor/inspector_dock.cpp +msgid "Expand All Properties" +msgstr "Expandir Tódalas Propiedades" + +#: editor/inspector_dock.cpp +msgid "Collapse All Properties" +msgstr "Colapsar Tódalas Propiedades" + +#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Save As..." +msgstr "Gardar Como..." + +#: editor/inspector_dock.cpp +msgid "Copy Params" +msgstr "Copiar Parámetros" + +#: editor/inspector_dock.cpp +msgid "Edit Resource Clipboard" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Resource" +msgstr "Copiar Recurso" + +#: editor/inspector_dock.cpp +msgid "Make Built-In" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Sub-Resources Unique" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Open in Help" +msgstr "Abrir na Axuda" + +#: editor/inspector_dock.cpp +msgid "Create a new resource in memory and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Load an existing resource from disk and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Save the currently edited resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the previous edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the next edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "History of recently edited objects." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Object properties." +msgstr "Propiedade de Obxectos." + +#: editor/inspector_dock.cpp +msgid "Filter properties" +msgstr "Filtrar propiedades" + +#: editor/inspector_dock.cpp +msgid "Changes may be lost!" +msgstr "Os cambios poderÃan perderse!" + +#: editor/multi_node_edit.cpp +msgid "MultiNode Set" +msgstr "" + +#: editor/node_dock.cpp +msgid "Select a single node to edit its signals and groups." +msgstr "Seleccione un nodo para editar as súas sinais e grupos." + +#: editor/plugin_config_dialog.cpp +msgid "Edit a Plugin" +msgstr "Editar unha CaracterÃstica Adicional (Plugin)" + +#: editor/plugin_config_dialog.cpp +msgid "Create a Plugin" +msgstr "Crear unha CaracterÃstica Adicional (Plugin)" + +#: editor/plugin_config_dialog.cpp +msgid "Plugin Name:" +msgstr "Nome do Plugin:" + +#: editor/plugin_config_dialog.cpp +msgid "Subfolder:" +msgstr "Subcartafol:" + +#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp +msgid "Language:" +msgstr "Linguaxe:" + +#: editor/plugin_config_dialog.cpp +msgid "Script Name:" +msgstr "Nome do Script:" + +#: editor/plugin_config_dialog.cpp +msgid "Activate now?" +msgstr "Activar agora?" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon" +msgstr "Crear PolÃgono" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create points." +msgstr "Crear puntos." + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "" +"Edit points.\n" +"LMB: Move Point\n" +"RMB: Erase Point" +msgstr "" +"Editar puntos.\n" +"Clic Izq: Mover Punto\n" +"Clic Der: Eliminar Punto" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Erase points." +msgstr "Borrar puntos." + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon" +msgstr "Editar PolÃgono" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Insert Point" +msgstr "Inserir Punto" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon (Remove Point)" +msgstr "Editar PolÃgono (Eliminar Punto)" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Remove Polygon And Point" +msgstr "Eliminar PolÃgono e Punto" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Animation" +msgstr "Engadir Animación" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Load..." +msgstr "Cargar..." + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Move Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "This type of node can't be used. Only root nodes are allowed." +msgstr "Non se pode usar este tipo de nodo. Só nodos raÃz están permitidos." + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Animation Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Remove BlendSpace1D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Move BlendSpace1D Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"AnimationTree is inactive.\n" +"Activate to enable playback, check node warnings if activation fails." +msgstr "" +"O AnimationTree está inactivo.\n" +"ActÃvao para permitir a reprodución; e comproba os avisos do nodo se hai un " +"erro na activación." + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Set the blending position within the space" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Select and move points, create points with RMB." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp +msgid "Enable snap and show grid." +msgstr "Activar axuste de cuadrÃcula e amosar cuadrÃcula." + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Point" +msgstr "Punto" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Open Editor" +msgstr "Abrir Editor" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Open Animation Node" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Triangle already exists." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Triangle" +msgstr "Engadir Triángulo" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "BlendSpace2D does not belong to an AnimationTree node." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "No triangles exist, so no blending can take place." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Toggle Auto Triangles" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create triangles by connecting points." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Erase points and triangles." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Generate blend triangles automatically (instead of manually)" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend:" +msgstr "Mezcla:" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Parameter Changed" +msgstr "Parámetro Cambiado" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Filters" +msgstr "Editar Flitros" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Output node can't be added to the blend tree." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Add Node to BlendTree" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Node Moved" +msgstr "Nodo Movido" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Unable to connect, port may be in use or connection may be invalid." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Connected" +msgstr "Nodos Conectado" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Disconnected" +msgstr "Nodos Desconectados" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Set Animation" +msgstr "Establecer Animación" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Node" +msgstr "Eliminar Nodo" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/scene_tree_dock.cpp +msgid "Delete Node(s)" +msgstr "Eliminar Nodo(s)" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Toggle Filter On/Off" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Change Filter" +msgstr "Cambiar Filtro" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "No animation player set, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Player path set is invalid, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "" +"Animation player has no valid root node path, so unable to retrieve track " +"names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Anim Clips" +msgstr "Clips de Animación" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Audio Clips" +msgstr "Clips de Audio" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Functions" +msgstr "Funcións" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Renamed" +msgstr "Nodo Renomeado" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node..." +msgstr "Engadir Nodo..." + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Edit Filtered Tracks:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Enable Filtering" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Toggle Autoplay" +msgstr "Act./Desact. Auto-reproducción" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Anim" +msgstr "Nova Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Animation?" +msgstr "Eliminar Animación?" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Remove Animation" +msgstr "Eliminar Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Invalid animation name!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation name already exists!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Rename Animation" +msgstr "Renomear Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Next Changed" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Blend Time" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Load Animation" +msgstr "Cargar Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Duplicate Animation" +msgstr "Duplicar Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to copy!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation resource on clipboard!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pasted Animation" +msgstr "Animación Pegada" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Paste Animation" +msgstr "Pegar Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to edit!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from current pos. (A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from end. (Shift+A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Stop animation playback. (S)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from start. (Shift+D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from current pos. (D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation position (in seconds)." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Scale animation playback globally for the node." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Tools" +msgstr "Ferramentas de Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation" +msgstr "Animación" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Edit Transitions..." +msgstr "Editar Transicións..." + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Open in Inspector" +msgstr "Abrir no Inspector" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Display list of animations in player." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Autoplay on Load" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Enable Onion Skinning" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Onion Skinning Options" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Directions" +msgstr "Direccións" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Past" +msgstr "Pasado" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Future" +msgstr "Futuro" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Depth" +msgstr "Profundidad" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "1 step" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "2 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "3 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Differences Only" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Force White Modulate" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Include Gizmos (3D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pin AnimationPlayer" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Create New Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Name:" +msgstr "Nome da Animación:" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +msgid "Error!" +msgstr "Erro!" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Times:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Next (Auto Queue):" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Cross-Animation Blend Times" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Move Node" +msgstr "Mover Nodo" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition exists!" +msgstr "Existe transición!" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Add Transition" +msgstr "Engadir Transición" + +#: editor/plugins/animation_state_machine_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node" +msgstr "Engadir Nodo" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "End" +msgstr "Fin" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Immediate" +msgstr "Inmediata" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Sync" +msgstr "Sincronizar" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "At End" +msgstr "Ao Final" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Travel" +msgstr "Viaxe" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Start and end nodes are needed for a sub-transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "No playback resource set at path: %s." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Removed" +msgstr "Nodo Eliminado" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition Removed" +msgstr "Transición Eliminada" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set Start Node (Autoplay)" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"Select and move nodes.\n" +"RMB to add new nodes.\n" +"Shift+LMB to create connections." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Create new nodes." +msgstr "Crear novos nodos." + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Connect nodes." +msgstr "Conectar nodos." + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Remove selected node or transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Toggle autoplay this animation on start, restart or seek to zero." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set the end animation. This is useful for sub-transitions." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition: " +msgstr "Transición: " + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Play Mode:" +msgstr "Modo de Reprodución:" + +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "AnimationTree" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "New name:" +msgstr "Novo nome:" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Scale:" +msgstr "Escala:" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade In (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade Out (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend" +msgstr "Mezcla" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix" +msgstr "Mezcla" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Auto Restart:" +msgstr "Auto Reinicio:" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Restart (s):" +msgstr "Reiniciar (s):" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Random Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Start!" +msgstr "Comezar!" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Amount:" +msgstr "Cantidade:" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 0:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 1:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "X-Fade Time (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Current:" +msgstr "Actual:" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input" +msgstr "Engadir Entrada" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Clear Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Set Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Delete Input" +msgstr "Eliminar Entrada" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is valid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is invalid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation Node" +msgstr "Nodo de Animación" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "OneShot Node" +msgstr "Nodo de Execución Única (Oneshot)" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend2 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend3 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend4 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeScale Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeSeek Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Transition Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Import Animations..." +msgstr "Importar Animacións..." + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Node Filters" +msgstr "Editar Filtros do Nodo" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Filters..." +msgstr "Filtros..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Contents:" +msgstr "Contidos:" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "View Files" +msgstr "Ver Arquivos" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connection error, please try again." +msgstr "Houbo un erro na conexión; por favor, inténtao de novo." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect to host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response from host:" +msgstr "Non houbo respota por parte do host:" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve hostname:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, return code:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed." +msgstr "A petición fallou." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Cannot save response to:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Write error." +msgstr "Erro de escritura." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, too many redirects" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Redirect loop." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, timeout" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Timeout." +msgstr "Timeout." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Bad download hash, assuming file has been tampered with." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Expected:" +msgstr "Esperado:" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Got:" +msgstr "Recibido:" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed SHA-256 hash check" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Asset Download Error:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading (%s / %s)..." +msgstr "Descargando (%s / %s)..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading..." +msgstr "Descargando..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Resolving..." +msgstr "Resolvendo..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Error making request" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Idle" +msgstr "Ocioso" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Install..." +msgstr "Instalar..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Retry" +msgstr "Reintentar" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download Error" +msgstr "Erro na Descarga" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download for this asset is already in progress!" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Recently Updated" +msgstr "Actualizado Recentemente" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Least Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (A-Z)" +msgstr "Nome (A-Z)" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (Z-A)" +msgstr "Nome (Z-A)" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (A-Z)" +msgstr "Licenza (A-Z)" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (Z-A)" +msgstr "Licenza (Z-A)" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "First" +msgstr "Primeiro" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Previous" +msgstr "Anterior" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Next" +msgstr "Seguinte" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Last" +msgstr "Derradeiro" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "All" +msgstr "Todos" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No results for \"%s\"." +msgstr "Non houbo resultado para \"%s\"." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Import..." +msgstr "Importar..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Plugins..." +msgstr "CaracterÃsticas Adicionais (Plugins)..." + +#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp +msgid "Sort:" +msgstr "Ordenar:" + +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/project_settings_editor.cpp +msgid "Category:" +msgstr "CategorÃa:" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Site:" +msgstr "Sitio:" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Support" +msgstr "Soporte" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Official" +msgstr "Oficial" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Testing" +msgstr "Probas" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Loading..." +msgstr "Cargando..." + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Assets ZIP File" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Can't determine a save path for lightmap images.\n" +"Save your scene and try again." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " +"Light' flag is on." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed creating lightmap images, make sure path is writable." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Algunha malla é inválida. Asegúrese de que o os valores do canle UV2 están " +"contidos dentro da rexión cadrada ([0.0,1.0], [0.0,1.0])." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Bake Lightmaps" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + +#: editor/plugins/camera_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Preview" +msgstr "Vista Previa" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Configure Snap" +msgstr "Configurar Axuste de CuadrÃcula" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Primary Line Every:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "steps" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Vertical Guide" +msgstr "Mover GuÃa Vertical" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Vertical Guide" +msgstr "Crear GuÃa Vertical" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Vertical Guide" +msgstr "Eliminar GuÃa Vertical" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Horizontal Guide" +msgstr "Mover GuÃa Horizontal" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal Guide" +msgstr "Crear GuÃa Horizontal" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Horizontal Guide" +msgstr "Eliminar GuÃa Horizontal" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal and Vertical Guides" +msgstr "Crear GuÃas Horizontais e Verticais" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate CanvasItem \"%s\" to %d degrees" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Node2D \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Resize Control \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale CanvasItem \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Children of containers have their anchors and margins values overridden by " +"their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Presets for the anchors and margins values of a Control node." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"When active, moving Control nodes changes their anchors instead of their " +"margins." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Left" +msgstr "Arriba á Esquerda" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Right" +msgstr "Arriba á Dereita" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Right" +msgstr "Abaixo á Dereita" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Left" +msgstr "Abaixo á Esquerda" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Left" +msgstr "Centro á Esquerda" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Top" +msgstr "Centro Arriba" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Right" +msgstr "Centro á Dereita" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Bottom" +msgstr "Centro Abaixo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center" +msgstr "Centro" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Left Wide" +msgstr "Esquerdo Alto" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Wide" +msgstr "Arriba Ancho" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Right Wide" +msgstr "Dereito Alto" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Wide" +msgstr "Abaixo Ancho" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "VCenter Wide" +msgstr "CentradoV Alto" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "HCenter Wide" +msgstr "CentradoH Ancho" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Full Rect" +msgstr "Recta Completa" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Keep Ratio" +msgstr "Manter Relación de Aspecto" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Anchors only" +msgstr "Só Ãncoras" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors and Margins" +msgstr "Cambiar Ãncoras e Marxes" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors" +msgstr "Cambiar Ãncoras" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"Overrides game camera with editor viewport camera." +msgstr "" +"SubstituÃr a Cámara do Xogo\n" +"Substitue a cámara do xogo pola cámara da Mini-ventá (Viewport) do editor." + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"No game instance running." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Group Selected" +msgstr "Agrupar Selección" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Ungroup Selected" +msgstr "Desagrupar Selección" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Paste Pose" +msgstr "Pegar Pose" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Guides" +msgstr "Limpar GuÃas" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Bones" +msgstr "Limpar Ósos" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Warning: Children of a container get their position and size determined only " +"by their parent." +msgstr "" +"Aviso: Os nodos fillos dun contedor (Container) teñen determinada a súa " +"posición e tamaño unicamente polo seu padre." + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Reset" +msgstr "Restablecer Zoom" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Select Mode" +msgstr "Elixir Modo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Drag: Rotate" +msgstr "Arrastrar: Rotar" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+Drag: Move" +msgstr "Alt+Arrastrar: Mover" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Move Mode" +msgstr "Mover Modo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Mode" +msgstr "Modo Rotación" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Mode" +msgstr "Modo Escalado" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Show a list of all objects at the position clicked\n" +"(same as Alt+RMB in select mode)." +msgstr "" +"Amosa unha lista de obxectos na posición na que se fixo clic\n" +"(O mesmo que usar Alt+Clic Dereito en modo selección)." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Click to change object's rotation pivot." +msgstr "Faga clic para cambiar o pivote de rotación do obxecto." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Ruler Mode" +msgstr "Modo Regra" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle smart snapping." +msgstr "Act./Desact. axuste intelixente." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Smart Snap" +msgstr "Usar Axuste Intelixente" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle grid snapping." +msgstr "Act./Desact. axuste de cuadrÃcula." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Grid Snap" +msgstr "Usar Axuste de CuadrÃcula" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snapping Options" +msgstr "Opcións de Axuste de CuadrÃcula" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Rotation Snap" +msgstr "Empregar Axuste de Rotación" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Scale Snap" +msgstr "Empregar Axuste de Escalado" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap Relative" +msgstr "Axuste Relativo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Pixel Snap" +msgstr "Empregar Axuste aos PÃxeles" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Smart Snapping" +msgstr "Axuste Intelixente" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Configure Snap..." +msgstr "Configurar Axuste de CuadrÃcula..." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Parent" +msgstr "Axustar ao Pai" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Anchor" +msgstr "Axustar á Ãncora do Nodo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Sides" +msgstr "Axustar aos Laterais do Nodo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Center" +msgstr "Axustar ao Centro do Nodo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Other Nodes" +msgstr "Axustar a Outros Nodos" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Guides" +msgstr "Axustar as GuÃas" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock the selected object in place (can't be moved)." +msgstr "Fixar o obxecto no sitio (non se poderá mover)." + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock the selected object (can be moved)." +msgstr "Liberar o obxecto seleccionado (pode moverse)." + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Makes sure the object's children are not selectable." +msgstr "Asegúrase de que os fillos do obxecto non sexan seleccionables." + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Restores the object's children's ability to be selected." +msgstr "Volve a permitir seleccionar os fillos do obxecto." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Skeleton Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Bones" +msgstr "Amosar Ósos" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make Custom Bone(s) from Node(s)" +msgstr "Crear Óso(s) Personalizados a partir de Nodo(s)" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Custom Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View" +msgstr "Ver" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Always Show Grid" +msgstr "Sempre Amosar a CuadrÃcula" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Helpers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Rulers" +msgstr "Amosar Regras" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Guides" +msgstr "Amosar GuÃas" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Origin" +msgstr "Amosar Orixe" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Viewport" +msgstr "Amosar Mini-Ventá (Viewport)" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Group And Lock Icons" +msgstr "Amosar Grupo e Bloquear Iconas" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Selection" +msgstr "Centrar Selección" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Frame Selection" +msgstr "Encadrar Selección" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Preview Canvas Scale" +msgstr "Vista Previa da Escala do Lenzo (Canvas)" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Translation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert keys (based on mask)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Auto insert keys when objects are translated, rotated or scaled (based on " +"mask).\n" +"Keys are only added to existing tracks, no new tracks will be created.\n" +"Keys must be inserted manually for the first time." +msgstr "" +"Inserción automática de claves cando os obxectos son trasladados, rotados, " +"ou escalados (depenendo da Máscara).\n" +"As chaves só engádense a pistas xa existentes; nunca se crean novas pistas.\n" +"As chaves teñen que insertarse manualmente cando se utiliza por primeira vez." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Auto Insert Key" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Animation Key and Pose Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key (Existing Tracks)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Copy Pose" +msgstr "Copiar Pose" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Pose" +msgstr "Restablecer Pose" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Multiply grid step by 2" +msgstr "Multiplicar Dimensión da CuadrÃcula por 2" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Divide grid step by 2" +msgstr "Dividir Dimensión da CuadrÃcula por 2" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Add %s" +msgstr "Engadir %s" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Adding %s..." +msgstr "Engadindo %s..." + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Cannot instantiate multiple nodes without root." +msgstr "Non se pode instanciar varios nodos sen un nodo raÃz." + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Create Node" +msgstr "Crear Nodo" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Error instancing scene from %s" +msgstr "Erro instanciado escena desde %s" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Default Type" +msgstr "Cambiar Tipo por Defecto" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Drag & drop + Shift : Add node as sibling\n" +"Drag & drop + Alt : Change node type" +msgstr "" +"Arrastrar e Soltar + Shift : Engade nodo como irmán\n" +"Arrastrar e Soltar + Alt : Cambiar tipo de nodo" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Create Polygon3D" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly" +msgstr "Editar PolÃgono" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly (Remove Point)" +msgstr "Editar PolÃgono (Eliminar Punto)" + +#: editor/plugins/collision_shape_2d_editor_plugin.cpp +msgid "Set Handle" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Load Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "Reiniciar" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Clear Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Particles" +msgstr "PartÃculas" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generated Point Count:" +msgstr "Número de Puntos Xerados:" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Solid Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Directed Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Capture from Pixel" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Colors" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +msgid "CPUParticles" +msgstr "CPUParticles" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Mesh" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Node" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 0" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 1" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease In" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease Out" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Smoothstep" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Curve Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Add Point" +msgstr "Engadir Punto" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Point" +msgstr "Eliminar Punto" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Left Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Toggle Curve Linear Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Hold Shift to edit tangents individually" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right click to add point" +msgstr "" + +#: editor/plugins/gi_probe_editor_plugin.cpp +msgid "Bake GI Probe" +msgstr "" + +#: editor/plugins/gradient_editor_plugin.cpp +msgid "Gradient Edited" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item %d" +msgstr "Elemento %d" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Items" +msgstr "Elementos" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item List Editor" +msgstr "" + +#: editor/plugins/light_occluder_2d_editor_plugin.cpp +msgid "Create Occluder Polygon" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh is empty!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a Trimesh collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Static Trimesh Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "This doesn't work on scene root!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create a single convex collision shape for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a single convex collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create multiple convex collision shapes for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create any collision shapes." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Shapes" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Navigation Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Contained Mesh is not of type ArrayMesh." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Unwrap failed, mesh may not be manifold?" +msgstr "" +"Fallo no Unwrap de UV. Posiblemente a malla non é unha variedade (é dicir, " +"que a malla non forma unha superficie conexa, contÃnua, e con dous caras " +"diferenciables). En programas de modelaxe 3D pódese eliminar xeometrÃa que " +"non sexa unha variedade (\"Non Manifold\") fácilmente." + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "No mesh to debug." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Model has no UV in this layer" +msgstr "O modelo non ten UVs nesta capa" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "MeshInstance lacks a Mesh!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh has not surface to create outlines from!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Could not create outline!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh" +msgstr "Malla" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a StaticBody and assigns a polygon-based collision shape to it " +"automatically.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" +"Crear un nodo StaticBody e asÃgnalle automáticamente unha forma fÃsica " +"baseada en polÃgonos.\n" +"Esta é a forma máis precisa (e máis lenta) de detección de colisións." + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" +"Crea unha formá fÃsica baseada en polÃgonos.\n" +"Esta é a forma máis precisa (pero máis lenta) de detectar colisións." + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a single convex collision shape.\n" +"This is the fastest (but least accurate) option for collision detection." +msgstr "" +"Crea unha única forma fÃsica convexa.\n" +"Esta é a maneira más eficiente (pero menos precisa) de detectar colisións." + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Collision Siblings" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is a performance middle-ground between the two above options." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh..." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a static outline mesh. The outline mesh will have its normals " +"flipped automatically.\n" +"This can be used instead of the SpatialMaterial Grow property when using " +"that property isn't possible." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV1" +msgstr "Amosar UV1" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV2" +msgstr "Amosar UV2" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Unwrap UV2 for Lightmap/AO" +msgstr "Facer Unwrap do UV2 para Lightmap/AO" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Outline Size:" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Channel Debug" +msgstr "Depuración do Canle UV" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove item %d?" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "" +"Update from existing scene?:\n" +"%s" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Mesh Library" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Item" +msgstr "Engadir Elemento" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove Selected Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import from Scene" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Update from Scene" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and no MultiMesh set in node)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and MultiMesh contains no Mesh)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (not a MeshInstance)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (contains no Mesh resource)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No surface source specified." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no geometry)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no faces)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate Surface" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate MultiMesh" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "X-Axis" +msgstr "Eixe X" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Y-Axis" +msgstr "Eixe Y" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Z-Axis" +msgstr "Eixe Z" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh Up Axis:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Rotation:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Tilt:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Scale:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate" +msgstr "Encher" + +#: editor/plugins/navigation_polygon_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Navigation Polygon" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Convert to CPUParticles" +msgstr "Converter a CPUParticles" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generating Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generate Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Can only set point into a ParticlesMaterial process material" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Converter a CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generation Time (sec):" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry's faces don't contain any area." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry doesn't contain any faces." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't inherit from Spatial." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain face geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emitter" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Points:" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points+Normal (Directed)" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Volume" +msgstr "Volume" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Source: " +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "A processor material of type 'ParticlesMaterial' is required." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generating AABB" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generate Visibility AABB" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Point from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Out-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove In-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point to Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Split Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Point in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move In-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Out-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Select Points" +msgstr "Seleccionar Puntos" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Shift+Drag: Select Control Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Click: Add Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Left Click: Split Segment (in curve)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Right Click: Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Select Control Points (Shift+Drag)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point (in empty space)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Delete Point" +msgstr "Eliminar Puntos" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Close Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp +msgid "Options" +msgstr "Opcións" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Angles" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Lengths" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Curve Point #" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Point Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve In Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Out Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Path" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Path Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Out-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove In-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Segment (in curve)" +msgstr "" + +#: editor/plugins/physical_bone_plugin.cpp +msgid "Move Joint" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"The skeleton property of the Polygon2D does not point to a Skeleton2D node" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"No texture in this polygon.\n" +"Set a texture to be able to edit UV." +msgstr "" +"Non hai unha textura neste polÃgono.\n" +"Engada unha textura para editar o UV." + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create UV Map" +msgstr "Crear Mapa UV" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Polygon 2D has internal vertices, so it can no longer be edited in the " +"viewport." +msgstr "" +"O polÃgono 2D ten vértices internos, polo que xa non se pode editar na Mini-" +"Ventá (Viewport)." + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon & UV" +msgstr "Crear PolÃgono e UV" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Invalid Polygon (need 3 different vertices)" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Add Custom Polygon" +msgstr "Engadir PolÃgono Personalizado" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Custom Polygon" +msgstr "Eliminar PolÃgono Personalizado" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform UV Map" +msgstr "Transformar Mapa UV" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint Bone Weights" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Open Polygon 2D UV editor." +msgstr "Abrir Editor UV de PolÃgonos 2D." + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygon 2D UV Editor" +msgstr "Editor UV de PolÃgonos 2D" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "UV" +msgstr "UV" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Points" +msgstr "Puntos" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygons" +msgstr "PolÃgonos" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Bones" +msgstr "Ósos" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Points" +msgstr "Mover Puntos" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Command: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift: Move All" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Command: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Ctrl: Rotate" +msgstr "Ctrl: Rotar" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Ctrl: Scale" +msgstr "Shift+Ctrl: Escalar" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Polygon" +msgstr "Mover PolÃgono" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Rotate Polygon" +msgstr "Rotar PolÃgono" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Scale Polygon" +msgstr "Escalar PolÃgono" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create a custom polygon. Enables custom polygon rendering." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Remove a custom polygon. If none remain, custom polygon rendering is " +"disabled." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Unpaint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Radius:" +msgstr "Radio:" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy Polygon to UV" +msgstr "Copiar PolÃgono a UV" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy UV to Polygon" +msgstr "Copiar UV a PolÃgono" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Clear UV" +msgstr "Limpar UV" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Settings" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Snap" +msgstr "Axuste de CuadrÃcula" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Enable Snap" +msgstr "Activar Axuste" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid" +msgstr "CuadrÃcula" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Show Grid" +msgstr "Amosar CuadrÃcula" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Configure Grid:" +msgstr "Configurar CuadrÃcula:" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones to Polygon" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ERROR: Couldn't load resource!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Add Resource" +msgstr "Engadir Recurso" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Rename Resource" +msgstr "Renomear Recurso" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Resource" +msgstr "Eliminar Recurso" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Resource clipboard is empty!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Paste Resource" +msgstr "Pegar Recurso" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instancia:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Type:" +msgstr "Tipo:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Load Resource" +msgstr "Cargar Recurso" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ResourcePreloader" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "AnimationTree has no path set to an AnimationPlayer" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Path to AnimationPlayer is invalid" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Files" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close and save changes?" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error writing TextFile:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Could not load file at:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving file!" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Saving" +msgstr "Erro ao Gardar" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error importing theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Importing" +msgstr "Erro ao Importar" + +#: editor/plugins/script_editor_plugin.cpp +msgid "New Text File..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open File" +msgstr "Abrir Arquivo" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save File As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Can't obtain the script for running." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script failed reloading, check console for errors." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script is not in tool mode, will not be able to run." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"To run this script, it must inherit EditorScript and be set to tool mode." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme" +msgstr "Importar Tema" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving" +msgstr "Erro ao gardar" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "%s Class Reference" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Next" +msgstr "Atopar Seguinte" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Previous" +msgstr "Atopar Anterior" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "Filtrar scripts" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Toggle alphabetical sorting of the method list." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "Filtrar métodos" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Sort" +msgstr "Ordenar" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Up" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Down" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Next script" +msgstr "Seguinte script" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Previous script" +msgstr "Anterior script" + +#: editor/plugins/script_editor_plugin.cpp +msgid "File" +msgstr "Arquivo" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open..." +msgstr "Abrir..." + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reopen Closed Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save All" +msgstr "Gardar Todo" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Soft Reload Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Copy Script Path" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme" +msgstr "Tema" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme..." +msgstr "Importar Tema..." + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reload Theme" +msgstr "Volver a Cargar Tema" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme" +msgstr "Gardar Tema" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close All" +msgstr "Pechar Todo" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close Docs" +msgstr "Pechar Documentación" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +msgid "Run" +msgstr "Executar" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Buscar" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Into" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Over" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Break" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +#: editor/script_editor_debugger.cpp +msgid "Continue" +msgstr "Continuar" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Keep Debugger Open" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Debug with External Editor" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open Godot online documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search the reference documentation." +msgstr "Buscar na documentación de referencia." + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to previous edited document." +msgstr "Ir ao anterior documento editado." + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to next edited document." +msgstr "Ir ao seguinte documento editado." + +#: editor/plugins/script_editor_plugin.cpp +msgid "Discard" +msgstr "Descartar" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Debugger" +msgstr "Depurador" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Results" +msgstr "Resultados de Búsqueda" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Scripts" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Connections to method:" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp +msgid "Source" +msgstr "Fonte" + +#: editor/plugins/script_text_editor.cpp +msgid "Target" +msgstr "Obxectivo" + +#: editor/plugins/script_text_editor.cpp +msgid "" +"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "[Ignore]" +msgstr "[Ignorar]" + +#: editor/plugins/script_text_editor.cpp +msgid "Line" +msgstr "Liña" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function" +msgstr "Ir a Función" + +#: editor/plugins/script_text_editor.cpp +msgid "Only resources from filesystem can be dropped." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't drop nodes because script '%s' is not used in this scene." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Lookup Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Pick Color" +msgstr "Elexir Cor" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Convert Case" +msgstr "Converter Maiús./Minús." + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Uppercase" +msgstr "Maiúscula" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Lowercase" +msgstr "Minúscula" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Capitalize" +msgstr "Capitalizar" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Syntax Highlighter" +msgstr "Marcador de Sintaxe" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Bookmarks" +msgstr "Marcadores" + +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Go To" +msgstr "Ir a" + +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Cut" +msgstr "Cortar" + +#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Seleccionar Todo" + +#: editor/plugins/script_text_editor.cpp +msgid "Delete Line" +msgstr "Eliminar Liña" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Left" +msgstr "Sangrado á Esquerda" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Right" +msgstr "Sangrado á Dereita" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Comment" +msgstr "Comentar/Descomentar" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold/Unfold Line" +msgstr "Expandir/Colapsar Liña" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold All Lines" +msgstr "Colapsar Tódalas Liñas" + +#: editor/plugins/script_text_editor.cpp +msgid "Unfold All Lines" +msgstr "Expandir Tódalas Liñas" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clonar Liña" + +#: editor/plugins/script_text_editor.cpp +msgid "Complete Symbol" +msgstr "Completar SÃmbolo" + +#: editor/plugins/script_text_editor.cpp +msgid "Evaluate Selection" +msgstr "Evaluar Selección" + +#: editor/plugins/script_text_editor.cpp +msgid "Trim Trailing Whitespace" +msgstr "Eliminar Espazos ao Final da Liña" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Spaces" +msgstr "Convertir Indentación a Espazos" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Tabs" +msgstr "Convertir Identación a Tabulacións" + +#: editor/plugins/script_text_editor.cpp +msgid "Auto Indent" +msgstr "Auto Indentar" + +#: editor/plugins/script_text_editor.cpp +msgid "Find in Files..." +msgstr "Buscar en Arquivos.." + +#: editor/plugins/script_text_editor.cpp +msgid "Contextual Help" +msgstr "Axuda Contextual" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Bookmark" +msgstr "Act./Desact. Marcapáxinas" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Bookmark" +msgstr "Ir ao Seguinte Marcapáxinas" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Bookmark" +msgstr "Ir ao Anterior Marcapáxinas" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Bookmarks" +msgstr "Eliminar Tódolos Marcapáxinas" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function..." +msgstr "Ir a Función..." + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Line..." +msgstr "Ir a Liña..." + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Toggle Breakpoint" +msgstr "Act./Desact. Punto de Interrupción (Breakpoint)" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Breakpoints" +msgstr "Eliminar Tódolos Puntos de Interrupción (Breakpoints)" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Breakpoint" +msgstr "Ir ao Seguinte Punto de Interrupción" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Breakpoint" +msgstr "Ir ao Anterior Punto de Interrupción" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "" +"This shader has been modified on on disk.\n" +"What action should be taken?" +msgstr "" +"Este shader foi modificado en disco.\n" +"Que acción deberÃan de tomarse?" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "Shader" +msgstr "Shader" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "This skeleton has no bones, create some children Bone2D nodes." +msgstr "Este esqueleto non ten ósos; crea uns nodos fillo Bone2D." + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Create Rest Pose from Bones" +msgstr "Crear Pose de Repouso a partir dos Ósos" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Rest Pose to Bones" +msgstr "Asignar Pose de Repouso aos Ósos" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Skeleton2D" +msgstr "Skeleton2D" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Make Rest Pose (From Bones)" +msgstr "Crear Pose de Repouso (a partir dos Ósos)" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Bones to Rest Pose" +msgstr "Asignar Pose de Repouso aos Ósos" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical bones" +msgstr "Crear ósos fÃsicos" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Skeleton" +msgstr "Esqueleto" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical skeleton" +msgstr "Crear esqueleto fÃsico" + +#: editor/plugins/skeleton_ik_editor_plugin.cpp +msgid "Play IK" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Orthogonal" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective" +msgstr "Perspetiva" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Aborted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "X-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Y-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Z-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Plane Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scaling: " +msgstr "Escalado: " + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translating: " +msgstr "Trasladando: " + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotating %s degrees." +msgstr "Rotando % graos." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Keying is disabled (no key inserted)." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Animation Key Inserted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pitch" +msgstr "Cabeceo" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Yaw" +msgstr "Guiñada" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Tamaño" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Objects Drawn" +msgstr "Obxectos Debuxados" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Material Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Shader Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Surface Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Draw Calls" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Vertices" +msgstr "Vértices" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View." +msgstr "Vista Superior." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View." +msgstr "Vista Inferior." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom" +msgstr "Inferior" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View." +msgstr "Vista Esquerda." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left" +msgstr "Esquerda" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View." +msgstr "Vista Dereita." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right" +msgstr "Dereita" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View." +msgstr "Vista Frontal." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front" +msgstr "Frontal" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View." +msgstr "Vista Traseria." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear" +msgstr "Traseira" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Transform with View" +msgstr "Aliñar Transformación con Perspectiva" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Rotation with View" +msgstr "Aliñar Rotación con Perspectiva" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "No parent to instance a child at." +msgstr "Non hai un pai ao que instanciarlle un fillo." + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "This operation requires a single selected node." +msgstr "Esta operación precisa un único nodo seleccionado." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "Auto Ortogonal Activado" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock View Rotation" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Normal" +msgstr "Mostrar de Forma Normal" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Wireframe" +msgstr "Mostrar Malla" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Overdraw" +msgstr "Mostrar Zonas Redebuxadas (Overdraw)" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Unshaded" +msgstr "Mostrar Sen Sombreado" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Environment" +msgstr "Amosar Entorno" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Gizmos" +msgstr "Amosar Gizmos" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Information" +msgstr "Amosar Información" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View FPS" +msgstr "Ver FPS" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Half Resolution" +msgstr "Resolución á Metade" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Audio Listener" +msgstr "OÃnte de Son" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Enable Doppler" +msgstr "Activar Efecto Doppler" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Cinematic Preview" +msgstr "Vista Previa Cinemática" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Not available when using the GLES2 renderer." +msgstr "Non dispoñible cando se está usando o renderizador GLES2." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Forward" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Backwards" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Up" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Down" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Speed Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Slow Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." +msgstr "" +"Nota: o valor dos FPS corresponde aos fotogramas por segundo do editor.\n" +"Non pode usarse como unha forma fiable de medir o rendemento do xogo." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "XForm Dialog" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Click to toggle between visibility states.\n" +"\n" +"Open eye: Gizmo is visible.\n" +"Closed eye: Gizmo is hidden.\n" +"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")." +msgstr "" +"Faga clic para cambiar entre estados de visibilidade.\n" +"\n" +"Ollo aberto: Gizmo visible.\n" +"Ollo pechado: Gizmo oculto.\n" +"Ollo medio aberto, medio pechado: Gizmo visible ao través de superficies " +"opacas (\"raios x\")." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Nodes To Floor" +msgstr "Axustar Nodos ao Chan" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Couldn't find a solid floor to snap the selection to." +msgstr "Non se puido encontrar chan sólido no que poder axustar a selección." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Drag: Rotate\n" +"Alt+Drag: Move\n" +"Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Local Space" +msgstr "Usar Espazo Local" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Snap" +msgstr "Usar Axuste de CuadrÃcula" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View" +msgstr "Vista Inferior" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View" +msgstr "Vista Superior" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View" +msgstr "Vista Traseira" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View" +msgstr "Vista Frontal" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View" +msgstr "Vista Esquerda" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View" +msgstr "Vista Dereita" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Switch Perspective/Orthogonal View" +msgstr "Vista Perspectiva/Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Insert Animation Key" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Toggle Freelook" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform" +msgstr "Transformación" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Object to Floor" +msgstr "Axustar Obxecto ao Chan" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Dialog..." +msgstr "Aplicar Transformación..." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "1 Viewport" +msgstr "1 Ventá" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports" +msgstr "2 Ventás" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports (Alt)" +msgstr "2 Ventás (Alt)" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports" +msgstr "3 Ventás" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports (Alt)" +msgstr "3 Ventás (Alt)" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "4 Viewports" +msgstr "4 Ventás" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Origin" +msgstr "Amosar Orixe" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Grid" +msgstr "Amosar CuadrÃcula" + +#: editor/plugins/spatial_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Settings..." +msgstr "Axustes..." + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Settings" +msgstr "Configuración de Axuste" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate Snap:" +msgstr "Axuste de Translación:" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Snap (deg.):" +msgstr "Axuste de Rotación (graos):" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Snap (%):" +msgstr "Axuste de Escalado (%):" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Viewport Settings" +msgstr "Axustes de Visión" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective FOV (deg.):" +msgstr "Campo de Visión (graos):" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Near:" +msgstr "Plano Próximo:" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Far:" +msgstr "Plano Afastado:" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Change" +msgstr "Cambio de Transformación" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate:" +msgstr "Trasladar:" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate (deg.):" +msgstr "Rotar (graos):" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale (ratio):" +msgstr "Escalar (Razón):" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Type" +msgstr "Tipo de Transformación" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pre" +msgstr "Anterior (Pre)" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Post" +msgstr "Posterior (Post)" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Nameless gizmo" +msgstr "Gizmo sen nome" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Mesh2D" +msgstr "Crear Mesh2D" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Mesh2D Preview" +msgstr "Vista Previa de Mesh2D" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Polygon2D" +msgstr "Crear Polygon2D" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Polygon2D Preview" +msgstr "Vista Previa Polygon2D" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "CollisionPolygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "LightOccluder2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite is empty!" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Can't convert a sprite using animation frames to mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't replace by mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Polygon2D" +msgstr "Convertir a Polygon2D" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create collision polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create light occluder." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Simplification: " +msgstr "Simplificación: " + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Shrink (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Grow (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Update Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Settings:" +msgstr "Axustes:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "No Frames Selected" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add %d Frame(s)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Unable to load images" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "ERROR: Couldn't load frame resource!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Resource clipboard is empty or not a texture!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Paste Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Empty" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation FPS" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "(empty)" +msgstr "(baleiro)" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animations:" +msgstr "Animacións:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "New Animation" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Speed:" +msgstr "Velocidade:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Loop" +msgstr "Bucle" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animation Frames:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add a Texture from File" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frames from a Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Horizontal:" +msgstr "Horizontal:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Vertical:" +msgstr "Vertical:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select/Clear All Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Create Frames from Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "SpriteFrames" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Region Rect" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Margin" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Snap Mode:" +msgstr "Modo de Axuste:" + +#: editor/plugins/texture_region_editor_plugin.cpp +#: scene/resources/visual_shader.cpp +msgid "None" +msgstr "Ningún" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Pixel Snap" +msgstr "Axustar aos PÃxeles" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Grid Snap" +msgstr "Axuste de CuadrÃcula" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Auto Slice" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Offset:" +msgstr "Offset:" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Step:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Sep.:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "TextureRegion" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp +msgid "Remove All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Edit Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme editing menu." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Editor Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create From Current Editor Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Toggle Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Check Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Named Sep." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Submenu" +msgstr "Submenú" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has" +msgstr "Ten" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Many" +msgstr "Moitas" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled LineEdit" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 3" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Editable Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subtree" +msgstr "Subárbore" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has,Many,Options" +msgstr "Ten,Moitas,Opcións" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Data Type:" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon" +msgstr "Icona" + +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Style" +msgstr "Estilo" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Font" +msgstr "Fonte" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Color" +msgstr "Cor" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme File" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Fix Invalid Tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cut Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Line Draw" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Bucket Fill" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Find Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Transpose" +msgstr "Transpoñer" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Disable Autotile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Enable Priority" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Filter tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Give a TileSet resource to this TileMap to use its tiles." +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Command+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Ctrl+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Pick Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Left" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Right" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Horizontally" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Vertically" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Clear Transform" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Add Texture(s) to TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected Texture from TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Single Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Autotile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Atlas" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Next Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the next shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Previous Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the previous shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region" +msgstr "Rexión" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision" +msgstr "Colisión" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion" +msgstr "Oclusión" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation" +msgstr "Navegación" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask" +msgstr "Máscara de Bits" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority" +msgstr "Prioridade" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Copy bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Erase bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new rectangle." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Rectangle" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete Selected Shape" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Keep polygon inside region Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Enable snap and show grid (configurable via the Inspector)." +msgstr "" +"Activar axuste de cuadrÃcula e amosar cuadrÃcula (configurable no inspector)." + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Display Tile Names (Hold Alt Key)" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Add or select a texture on the left panel to edit the tiles bound to it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected texture? This will remove all tiles which use it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "You haven't selected a texture to remove." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from scene? This will overwrite all current tiles." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from scene?" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Texture" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "%s file(s) were not added because was already on the list." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Drag handles to edit Rect.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete selected Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select current edited sub-tile.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"LMB: Set bit on.\n" +"RMB: Set bit off.\n" +"Shift+LMB: Set wildcard bit.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to use as icon, this will be also used on invalid autotile " +"bindings.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its priority.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its z index.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Icon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Clear Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "This property can't be changed." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "TileSet" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No VCS addons are available." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Error" +msgstr "Erro" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No files added to stage" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "VCS Addon is not initialized" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control System" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Initialize" +msgstr "Inicializar" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Staging area" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Changes" +msgstr "Cambios" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "Modificado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "Renomeado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "Eliminado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage Selected" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage All" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Status" +msgstr "Estado" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View file diffs before committing them to the latest version" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No file diff is active" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect changes in file diff" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(GLES3 only)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Output" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar" +msgstr "Escalar" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector" +msgstr "Vector" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean" +msgstr "Booleano" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sampler" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set expression" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Resize VisualShader node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Uniform Name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Input Default Port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node to Visual Shader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Node(s) Moved" +msgstr "Nodo(s) Movido(s)" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Duplicate Nodes" +msgstr "Duplicar Nodos" + +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste Nodes" +msgstr "Pegar Nodos" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Nodes" +msgstr "Eliminar Nodos" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Input Type Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "UniformRef Name Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vertex" +msgstr "Vertex" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Fragment" +msgstr "Fragment" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Light" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Show resulted shader code." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Create Shader Node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Grayscale function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts HSV vector to RGB equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts RGB vector to HSV equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sepia function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Burn operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Darken operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Difference operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Dodge operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "HardLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Lighten operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Overlay operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Screen operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "SoftLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the %s comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Equal (==)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than (>)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than or Equal (>=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided scalars are equal, greater or " +"less." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between NaN and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than (<)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than or Equal (<=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Not Equal (!=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated scalar if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF (or NaN) and a " +"scalar parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for all shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Input parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for light shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "E constant (2.718282). Represents the base of the natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Epsilon constant (0.00001). Smallest possible scalar number." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Phi constant (1.618034). Golden ratio." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/4 constant (0.785398) or 45 degrees." +msgstr "Constante Pi/4 (0.785398), ou 45 graos." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/2 constant (1.570796) or 90 degrees." +msgstr "Constante Pi/2 (1.570796), ou 90 graos." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi constant (3.141593) or 180 degrees." +msgstr "Constante Pi (3.141593), ou 180 graos." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Tau constant (6.283185) or 360 degrees." +msgstr "Constante Tau (6.283185), ou 360 graos." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sqrt2 constant (1.414214). Square root of 2." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the absolute value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Finds the nearest integer that is greater than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Constrains a value to lie between two further values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in radians to degrees." +msgstr "Converte unha cantidade de radiáns a graos." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-e Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer less than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Computes the fractional part of the argument." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse of the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the greater of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the lesser of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the opposite value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the value of the first parameter raised to the power of the second." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in degrees to radians." +msgstr "Converte unha cantidade de graos a radiáns." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest even integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Clamps the value between 0.0 and 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Extracts the sign of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" +"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" +"\n" +"Devolve 0.0 se 'x' é menor que 'edge0' e 1.0 se x é maior que 'edge1'. En " +"caso contrario devólvese un valor interpolado entre 0.0 e 1.0 usando " +"polinomios de Hermite." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" +"Step function( scalar(edge), scalar(x) ).\n" +"\n" +"Devolve 0.0 se 'x' e menor que 'edge'; e 1.0 en caso contrario." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the truncated value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds scalar to scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts scalar from scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the cubic texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Cubic texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup with triplanar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Calculate the outer product of a pair of vectors.\n" +"\n" +"OuterProduct treats the first parameter 'c' as a column vector (matrix with " +"one column) and the second parameter 'r' as a row vector (matrix with one " +"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix " +"whose number of rows is the number of components in 'c' and whose number of " +"columns is the number of components in 'r'." +msgstr "" +"Calcula o produto exterior dun par de vectores.\n" +"\n" +"OuterProduct trata o primeiro parámetro 'c' coma un vector columna (matriz " +"con unha soa columna), e o segundo parámetro 'r' coma un vector fila (matriz " +"con unha soa fila), e fai a multiplicación alxebráica 'c * r'. Esto devolve " +"unha matriz cun número de filas igual ao número de compoñentes en 'c', e cun " +"número de columnas igual ao número de compoñentes en 'r'." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes transform from four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes transform to four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the determinant of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the inverse of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the transpose of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies transform by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes vector from three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes vector to three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the cross product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the distance between two points." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the dot product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the same direction as a reference vector. " +"The function has three vector parameters : N, the vector to orient, I, the " +"incident vector, and Nref, the reference vector. If the dot product of I and " +"Nref is smaller than zero the return value is N. Otherwise -N is returned." +msgstr "" +"Devolve o vector que ten a mesma dirección que o vector de referencia. A " +"función ten tres vector como parámetros: N, o vector a orientar; I, o vector " +"incidente; e Nref, o vector de referencia. Se o produto escalar de I e Nref " +"é menor que cero (forman un ángulo maior que 90 graos) entón devolve N. En " +"caso contrario devolve -N." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the length of a vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors using scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the normalize product of vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the direction of reflection ( a : incident " +"vector, b : normal vector )." +msgstr "" +"Devolve o vector que apunta na dirección de reflexo ( a : vector incidente, " +"b : vector normal)." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the vector that points in the direction of refraction." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" +"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" +"\n" +"Devolve 0.0 se 'x' é menor que 'edge0' e 1.0 se x é maior que 'edge1'. En " +"caso contrario devólvese un valor interpolado entre 0.0 e 1.0 usando " +"polinomios de Hermite." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" +"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" +"\n" +"Devolve 0.0 se 'x' é menor que 'edge0' e 1.0 se x é maior que 'edge1'. En " +"caso contrario devólvese un valor interpolado entre 0.0 e 1.0 usando " +"polinomios de Hermite." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( vector(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" +"Step function( vector(edge), vector(x) ).\n" +"\n" +"Devolve 0.0 se 'x' e menor que 'edge'; e 1.0 en caso contrario." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" +"Step function( scalar(edge), vector(x) ).\n" +"\n" +"Devolve 0.0 se 'x' e menor que 'edge'; e 1.0 en caso contrario." + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds vector to vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts vector from vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, with custom amount of input and " +"output ports. This is a direct injection of code into the vertex/fragment/" +"light function, do not use it to write the function declarations inside." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns falloff based on the dot product of surface normal and view " +"direction of camera (pass associated inputs to it)." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, which is placed on top of the " +"resulted shader. You can place various function definitions inside and call " +"it later in the Expressions. You can also declare varyings, uniforms and " +"constants." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "A reference to an existing uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Scalar derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Vector derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "VisualShader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Edit Visual Property" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Mode Changed" +msgstr "" + +#: editor/project_export.cpp +msgid "Runnable" +msgstr "Executable" + +#: editor/project_export.cpp +msgid "Delete preset '%s'?" +msgstr "Eliminar axustes de exportación '%s'?" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"Export templates seem to be missing or invalid." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"This might be due to a configuration issue in the export preset or your " +"export settings." +msgstr "" +"Fallou a exportación do proxecto á plataforma '%s'.\n" +"Esto pode deberse a un problema cos axustes de exportación." + +#: editor/project_export.cpp +msgid "Release" +msgstr "" + +#: editor/project_export.cpp +msgid "Exporting All" +msgstr "" + +#: editor/project_export.cpp +msgid "The given export path doesn't exist:" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing/corrupted:" +msgstr "" + +#: editor/project_export.cpp +msgid "Presets" +msgstr "Axustes de Exportación" + +#: editor/project_export.cpp editor/project_settings_editor.cpp +msgid "Add..." +msgstr "Engadir..." + +#: editor/project_export.cpp +msgid "" +"If checked, the preset will be available for use in one-click deploy.\n" +"Only one preset per platform may be marked as runnable." +msgstr "" +"Ao estar activado, estes axustes de exportación estarán dispoñibles para o " +"usar co despregue dun só clic.\n" +"Só uns axustes de exportación por plataforma poden marcarse como executables." + +#: editor/project_export.cpp +msgid "Export Path" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources" +msgstr "Recursos" + +#: editor/project_export.cpp +msgid "Export all resources in the project" +msgstr "Exportar tódolos recursos no proxecto" + +#: editor/project_export.cpp +msgid "Export selected scenes (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected resources (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources to export:" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to export non-resource files/folders\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to exclude files/folders from project\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" +"Filtros para excluÃr arquivos/cartafois de proxectos\n" +"(separados por coma; exemplo: *json, *.txt, docs*)" + +#: editor/project_export.cpp +msgid "Features" +msgstr "CaracterÃsticas" + +#: editor/project_export.cpp +msgid "Custom (comma-separated):" +msgstr "" + +#: editor/project_export.cpp +msgid "Feature List:" +msgstr "" + +#: editor/project_export.cpp +msgid "Script" +msgstr "Script" + +#: editor/project_export.cpp +msgid "Script Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Text" +msgstr "Texto" + +#: editor/project_export.cpp +msgid "Compiled" +msgstr "Compilado" + +#: editor/project_export.cpp +msgid "Encrypted (Provide Key Below)" +msgstr "" + +#: editor/project_export.cpp +msgid "Invalid Encryption Key (must be 64 characters long)" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Encryption Key (256-bits as hex):" +msgstr "" + +#: editor/project_export.cpp +msgid "Export PCK/Zip" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Project" +msgstr "Exportar Proxecto" + +#: editor/project_export.cpp +msgid "Export mode?" +msgstr "" + +#: editor/project_export.cpp +msgid "Export All" +msgstr "" + +#: editor/project_export.cpp editor/project_manager.cpp +msgid "ZIP File" +msgstr "" + +#: editor/project_export.cpp +msgid "Godot Game Pack" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing:" +msgstr "" + +#: editor/project_export.cpp +msgid "Manage Export Templates" +msgstr "" + +#: editor/project_export.cpp +msgid "Export With Debug" +msgstr "" + +#: editor/project_manager.cpp +msgid "The path specified doesn't exist." +msgstr "" + +#: editor/project_manager.cpp +msgid "Error opening package file (it's not in ZIP format)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." +msgstr "" +"O arquivo de proxecto '.zip' non é válido; non conteñe ningún arquivo de " +"configuración 'project.godot'." + +#: editor/project_manager.cpp +msgid "Please choose an empty folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose a \"project.godot\" or \".zip\" file." +msgstr "Por favor, elixa un arquivo de tipo 'project.godot' ou '.zip'." + +#: editor/project_manager.cpp +msgid "This directory already contains a Godot project." +msgstr "O directorio xa contén un proxecto Godot." + +#: editor/project_manager.cpp +msgid "New Game Project" +msgstr "Novo Proxecto de Xogo" + +#: editor/project_manager.cpp +msgid "Imported Project" +msgstr "Proxecto Importado" + +#: editor/project_manager.cpp +msgid "Invalid Project Name." +msgstr "Nome de Proxecto Inválido." + +#: editor/project_manager.cpp +msgid "Couldn't create folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "There is already a folder in this path with the specified name." +msgstr "" + +#: editor/project_manager.cpp +msgid "It would be a good idea to name your project." +msgstr "SerÃa unha boa idea nomear o teu proxecto." + +#: editor/project_manager.cpp +msgid "Invalid project path (changed anything?)." +msgstr "A ruta ao proxecto non é valida. Cambiaches algo?" + +#: editor/project_manager.cpp +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"Non se pudo cargar o arquivo de configuración 'project.godot' na ruta do " +"proxecto (erro %d). Pode ser que o arquivo non exista; ou que esté " +"corrompido." + +#: editor/project_manager.cpp +msgid "Couldn't edit project.godot in project path." +msgstr "Non se pudo editar o arquivo 'project.godot' na ruta do proxecto." + +#: editor/project_manager.cpp +msgid "Couldn't create project.godot in project path." +msgstr "Non se pudo crear o arquivo 'project.godot' na ruta do proxecto." + +#: editor/project_manager.cpp +msgid "Rename Project" +msgstr "Renomear Proxecto" + +#: editor/project_manager.cpp +msgid "Import Existing Project" +msgstr "Importar Proxecto Existente" + +#: editor/project_manager.cpp +msgid "Import & Edit" +msgstr "Importar e Editar" + +#: editor/project_manager.cpp +msgid "Create New Project" +msgstr "Crear Novo Proxecto" + +#: editor/project_manager.cpp +msgid "Create & Edit" +msgstr "Crear e Editar" + +#: editor/project_manager.cpp +msgid "Install Project:" +msgstr "Instalar Proxecto:" + +#: editor/project_manager.cpp +msgid "Install & Edit" +msgstr "Instalar e Editar" + +#: editor/project_manager.cpp +msgid "Project Name:" +msgstr "Nome do Proxecto:" + +#: editor/project_manager.cpp +msgid "Project Path:" +msgstr "Ruta do Proxecto:" + +#: editor/project_manager.cpp +msgid "Project Installation Path:" +msgstr "Ruta de Instalación do Proxecto:" + +#: editor/project_manager.cpp +msgid "Renderer:" +msgstr "Renderizador:" + +#: editor/project_manager.cpp +msgid "OpenGL ES 3.0" +msgstr "OpenGL ES 3.0" + +#: editor/project_manager.cpp +msgid "Not supported by your GPU drivers." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Higher visual quality\n" +"All features available\n" +"Incompatible with older hardware\n" +"Not recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 2.0" +msgstr "OpenGL ES 2.0" + +#: editor/project_manager.cpp +msgid "" +"Lower visual quality\n" +"Some features not available\n" +"Works on most hardware\n" +"Recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer can be changed later, but scenes may need to be adjusted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Unnamed Project" +msgstr "Proxecto Sen Nome" + +#: editor/project_manager.cpp +msgid "Missing Project" +msgstr "Proxecto Faltante" + +#: editor/project_manager.cpp +msgid "Error: Project is missing on the filesystem." +msgstr "Erro: O proxecto non se pode encontrar no sistema de arquivos." + +#: editor/project_manager.cpp +msgid "Can't open project at '%s'." +msgstr "Non se pode abrir proxecto en '%s'." + +#: editor/project_manager.cpp +msgid "Are you sure to open more than one project?" +msgstr "Está seguro de que quere abrir máis dun proxecto?" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file does not specify the version of Godot " +"through which it was created.\n" +"\n" +"%s\n" +"\n" +"If you proceed with opening it, it will be converted to Godot's current " +"configuration file format.\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" +"O arquivo de configuración do seguinte proxecto non especifica a versión de " +"Godot ca cal foi creado.\n" +"\n" +"%s\n" +"\n" +"Se o abres o arquivo de configuración será convertido ao formato utilizado " +"na versión actual de Godot.\n" +"Aviso: Xa non poderás volver a abrir este proxecto con versións anteriores " +"de Godot." + +#: editor/project_manager.cpp +msgid "" +"The following project settings file was generated by an older engine " +"version, and needs to be converted for this version:\n" +"\n" +"%s\n" +"\n" +"Do you want to convert it?\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" +"O arquivo de configuración do seguinte proxecto foi xerado por unha versión " +"antiga de Godot, e é necesario convertelo á versión actual:\n" +"\n" +"%s\n" +"\n" +"Queres convertelo?\n" +"Aviso: Xa non poderás abrir o proxecto con versións anteriores de Godot." + +#: editor/project_manager.cpp +msgid "" +"The project settings were created by a newer engine version, whose settings " +"are not compatible with this version." +msgstr "" +"A configuración do proxecto foi creada por versións máis novas de Godot; " +"facéndoa incompatible con esta versión." + +#: editor/project_manager.cpp +msgid "" +"Can't run project: no main scene defined.\n" +"Please edit the project and set the main scene in the Project Settings under " +"the \"Application\" category." +msgstr "" +"Non se pode executar o proxecto: non hai unha escena principal definida.\n" +"Por favor, selecciona unha escena principal en \"Configuración do Proxecto" +"\", na categorÃa \"Aplicación\"." + +#: editor/project_manager.cpp +msgid "" +"Can't run project: Assets need to be imported.\n" +"Please edit the project to trigger the initial import." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to run %d projects at once?" +msgstr "Seguro que queres executar %d proxectos ao mesmo tempo?" + +#: editor/project_manager.cpp +msgid "" +"Remove %d projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" +"Eliminar %d proxectos da lista?\n" +"Os contidos da carpeta de proxectos non serán modificados." + +#: editor/project_manager.cpp +msgid "" +"Remove this project from the list?\n" +"The project folder's contents won't be modified." +msgstr "" +"Eliminar este proxecto da lista?\n" +"Os contidos da carpeta de proxectos non serán modificados." + +#: editor/project_manager.cpp +msgid "" +"Remove all missing projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" +"Eliminar todos os proxectos faltantes da lista?\n" +"Os contidos da carpeta de proxectos non serán modificados." + +#: editor/project_manager.cpp +msgid "" +"Language changed.\n" +"The interface will update after restarting the editor or project manager." +msgstr "" +"Linguaxe cambiada.\n" +"A interface actualizarase despois de reiniciar o editor ou administrador de " +"proxectos." + +#: editor/project_manager.cpp +msgid "" +"Are you sure to scan %s folders for existing Godot projects?\n" +"This could take a while." +msgstr "" +"Seguro que quere escanear proxectos de Godot en %s cartafois?\n" +"Esto poderÃa demorarse un tempo." + +#. TRANSLATORS: This refers to the application where users manage their Godot projects. +#: editor/project_manager.cpp +msgid "Project Manager" +msgstr "Administrador de Proxectos" + +#: editor/project_manager.cpp +msgid "Projects" +msgstr "Proxectos" + +#: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "" +"Examinando arquivos,\n" +"Por favor, espere..." + +#: editor/project_manager.cpp +msgid "Last Modified" +msgstr "Derradeira Modificación" + +#: editor/project_manager.cpp +msgid "Scan" +msgstr "Escanear" + +#: editor/project_manager.cpp +msgid "Select a Folder to Scan" +msgstr "Seleccionar un Cartafol para Escanear" + +#: editor/project_manager.cpp +msgid "New Project" +msgstr "Novo Proxecto" + +#: editor/project_manager.cpp +msgid "Remove Missing" +msgstr "Eliminar Faltantes" + +#: editor/project_manager.cpp +msgid "Templates" +msgstr "Proxectos Modelo" + +#: editor/project_manager.cpp +msgid "Restart Now" +msgstr "Reiniciar Agora" + +#: editor/project_manager.cpp +msgid "Can't run project" +msgstr "Non se pode executar proxecto" + +#: editor/project_manager.cpp +msgid "" +"You currently don't have any projects.\n" +"Would you like to explore official example projects in the Asset Library?" +msgstr "" +"Actualmente non tes ningún proxecto.\n" +"GustarÃalle buscar proxectos de exemplo oficiais na biblioteca de Assets?" + +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" +"A barra de búsqueda filtra os proxectos por nome e último compoñente da súa " +"ruta.\n" +"Se quere filtrar proxectos por nome e ruta completa, a consulta debe conter " +"polo menos un carácter '/'." + +#: editor/project_settings_editor.cpp +msgid "Key " +msgstr "Botón: " + +#: editor/project_settings_editor.cpp +msgid "Joy Button" +msgstr "Botón Joystick" + +#: editor/project_settings_editor.cpp +msgid "Joy Axis" +msgstr "Eixe Joystick" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button" +msgstr "Botón do Rato" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'" +msgstr "" +"Nome de acción inválido. O nome non pode estar baleiro, nin conter '/', ':', " +"'=', '\\' ou '\"'" + +#: editor/project_settings_editor.cpp +msgid "An action with the name '%s' already exists." +msgstr "Xa existe unha acción co nome '%s'." + +#: editor/project_settings_editor.cpp +msgid "Rename Input Action Event" +msgstr "Renomear Evento de Entrada" + +#: editor/project_settings_editor.cpp +msgid "Change Action deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action Event" +msgstr "Engadir Evento de Entrada" + +#: editor/project_settings_editor.cpp +msgid "All Devices" +msgstr "Tódolos Dispositivos" + +#: editor/project_settings_editor.cpp +msgid "Device" +msgstr "Dispositivo" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Press a Key..." +msgstr "Pulse algún botón..." + +#: editor/project_settings_editor.cpp +msgid "Mouse Button Index:" +msgstr "Ãndice do Botón do Rato:" + +#: editor/project_settings_editor.cpp +msgid "Left Button" +msgstr "Botón Esquerdo" + +#: editor/project_settings_editor.cpp +msgid "Right Button" +msgstr "Botón Dereito" + +#: editor/project_settings_editor.cpp +msgid "Middle Button" +msgstr "Botón Central" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up Button" +msgstr "Mover Roda cara Arriba" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down Button" +msgstr "Mover Roda cara Abaixo" + +#: editor/project_settings_editor.cpp +msgid "Wheel Left Button" +msgstr "Mover Roda cara a Esquerda" + +#: editor/project_settings_editor.cpp +msgid "Wheel Right Button" +msgstr "Mover Roda cara a Dereita" + +#: editor/project_settings_editor.cpp +msgid "X Button 1" +msgstr "Botón X 1" + +#: editor/project_settings_editor.cpp +msgid "X Button 2" +msgstr "Botón X 2" + +#: editor/project_settings_editor.cpp +msgid "Joypad Axis Index:" +msgstr "Ãndice do Eixe do Joystick:" + +#: editor/project_settings_editor.cpp +msgid "Axis" +msgstr "Eixe" + +#: editor/project_settings_editor.cpp +msgid "Joypad Button Index:" +msgstr "Ãndice do Botón do Joystick:" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action" +msgstr "Eliminar Acción de Entrada" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action Event" +msgstr "Eliminar Evento de Entrada" + +#: editor/project_settings_editor.cpp +msgid "Add Event" +msgstr "Engadir Evento" + +#: editor/project_settings_editor.cpp +msgid "Button" +msgstr "Botón" + +#: editor/project_settings_editor.cpp +msgid "Left Button." +msgstr "Botón Esquerdo." + +#: editor/project_settings_editor.cpp +msgid "Right Button." +msgstr "Botón Dereito." + +#: editor/project_settings_editor.cpp +msgid "Middle Button." +msgstr "Botón Central." + +#: editor/project_settings_editor.cpp +msgid "Wheel Up." +msgstr "Roda cara Arriba." + +#: editor/project_settings_editor.cpp +msgid "Wheel Down." +msgstr "Roda cara Abaixo." + +#: editor/project_settings_editor.cpp +msgid "Add Global Property" +msgstr "Engadir Propiedade Global" + +#: editor/project_settings_editor.cpp +msgid "Select a setting item first!" +msgstr "Primeiro seleccione un elemento!" + +#: editor/project_settings_editor.cpp +msgid "No property '%s' exists." +msgstr "Non existe a propiedade '%s'." + +#: editor/project_settings_editor.cpp +msgid "Setting '%s' is internal, and it can't be deleted." +msgstr "A propiedade '%s' é interna, e non pode ser eliminada." + +#: editor/project_settings_editor.cpp +msgid "Delete Item" +msgstr "Eliminar Elemento" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'." +msgstr "" +"Nome de acción inválido. Non pode estar baleiro, nin pode conter '/', ':', " +"'=', '\\' ou '\"'." + +#: editor/project_settings_editor.cpp +msgid "Add Input Action" +msgstr "Engadir Acción de Entrada" + +#: editor/project_settings_editor.cpp +msgid "Error saving settings." +msgstr "Erro gardando os axustes." + +#: editor/project_settings_editor.cpp +msgid "Settings saved OK." +msgstr "Axustes gardados correctamente." + +#: editor/project_settings_editor.cpp +msgid "Moved Input Action Event" +msgstr "Evento de Entrada Movido" + +#: editor/project_settings_editor.cpp +msgid "Override for Feature" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Translation" +msgstr "Engadir Tradución" + +#: editor/project_settings_editor.cpp +msgid "Remove Translation" +msgstr "Eliminar Tradución" + +#: editor/project_settings_editor.cpp +msgid "Add Remapped Path" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resource Remap Add Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Resource Remap Language" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap Option" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter Mode" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Project Settings (project.godot)" +msgstr "Configuración do Proxecto (project.godot)" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "General" +msgstr "Xeral" + +#: editor/project_settings_editor.cpp +msgid "Override For..." +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "The editor must be restarted for changes to take effect." +msgstr "O editor ten que reiniciarse para que os cambios teñan efecto." + +#: editor/project_settings_editor.cpp +msgid "Input Map" +msgstr "Mapeado de Entradas" + +#: editor/project_settings_editor.cpp +msgid "Action:" +msgstr "Acción:" + +#: editor/project_settings_editor.cpp +msgid "Action" +msgstr "Acción" + +#: editor/project_settings_editor.cpp +msgid "Deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device:" +msgstr "Dispositivo:" + +#: editor/project_settings_editor.cpp +msgid "Index:" +msgstr "Ãndice:" + +#: editor/project_settings_editor.cpp +msgid "Localization" +msgstr "Linguaxe" + +#: editor/project_settings_editor.cpp +msgid "Translations" +msgstr "Traducións" + +#: editor/project_settings_editor.cpp +msgid "Translations:" +msgstr "Traducións:" + +#: editor/project_settings_editor.cpp +msgid "Remaps" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resources:" +msgstr "Recursos:" + +#: editor/project_settings_editor.cpp +msgid "Remaps by Locale:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locale" +msgstr "Linguaxe" + +#: editor/project_settings_editor.cpp +msgid "Locales Filter" +msgstr "Filtrar Linguaxes" + +#: editor/project_settings_editor.cpp +msgid "Show All Locales" +msgstr "Amosar Tódolos Linguaxes" + +#: editor/project_settings_editor.cpp +msgid "Show Selected Locales Only" +msgstr "Amosar só os Linguaxes Seleccionados" + +#: editor/project_settings_editor.cpp +msgid "Filter mode:" +msgstr "Modo de Filtrado:" + +#: editor/project_settings_editor.cpp +msgid "Locales:" +msgstr "Linguaxes:" + +#: editor/project_settings_editor.cpp +msgid "AutoLoad" +msgstr "AutoCargador" + +#: editor/project_settings_editor.cpp +msgid "Plugins" +msgstr "CaracterÃsticas Adicionais (Plugins)" + +#: editor/property_editor.cpp +msgid "Preset..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Zero" +msgstr "Cero" + +#: editor/property_editor.cpp +msgid "Easing In-Out" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing Out-In" +msgstr "" + +#: editor/property_editor.cpp +msgid "File..." +msgstr "Arquivo..." + +#: editor/property_editor.cpp +msgid "Dir..." +msgstr "Directorio..." + +#: editor/property_editor.cpp +msgid "Assign" +msgstr "Asignar" + +#: editor/property_editor.cpp +msgid "Select Node" +msgstr "Seleccionar Nodos" + +#: editor/property_editor.cpp +msgid "Error loading file: Not a resource!" +msgstr "Erro cargando arquivo: Non é un recurso!" + +#: editor/property_editor.cpp +msgid "Pick a Node" +msgstr "Elixe un Nodo" + +#: editor/property_editor.cpp +msgid "Bit %d, val %d." +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Property" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Virtual Method" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Method" +msgstr "" + +#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp +msgid "Batch Rename" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Replace:" +msgstr "SubstituÃr:" + +#: editor/rename_dialog.cpp +msgid "Prefix:" +msgstr "Prefixo:" + +#: editor/rename_dialog.cpp +msgid "Suffix:" +msgstr "Sufixo:" + +#: editor/rename_dialog.cpp +msgid "Use Regular Expressions" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Advanced Options" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Substitute" +msgstr "SubstituÃr" + +#: editor/rename_dialog.cpp +msgid "Node name" +msgstr "Nome do nodo" + +#: editor/rename_dialog.cpp +msgid "Node's parent name, if available" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node type" +msgstr "Tipo de nodo" + +#: editor/rename_dialog.cpp +msgid "Current scene name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Root node name" +msgstr "Nome do nodo raÃz" + +#: editor/rename_dialog.cpp +msgid "" +"Sequential integer counter.\n" +"Compare counter options." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Per-level Counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "If set, the counter restarts for each group of child nodes." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Initial value for the counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Step" +msgstr "Paso" + +#: editor/rename_dialog.cpp +msgid "Amount by which counter is incremented for each node" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Padding" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Minimum number of digits for the counter.\n" +"Missing digits are padded with leading zeros." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Post-Process" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Keep" +msgstr "Manter" + +#: editor/rename_dialog.cpp +msgid "PascalCase to snake_case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "snake_case to PascalCase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Case" +msgstr "Maiús./Minús." + +#: editor/rename_dialog.cpp +msgid "To Lowercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Uppercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Reset" +msgstr "Restablecer" + +#: editor/rename_dialog.cpp +msgid "Regular Expression Error:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "At character %s" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent Node" +msgstr "Remparentar Nodo" + +#: editor/reparent_dialog.cpp +msgid "Reparent Location (Select new Parent):" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Keep Global Transform" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent" +msgstr "Remparentar" + +#: editor/run_settings_dialog.cpp +msgid "Run Mode:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Current Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene Arguments:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Scene Run Settings" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "No parent to instance the scenes at." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error loading scene from %s" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot instance the scene '%s' because the current scene exists within one " +"of its nodes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Scene(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Replace with Branch Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Child Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Pegar Nodos" + +#: editor/scene_tree_dock.cpp +msgid "Detach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on the tree root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Node In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Nodes In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Duplicate Node(s)" +msgstr "Duplicar Nodo(s)" + +#: editor/scene_tree_dock.cpp +msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Node must belong to the edited scene to become root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instantiated scenes can't become root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make node as Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes and any children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes?" +msgstr "Eliminar %d nodos?" + +#: editor/scene_tree_dock.cpp +msgid "Delete the root node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\" and its children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\"?" +msgstr "Eliminar nodo \"%s\"?" + +#: editor/scene_tree_dock.cpp +msgid "Can not perform with the root node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on instanced scenes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Save New Scene As..." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Disabling \"editable_instance\" will cause all properties of the node to be " +"reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and " +"cause all properties of the node to be reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "New Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Create Root Node:" +msgstr "Crear nodo raÃz:" + +#: editor/scene_tree_dock.cpp +msgid "2D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "3D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "User Interface" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Other Node" +msgstr "Outro Nodo" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes from a foreign scene!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes the current scene inherits from!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Cortar Nodos" + +#: editor/scene_tree_dock.cpp +msgid "Remove Node(s)" +msgstr "Eliminar Nodo(s)" + +#: editor/scene_tree_dock.cpp +msgid "Change type of node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Couldn't save new scene. Likely dependencies (instances) couldn't be " +"satisfied." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error saving scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error duplicating scene to save it." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Sub-Resources" +msgstr "Sub-Recursos" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Editable Children" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Load As Placeholder" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Open Documentation" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot attach a script: there are no languages registered.\n" +"This is probably because this editor was built with all language modules " +"disabled." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add Child Node" +msgstr "Engadir Nodo Fillo" + +#: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change Type" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Reparent to New Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Merge From Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Save Branch as Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Copy Node Path" +msgstr "Copiar Ruta do Nodo" + +#: editor/scene_tree_dock.cpp +msgid "Delete (No Confirm)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add/Create a New Node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Instance a scene file as a Node. Creates an inherited scene if no root node " +"exists." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach a new or existing script to the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach the script from the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remote" +msgstr "Remoto" + +#: editor/scene_tree_dock.cpp +msgid "Local" +msgstr "Local" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance? (No Undo!)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visible" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Unlock Node" +msgstr "Desbloquear Nodo" + +#: editor/scene_tree_editor.cpp +msgid "Button Group" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "(Connecting From)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node configuration warning:" +msgstr "Aviso sobre a configuración do nodo:" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s) and %s group(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is in %s group(s).\n" +"Click to show groups dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Open Script:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is locked.\n" +"Click to unlock it." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Children are not selectable.\n" +"Click to make selectable." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visibility" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"AnimationPlayer is pinned.\n" +"Click to unpin." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Invalid node name, the following characters are not allowed:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Rename Node" +msgstr "Renomear Nodo" + +#: editor/scene_tree_editor.cpp +msgid "Scene Tree (Nodes):" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node Configuration Warning!" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Select a Node" +msgstr "Seleccione un Nodo" + +#: editor/script_create_dialog.cpp +msgid "Path is empty." +msgstr "A ruta está baleira." + +#: editor/script_create_dialog.cpp +msgid "Filename is empty." +msgstr "O nome de arquivo está baleiro." + +#: editor/script_create_dialog.cpp +msgid "Path is not local." +msgstr "A ruta non é local." + +#: editor/script_create_dialog.cpp +msgid "Invalid base path." +msgstr "Ruta base inválida." + +#: editor/script_create_dialog.cpp +msgid "A directory with the same name exists." +msgstr "Xa existe un directorio co mesmo nome." + +#: editor/script_create_dialog.cpp +msgid "File does not exist." +msgstr "O arquivo non existe." + +#: editor/script_create_dialog.cpp +msgid "Invalid extension." +msgstr "Extensión inválida." + +#: editor/script_create_dialog.cpp +msgid "Wrong extension chosen." +msgstr "Extensión incorrecta elixida." + +#: editor/script_create_dialog.cpp +msgid "Error loading template '%s'" +msgstr "Erro cargando o modelo '%s'" + +#: editor/script_create_dialog.cpp +msgid "Error - Could not create script in filesystem." +msgstr "Erro - Non se puido gardar o Script no sistema de arquivos." + +#: editor/script_create_dialog.cpp +msgid "Error loading script from %s" +msgstr "Erro cargando script desde %s" + +#: editor/script_create_dialog.cpp +msgid "Overrides" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "N/A" +msgstr "N/A" + +#: editor/script_create_dialog.cpp +msgid "Open Script / Choose Location" +msgstr "Abrir Script / Elixir Ubicación" + +#: editor/script_create_dialog.cpp +msgid "Open Script" +msgstr "Abrir Script" + +#: editor/script_create_dialog.cpp +msgid "File exists, it will be reused." +msgstr "O arquivo xa existe; será reutilizado." + +#: editor/script_create_dialog.cpp +msgid "Invalid path." +msgstr "Ruta inválida." + +#: editor/script_create_dialog.cpp +msgid "Invalid class name." +msgstr "Nome de clase inválido." + +#: editor/script_create_dialog.cpp +msgid "Invalid inherited parent name or path." +msgstr "A ruta ou o nome do pai herdado é inválido." + +#: editor/script_create_dialog.cpp +msgid "Script path/name is valid." +msgstr "A ruta e nome do script son válidos." + +#: editor/script_create_dialog.cpp +msgid "Allowed: a-z, A-Z, 0-9, _ and ." +msgstr "Permitido: a-z, A-Z, 0-9,_ e ." + +#: editor/script_create_dialog.cpp +msgid "Built-in script (into scene file)." +msgstr "Script integrada na escena." + +#: editor/script_create_dialog.cpp +msgid "Will create a new script file." +msgstr "Crearase un novo arquivo de script." + +#: editor/script_create_dialog.cpp +msgid "Will load an existing script file." +msgstr "Cargarase un arquivo de script xa existente." + +#: editor/script_create_dialog.cpp +msgid "Script file already exists." +msgstr "Xa existe un arquivo script na mesma ruta." + +#: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" +"Nota: Os scripts integrados teñen algunhas limitacións, e non poden editarse " +"usando editores externos." + +#: editor/script_create_dialog.cpp +msgid "Class Name:" +msgstr "Nome da Clase:" + +#: editor/script_create_dialog.cpp +msgid "Template:" +msgstr "Modelo:" + +#: editor/script_create_dialog.cpp +msgid "Built-in Script:" +msgstr "Script Integrado:" + +#: editor/script_create_dialog.cpp +msgid "Attach Node Script" +msgstr "Adxuntar Script de Nodo" + +#: editor/script_editor_debugger.cpp +msgid "Remote " +msgstr "Remoto " + +#: editor/script_editor_debugger.cpp +msgid "Bytes:" +msgstr "Bytes:" + +#: editor/script_editor_debugger.cpp +msgid "Warning:" +msgstr "Aviso:" + +#: editor/script_editor_debugger.cpp +msgid "Error:" +msgstr "Erro:" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error" +msgstr "Erro de C++" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error:" +msgstr "Erro de C++:" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source" +msgstr "Fonte C++" + +#: editor/script_editor_debugger.cpp +msgid "Source:" +msgstr "Fonte:" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source:" +msgstr "Fonte C++:" + +#: editor/script_editor_debugger.cpp +msgid "Stack Trace" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Errors" +msgstr "Erros" + +#: editor/script_editor_debugger.cpp +msgid "Child process connected." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Copy Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Video RAM" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Skip Breakpoints" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Previous Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Next Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Frames" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Profiler" +msgstr "AnalÃtica de Rendemento" + +#: editor/script_editor_debugger.cpp +msgid "Network Profiler" +msgstr "AnalÃtica de Rendemento de Rede" + +#: editor/script_editor_debugger.cpp +msgid "Monitor" +msgstr "Monitor" + +#: editor/script_editor_debugger.cpp +msgid "Value" +msgstr "Valor" + +#: editor/script_editor_debugger.cpp +msgid "Monitors" +msgstr "Monitores" + +#: editor/script_editor_debugger.cpp +msgid "Pick one or more items from the list to display the graph." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "List of Video Memory Usage by Resource:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Total:" +msgstr "Total:" + +#: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Resource Path" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Type" +msgstr "Tipo" + +#: editor/script_editor_debugger.cpp +msgid "Format" +msgstr "Formato" + +#: editor/script_editor_debugger.cpp +msgid "Usage" +msgstr "Uso" + +#: editor/script_editor_debugger.cpp +msgid "Misc" +msgstr "Outros" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control Type:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Live Edit Root:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Set From Tree" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export measures as CSV" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Erase Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Restore Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Change Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Editor Settings" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Shortcuts" +msgstr "Atallos" + +#: editor/settings_config_dialog.cpp +msgid "Binding" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Light Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change AudioStreamPlayer3D Emission Angle" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera FOV" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera Size" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Notifier AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Particles AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Probe Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Sphere Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Box Shape Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Ray Shape Length" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Height" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Inner Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Outer Radius" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select the dynamic library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select dependencies of the library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Remove current entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Double click to create a new entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform:" +msgstr "Plataforma:" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform" +msgstr "Plataforma" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dynamic Library" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Add an architecture entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "GDNativeLibrary" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Enabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Disabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Library" +msgstr "Biblioteca" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Libraries: " +msgstr "Bibliotecas: " + +#: modules/gdnative/register_types.cpp +msgid "GDNative" +msgstr "GDNative" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Step argument is zero!" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not a script with an instance" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a script" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a resource file" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (missing @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (can't load script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (invalid script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary (invalid subclasses)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Object can't provide a length." +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Plano:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" +msgstr "Chan:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Delete Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paste Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paint" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" +msgstr "Axustar Vista" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Disabled" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Above" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Below" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit X Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Y Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Z Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Clear Rotation" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Paste Selects" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clear Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Settings" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Pick Distance:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Filter meshes" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Give a MeshLibrary resource to this GridMap to use its meshes." +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + +#: modules/mono/csharp_script.cpp +msgid "Class name can't be a reserved keyword" +msgstr "" + +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Bake NavMesh" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Clear the navigation mesh." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Setting up Configuration..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Calculating grid size..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Marking walkable triangles..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Constructing compact heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Eroding walkable area..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Partitioning..." +msgstr "Particionando..." + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating contours..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating polymesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Converting to native navigation mesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Navigation Mesh Generator Setup:" +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Parsing Geometry..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Done!" +msgstr "Feito!" + +#: modules/visual_script/visual_script.cpp +msgid "" +"A node yielded without working memory, please read the docs on how to yield " +"properly!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Node yielded, but did not return a function state in the first working " +"memory." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Return value must be assigned to first element of node working memory! Fix " +"your node please." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Node returned an invalid sequence output: " +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Found sequence bit but not the node in the stack, report bug!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Stack overflow with stack depth: " +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Signal Arguments" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Default Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Override an existing built-in function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Variables:" +msgstr "Variables:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new variable." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Signals:" +msgstr "Sinais:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new signal." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name is not a valid identifier:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name already in use by another func/var/signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete input port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Expression" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Duplicate VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Preload Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node(s) From Tree" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "" +"Can't drop properties because script '%s' is not used in this scene.\n" +"Drop holding 'Shift' to just copy the signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Getter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Setter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Move Node(s)" +msgstr "Mover Nodo(s)" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Nodes" +msgstr "Conectar Nodos" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Disconnect Nodes" +msgstr "Desconectar Nodos" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Data" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Sequence" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Script already has function '%s'" +msgstr "O script xa ten unha función chamada '%s'" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Input Value" +msgstr "Cambiar Valor de Entrada" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Resize Comment" +msgstr "Cambiar Tamaño do Comentario" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't copy the function node." +msgstr "Non se pode copiar o nodo función." + +#: modules/visual_script/visual_script_editor.cpp +msgid "Clipboard is empty!" +msgstr "O portapapeis está baleiro!" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste VisualScript Nodes" +msgstr "Pegar Nodos VisualScript" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function with a function node." +msgstr "Non se pode crear unha función cun nodo función." + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function of nodes from nodes of multiple functions." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select at least one node with sequence port." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Try to only have one sequence input in selection." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create Function" +msgstr "Crear Función" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Function" +msgstr "Eliminar Función" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Variable" +msgstr "Eliminar Variable" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Variable:" +msgstr "Editando Variable:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Signal" +msgstr "Eliminar Sinal" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Signal:" +msgstr "Editando Sinal:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Tool:" +msgstr "Ferramenta:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Members:" +msgstr "Membros:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type:" +msgstr "Cambiar Tipo Base:" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Nodes..." +msgstr "Engadir Nodos..." + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function..." +msgstr "Engadir Función..." + +#: modules/visual_script/visual_script_editor.cpp +msgid "function_name" +msgstr "nome_da_funcion" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select or create a function to edit its graph." +msgstr "Seleccione ou cree unha función para editar a sua gráfica." + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete Selected" +msgstr "Eliminar Selección" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Find Node Type" +msgstr "Encontrar Tipo de Nodo" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Copy Nodes" +msgstr "Copiar Nodos" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Cut Nodes" +msgstr "Cortar Nodos" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Refresh Graph" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit Member" +msgstr "Editar Membro" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Input type not iterable: " +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid: " +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name." +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Base object is not a Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Path does not lead Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name '%s' in node %s." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid argument of type: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid arguments: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableGet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableSet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Custom node has no _step() method, can't process graph." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "" +"Invalid return value from _step(), must be integer (seq out), or string " +"(error)." +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search VisualScript" +msgstr "Buscar en VisualScript" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Set %s" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package name is missing." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package segments must be of non-zero length." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' is not allowed in Android application package names." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A digit cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The package must have at least one '.' separator." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Select device from the list" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find the 'apksigner' tool." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Debug keystore not configured in the Editor Settings nor in the preset." +msgstr "" +"Non está configurado o Keystore de depuración nin na configuración do " +"editor, nin nos axustes de exportación." + +#: platform/android/export/export.cpp +msgid "Release keystore incorrectly configured in the export preset." +msgstr "" +"O Keystore Release non está configurado correctamente nos axustes de " +"exportación." + +#: platform/android/export/export.cpp +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid Android SDK path in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'platform-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid public key for APK expansion." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid package name:" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" " +"project setting (changed in Godot 3.2.2).\n" +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Use Custom Build\" must be enabled to use the plugins." +msgstr "" +"\"Use Custom Build\" debe estar activado para usar estas caracterÃsticas " +"adicionais (plugins)." + +#: platform/android/export/export.cpp +msgid "" +"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR" +"\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android App Bundle requires the *.aab extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "APK Expansion not compatible with Android App Bundle." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android APK requires the *.apk extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Trying to build from a custom built template, but no version info for it " +"exists. Please reinstall from the 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build version mismatch:\n" +" Template installed: %s\n" +" Godot Version: %s\n" +"Please reinstall Android build template from 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Building Android Project (gradle)" +msgstr "Construir Proxecto Android (gradle)" + +#: platform/android/export/export.cpp +msgid "" +"Building of Android project failed, check output for the error.\n" +"Alternatively visit docs.godotengine.org for Android build documentation." +msgstr "" +"A creación do proxecto para Android fallou; comproba a saÃda para encontrar " +"o erro.\n" +"Ou visita docs.godotengine.org para ver a documentación sobre compilación " +"para Android." + +#: platform/android/export/export.cpp +msgid "Moving output" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Unable to copy and rename export file, check gradle project directory for " +"outputs." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Identifier is missing." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "The character '%s' is not allowed in Identifier." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "App Store Team ID not specified - cannot configure the project." +msgstr "" +"ID de App Store Team non especificado - non se pode configurar o proxecto." + +#: platform/iphone/export/export.cpp +msgid "Invalid Identifier:" +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Required icon is not specified in the preset." +msgstr "" +"As iconas requeridas non están especificadas nos axustes de exportación." + +#: platform/javascript/export/export.cpp +msgid "Stop HTTP Server" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run in Browser" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run exported HTML in the system's default browser." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not write file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not open template for export:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Invalid export template:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read custom HTML shell:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read boot splash image file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Using default boot splash image." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package short name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package unique name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package publisher display name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid product GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid publisher GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid background color." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid Store Logo image dimensions (should be 50x50)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid splash screen image dimensions (should be 620x300)." +msgstr "" + +#: scene/2d/animated_sprite.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite to display frames." +msgstr "" + +#: scene/2d/canvas_modulate.cpp +msgid "" +"Only one visible CanvasModulate is allowed per scene (or set of instanced " +"scenes). The first created one will work, while the rest will be ignored." +msgstr "" + +#: scene/2d/collision_object_2d.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " +"define its shape." +msgstr "" +"Este nodo non ten unha forma fÃsica definida, polo que non pode colisionar " +"ou interactuar con outros obxectos.\n" +"Engade un nodo CollisionShape2D ou CollisionPolygon2D como fillo para " +"definir a sua forma." + +#: scene/2d/collision_polygon_2d.cpp +msgid "" +"CollisionPolygon2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" +"O nodo CollisionPolygon2D só serve para darlle unha forma fÃsica a nodos " +"derivados de CollisionObject2D. É decir, do tipo Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D, etc." + +#: scene/2d/collision_polygon_2d.cpp +msgid "An empty CollisionPolygon2D has no effect on collision." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"CollisionShape2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" +"O nodo CollisionShape2D só serve para darlle unha forma fÃsica a nodos " +"derivados de CollisionObject2D. É decir, do tipo Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D, etc." + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"A shape must be provided for CollisionShape2D to function. Please create a " +"shape resource for it!" +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"Polygon-based shapes are not meant be used nor edited directly through the " +"CollisionShape2D node. Please use the CollisionPolygon2D node instead." +msgstr "" +"As formas fÃsicas baseadas en polÃgonos non están pensadas para editarse " +"directamente mediante o nodo CollisionShape2D. Por favor, usa o nodo " +"CollisionPolygon2D no seu lugar." + +#: scene/2d/cpu_particles_2d.cpp +msgid "" +"CPUParticles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be PhysicsBody2Ds" +msgstr "Os nodo A e B teñen que ser do tipo PhysicsBody2D" + +#: scene/2d/joints_2d.cpp +msgid "Node A must be a PhysicsBody2D" +msgstr "O nodo A ten que ser un nodo PhysicsBody2D" + +#: scene/2d/joints_2d.cpp +msgid "Node B must be a PhysicsBody2D" +msgstr "O nodo B ten que ser un nodo PhysicsBody2D" + +#: scene/2d/joints_2d.cpp +msgid "Joint is not connected to two PhysicsBody2Ds" +msgstr "A articulación non está conectada a dous nodos PhysicsBody2D" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be different PhysicsBody2Ds" +msgstr "Os nodos A e B teñen que ser nodos PhysicsBody2D distintos" + +#: scene/2d/light_2d.cpp +msgid "" +"A texture with the shape of the light must be supplied to the \"Texture\" " +"property." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "" +"An occluder polygon must be set (or drawn) for this occluder to take effect." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"A NavigationPolygon resource must be set or created for this node to work. " +"Please set a property or draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"NavigationPolygonInstance must be a child or grandchild to a Navigation2D " +"node. It only provides navigation data." +msgstr "" + +#: scene/2d/parallax_layer.cpp +msgid "" +"ParallaxLayer node only works when set as child of a ParallaxBackground node." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles2D node instead. You can use the \"Convert to " +"CPUParticles\" option for this purpose." +msgstr "" +"As partÃculas baseadas na GPU non están soportas por o controlador de vÃdeo " +"de GLES2.\n" +"Usa o nodo CPUParticles2D no seu lugar. Podes usar a opción \"Converter a " +"CPUParticles\" con tal motivo." + +#: scene/2d/particles_2d.cpp scene/3d/particles.cpp +msgid "" +"A material to process the particles is not assigned, so no behavior is " +"imprinted." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"Particles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/path_2d.cpp +msgid "PathFollow2D only works when set as a child of a Path2D node." +msgstr "" + +#: scene/2d/physics_body_2d.cpp +msgid "" +"Size changes to RigidBody2D (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" +"Os cambios ao tamaño do RigidBody2D (en modo rÃxido ou modo personaxe) serán " +"sobreescritos por o motor fÃsico cando a aplicación estea executándose.\n" +"Cambia o tamaño dos nodos fillos (CollisionShape2D e CollisionPolygon2D) no " +"seu lugar." + +#: scene/2d/remote_transform_2d.cpp +msgid "Path property must point to a valid Node2D node to work." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "This Bone2D chain should end at a Skeleton2D node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "" +"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." +msgstr "" + +#: scene/2d/tile_map.cpp +msgid "" +"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes " +"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " +"KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/visibility_notifier_2d.cpp +msgid "" +"VisibilityEnabler2D works best when used with the edited scene root directly " +"as parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRCamera must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRController must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The controller ID must not be 0 or this controller won't be bound to an " +"actual controller." +msgstr "" +"O ID do controlador non pode ser 0, ou o controlador non estará asociado a " +"ningún controlador real." + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRAnchor must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The anchor ID must not be 0 or this anchor won't be bound to an actual " +"anchor." +msgstr "" +"O ID da áncora non pode ser 0, ou esta áncora non estará asociada a ningunha " +"áncora real." + +#: scene/3d/arvr_nodes.cpp +msgid "ARVROrigin requires an ARVRCamera child node." +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Finding meshes and lights" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing geometry (%d/%d)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing environment" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Generating capture" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Done" +msgstr "Feito" + +#: scene/3d/collision_object.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape or CollisionPolygon as a child to define " +"its shape." +msgstr "" +"Este nodo non ten unha forma fÃsica definida, polo que non pode colisionar " +"ou interactuar con outros obxectos.\n" +"Engade un nodo CollisionShape ou CollisionPolygon como fillo para definir a " +"sua forma." + +#: scene/3d/collision_polygon.cpp +msgid "" +"CollisionPolygon only serves to provide a collision shape to a " +"CollisionObject derived node. Please only use it as a child of Area, " +"StaticBody, RigidBody, KinematicBody, etc. to give them a shape." +msgstr "" +"O nodo CollisionPolygon só serve para darlle unha forma fÃsica a nodos " +"derivados de CollisionObject. É decir, do tipo Area, StaticBody, RigidBody, " +"KinematicBody, etc." + +#: scene/3d/collision_polygon.cpp +msgid "An empty CollisionPolygon has no effect on collision." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"CollisionShape only serves to provide a collision shape to a CollisionObject " +"derived node. Please only use it as a child of Area, StaticBody, RigidBody, " +"KinematicBody, etc. to give them a shape." +msgstr "" +"O nodo CollisionShape só serve para darlle unha forma fÃsica a nodos " +"derivados de CollisionObject. É decir, do tipo Area, StaticBody, RigidBody, " +"KinematicBody, etc." + +#: scene/3d/collision_shape.cpp +msgid "" +"A shape must be provided for CollisionShape to function. Please create a " +"shape resource for it." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"Plane shapes don't work well and will be removed in future versions. Please " +"don't use them." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"ConcavePolygonShape doesn't support RigidBody in another mode than static." +msgstr "" +"A forma fÃsica ConcavePolygonShape non está soportada en nodos RigidBody en " +"ningún outro modo que non sexa o estático." + +#: scene/3d/cpu_particles.cpp +msgid "Nothing is visible because no mesh has been assigned." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "" +"CPUParticles animation requires the usage of a SpatialMaterial whose " +"Billboard Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Plotting Meshes" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "" +"GIProbes are not supported by the GLES2 video driver.\n" +"Use a BakedLightmap instead." +msgstr "" + +#: scene/3d/interpolated_camera.cpp +msgid "" +"InterpolatedCamera has been deprecated and will be removed in Godot 4.0." +msgstr "" + +#: scene/3d/light.cpp +msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "A NavigationMesh resource must be set or created for this node to work." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "" +"NavigationMeshInstance must be a child or grandchild to a Navigation node. " +"It only provides navigation data." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" +"\" option for this purpose." +msgstr "" +"As partÃculas baseadas na GPU non están soportas por o controlador de vÃdeo " +"de GLES2.\n" +"Usa o nodo CPUParticles no seu lugar. Podes usar a opción \"Converter a " +"CPUParticles\" con tal motivo." + +#: scene/3d/particles.cpp +msgid "" +"Nothing is visible because meshes have not been assigned to draw passes." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Particles animation requires the usage of a SpatialMaterial whose Billboard " +"Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/path.cpp +msgid "PathFollow only works when set as a child of a Path node." +msgstr "" + +#: scene/3d/path.cpp +msgid "" +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." +msgstr "" + +#: scene/3d/physics_body.cpp +msgid "" +"Size changes to RigidBody (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" +"Os cambios ao tamaño do RigidBody (en modo rÃxido ou modo personaxe) serán " +"sobreescritos por o motor fÃsico cando a aplicación estea executándose.\n" +"Cambia o tamaño dos nodos fillos (CollisionShape e CollisionPolygon) no seu " +"lugar." + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A must be a PhysicsBody" +msgstr "O nodo A ten que ser un nodo PhysicsBody" + +#: scene/3d/physics_joint.cpp +msgid "Node B must be a PhysicsBody" +msgstr "O nodo B ten que ser un nodo PhysicsBody" + +#: scene/3d/physics_joint.cpp +msgid "Joint is not connected to any PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be different PhysicsBodies" +msgstr "" + +#: scene/3d/remote_transform.cpp +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "This body will be ignored until you set a mesh." +msgstr "Este corpo será ignorado ata que se lle sea asignado unha malla." + +#: scene/3d/soft_body.cpp +msgid "" +"Size changes to SoftBody will be overridden by the physics engine when " +"running.\n" +"Change the size in children collision shapes instead." +msgstr "" +"Os cambios ao tamaño do SoftBody serán sobreescritos por o motor fÃsico " +"cando a aplicación estea executándose.\n" +"Cambia o tamaño dos nodos fillos (CollisionShape e CollisionPolygon) no seu " +"lugar." + +#: scene/3d/sprite_3d.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite3D to display frames." +msgstr "" + +#: scene/3d/vehicle_body.cpp +msgid "" +"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " +"it as a child of a VehicleBody." +msgstr "" +"O nodo VehicleWheel (Roda de VehÃculo) serve para proporcionar un sistema de " +"rodas a un nodo VehicleBody. Por favor; úsao como fillo dun nodo VehicleBody." + +#: scene/3d/world_environment.cpp +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " +"this environment's Background Mode to Canvas (for 2D scenes)." +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "On BlendTree node '%s', animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "Animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "In node '%s', invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Nothing connected to input '%s' of node '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "No root AnimationNode for the graph is set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path to an AnimationPlayer node containing animations is not set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "The AnimationPlayer root node is not a valid node." +msgstr "" + +#: scene/animation/animation_tree_player.cpp +msgid "This node has been deprecated. Use AnimationTree instead." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "" +"Color: #%s\n" +"LMB: Set color\n" +"RMB: Remove preset" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Pick a color from the editor window." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Sen Procesar (Raw)" + +#: scene/gui/color_picker.cpp +msgid "Switch between hexadecimal and code values." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Add current color as a preset." +msgstr "" + +#: scene/gui/container.cpp +msgid "" +"Container by itself serves no purpose unless a script configures its " +"children placement behavior.\n" +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" +"Un nodo contedor (Container) por sà mesmo non ten ningunha utilidade, salvo " +"que se lle engada algún Script que configure a colocación dos seus nodos " +"fillos.\n" +"Se non tes pensado engadir un Script, utilizada un nodo Control no seu lugar." + +#: scene/gui/control.cpp +msgid "" +"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to " +"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"." +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Alert!" +msgstr "Alerta!" + +#: scene/gui/dialogs.cpp +msgid "Please Confirm..." +msgstr "Por favor, confirma..." + +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + +#: scene/gui/graph_edit.cpp +msgid "Enable grid minimap." +msgstr "" + +#: scene/gui/popup.cpp +msgid "" +"Popups will hide by default unless you call popup() or any of the popup*() " +"functions. Making them visible for editing is fine, but they will hide upon " +"running." +msgstr "" +"As ventás emerxentes (Popups) están ocultas por defecto, a non ser que " +"chames a popup() ou calquera das funcións popup*(). Podes facelas visibles " +"para editalas, pero ocultarasen ao iniciar a execución." + +#: scene/gui/range.cpp +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." +msgstr "" + +#: scene/gui/scroll_container.cpp +msgid "" +"ScrollContainer is intended to work with a single child control.\n" +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " +"minimum size manually." +msgstr "" + +#: scene/gui/tree.cpp +msgid "(Other)" +msgstr "(Outros)" + +#: scene/main/scene_tree.cpp +msgid "" +"Default Environment as specified in Project Settings (Rendering -> " +"Environment -> Default Environment) could not be loaded." +msgstr "" + +#: scene/main/viewport.cpp +msgid "" +"This viewport is not set as render target. If you intend for it to display " +"its contents directly to the screen, make it a child of a Control so it can " +"obtain a size. Otherwise, make it a RenderTarget and assign its internal " +"texture to some node for display." +msgstr "" +"Esta Mini-Ventá (Viewport) no está configurada como obxectivo de " +"renderizado. Se quere que o seu contido se mostre directamente na pantalla, " +"convértao nun nodo fillo dun nodo Control para que poida recibir dimensións. " +"Ou ben, fágao un RenderTarget e asigne a súa textura a algún nodo." + +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" +"As dimensións da Mini-Ventá (Viewport) deben de ser maior que 0 para poder " +"renderizar nada." + +#: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for preview." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for shader." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid comparison function for that type." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to uniform." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Varyings can only be assigned in vertex function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Constants cannot be modified." +msgstr "" diff --git a/editor/translations/he.po b/editor/translations/he.po index 57746c75b0..7b3e8815ec 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -18,12 +18,13 @@ # yariv benj <yariv4400@gmail.com>, 2020. # Guy Dadon <guydadon14@gmail.com>, 2020. # bruvzg <bruvzg13@gmail.com>, 2020. +# Omer I.S. <omeritzicschwartz@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-03 19:28+0000\n" -"Last-Translator: Ziv D <wizdavid@gmail.com>\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" +"Last-Translator: Omer I.S. <omeritzicschwartz@gmail.com>\n" "Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/" "godot/he/>\n" "Language: he\n" @@ -32,7 +33,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -379,9 +380,8 @@ msgid "Anim Insert" msgstr "הוסף ×”× ×¤×©×”" #: editor/animation_track_editor.cpp -#, fuzzy msgid "AnimationPlayer can't animate itself, only other players." -msgstr "× ×’×Ÿ ×”× ×¤×©×•×ª ×œ× ×™×›×•×œ ×œ×”× ×¤×™×© ×ת עצמו, רק ×©×—×§× ×™× ×חרי×." +msgstr "× ×’×Ÿ ×”×”× ×¤×©×•×ª ×œ× ×™×›×•×œ ×œ×”× ×¤×™×© ×ת עצמו, רק ×©×—×§× ×™× ×חרי×." #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" @@ -662,7 +662,7 @@ msgstr "בחירת רצועות להעתקה" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "העתקה" @@ -900,9 +900,8 @@ msgid "Connect a Signal to a Method" msgstr "שגי×ת חיבור" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "שגי×ת חיבור" +msgstr "עריכת חיבור:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -1102,7 +1101,7 @@ msgstr "דפדפן מש××‘×™× ×™×ª×•×ž×™×" #: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp #: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp msgid "Delete" -msgstr "למחוק" +msgstr "מחיקה" #: editor/dependency_editor.cpp msgid "Owns" @@ -1194,9 +1193,8 @@ msgid "License" msgstr "רישיון" #: editor/editor_about.cpp -#, fuzzy msgid "Third-party Licenses" -msgstr "רישיון צד שלישי" +msgstr "×¨×©×™×•× ×•×ª צד שלישי" #: editor/editor_about.cpp msgid "" @@ -1657,9 +1655,8 @@ msgid "Script Editor" msgstr "פתיחת עורך סקריפטי×" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "×™×™×¦×•× ×¡×¤×¨×™×”" +msgstr "ספריית מש×בי×" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" @@ -1966,10 +1963,6 @@ msgstr "תצוגה מקדימה:" msgid "File:" msgstr "קובץ:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "יש להשתמש בסיומת ×ª×§× ×™×ª." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "סריקת מקורות" @@ -2392,6 +2385,10 @@ msgid "There is no defined scene to run." msgstr "×ין ×¡×¦× ×” מוגדרת להרצה." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "×œ× × ×™×ª×Ÿ להפעיל תהליך ×ž×©× ×”!" @@ -2435,18 +2432,6 @@ msgstr "דרוש מפרק שורש כדי לשמור ×ת ×”×¡×¦×™× ×”." msgid "Save Scene As..." msgstr "שמירת ×¡×¦× ×” בש×…" -#: editor/editor_node.cpp -msgid "No" -msgstr "ל×" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "כן" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "×¡×¦× ×” ×–×ת ×ž×¢×•×œ× ×œ× × ×©×ž×¨×”. לשמור ×œ×¤× ×™ ההרצה?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "×œ× × ×™×ª×Ÿ לבצע פעולה זו ×œ×œ× ×¡×¦× ×”." @@ -2496,6 +2481,10 @@ msgid "Quit" msgstr "יצי××”" #: editor/editor_node.cpp +msgid "Yes" +msgstr "כן" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "לצ×ת מהעורך?" @@ -2540,7 +2529,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "×œ× × ×™×ª×Ÿ לפתוח ×ת תוסף ההרחבות ×‘× ×ª×™×‘: '%s' ×¤×¢× ×•×— ההגדרות × ×›×©×œ." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "×œ× × ×™×ª×Ÿ ×œ×ž×¦×•× ×©×“×” סקריפט עבור תוסף הרחבה ×‘× ×ª×™×‘ 'res://addons/%s'." #: editor/editor_node.cpp @@ -2960,14 +2950,6 @@ msgid "Help" msgstr "עזרה" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "חיפוש" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "×ž×¡×ž×›×™× ×ž×§×•×•× ×™×" @@ -3128,6 +3110,24 @@ msgid "Open & Run a Script" msgstr "פתיחה והרצה של סקריפט" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n" +"ב×ילו פעולות ×œ× ×§×•×˜?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "×¨×¢× ×•×Ÿ" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "שמירה מחדש" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "חדש בירושה" @@ -3336,7 +3336,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "הדבקה" @@ -5038,7 +5038,8 @@ msgid "Got:" msgstr "התקבל:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "בדיקת ×”×ש sha256 × ×›×©×œ×”" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5171,10 +5172,10 @@ msgid "Assets ZIP File" msgstr "קובץ ZIP של × ×›×¡×™×" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "×ין ×פשרות לקבוע × ×ª×™×‘ שמירה עבור ×ª×ž×•× ×•×ª lightmap.\n" "שמור/×™ ×ת ×”×¡×¦×™× ×” שלך (כדי ×©×ª×ž×•× ×•×ª יישמרו ב×ותה תיקייה), ×ו בחר/×™ × ×ª×™×‘ שמירה " @@ -5191,9 +5192,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "יצירת ×ª×ž×•× ×•×ª lightmap × ×›×©×œ×”, וד×/×™ ×©×”× ×ª×™×‘ × ×™×ª×Ÿ לכתיבה." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "×פיית Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "בחירת קובץ ×ª×‘× ×™×ª" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -5486,9 +5507,8 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Reset" -msgstr "להתרחק" +msgstr "×יפוס התקריב" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6306,6 +6326,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "המרה ל×ותיות גדולות" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6366,10 +6391,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6974,6 +6995,14 @@ msgstr "סגירת מסמכי×" msgid "Run" msgstr "הרצה" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "חיפוש" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "לצעוד לתוך" @@ -7029,16 +7058,6 @@ msgstr "" "×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n" "ב×ילו פעולות ×œ× ×§×•×˜?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "×¨×¢× ×•×Ÿ" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "שמירה מחדש" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "× ×™×¤×•×™ שגי×ות" @@ -7137,8 +7156,8 @@ msgstr "מחיקת × ×§×•×“×•×ª" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "גזירה" @@ -7265,13 +7284,12 @@ msgid "Go to Previous Breakpoint" msgstr "מעבר ×œ× ×§×•×“×ª העצירה הקודמת" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" "×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n" -"ב×ילו פעולות ×œ× ×§×•×˜?:" +"ב×ילו פעולות ×œ× ×§×•×˜?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -7379,6 +7397,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10040,6 +10062,13 @@ msgid "Projects" msgstr "מיז×" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "" +"×”×§×‘×¦×™× × ×¡×¨×§×™×,\n" +"× × ×œ×”×ž×ª×™×Ÿâ€¦" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10669,6 +10698,16 @@ msgid "Instance Child Scene" msgstr "יצירת מופע ×œ×¡×¦× ×” הצ×צ×ית" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "×œ× ×™×›×•×œ לפעול על ×ž×¤×¨×§×™× ×ž×¡×¦× ×” זרה!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "הדבקת מפרקי×" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "× ×™×ª×•×§ סקריפט" @@ -10792,6 +10831,11 @@ msgid "Attach Script" msgstr "חיבור סקריפט" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "גזירת מפרקי×" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "הסרת מפרק(×™×)" @@ -11592,6 +11636,38 @@ msgstr "×¡×™× ×•×Ÿ רשתות" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "יש לחבר מש×ב MeshLibrary ל- GridMap ×”×–×” כדי להשתמש ברשתות שלו." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "×›×™×•×•× ×™×" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "×”×–×—×” מימין" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "גרסה × ×•×›×—×™×ª:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "מדפיס ת×ורות:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "×©× ×ž×—×œ×§×” ×œ× ×™×›×•×œ להיות מילת מפתח שמורה" @@ -12095,12 +12171,14 @@ msgid "Select device from the list" msgstr "× × ×œ×‘×—×•×¨ התקן מהרשימה" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "קובץ ההפעלה של ADB ×œ× × ×§×‘×¢ בהגדרות העורך." +msgid "Unable to find the 'apksigner' tool." +msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner ×œ× × ×§×‘×¢ בהגדרות העורך." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "×ª×‘× ×™×ª ×‘× ×™×™×” ל×× ×“×¨×•×יד ×œ× ×ž×•×ª×§× ×ª בפרוייקט. ×”×”×ª×§× ×” ×”×™× ×ž×ª×¤×¨×™×˜ המיז×." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12111,12 +12189,14 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "מפתח גירסת שיחרור × ×§×‘×¢ ב×ופן שגוי בהגדרות הייצו×." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"×‘× ×™×™×” מות×מת ×ישית דורשת × ×ª×™×‘ חוקי של ערכת פיתוח ל×× ×“×¨×•×יד בהגדרות העורך." +"× ×ª×™×‘ ×œ× ×—×•×§×™ לערכת פיתוח ×× ×“×¨×•×יד עבור ×‘× ×™×™×” מות×מת ×ישית בהגדרות העורך." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "" "× ×ª×™×‘ ×œ× ×—×•×§×™ לערכת פיתוח ×× ×“×¨×•×יד עבור ×‘× ×™×™×” מות×מת ×ישית בהגדרות העורך." @@ -12125,10 +12205,22 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." -msgstr "×ª×‘× ×™×ª ×‘× ×™×™×” ל×× ×“×¨×•×יד ×œ× ×ž×•×ª×§× ×ª בפרוייקט. ×”×”×ª×§× ×” ×”×™× ×ž×ª×¤×¨×™×˜ המיז×." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"× ×ª×™×‘ ×œ× ×—×•×§×™ לערכת פיתוח ×× ×“×¨×•×יד עבור ×‘× ×™×™×” מות×מת ×ישית בהגדרות העורך." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12569,28 +12661,32 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin דורש צ××¦× ×ž×¡×•×’ ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(זמן ×©× ×•×ª×¨: %d:%02d ×©× ×³)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "× ×™×ª×•×— ×’×™×ומטרי..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "מדפיס רשתות: " +#, fuzzy +msgid "Preparing environment" +msgstr "צפייה בסביבה" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "מדפיס ת×ורות:" +#, fuzzy +msgid "Generating capture" +msgstr "× ×•×¦×¨×•×ª מפות ת×ורה" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "×ž×¡×™×™× ×”×“×¤×¡×”" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "× ×•×¦×¨×•×ª מפות ת×ורה" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "רשתות ת×ורה: " +msgid "Done" +msgstr "בוצע" #: scene/3d/collision_object.cpp msgid "" @@ -12660,6 +12756,10 @@ msgid "Plotting Meshes" msgstr "הדפסת רשתות" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "×ž×¡×™×™× ×”×“×¤×¡×”" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12906,6 +13006,10 @@ msgstr "×זהרה!" msgid "Please Confirm..." msgstr "× × ×œ×שר…" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "יש להשתמש בסיומת ×ª×§× ×™×ª." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -12962,6 +13066,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "גודל חלון התצוגה חייב להיות גדול מ-0 על ×ž× ×ª להציג משהו." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "מקור ×œ× ×ª×§×™×Ÿ לתצוגה מקדימה." @@ -12989,6 +13099,34 @@ msgstr "× ×™×ª×Ÿ להקצות ×©×™× ×•×™×™× ×¨×§ ×‘×¤×•× ×§×¦×™×ª vertex." msgid "Constants cannot be modified." msgstr "××™ ×פשר ×œ×©× ×•×ª קבועי×." +#~ msgid "No" +#~ msgstr "ל×" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "×¡×¦× ×” ×–×ת ×ž×¢×•×œ× ×œ× × ×©×ž×¨×”. לשמור ×œ×¤× ×™ ההרצה?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "קובץ ההפעלה של ADB ×œ× × ×§×‘×¢ בהגדרות העורך." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner ×œ× × ×§×‘×¢ בהגדרות העורך." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "×‘× ×™×™×” מות×מת ×ישית דורשת × ×ª×™×‘ חוקי של ערכת פיתוח ל×× ×“×¨×•×יד בהגדרות העורך." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(זמן ×©× ×•×ª×¨: %d:%02d ×©× ×³)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "מדפיס רשתות: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "רשתות ת×ורה: " + #, fuzzy #~ msgid "Search complete" #~ msgstr "חיפוש טקסט" @@ -13174,9 +13312,6 @@ msgstr "××™ ×פשר ×œ×©× ×•×ª קבועי×." #~ msgid "Failed to save solution." #~ msgstr "שמירת הפתרון × ×›×©×œ×”." -#~ msgid "Done" -#~ msgstr "בוצע" - #~ msgid "Failed to create C# project." #~ msgstr "יצירת ×ž×™×–× C#‎ × ×›×©×œ×”." diff --git a/editor/translations/hi.po b/editor/translations/hi.po index 7c3f2834ad..a4d46d6147 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -9,7 +9,7 @@ # Abhay Patel <abhay111patel@gmail.com>, 2019. # Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019. # Devashishsingh98 <devashishsingh98@gmail.com>, 2019. -# Shirious <sad3119823@gmail.com>, 2020. +# Shirious <sad3119823@gmail.com>, 2020, 2021. # Abhay Patel <Traumaticbean@protonmail.com>, 2020. # Bishwajeet Parhi <bishwajeet.techmaster@gmail.com>, 2020. # l4KKY <greenforcesave@gmail.com>, 2020. @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-19 04:29+0000\n" -"Last-Translator: l4KKY <greenforcesave@gmail.com>\n" +"PO-Revision-Date: 2021-01-06 18:29+0000\n" +"Last-Translator: Shirious <sad3119823@gmail.com>\n" "Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/" "hi/>\n" "Language: hi\n" @@ -26,7 +26,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.4.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -649,7 +649,7 @@ msgstr "कॉपी करने के लिठटà¥à¤°à¥ˆà¤• का चय #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "कॉपी" @@ -1477,7 +1477,7 @@ msgstr "औटोलोड पà¥à¤¨à¤°à¥à¤µà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करेà #: editor/editor_autoload_settings.cpp msgid "Can't add autoload:" -msgstr "" +msgstr "औटोलोड नहीं डाल सकते:" #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" @@ -1944,10 +1944,6 @@ msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:" msgid "File:" msgstr "फ़ाइल:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "मानà¥à¤¯ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤¨à¤¶à¤¨ इसà¥à¤¤à¥‡à¤®à¤¾à¤² कीजिये." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "सà¥à¤°à¥‹à¤¤à¤¸à¥à¤•ैन कीजिये" @@ -2303,6 +2299,8 @@ msgid "" "An error occurred while trying to save the editor layout.\n" "Make sure the editor's user data path is writable." msgstr "" +"लेआउट सेव करते वक़à¥à¤¤ à¤à¤°à¤° आ रहा है|\n" +"à¤à¤¡à¥€à¤Ÿà¤° का पाथ writeable है ये सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ किजिये|" #: editor/editor_node.cpp msgid "" @@ -2310,6 +2308,8 @@ msgid "" "To restore the Default layout to its base settings, use the Delete Layout " "option and delete the Default layout." msgstr "" +"मूल à¤à¤¡à¥€à¤Ÿà¤° लेआउट ओवराईड हो चà¥à¤•ा है.\n" +"मूल लेआउट को पà¥à¤¨: सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करने के लिये, डिलिट लेआउट परà¥à¤¯à¤¾à¤¯ का पà¥à¤°à¤¯à¥‹à¤— करे." #: editor/editor_node.cpp msgid "Layout name not found!" @@ -2373,6 +2373,10 @@ msgid "There is no defined scene to run." msgstr "चलाने के लिठकोई परिà¤à¤¾à¤·à¤¿à¤¤ दृशà¥à¤¯ नहीं है ।" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "उपपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ शà¥à¤°à¥‚ नहीं कर सका!" @@ -2416,18 +2420,6 @@ msgstr "दृशà¥à¤¯ को बचाने के लिठà¤à¤• रूट msgid "Save Scene As..." msgstr "दृशà¥à¤¯ के रूप में सहेजें ..." -#: editor/editor_node.cpp -msgid "No" -msgstr "नहीं" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "हाà¤" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "इस सीन को कà¤à¥€ नहीं बचाया गया। दौड़ने से पहले सहेजें?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "यह ऑपरेशन बिना किसी दृशà¥à¤¯ के नहीं किया जा सकता है।" @@ -2466,6 +2458,8 @@ msgid "" "The current scene has unsaved changes.\n" "Reload the saved scene anyway? This action cannot be undone." msgstr "" +"वरà¥à¤¤à¤®à¤¾à¤¨ सीन मे कà¥à¤› अनसेवà¥à¤¡ बदलाव है|\n" +"फिर à¤à¥€ सीन रेलोड करे? यह कà¥à¤°à¤¿à¤¯à¤¾ पूरà¥à¤µà¤µà¤¤ नहीं की जा सकती|" #: editor/editor_node.cpp msgid "Quick Run Scene..." @@ -2476,6 +2470,10 @@ msgid "Quit" msgstr "छोड़ना" #: editor/editor_node.cpp +msgid "Yes" +msgstr "हाà¤" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "संपादक से बाहर निकलें?" @@ -2520,7 +2518,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन को सकà¥à¤·à¤® करने में असमरà¥à¤¥: '%' कॉनà¥à¤«à¤¿à¤— का पारà¥à¤¸à¤¿à¤‚ग विफल रहा।" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन के लिठसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ फ़ीलà¥à¤¡ खोजने में असमरà¥à¤¥: 'res://addons/% s'।" #: editor/editor_node.cpp @@ -2810,6 +2809,10 @@ msgid "" "mobile device).\n" "You don't need to enable it to use the GDScript debugger locally." msgstr "" +"जब यह परà¥à¤¯à¤¾à¤¯ सकà¥à¤°à¤¿à¤¯ होता है, तब यह one-click deploy à¤à¤•à¥à¤¸à¤¯à¥à¤Ÿà¥‡à¤¬à¤² को इस कोमà¥à¤ªà¥à¤Ÿà¤° के IP " +"को जोडने कि कोशिश करेगा ताकि चालॠपà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डिबग हो सके|\n" +"यह परà¥à¤¯à¤¾à¤¯ रिमोट डिबगींग (कोई और मशीन, आम तौर पर मोबाईल) के लिये उदà¥à¤¦à¥‡à¤¶à¤¿à¤¤ है|\n" +"इसे GDScript इसि मशीन पर डिबग करने के लिये इसे सकà¥à¤°à¤¿à¤¯ करने कि जरà¥à¤°à¤¤ नही|" #: editor/editor_node.cpp #, fuzzy @@ -2944,14 +2947,6 @@ msgid "Help" msgstr "मदद" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "ढूंढें" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "ऑनलाइन डॉकà¥à¤¸" @@ -3115,6 +3110,23 @@ msgid "Open & Run a Script" msgstr "ओपन à¤à¤‚ड रन à¤à¤• सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "निमà¥à¤¨ फ़ाइलों का निसà¥à¤¸à¤¾à¤°à¤£ नहीं हो पाया:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "नई विरासत में मिली" @@ -3322,7 +3334,7 @@ msgstr "अदà¥à¤µà¤¿à¤¤à¥€à¤¯ बनाओ" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "चिपकाà¤à¤" @@ -3395,7 +3407,7 @@ msgstr "कà¥à¤¯à¤¾ आप '_run' विधि को à¤à¥‚ल गà¤?" #: editor/editor_spin_slider.cpp msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." -msgstr "" +msgstr "पूरà¥à¤£à¤¾à¤‚क के लिठCtrl दबाठरखें. सटीक अंक के लिये Shift दबाठरखें." #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -3678,6 +3690,11 @@ msgid "" "\n" "Do you wish to overwrite them?" msgstr "" +"निमà¥à¤¨à¤²à¤¿à¤–ित फ़ाइले या फ़ोलà¥à¤¡à¤° दिये हà¥à¤ जगह '%s' के समान है:\n" +"\n" +"%s\n" +"\n" +"कà¥à¤¯à¤¾ आप उस पर लिखना चाहते है ?" #: editor/filesystem_dock.cpp msgid "Renaming file:" @@ -3709,7 +3726,7 @@ msgstr "खà¥à¤²à¥‡ दृशà¥à¤¯" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "इनसà¥à¤Ÿà¤¨à¥à¤¸" #: editor/filesystem_dock.cpp msgid "Add to Favorites" @@ -3725,11 +3742,11 @@ msgstr "निरà¥à¤à¤°à¤¿à¤¤ फ़ाइलें संपादित क #: editor/filesystem_dock.cpp msgid "View Owners..." -msgstr "" +msgstr "ओनरà¥à¤¸ देखे..." #: editor/filesystem_dock.cpp msgid "Move To..." -msgstr "" +msgstr "मे ले जाà¤à¤..." #: editor/filesystem_dock.cpp msgid "New Scene..." @@ -3737,7 +3754,7 @@ msgstr "नया दृशà¥à¤¯..." #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "New Script..." -msgstr "" +msgstr "नई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ..." #: editor/filesystem_dock.cpp msgid "New Resource..." @@ -3746,12 +3763,12 @@ msgstr "नया संसाधन..." #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp msgid "Expand All" -msgstr "" +msgstr "सà¤à¥€ बढाय" #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp msgid "Collapse All" -msgstr "" +msgstr "सà¤à¥€ ढहाय" #: editor/filesystem_dock.cpp msgid "Duplicate..." @@ -3764,23 +3781,23 @@ msgstr "औटोलोड हिलाइये" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." -msgstr "" +msgstr "नाम बदली..." #: editor/filesystem_dock.cpp msgid "Previous Folder/File" -msgstr "" +msgstr "पिछला फ़ोलà¥à¤¡à¤°/फ़ाइल" #: editor/filesystem_dock.cpp msgid "Next Folder/File" -msgstr "" +msgstr "अâ€à¤—ला फ़ोलà¥à¤¡à¤°/फ़ाइल" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "" +msgstr "फाइलसिसà¥à¤Ÿà¥‡à¤® पà¥à¤¨:सà¥à¤•ैन करे" #: editor/filesystem_dock.cpp msgid "Toggle Split Mode" -msgstr "" +msgstr "सà¥à¤ªà¥à¤²à¤¿à¤Ÿ मोड टॉगल कीजिये" #: editor/filesystem_dock.cpp msgid "Search files" @@ -3791,76 +3808,79 @@ msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" +"फ़ाइले सà¥à¤•ैन कर रहा है,\n" +"कृपया रà¥à¤•िये..." #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "हिलाइये" #: editor/filesystem_dock.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/project_manager.cpp editor/rename_dialog.cpp #: editor/scene_tree_dock.cpp msgid "Rename" -msgstr "" +msgstr "नाम बदली" #: editor/filesystem_dock.cpp msgid "Overwrite" -msgstr "" +msgstr "मौजूदा के ऊपर लिखे" #: editor/filesystem_dock.cpp msgid "Create Scene" -msgstr "दृशà¥à¤¯ बनाà¤à¤‚" +msgstr "सीन बनाà¤à¤‚" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "" +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ बनाइये" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp msgid "Find in Files" -msgstr "" +msgstr "फ़ाइलों मे तलाशिये" #: editor/find_in_files.cpp msgid "Find:" -msgstr "" +msgstr "तलाशिये:" #: editor/find_in_files.cpp msgid "Folder:" -msgstr "" +msgstr "फ़ोलà¥à¤¡à¤°:" #: editor/find_in_files.cpp msgid "Filters:" -msgstr "" +msgstr "फिलà¥à¤Ÿà¤°:" #: editor/find_in_files.cpp msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"निमà¥à¤¨à¤²à¤¿à¤–ित à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन कि फ़ाइले शामिल कि गई है. इनà¥à¤¹à¥‡ पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸ मे डालिये या निकालिये." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find..." -msgstr "" +msgstr "तलाशिये..." #: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp msgid "Replace..." -msgstr "" +msgstr "बदली करे..." #: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" -msgstr "" +msgstr "रदà¥à¤¦ करें" #: editor/find_in_files.cpp msgid "Find: " -msgstr "" +msgstr "तलाशिये: " #: editor/find_in_files.cpp msgid "Replace: " -msgstr "" +msgstr "बदली करे: " #: editor/find_in_files.cpp msgid "Replace all (no undo)" -msgstr "" +msgstr "सà¤à¥€ बदली करे (इसे अंडू नहीं किया जा सकता है)" #: editor/find_in_files.cpp msgid "Searching..." @@ -3883,15 +3903,15 @@ msgstr "%d मिल गया।" #: editor/groups_editor.cpp msgid "Add to Group" -msgstr "" +msgstr "गà¥à¤°à¥à¤ª मे à¤à¤¡ करे" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "" +msgstr "गà¥à¤°à¥à¤ª मे से निकालिये" #: editor/groups_editor.cpp msgid "Group name already exists." -msgstr "" +msgstr "गà¥à¤°à¥à¤ª इस नाम से पहले से मौजूद." #: editor/groups_editor.cpp msgid "Invalid group name." @@ -3907,24 +3927,24 @@ msgstr "गà¥à¤°à¥à¤ª डिलीट करें" #: editor/groups_editor.cpp editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "अनेक गà¥à¤°à¥à¤ª" #: editor/groups_editor.cpp msgid "Nodes Not in Group" -msgstr "" +msgstr "नोड गà¥à¤°à¥à¤ª मे नहीं" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp #: editor/scene_tree_editor.cpp msgid "Filter nodes" -msgstr "" +msgstr "नोड फिलà¥à¤Ÿà¤° किजिये" #: editor/groups_editor.cpp msgid "Nodes in Group" -msgstr "" +msgstr "गà¥à¤°à¥à¤ª मे से नोड" #: editor/groups_editor.cpp msgid "Empty groups will be automatically removed." -msgstr "" +msgstr "खाली गà¥à¤°à¥à¤ª अपनेआप निकाले जायेंगे." #: editor/groups_editor.cpp msgid "Group Editor" @@ -3932,72 +3952,72 @@ msgstr "समूह संपादक" #: editor/groups_editor.cpp msgid "Manage Groups" -msgstr "" +msgstr "गà¥à¤°à¥à¤ª वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¨ कीजिये" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "" +msgstr "अकेले सीन कि तरह इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "" +msgstr "अलग अलग अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "" +msgstr "अलग अलग मटेरियल के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "" +msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "" +msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ+मटेरियल के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "" +msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ+अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "" +msgstr "अलग अलग मटेरियल+अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "" +msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ+मटेरियल+अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "" +msgstr "अनेक सीन के रà¥à¤ª इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "अनेक सीन+मटेरियल के रà¥à¤ª इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "सीन इंपोरà¥à¤Ÿ किजिये" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "" +msgstr "सीन इंपोरà¥à¤Ÿ कर रहा है..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" -msgstr "" +msgstr "लाईटमॅप बना रहा है" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "मेश के लिये बना रहा है: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." -msgstr "" +msgstr "कसà¥à¤Ÿà¤® सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ चला रहा है..." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "इंपोरà¥à¤Ÿ-पशà¥à¤šà¤¾à¤¤ कि सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं लोड कर पाय:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" @@ -4962,7 +4982,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5097,8 +5117,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5112,9 +5131,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ फ़ाइल का चयन करें" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6175,6 +6214,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6235,10 +6279,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6833,6 +6873,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "ढूंढें" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6884,16 +6932,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6990,8 +7028,8 @@ msgstr "à¤à¤• नया बनाà¤à¤‚" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7214,6 +7252,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "आकार: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9804,6 +9847,11 @@ msgid "Projects" msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "दरà¥à¤ªà¤£ को पà¥à¤¨à¤ƒ पà¥à¤°à¤¾à¤ªà¥à¤¤ करना, कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें ..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10411,6 +10459,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "नई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ" @@ -10537,6 +10594,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11342,6 +11404,36 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "निरà¥à¤¦à¥‡à¤¶à¥‹à¤‚" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "लाईटमॅप बना रहा है" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11851,11 +11943,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11867,11 +11961,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11879,9 +11973,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12279,27 +12383,29 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "लाईटमॅप बना रहा है" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "लाईटमॅप बना रहा है" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12359,6 +12465,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12574,6 +12684,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "मानà¥à¤¯ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤¨à¤¶à¤¨ इसà¥à¤¤à¥‡à¤®à¤¾à¤² कीजिये." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12619,6 +12733,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "गलत फॉणà¥à¤Ÿ का आकार |" @@ -12649,6 +12769,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "नहीं" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "इस सीन को कà¤à¥€ नहीं बचाया गया। दौड़ने से पहले सहेजें?" + #~ msgid "Error trying to save layout!" #~ msgstr "लेआउट को बचाने की कोशिश कर रहा तà¥à¤°à¥à¤Ÿà¤¿!" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index d429c51904..4803018028 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -631,7 +631,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopiraj" @@ -1904,10 +1904,6 @@ msgstr "Pregled:" msgid "File:" msgstr "Datoteka:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Nastavak mora biti ispravan." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2311,6 +2307,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2354,18 +2354,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2413,6 +2401,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2455,7 +2447,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2845,14 +2837,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3006,6 +2990,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3208,7 +3208,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4840,7 +4840,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4975,8 +4975,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4990,9 +4989,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6048,6 +6066,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6108,10 +6130,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6693,6 +6711,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6744,16 +6770,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6846,8 +6862,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7068,6 +7084,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9601,6 +9621,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10204,6 +10228,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Brisati odabrani kljuÄ/odabrane kljuÄeve" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Odspoji Skriptu" @@ -10324,6 +10357,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11110,6 +11147,35 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Direkcije" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11611,11 +11677,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11627,11 +11695,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11639,9 +11707,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12032,27 +12110,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12112,6 +12190,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12325,6 +12407,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Nastavak mora biti ispravan." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12370,6 +12456,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index fe5b5741ef..db3403fdf1 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -14,12 +14,13 @@ # cefrebevalo <szmarci711@gmail.com>, 2020. # thekeymethod <csokan.andras87@protonmail.ch>, 2020. # Czmorek Dávid <czmdav.soft@gmail.com>, 2020. +# Újvári Marcell <mmarci72@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-07 08:11+0000\n" -"Last-Translator: Czmorek Dávid <czmdav.soft@gmail.com>\n" +"PO-Revision-Date: 2021-01-22 10:21+0000\n" +"Last-Translator: Újvári Marcell <mmarci72@gmail.com>\n" "Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/" "godot/hu/>\n" "Language: hu\n" @@ -27,7 +28,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -662,7 +663,7 @@ msgstr "Másolandó nyomvonalak kiválasztása" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Másolás" @@ -738,10 +739,9 @@ msgstr "Csak a kijelölés" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Alapértelmezett" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Toggle Scripts Panel" msgstr "Szkript panel váltása" @@ -1948,10 +1948,6 @@ msgstr "ElÅ‘nézet:" msgid "File:" msgstr "Fájl:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Használjon érvényes kiterjesztést." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Források Vizsgálata" @@ -2385,6 +2381,10 @@ msgid "There is no defined scene to run." msgstr "Nincs meghatározva Scene a futtatáshoz." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Az alprocesszt nem lehetett elindÃtani!" @@ -2428,18 +2428,6 @@ msgstr "" msgid "Save Scene As..." msgstr "Scene mentés másként..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nem" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Igen" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Ez a Scene még soha nem volt mentve. Menti futtatás elÅ‘tt?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ezt a műveletet nem lehet végrehajtani egy Scene nélkül." @@ -2489,6 +2477,10 @@ msgid "Quit" msgstr "Kilépés" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Igen" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Kilép a szerkesztÅ‘bÅ‘l?" @@ -2538,7 +2530,8 @@ msgstr "" "megbukott." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Nem található szkript mezÅ‘ az addon pluginnak a következÅ‘ helyen: 'res://" "addons/%s'." @@ -2978,14 +2971,6 @@ msgid "Help" msgstr "Súgó" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Keresés" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online Dokumentáció" @@ -3141,6 +3126,25 @@ msgid "Open & Run a Script" msgstr "Szkriptet Megnyit és Futtat" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"A alábbi fájlok újabbak a lemezen.\n" +"Mit szeretne lépni?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Újratöltés" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Újramentés" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Új Örökölt" @@ -3343,7 +3347,7 @@ msgstr "Egyedivé tétel" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Beillesztés" @@ -5001,7 +5005,8 @@ msgid "Got:" msgstr "Kapott:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "sha256 hash ellenÅ‘rzés megbukott" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5134,10 +5139,10 @@ msgid "Assets ZIP File" msgstr "Eszköz ZIP Fájl" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Nem lehet megállapÃtani mentési útvonalat a fénytérképeknek.\n" "Mentse el a jelenetét (hogy aztán a képek ugyanabba a mappába legyenek " @@ -5160,9 +5165,29 @@ msgstr "" "Ãrható." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Fény Besütése" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Válasszon sablonfájlt" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6240,6 +6265,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Csak egy ParticlesMaterial feldolgozó anyagba állÃthat pontot" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Konvertálás CPU-részecskékké" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Generálási IdÅ‘ (mp):" @@ -6300,10 +6330,6 @@ msgstr "AABB Generálása" msgid "Generate Visibility AABB" msgstr "Láthatósági AABB Generálása" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "AABB Generálása" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Pont EltávolÃtása GörbérÅ‘l" @@ -6891,6 +6917,14 @@ msgstr "Dokumentációs Lapok Bezárása" msgid "Run" msgstr "Futtatás" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Keresés" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Belépés" @@ -6944,16 +6978,6 @@ msgstr "" "A alábbi fájlok újabbak a lemezen.\n" "Mit szeretne lépni?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Újratöltés" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Újramentés" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "HibakeresÅ‘" @@ -7046,8 +7070,8 @@ msgstr "Töréspontok" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Kivágás" @@ -7234,7 +7258,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Z-Axis Transform." -msgstr "" +msgstr "Z-Tengely transzformáció" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Plane Transform." @@ -7269,6 +7293,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Méret: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Rajzolt objektumok" @@ -9818,6 +9847,11 @@ msgid "Projects" msgstr "Projektek" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Tükrök letöltése, kérjük várjon..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10425,6 +10459,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Node-ok beillesztése" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Szkript leválasztása" @@ -10545,6 +10588,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Node-ok kivágása" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11334,6 +11382,39 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "AABB Generálása" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Irányok" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Behúzás Jobbra" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Kifejezés beállÃtása" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Fénytérképek Létrehozása" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11835,11 +11916,13 @@ msgid "Select device from the list" msgstr "Válasszon készüléket a listából" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11851,11 +11934,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11863,9 +11946,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12260,28 +12353,33 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Geometria Elemzése…" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "" +#, fuzzy +msgid "Preparing environment" +msgstr "Geometria Elemzése…" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Fénytérképek Létrehozása" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Fénytérképek Létrehozása" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "" +#, fuzzy +msgid "Done" +msgstr "Kész!" #: scene/3d/collision_object.cpp msgid "" @@ -12340,6 +12438,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12553,6 +12655,10 @@ msgstr "Figyelem!" msgid "Please Confirm..." msgstr "Kérjük erÅ‘sÃtse meg..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Használjon érvényes kiterjesztést." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -12603,6 +12709,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Érvénytelen forrás az elÅ‘nézethez." @@ -12631,6 +12743,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "Nem" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ez a Scene még soha nem volt mentve. Menti futtatás elÅ‘tt?" + #~ msgid "Search complete" #~ msgstr "A keresés kész" diff --git a/editor/translations/id.po b/editor/translations/id.po index 98a8f19b60..91e4392ab4 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -671,7 +671,7 @@ msgstr "Pilih Trek untuk Disalin" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopy" @@ -1969,10 +1969,6 @@ msgstr "Pratinjau:" msgid "File:" msgstr "File:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Harus menggunakan ekstensi yang sah." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Sumber Pemindaian" @@ -2405,6 +2401,10 @@ msgid "There is no defined scene to run." msgstr "Tidak ada skena yang didefinisikan untuk dijalankan." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Tidak dapat memulai subproses!" @@ -2448,18 +2448,6 @@ msgstr "Node akar diperlukan untuk menyimpan skena." msgid "Save Scene As..." msgstr "Simpan Skena Sebagai..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Tidak" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ya" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Skena ini belum pernah disimpan. Simpan sebelum menjalankan?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Operasi ini tidak dapat diselesaikan tanpa skena." @@ -2510,6 +2498,10 @@ msgid "Quit" msgstr "Keluar" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ya" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Keluar editor?" @@ -2556,7 +2548,8 @@ msgstr "" "gagal." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Tidak dapat mencari bidang script untuk addon plugin pada: 'res://addons/%s'." @@ -2997,14 +2990,6 @@ msgid "Help" msgstr "Bantuan" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Cari" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online Dokumentasi" @@ -3169,6 +3154,25 @@ msgid "Open & Run a Script" msgstr "Buka & Jalankan Skrip" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Berkas berikut lebih baru dalam diska.\n" +"Aksi apa yang ingin diambil?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Muat Ulang" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Simpan Ulang" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Turunan Baru" @@ -3380,7 +3384,7 @@ msgstr "Jadikan Unik" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Tempel" @@ -5044,7 +5048,8 @@ msgid "Got:" msgstr "Yang Didapat:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Gagal mengecek hash sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5177,10 +5182,10 @@ msgid "Assets ZIP File" msgstr "Berkas Aset ZIP" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Tidak dapat menentukan lokasi penyimpanan untuk gambar lightmap.\n" "Simpan skena Anda (untuk gambar yang akan disimpan di direktori yang sama), " @@ -5199,9 +5204,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "Gagal membuat gambar lightmap, pastikan path dapat ditulis." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Panggang Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Pilih berkas templat" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6305,6 +6330,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Hanya dapat mengatur titik ke dalam material proses ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Konversikan menjadi CPUParticles" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Waktu Pembuatan (detik):" @@ -6365,10 +6395,6 @@ msgstr "Membuat AABB" msgid "Generate Visibility AABB" msgstr "Buat Penampakan AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Buat AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Hapus Titik dari Kurva" @@ -6962,6 +6988,14 @@ msgstr "Tutup Dokumentasi" msgid "Run" msgstr "Jalankan" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Cari" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Masuki" @@ -7015,16 +7049,6 @@ msgstr "" "Berkas berikut lebih baru dalam diska.\n" "Aksi apa yang ingin diambil?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Muat Ulang" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Simpan Ulang" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Pengawakutu" @@ -7122,8 +7146,8 @@ msgstr "Breakpoint" msgid "Go To" msgstr "Pergi Ke" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Potong" @@ -7347,6 +7371,11 @@ msgid "Yaw" msgstr "Oleng" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Ukuran: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objek Digambar" @@ -10040,6 +10069,11 @@ msgid "Projects" msgstr "Proyek" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Mendapatkan informasi cermin, silakan tunggu..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Terakhir Diubah" @@ -10665,6 +10699,16 @@ msgstr "Instansi Skena Anak" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Tidak dapat bekerja pada node dari skena luar!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Rekatkan Node" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Detach Script" msgstr "Lampirkan Skrip" @@ -10795,6 +10839,11 @@ msgid "Attach Script" msgstr "Lampirkan Skrip" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Potong Node" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Hapus Node" @@ -11603,6 +11652,39 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "Berikan resource MeshLibrary ke GridMap ini untuk menggunakan mesh-nya." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "Buat AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Arah" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Indentasi Kanan" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Pasca Proses" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Plotting Lights:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Nama kelas tidak boleh reserved keyword" @@ -12116,12 +12198,16 @@ msgid "Select device from the list" msgstr "Pilih perangkat pada daftar" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Lokasi executable ADB belum dikonfigurasi dalam Pengaturan Editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "Lokasi jarsigner OpenJDK belum dikonfigurasi dalam Pengaturan Editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Templat build Android belum terpasang dalam proyek. Pasanglah dari menu " +"Proyek." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12137,13 +12223,15 @@ msgstr "" "prasetel proyek." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Membangun kustom APK memerlukan lokasi Android SDK yang valid dalam " -"Pengaturan Editor." +"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan " +"Editor." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "" "Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan " "Editor." @@ -12153,12 +12241,23 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan " +"Editor." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"Templat build Android belum terpasang dalam proyek. Pasanglah dari menu " -"Proyek." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12618,29 +12717,33 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin membutuhkan node anak ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Waktu tersisa: %d:%02d s)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Mengurai Geometri..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Plotting Meshes: " +#, fuzzy +msgid "Preparing environment" +msgstr "Tampilkan Lingkungan" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Plotting Lights:" +#, fuzzy +msgid "Generating capture" +msgstr "Membuat Pemetaan Cahaya" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Menyelesaikan Pemetaan" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Membuat Pemetaan Cahaya" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Lighting Meshes: " -msgstr "Lighting Meshes: " +msgid "Done" +msgstr "Selesai!" #: scene/3d/collision_object.cpp msgid "" @@ -12710,6 +12813,10 @@ msgid "Plotting Meshes" msgstr "Memetakan Mesh" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Menyelesaikan Pemetaan" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12957,6 +13064,10 @@ msgstr "Peringatan!" msgid "Please Confirm..." msgstr "Mohon konfirmasi..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Harus menggunakan ekstensi yang sah." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -13019,6 +13130,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Ukuran viewport harus lebih besar dari 0 untuk me-render apa pun." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Sumber tidak sah untuk pratinjau." @@ -13046,6 +13163,37 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex." msgid "Constants cannot be modified." msgstr "Konstanta tidak dapat dimodifikasi." +#~ msgid "No" +#~ msgstr "Tidak" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Skena ini belum pernah disimpan. Simpan sebelum menjalankan?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Lokasi executable ADB belum dikonfigurasi dalam Pengaturan Editor." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "" +#~ "Lokasi jarsigner OpenJDK belum dikonfigurasi dalam Pengaturan Editor." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Membangun kustom APK memerlukan lokasi Android SDK yang valid dalam " +#~ "Pengaturan Editor." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Waktu tersisa: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Plotting Meshes: " + +#, fuzzy +#~ msgid "Lighting Meshes: " +#~ msgstr "Lighting Meshes: " + #~ msgid "Search complete" #~ msgstr "Pencarian selesai" diff --git a/editor/translations/is.po b/editor/translations/is.po index 87a23006cc..6de37d39fb 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -659,7 +659,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1927,10 +1927,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2335,6 +2331,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2378,18 +2378,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2437,6 +2425,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2480,7 +2472,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2873,14 +2865,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3035,6 +3019,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3238,7 +3238,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4884,7 +4884,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5019,8 +5019,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5034,9 +5033,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6103,6 +6121,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6163,10 +6185,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6753,6 +6771,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6804,16 +6830,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6906,8 +6922,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7129,6 +7145,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9693,6 +9713,10 @@ msgid "Projects" msgstr "Verkefna Stjóri" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10299,6 +10323,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "TvÃteknir lyklar" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10423,6 +10456,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "TvÃteknir lyklar" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11212,6 +11250,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11717,11 +11783,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11733,11 +11801,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11745,9 +11813,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12138,27 +12216,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12218,6 +12296,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12431,6 +12513,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12476,6 +12562,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index d87bb71712..2daa387575 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -36,7 +36,7 @@ # Davide Giuliano <davidegiuliano00@gmail.com>, 2019. # Stefano Merazzi <asso99@hotmail.com>, 2019. # Sinapse X <sinapsex13@gmail.com>, 2019. -# Micila Micillotto <micillotto@gmail.com>, 2019, 2020. +# Micila Micillotto <micillotto@gmail.com>, 2019, 2020, 2021. # Mirko Soppelsa <miknsop@gmail.com>, 2019, 2020. # No <kingofwizards.kw7@gmail.com>, 2019. # StarFang208 <polaritymanx@yahoo.it>, 2019. @@ -52,15 +52,16 @@ # Anonymous <noreply@weblate.org>, 2020. # riccardo boffelli <riccardo.boffelli.96@gmail.com>, 2020. # Lorenzo Asolan <brixiumx@gmail.com>, 2020. -# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020. +# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020, 2021. # Federico Manzella <ferdiu.manzella@gmail.com>, 2020. # Ziv D <wizdavid@gmail.com>, 2020. +# Riteo Siuga <lorenzocerqua@tutanota.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-22 21:12+0000\n" -"Last-Translator: Lorenzo Cerqua <lorenzocerqua@tutanota.com>\n" +"PO-Revision-Date: 2021-02-21 10:50+0000\n" +"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -68,7 +69,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -190,9 +191,8 @@ msgid "Anim Delete Keys" msgstr "Elimina delle chiavi d'animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Time" -msgstr "Cambia il tempo di un fotogramma chiave" +msgstr "Cambia Intervallo Fotogramma Principale Animazione" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" @@ -203,49 +203,41 @@ msgid "Anim Change Transform" msgstr "Cambia la trasformazione di un'animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Value" -msgstr "Cambia il valore del fotogramma chiave di un'animazione" +msgstr "Cambia Valore Fotogramma Principale Animazione" #: editor/animation_track_editor.cpp msgid "Anim Change Call" msgstr "Cambia la chiamata di un'animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Keyframe Time" -msgstr "Cambia il tempo di più fotogrammi chiave" +msgstr "Cambia Multipli Intervalli Fotogramma Principale Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transition" -msgstr "Cambia la transizione di più animazioni" +msgstr "Cambi Multipli Transizione Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transform" -msgstr "Cambia le trasformazioni di più animazioni" +msgstr "Cambi Multipli Trasformazione Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Keyframe Value" -msgstr "Cambia il valore di più fotogrammi chiave di un'Animazione" +msgstr "Cambia Multipli Valori Fotogramma Principale Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Call" -msgstr "Cambia la chiamata di metodo di più animazioni" +msgstr "Cambi Multipli Chiamata Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Length" -msgstr "Cambia la lunghezza di un'animazione" +msgstr "Cambia Lunghezza Animazione" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Change Animation Loop" -msgstr "Commuta ciclicità animazione" +msgstr "Cambia Loop Animazione" #: editor/animation_track_editor.cpp msgid "Property Track" @@ -317,9 +309,8 @@ msgid "Interpolation Mode" msgstr "Modalità d'interpolazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "Modalità ciclo ad anello (interpola la fine con l'inizio del ciclo)" +msgstr "Modalità Ciclo ad Anello (interpola la fine con l'inizio a ciclo)" #: editor/animation_track_editor.cpp msgid "Remove this track." @@ -342,17 +333,14 @@ msgid "Discrete" msgstr "Discreta" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Trigger" -msgstr "Attivazione" +msgstr "Attivatore" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Capture" msgstr "Cattura" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Nearest" msgstr "Più vicino" @@ -366,30 +354,25 @@ msgid "Cubic" msgstr "Cubica" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Clamp Loop Interp" -msgstr "Blocca l'interpolazione d'un ciclo" +msgstr "Blocca Interpolazione Ciclo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Wrap Loop Interp" -msgstr "Continua l'interpolazione d'un ciclo" +msgstr "Avvolgi Interpolazione Ciclo" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Insert Key" -msgstr "Inserisci un fotogramma chiave" +msgstr "Inserisci Fotogramma Chiave" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Duplicate Key(s)" -msgstr "Duplica i fotogrammi chiave selezionati" +msgstr "Duplica Fotogrammi Chiave Selezionati" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Key(s)" -msgstr "Elimina i fotogrammi chiave selezionati" +msgstr "Elimina Fotogrammi Chiave Selezionati" #: editor/animation_track_editor.cpp msgid "Change Animation Update Mode" @@ -408,14 +391,12 @@ msgid "Remove Anim Track" msgstr "Rimuovi la traccia di un'animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Create NEW track for %s and insert key?" -msgstr "Creare una NUOVA traccia per %s e inserirci il fotogramma chiave?" +msgstr "Crea NUOVA traccia per %s ed inserire fotogramma chiave?" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Create %d NEW tracks and insert keys?" -msgstr "Creare %d NUOVE tracce e inserirci i fotogrammi chiavi?" +msgstr "Crea %d NUOVE tracce ed inserire fotogrammi chiave?" #: editor/animation_track_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp @@ -434,24 +415,20 @@ msgid "Anim Insert" msgstr "Inserisci un'animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "AnimationPlayer can't animate itself, only other players." -msgstr "AnimationPlayer non può animarsi, solo altri nodi." +msgstr "AnimationPlayer può solo animare altri riproduttori, non se stesso." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Create & Insert" -msgstr "Crea un'animazione e inserisci un fotogramma chiave" +msgstr "Crea & Inserisci Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Insert Track & Key" -msgstr "Inserisci un traccia con un fotogramma chiave in un'animazione" +msgstr "Inserisci Traccia e Fotogramma Chiave Animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Insert Key" -msgstr "Inserisci un fotogramma chiave in un'animazione" +msgstr "Inserisci Fotogramma Chiave Animazione" #: editor/animation_track_editor.cpp msgid "Change Animation Step" @@ -462,13 +439,12 @@ msgid "Rearrange Tracks" msgstr "Riordina delle tracce" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Transform tracks only apply to Spatial-based nodes." msgstr "" -"Le tracce di trasformazioni 3D si applicano solo a nodi di tipo Spatial." +"Le tracce di trasformazione possono essere applicate soltanto ai nodi basati " +"sul nodo Spatial." #: editor/animation_track_editor.cpp -#, fuzzy msgid "" "Audio tracks can only point to nodes of type:\n" "-AudioStreamPlayer\n" @@ -487,26 +463,26 @@ msgstr "" "AnimationPlayer." #: editor/animation_track_editor.cpp -#, fuzzy msgid "An animation player can't animate itself, only other players." -msgstr "Un AnimationPlayer non può animare se stesso, solo altri riproduttori." +msgstr "" +"Un riproduttore di animazioni può solo animare altri riproduttori, non se " +"stesso." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Not possible to add a new track without a root" msgstr "Non è possibile aggiungere una nuova traccia senza un nodo radice" #: editor/animation_track_editor.cpp msgid "Invalid track for Bezier (no suitable sub-properties)" -msgstr "Traccia non valida per la curva Bézier (nessuna sottoproprietà adatta)" +msgstr "Traccia non valida per Bezier (nessuna sotto-proprietà valida)" #: editor/animation_track_editor.cpp msgid "Add Bezier Track" -msgstr "Aggiungi traccia Bézier" +msgstr "Aggiungi una traccia di curve di Bézier" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "Il tracciato non è valido, non è possibile aggiungere una chiave." +msgstr "La traccia non è valida, quindi è impossibile aggiungere una chiave." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" @@ -514,21 +490,21 @@ msgstr "La traccia non è di tipo Spatial, impossibile aggiungere la chiave" #: editor/animation_track_editor.cpp msgid "Add Transform Track Key" -msgstr "Aggiungi chiave traccia Transform" +msgstr "Aggiungi una chiave a una traccia di trasformazioni" #: editor/animation_track_editor.cpp msgid "Add Track Key" -msgstr "Aggiungi chiave traccia" +msgstr "Aggiungi una chiave a una traccia" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." msgstr "" -"Il tracciato non è valido, non è possibile aggiungere una chiave di chiamata " -"di funzione." +"La traccia non è valida, quindi, non è stato possibile aggiungere una chiave " +"chiamata metodo." #: editor/animation_track_editor.cpp msgid "Add Method Track Key" -msgstr "Aggiungi chiave alla traccia metodo" +msgstr "Aggiungi una chiave a una traccia di chiamate di metodi" #: editor/animation_track_editor.cpp msgid "Method not found in object: " @@ -536,7 +512,7 @@ msgstr "Metodo non trovato nell'oggetto: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" -msgstr "Sposta chiavi animazione" +msgstr "Sposta delle chiavi d'animazione" #: editor/animation_track_editor.cpp msgid "Clipboard is empty" @@ -544,18 +520,18 @@ msgstr "Gli appunti sono vuoti" #: editor/animation_track_editor.cpp msgid "Paste Tracks" -msgstr "Incolla tracce" +msgstr "Incolla delle tracce" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "Scala chiavi animazione" +msgstr "Scala delle chiavi d'animazione" #: editor/animation_track_editor.cpp msgid "" "This option does not work for Bezier editing, as it's only a single track." msgstr "" -"Questa opzione non funziona per modificare curve di Bézier, dato che si " -"tratta di una traccia singola." +"Questa opzione non funziona per modificare delle curve di Bézier, dato che " +"si tratta di una singola traccia." #: editor/animation_track_editor.cpp msgid "" @@ -569,14 +545,14 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" -"Questa animazione appartiene a una scena importata, eventuali modifiche alle " -"tracce importate non saranno salvate.\n" +"Questa animazione appartiene ad una scena importata, quindi i cambiamenti " +"alle tracce importate non saranno salvate.\n" "\n" -"Per abilitare la possibilità di aggiungere ulteriori tracce, vai alle " -"impostazioni di importazione della scena e imposta\n" -"\"Animation > Storage\" su \"Files\", abilita \"Animation > Keep Custom " -"Tracks\", e infine reimporta la scena.\n" -"Altrimenti, usa un preset di importazione che importa le animazioni in file " +"Per abilitare l'aggiunta di tracce personalizzate, naviga alle impostazioni " +"d'importazione della scena ed imposta\n" +"\"Animation > Storage\" a \"Files\", abilita \"Animation > Keep Custom Tracks" +"\", e poi re-importa.\n" +"In alternativa, usa un preset d'importo che importa le animazioni da file " "separati." #: editor/animation_track_editor.cpp @@ -593,11 +569,11 @@ msgstr "Mostra solo le tracce dei nodi selezionati nell'albero." #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." -msgstr "Raggruppa le tracce per nodo o mostra una lista semplice." +msgstr "Raggruppa le tracce per nodo o le visualizza in una lista semplice." #: editor/animation_track_editor.cpp msgid "Snap:" -msgstr "Snap:" +msgstr "Scatto:" #: editor/animation_track_editor.cpp msgid "Animation step value." @@ -624,27 +600,27 @@ msgstr "Modifica" #: editor/animation_track_editor.cpp msgid "Animation properties." -msgstr "Proprietà animazione." +msgstr "Proprietà dell'animazione." #: editor/animation_track_editor.cpp msgid "Copy Tracks" -msgstr "Copia tracce" +msgstr "Copia le tracce" #: editor/animation_track_editor.cpp msgid "Scale Selection" -msgstr "Scala selezione" +msgstr "Scala la selezione" #: editor/animation_track_editor.cpp msgid "Scale From Cursor" -msgstr "Scala da cursore" +msgstr "Scala a partire dal cursore" #: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "Duplica selezione" +msgstr "Duplica la selezione" #: editor/animation_track_editor.cpp msgid "Duplicate Transposed" -msgstr "Duplica trasposto" +msgstr "Duplica Trasposto" #: editor/animation_track_editor.cpp msgid "Delete Selection" @@ -652,19 +628,19 @@ msgstr "Elimina la selezione" #: editor/animation_track_editor.cpp msgid "Go to Next Step" -msgstr "Va' al passo successivo" +msgstr "Vai allo Step Successivo" #: editor/animation_track_editor.cpp msgid "Go to Previous Step" -msgstr "Va' al passo precedente" +msgstr "Vai allo Step Precedente" #: editor/animation_track_editor.cpp msgid "Optimize Animation" -msgstr "Ottimizza animazione" +msgstr "Ottimizza l'animazione" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation" -msgstr "Pulisci animazione" +msgstr "Pulisci l'animazione" #: editor/animation_track_editor.cpp msgid "Pick the node that will be animated:" @@ -672,7 +648,7 @@ msgstr "Seleziona il nodo che verrà animato:" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" -msgstr "Usa curve di Bézier" +msgstr "Usa le curve di Bézier" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" @@ -680,15 +656,15 @@ msgstr "Ottimizzatore anim." #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" -msgstr "Max. errore lineare:" +msgstr "Max errore lineare:" #: editor/animation_track_editor.cpp msgid "Max. Angular Error:" -msgstr "Max. errore angolare:" +msgstr "Max errore angolare:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "Max. angolo ottimizzabile:" +msgstr "Max angolo ottimizzabile:" #: editor/animation_track_editor.cpp msgid "Optimize" @@ -696,11 +672,11 @@ msgstr "Ottimizza" #: editor/animation_track_editor.cpp msgid "Remove invalid keys" -msgstr "Rimuovi chiavi non valide" +msgstr "Rimuovi le chiavi non valide" #: editor/animation_track_editor.cpp msgid "Remove unresolved and empty tracks" -msgstr "Rimuovi tracce irrisolte e vuote" +msgstr "Rimuovi le tracce irrisolte e vuote" #: editor/animation_track_editor.cpp msgid "Clean-up all animations" @@ -708,7 +684,7 @@ msgstr "Pulisci tutte le animazioni" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "Pulisci animazione(i) (NON ANNULLABILE!)" +msgstr "Pulisci le animazioni (NON ANNULLABILE!)" #: editor/animation_track_editor.cpp msgid "Clean-Up" @@ -727,37 +703,37 @@ msgstr "Seleziona le tracce da copiare" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copia" #: editor/animation_track_editor.cpp msgid "Select All/None" -msgstr "Seleziona Tutto/Nulla" +msgstr "Seleziona tutto/nulla" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" -msgstr "Aggiungi traccia clip audio" +msgstr "Aggiungi audio in una traccia di riproduzione audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "Cambia Offset di Inizio della Clip della Traccia Audio" +msgstr "Cambia Offset Inizio Clip Traccia Audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "Cambia offset di fine della clip della traccia audio" +msgstr "Cambia Offset Fine Clip Traccia Audio" #: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "Ridimensiona array" +msgstr "Ridimensiona lista" #: editor/array_property_edit.cpp msgid "Change Array Value Type" -msgstr "Cambia tipo del valore dell'array" +msgstr "Cambia il tipo del valore della lista" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "Cambia valore array" +msgstr "Cambia il valore della lista" #: editor/code_editor.cpp msgid "Go to Line" @@ -765,7 +741,7 @@ msgstr "Vai alla linea" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "Numero linea:" +msgstr "Numero della linea:" #: editor/code_editor.cpp msgid "%d replaced." @@ -777,11 +753,11 @@ msgstr "%d corrispondenza." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." -msgstr "%d corrispondenza/e." +msgstr "%d corrispondenze." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "Distingui maiuscole" +msgstr "Distingui le maiuscole" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" @@ -797,7 +773,7 @@ msgstr "Rimpiazza tutti" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "Solo selezione" +msgstr "Solo nella selezione" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp @@ -806,7 +782,7 @@ msgstr "Standard" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "Commuta pannello degli script" +msgstr "Toggle Pannello Script" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -822,15 +798,15 @@ msgstr "Rimpicciolisci" #: editor/code_editor.cpp msgid "Reset Zoom" -msgstr "Resetta ingrandimento" +msgstr "Reimposta ingrandimento" #: editor/code_editor.cpp msgid "Warnings" -msgstr "Avvertenze" +msgstr "Avvisi" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "Numeri di riga e colonna." +msgstr "Numeri di riga e di colonna." #: editor/connections_dialog.cpp msgid "Method in target node must be specified." @@ -838,7 +814,7 @@ msgstr "Il metodo del nodo designato deve essere specificato." #: editor/connections_dialog.cpp msgid "Method name must be a valid identifier." -msgstr "Il nome del metodo dev'essere un identificatore valido." +msgstr "Il nome del metodo deve essere un identificatore valido." #: editor/connections_dialog.cpp msgid "" @@ -2028,10 +2004,6 @@ msgstr "Anteprima:" msgid "File:" msgstr "File:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "È necessaria un'estensione valida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Scansiona sorgenti" @@ -2473,6 +2445,10 @@ msgid "There is no defined scene to run." msgstr "Non c'è nessuna scena definita da eseguire." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Salva scena prima di eseguire..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Impossibile avviare il sottoprocesso!" @@ -2516,18 +2492,6 @@ msgstr "È necessario un nodo radice per salvare la scena." msgid "Save Scene As..." msgstr "Salva scena come…" -#: editor/editor_node.cpp -msgid "No" -msgstr "No" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Sì" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Questa scena non è mai stata salvata. Salvarla prima di eseguirla?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Questa operazione non può essere eseguita senza una scena." @@ -2577,6 +2541,10 @@ msgid "Quit" msgstr "Esci" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Sì" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Uscire dall'editor?" @@ -2625,7 +2593,8 @@ msgstr "" "configurazione fallita." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Impossibile trovare il campo dello script per il componente aggiuntivo in: " "'res://addons/%s'." @@ -3064,14 +3033,6 @@ msgid "Help" msgstr "Aiuto" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Cerca" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentazione online" @@ -3239,6 +3200,24 @@ msgid "Open & Run a Script" msgstr "Apri ed esegui uno script" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"I seguenti file sono più recenti sul disco.\n" +"Quale azione dovrebbe essere presa?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Ricarica" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Risalva" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nuova ereditata" @@ -3449,7 +3428,7 @@ msgstr "Rendi Unico" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Incolla" @@ -4010,19 +3989,16 @@ msgid "Searching..." msgstr "Ricerca..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d corrispondenza/e." +msgstr "%d corrispondenza in %d file." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d corrispondenza/e." +msgstr "%d corrispondenze in %d file." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d corrispondenza/e." +msgstr "%d corrispondenze in %d file." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5131,7 +5107,8 @@ msgid "Got:" msgstr "Ottenuto:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Check hash sha256 fallito" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5266,13 +5243,11 @@ msgstr "ZIP File degli Asset" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"Impossibile determinare un percorso di salvataggio per le immagini di " +"Impossibile determinare un percorso di salvataggio per le immagini " "lightmap.\n" -"Salva la scena (per salvare le immagini nella stessa directory), o scegli un " -"percorso di salvataggio nelle proprietà di BackedLightmap." +"Salva la scena e riprova." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5289,9 +5264,34 @@ msgstr "" "il percorso dei file sia scrivibile." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Impossibile determinare la dimensione della lightmap. La dimensione massima " +"(della lightmap) è troppo piccola?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Alcune mesh non sono valide. Sii sicuro che i valori dei canali UV2 siano " +"all'interno nella regione [0.0,1.0] quadra." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Godot Editor è stato costruito senza il supporto per il ray tracing, quindi " +"il baking delle lightmaps non è possibile." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Preprocessa Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Seleziona il file bake della lightmap:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6396,6 +6396,10 @@ msgstr "" "ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Converti in CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Tempo di Generazione (sec):" @@ -6456,10 +6460,6 @@ msgstr "Generando AABB" msgid "Generate Visibility AABB" msgstr "Genera Visibilità AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Genera AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Rimuovi Punto da Curva" @@ -7052,6 +7052,14 @@ msgstr "Chiudi la documentazione" msgid "Run" msgstr "Esegui" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Cerca" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Passo dentro all'istruzione" @@ -7105,16 +7113,6 @@ msgstr "" "I file seguenti sono più recenti su disco.\n" "Che azione deve essere intrapresa?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Ricarica" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Risalva" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Debugger" @@ -7210,8 +7208,8 @@ msgstr "Punti di interruzione" msgid "Go To" msgstr "Vai a" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Taglia" @@ -7434,6 +7432,10 @@ msgid "Yaw" msgstr "Imbardata" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Dimensione" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Oggetti disegnati" @@ -10134,6 +10136,10 @@ msgid "Projects" msgstr "Progetti" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Caricamento, per favore attendere..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Ultima Modifica" @@ -10754,6 +10760,16 @@ msgid "Instance Child Scene" msgstr "Istanzia Scena Figlia" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Impossibile operare su nodi da scena esterna!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Incolla nodi" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Rimuovi Script" @@ -10880,6 +10896,11 @@ msgid "Attach Script" msgstr "Allega Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Taglia nodi" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Rimuovi nodo(i)" @@ -11686,6 +11707,34 @@ msgstr "Filtra mesh" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Dai una risorsa MeshLibrary a questa GridMap per usare le sue mesh." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Inizia il Baking" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Preparando le strutture dati" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Genera buffers" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Luci dirette" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Luci indirette" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Post processing" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Stampando le lightmap" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Il nome della classe non può essere una parola chiave riservata" @@ -12203,12 +12252,16 @@ msgid "Select device from the list" msgstr "Seleziona il dispositivo dall'elenco" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Eseguibile ADB non configurato nelle Impostazioni dell'Editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "Impossibile trovare lo strumento 'apksigner'." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner non configurato nelle Impostazioni dell'Editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Il template build di Android non è installato in questo progetto. Installalo " +"dal menu Progetto." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12221,28 +12274,39 @@ msgstr "" "Release keystore non configurato correttamente nel preset di esportazione." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Le build personalizzate richiedono un percorso per un Android SDK valido " -"nelle impostazioni dell'editor." +"Un percorso valido per il SDK Android è richiesto nelle Impostazioni Editor." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Percorso per Android SDK per build personalizzata nelle impostazioni " -"dell'editor non è valido." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Un percorso invalido per il SDK Android nelle Impostazioni Editor." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Cartella 'platform-tools' inesistente!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" -"Il template build di Android non è installato in questo progetto. Installalo " -"dal menu Progetto." +"Impossibile trovare il comando adb negli strumenti di piattaforma del SDK " +"Android." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Per favore, controlla la directory specificata del SDK Android nelle " +"Impostazioni Editor." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Cartella 'build-tools' inesistente!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" +"Impossibile trovare il comando apksigner negli strumenti di piattaforma del " +"SDK Android." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12730,28 +12794,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin richiede un nodo figlio di tipo ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Cercando mesh e luci" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Tempo Rimanente: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Elaborazione Geometria (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Stampa Meshes: " +msgid "Preparing environment" +msgstr "Preparazione Ambiente" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Stampando Luci:" +msgid "Generating capture" +msgstr "Generando cattura" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Trama di Finitura" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Salvando Lightmap" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Illuminando Meshes: " +msgid "Done" +msgstr "Fatto" #: scene/3d/collision_object.cpp msgid "" @@ -12828,6 +12892,10 @@ msgid "Plotting Meshes" msgstr "Tracciando Meshes" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Trama di Finitura" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13084,10 +13152,13 @@ msgstr "Attenzione!" msgid "Please Confirm..." msgstr "Per Favore Conferma..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "È necessaria un'estensione valida." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Abilita Snap" +msgstr "Abilita mini-mappa griglia." #: scene/gui/popup.cpp msgid "" @@ -13144,6 +13215,14 @@ msgstr "" "visibile." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"La porta del sampler è connessa ma mai usata. Considera cambiare la sorgente " +"a 'SamplerPort'." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fonte non valida per l'anteprima." @@ -13172,6 +13251,35 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Le constanti non possono essere modificate." +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Questa scena non è mai stata salvata. Salvarla prima di eseguirla?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Eseguibile ADB non configurato nelle Impostazioni dell'Editor." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner non configurato nelle Impostazioni dell'Editor." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Le build personalizzate richiedono un percorso per un Android SDK valido " +#~ "nelle impostazioni dell'editor." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Tempo Rimanente: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Stampa Meshes: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Illuminando Meshes: " + #~ msgid "Search complete" #~ msgstr "Ricerca completata" @@ -13523,9 +13631,6 @@ msgstr "Le constanti non possono essere modificate." #~ msgid "Failed to save solution." #~ msgstr "Impossibile salvare la soluzione." -#~ msgid "Done" -#~ msgstr "Fatto" - #~ msgid "Failed to create C# project." #~ msgstr "Impossibile creare il progetto C#." diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 4b80b73525..6c7ce36693 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -18,7 +18,7 @@ # sugusan <sugusan.development@gmail.com>, 2018, 2019. # Nathan Lovato <nathan.lovato.art@gmail.com>, 2018. # nyanode <akaruooyagi@yahoo.co.jp>, 2018. -# nitenook <admin@alterbaum.net>, 2018, 2019, 2020. +# nitenook <admin@alterbaum.net>, 2018, 2019, 2020, 2021. # Rob Matych <robertsmatych@gmail.com>, 2018. # Hidetsugu Takahashi <manzyun@gmail.com>, 2019. # Wataru Onuki <watonu@magadou.com>, 2019. @@ -29,14 +29,14 @@ # Tarou Yamada <mizuningyou@yahoo.co.jp>, 2019. # kazuma kondo <kazmax7@gmail.com>, 2019. # Akihiro Ogoshi <technical@palsystem-game.com>, 2019, 2020. -# Wataru Onuki <bettawat@yahoo.co.jp>, 2020. +# Wataru Onuki <bettawat@yahoo.co.jp>, 2020, 2021. # sporeball <sporeballdev@gmail.com>, 2020. -# BinotaLIU <me@binota.org>, 2020. +# BinotaLIU <me@binota.org>, 2020, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-27 02:25+0000\n" +"PO-Revision-Date: 2021-02-21 10:50+0000\n" "Last-Translator: nitenook <admin@alterbaum.net>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" @@ -45,12 +45,12 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." -msgstr "convert() ã®å¼•æ•°ã®åž‹ãŒç„¡åйã§ã™ã€‚TYPE_* 定数を使ã£ã¦ãã ã•ã„。" +msgstr "convert() ã®å¼•æ•°ã®åž‹ãŒç„¡åйã§ã™ã€‚TYPE_* 定数を使用ã—ã¦ãã ã•ã„。" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." @@ -676,7 +676,7 @@ msgstr "コピーã™ã‚‹ãƒˆãƒ©ãƒƒã‚¯ã‚’é¸æŠž" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "コピー" @@ -1590,7 +1590,7 @@ msgstr "ファイルã®ä¿å˜:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" -msgstr "エクスãƒãƒ¼ãƒˆ テンプレートãŒäºˆæƒ³ã•れãŸãƒ‘スã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:" +msgstr "エクスãƒãƒ¼ãƒˆ テンプレートãŒäºˆæœŸã•れãŸãƒ‘スã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:" #: editor/editor_export.cpp msgid "Packing" @@ -1973,10 +1973,6 @@ msgstr "プレビュー:" msgid "File:" msgstr "ファイル:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "æœ‰åŠ¹ãªæ‹¡å¼µåを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "スã‚ャンソース" @@ -2413,6 +2409,10 @@ msgid "There is no defined scene to run." msgstr "実行ã™ã‚‹ã‚·ãƒ¼ãƒ³ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“。" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "実行å‰ã«ã‚·ãƒ¼ãƒ³ã‚’ä¿å˜..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "サブプãƒã‚»ã‚¹ã‚’é–‹å§‹ã§ãã¾ã›ã‚“ã§ã—ãŸ!" @@ -2456,18 +2456,6 @@ msgstr "シーンをä¿å˜ã™ã‚‹ã«ã¯ãƒ«ãƒ¼ãƒˆãƒŽãƒ¼ãƒ‰ãŒå¿…è¦ã§ã™ã€‚" msgid "Save Scene As..." msgstr "åå‰ã‚’付ã‘ã¦ã‚·ãƒ¼ãƒ³ã‚’ä¿å˜..." -#: editor/editor_node.cpp -msgid "No" -msgstr "ã„ã„ãˆ" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "ã¯ã„" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "ã“ã®ã‚·ãƒ¼ãƒ³ã¯ä¸€åº¦ã‚‚ä¿å˜ã•れã¦ã„ã¾ã›ã‚“。実行ã™ã‚‹å‰ã«ä¿å˜ã—ã¾ã™ã‹ï¼Ÿ" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "ã“ã®æ“作ã«ã¯ã‚·ãƒ¼ãƒ³ãŒå¿…è¦ã§ã™ã€‚" @@ -2517,6 +2505,10 @@ msgid "Quit" msgstr "終了" #: editor/editor_node.cpp +msgid "Yes" +msgstr "ã¯ã„" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "エディタを終了ã—ã¾ã™ã‹ï¼Ÿ" @@ -2562,7 +2554,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "アドオンプラグインを有効ã«ã§ãã¾ã›ã‚“: '%s' è¨å®šã®è§£æžã«å¤±æ•—ã—ã¾ã—ãŸã€‚" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "アドオンプラグインã®ã‚¹ã‚¯ãƒªãƒ—トフィールド㌠'res://addons/%s' ã‹ã‚‰è¦‹ã¤ã‹ã‚Šã¾ã›" "ん。" @@ -2996,14 +2989,6 @@ msgid "Help" msgstr "ヘルプ" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "検索" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "オンラインドã‚ュメント" @@ -3169,6 +3154,24 @@ msgid "Open & Run a Script" msgstr "スクリプトを開ã„ã¦å®Ÿè¡Œ" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"以下ã®ãƒ•ァイルより新ã—ã„ã‚‚ã®ãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å˜åœ¨ã—ã¾ã™ã€‚\n" +"ã©ã†ã—ã¾ã™ã‹?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "å†èªè¾¼" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "å†ä¿å˜" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "æ–°è¦ã®ç¶™æ‰¿" @@ -3379,7 +3382,7 @@ msgstr "ユニーク化" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "貼り付ã‘" @@ -3933,19 +3936,16 @@ msgid "Searching..." msgstr "検索ä¸..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" +msgstr "%d ä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%d 個ã®ãƒ•ァイル内)。" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" +msgstr "%d ä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%d 個ã®ãƒ•ァイル内)。" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" +msgstr "%d ä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%d 個ã®ãƒ•ァイル内)。" #: editor/groups_editor.cpp msgid "Add to Group" @@ -5046,7 +5046,8 @@ msgid "Got:" msgstr "å–å¾—:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "sha256 ãƒãƒƒã‚·ãƒ¥ãƒã‚§ãƒƒã‚¯å¤±æ•—" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5181,12 +5182,10 @@ msgstr "アセットã®zipファイル" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "ライトマップ画åƒã®ä¿å˜ãƒ‘スを確定ã§ãã¾ã›ã‚“。\n" -"シーンをä¿å˜ã™ã‚‹ (ç”»åƒãŒåŒã˜ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ä¿å˜ã•れる) ã‹ã€BakedLightmapプãƒãƒ‘" -"ティã‹ã‚‰ä¿å˜ãƒ‘ã‚¹ã‚’é¸æŠžã—ã¦ãã ã•ã„。" +"シーンをä¿å˜ã—ã¦ã‹ã‚‰å†åº¦è¡Œã£ã¦ãã ã•ã„。" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5203,9 +5202,34 @@ msgstr "" "ãã ã•ã„。" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"ライトマップサイズã®ç¢ºå®šã«å¤±æ•—ã—ã¾ã—ãŸã€‚ãƒ©ã‚¤ãƒˆãƒžãƒƒãƒ—ã®æœ€å¤§ã‚µã‚¤ã‚ºãŒå°ã•ã™ãŽã¾" +"ã™ã‹ï¼Ÿ" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"一部ã®ãƒ¡ãƒƒã‚·ãƒ¥ãŒç„¡åйã§ã™ã€‚UV2ãƒãƒ£ãƒ³ãƒãƒ«ã®å€¤ãŒ [0.0,1.0] ã®æ£æ–¹å½¢é ˜åŸŸå†…ã«ã‚ã‚‹" +"ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"GodotエディタãŒãƒ¬ã‚¤ãƒˆãƒ¬ãƒ¼ã‚·ãƒ³ã‚°ã«å¯¾å¿œã›ãšã«ãƒ“ルドã•れã¦ãŠã‚Šã€ãƒ©ã‚¤ãƒˆãƒžãƒƒãƒ—ã®ãƒ™" +"イクãŒã§ãã¾ã›ã‚“。" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "ライトマップを焼ã込む" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "ãƒ©ã‚¤ãƒˆãƒžãƒƒãƒ—ãƒ™ã‚¤ã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6298,6 +6322,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "ParticlesMaterialプãƒã‚»ã‚¹ãƒžãƒ†ãƒªã‚¢ãƒ«ã«ã®ã¿ç‚¹ã‚’è¨å®šã§ãã¾ã™" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "CPUParticles2D ã«å¤‰æ›" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "ç”Ÿæˆæ™‚é–“ (ç§’):" @@ -6358,10 +6386,6 @@ msgstr "AABBを生æˆä¸" msgid "Generate Visibility AABB" msgstr "å¯è¦–性ã®AABBを生æˆ" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "AABBを生æˆ" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "曲線ã‹ã‚‰ãƒã‚¤ãƒ³ãƒˆã‚’除去" @@ -6950,6 +6974,14 @@ msgstr "ドã‚ュメントを閉ã˜ã‚‹" msgid "Run" msgstr "実行" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "検索" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "ステップイン" @@ -7003,16 +7035,6 @@ msgstr "" "以下ã®ãƒ•ァイルより新ã—ã„ã‚‚ã®ãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å˜åœ¨ã—ã¾ã™ã€‚\n" "ã©ã†ã—ã¾ã™ã‹?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "å†èªè¾¼" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "å†ä¿å˜" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "デãƒãƒƒã‚¬" @@ -7109,8 +7131,8 @@ msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ" msgid "Go To" msgstr "å‚ç…§" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "切りå–り" @@ -7333,6 +7355,10 @@ msgid "Yaw" msgstr "ヨー" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "サイズ" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "æç”»ã•れãŸã‚ªãƒ–ジェクト" @@ -7466,7 +7492,7 @@ msgstr "オーディオリスナー" #: editor/plugins/spatial_editor_plugin.cpp msgid "Enable Doppler" -msgstr "ドップラー効果を有効化ã™ã‚‹" +msgstr "ドップラー効果を有効化" #: editor/plugins/spatial_editor_plugin.cpp msgid "Cinematic Preview" @@ -10009,6 +10035,10 @@ msgid "Projects" msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆ" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "èªã¿è¾¼ã¿ä¸ã€ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "最終更新" @@ -10628,6 +10658,16 @@ msgid "Instance Child Scene" msgstr "åシーンをインスタンス化" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "別ã®ã‚·ãƒ¼ãƒ³ã‹ã‚‰ãƒŽãƒ¼ãƒ‰ã‚’æ“作ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "ノードを貼り付ã‘" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "スクリプトをデタッãƒ" @@ -10753,6 +10793,11 @@ msgid "Attach Script" msgstr "スクリプトをアタッãƒ" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "ノードを切りå–ã‚‹" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "ノードを除去" @@ -10824,7 +10869,7 @@ msgstr "親ノードを新è¦ãƒŽãƒ¼ãƒ‰ã«å¤‰æ›´" #: editor/scene_tree_dock.cpp msgid "Make Scene Root" -msgstr "シーンをルートã«ã™ã‚‹" +msgstr "シーンã®ãƒ«ãƒ¼ãƒˆã«ã™ã‚‹" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -11560,6 +11605,38 @@ msgstr "" "メッシュを使ã†ã«ã¯ãƒ¡ãƒƒã‚·ãƒ¥ãƒ©ã‚¤ãƒ–ラリリソースをã“ã®ã‚°ãƒªãƒƒãƒ‰ãƒžãƒƒãƒ—ã«è¨å®šã—ã¦ã" "ã ã•ã„。" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "ベイク開始" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã®æº–å‚™" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "ãƒãƒƒãƒ•ァを生æˆ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "æ–¹å‘" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "å³ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "ãƒã‚¹ãƒˆãƒ—ãƒã‚»ã‚¹" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "å…‰æºã‚’æç”»ä¸:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "クラスåを予約ã‚ーワードã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" @@ -12074,12 +12151,16 @@ msgid "Select device from the list" msgstr "一覧ã‹ã‚‰ãƒ‡ãƒã‚¤ã‚¹ã‚’é¸æŠž" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" +msgid "Unable to find the 'apksigner' tool." +msgstr "'apksigner' ツールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Android ビルド テンプレートãŒãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。[プãƒ" +"ジェクト] メニューã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã€‚" #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12090,24 +12171,32 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "エクスãƒãƒ¼ãƒˆè¨å®šã«ã¦ãƒªãƒªãƒ¼ã‚¹ ã‚ーストアãŒèª¤ã£ã¦è¨å®šã•れã¦ã„ã¾ã™ã€‚" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "カスタムビルドã«ã¯ã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§æœ‰åйãªAndroid SDKパスãŒå¿…è¦ã§ã™ã€‚" +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "エディタè¨å®šã§Android SDKãƒ‘ã‚¹ã®æŒ‡å®šãŒå¿…è¦ã§ã™ã€‚" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "エディタè¨å®šã®ã‚«ã‚¹ã‚¿ãƒ ビルドã®Android SDKパスãŒç„¡åйã§ã™ã€‚" +msgid "Invalid Android SDK path in Editor Settings." +msgstr "エディタè¨å®šã®Android SDKパスãŒç„¡åйã§ã™ã€‚" #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "'platform-tools' ディレクトリãŒã‚りã¾ã›ã‚“ï¼" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." -msgstr "" -"Android ビルド テンプレートãŒãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。[プãƒ" -"ジェクト] メニューã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã€‚" +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "Android SDK platform-toolsã®adbコマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "エディタè¨å®šã§æŒ‡å®šã•れãŸAndroid SDKã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’確èªã—ã¦ãã ã•ã„。" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "'build-tools' ディレクトリãŒã‚りã¾ã›ã‚“ï¼" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "Android SDK build-toolsã®apksignerコマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12580,28 +12669,31 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROriginã¯åノードã«ARVRCameraãŒå¿…è¦ã§ã™ã€‚" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Time Left: %d分%02dç§’)" +msgid "Preparing geometry (%d/%d)" +msgstr "ジオメトリを解æžã—ã¦ã„ã¾ã™ (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "メッシュをæç”»ä¸: " +#, fuzzy +msgid "Preparing environment" +msgstr "環境を表示" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "å…‰æºã‚’æç”»ä¸:" +#, fuzzy +msgid "Generating capture" +msgstr "ライトマップã®ç”Ÿæˆ" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "æç”»å®Œäº†" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "ライトマップã®ç”Ÿæˆ" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "ライティングメッシュ: " +msgid "Done" +msgstr "完了" #: scene/3d/collision_object.cpp msgid "" @@ -12678,6 +12770,10 @@ msgid "Plotting Meshes" msgstr "メッシュã®ãƒ—ãƒãƒƒãƒˆ" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "æç”»å®Œäº†" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12934,10 +13030,13 @@ msgstr "è¦å‘Š!" msgid "Please Confirm..." msgstr "確èª..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "æœ‰åŠ¹ãªæ‹¡å¼µåを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "スナップを有効ã«ã™ã‚‹" +msgstr "グリッドミニマップを有効ã«ã™ã‚‹ã€‚" #: scene/gui/popup.cpp msgid "" @@ -12992,6 +13091,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "レンダーã™ã‚‹ã«ã¯ãƒ“ューãƒãƒ¼ãƒˆã®ã‚µã‚¤ã‚ºãŒ 0 より大ãã„å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "プレビューã®ã‚½ãƒ¼ã‚¹ãŒç„¡åйã§ã™ã€‚" @@ -13019,6 +13124,33 @@ msgstr "Varying変数ã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã msgid "Constants cannot be modified." msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。" +#~ msgid "No" +#~ msgstr "ã„ã„ãˆ" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "ã“ã®ã‚·ãƒ¼ãƒ³ã¯ä¸€åº¦ã‚‚ä¿å˜ã•れã¦ã„ã¾ã›ã‚“。実行ã™ã‚‹å‰ã«ä¿å˜ã—ã¾ã™ã‹ï¼Ÿ" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "カスタムビルドã«ã¯ã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§æœ‰åйãªAndroid SDKパスãŒå¿…è¦ã§ã™ã€‚" + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Time Left: %d分%02dç§’)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "メッシュをæç”»ä¸: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "ライティングメッシュ: " + #~ msgid "Search complete" #~ msgstr "検索完了" @@ -13031,12 +13163,6 @@ msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。" #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "ã“ã®ãƒ‘スã«ã¯ã€æ—¢ã«åŒåã®ãƒ•ァイルã‹ãƒ•ォルダãŒã‚りã¾ã™ã€‚" -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "'build-tools' ディレクトリãŒã‚りã¾ã›ã‚“ï¼" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "zipalign ツールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" - #~ msgid "Aligning APK..." #~ msgstr "APKを最é©åŒ–..." @@ -13382,9 +13508,6 @@ msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。" #~ msgid "Failed to save solution." #~ msgstr "ソリューションã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" -#~ msgid "Done" -#~ msgstr "完了" - #~ msgid "Failed to create C# project." #~ msgstr "C#プãƒã‚¸ã‚§ã‚¯ãƒˆã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index f25c96166c..b9f4a92e47 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -675,7 +675,7 @@ msgstr "დáƒáƒ§áƒ”ნდეს გáƒáƒ“áƒáƒ¡áƒ•ლები შემდეá #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1995,10 +1995,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2413,6 +2409,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2457,18 +2457,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2517,6 +2505,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2560,7 +2552,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2957,14 +2949,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3119,6 +3103,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3324,7 +3324,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -5006,7 +5006,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5145,8 +5145,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5160,9 +5159,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "წáƒáƒ•შáƒáƒšáƒáƒ— მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ”ბი?" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6247,6 +6266,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "შექმნáƒ" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6307,10 +6331,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6906,6 +6926,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6957,16 +6985,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7066,8 +7084,8 @@ msgstr "შექმნáƒ" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7295,6 +7313,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9896,6 +9918,11 @@ msgid "Projects" msgstr "პრáƒáƒ”ქტის დáƒáƒ›áƒ¤áƒ£áƒ«áƒœáƒ”ბლები" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "ძებნáƒ:" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10507,6 +10534,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებების შემსწáƒáƒ ებელი" @@ -10633,6 +10669,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11440,6 +11481,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11952,11 +12021,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11968,11 +12039,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11980,9 +12051,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12380,27 +12461,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12460,6 +12541,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12677,6 +12762,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12722,6 +12811,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ ი ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ." diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 2568545544..872cb1550c 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -662,7 +662,7 @@ msgstr "ë³µì‚¬í• íŠ¸ëž™ ì„ íƒ" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "복사" @@ -1956,10 +1956,6 @@ msgstr "미리 보기:" msgid "File:" msgstr "파ì¼:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "올바른 확장ìžë¥¼ 사용해야 합니다." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "소스 스캔중" @@ -2387,6 +2383,10 @@ msgid "There is no defined scene to run." msgstr "ì‹¤í–‰í• ì”¬ì´ ì„¤ì •ë˜ì§€ 않았습니다." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "하위 프로세스를 ì‹œìž‘í• ìˆ˜ 없습니다!" @@ -2430,18 +2430,6 @@ msgstr "ì”¬ì„ ì €ìž¥í•˜ë ¤ë©´ 루트 노드가 필요합니다." msgid "Save Scene As..." msgstr "ì”¬ì„ ë‹¤ë¥¸ ì´ë¦„으로 ì €ìž¥..." -#: editor/editor_node.cpp -msgid "No" -msgstr "아니오" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "예" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "ì´ ì”¬ì€ ì•„ì§ ì €ìž¥í•˜ì§€ 않았습니다. 실행하기 ì „ì— ì €ìž¥í• ê¹Œìš”?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "ì´ ìž‘ì—…ì—는 ì”¬ì´ í•„ìš”í•©ë‹ˆë‹¤." @@ -2491,6 +2479,10 @@ msgid "Quit" msgstr "종료" #: editor/editor_node.cpp +msgid "Yes" +msgstr "예" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "편집기를 ëŒê¹Œìš”?" @@ -2537,7 +2529,8 @@ msgstr "" "실패했습니다." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "ë‹¤ìŒ ê²½ë¡œì—서 ì• ë“œì˜¨ 플러그ì¸ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ: 'res://addons/%s'." #: editor/editor_node.cpp @@ -2966,14 +2959,6 @@ msgid "Help" msgstr "ë„움ë§" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "검색" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "온ë¼ì¸ 문서" @@ -3135,6 +3120,25 @@ msgid "Open & Run a Script" msgstr "스í¬ë¦½íЏ 열기 & 실행" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"해당 파ì¼ì€ 디스í¬ì— 있는 게 ë” ìµœì‹ ìž…ë‹ˆë‹¤.\n" +"어떻게 í• ê±´ê°€ìš”?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "ìƒˆë¡œê³ ì¹¨" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "다시 ì €ìž¥" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "새 ìƒì† 씬" @@ -3343,7 +3347,7 @@ msgstr "ìœ ì¼í•˜ê²Œ 만들기" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "붙여넣기" @@ -5005,7 +5009,8 @@ msgid "Got:" msgstr "ë°›ìŒ:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "sha256 해시 í™•ì¸ ì‹¤íŒ¨" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5138,10 +5143,10 @@ msgid "Assets ZIP File" msgstr "ì• ì…‹ ZIP 파ì¼" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "ë¼ì´íŠ¸ë§µ ì´ë¯¸ì§€ì˜ ì €ìž¥ 경로를 íŒŒì•…í• ìˆ˜ 없습니다.\n" "(ê°™ì€ ê²½ë¡œì— ì´ë¯¸ì§€ë¥¼ ì €ìž¥í• ìˆ˜ 있ë„ë¡) ì”¬ì„ ì €ìž¥í•˜ê±°ë‚˜, BakedLightmap ì†ì„±ì—" @@ -5160,9 +5165,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "ë¼ì´íŠ¸ë§µ ì´ë¯¸ì§€ ìƒì„± 실패. 작성 가능한 경로ì¸ì§€ 확ì¸í•´ì£¼ì„¸ìš”." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "ë¼ì´íŠ¸ë§µ 굽기" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "템플릿 íŒŒì¼ ì„ íƒ" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6252,6 +6277,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "ParticlesMaterial 프로세스 머티리얼 안ì—ë§Œ ì ì„ ì„¤ì •í• ìˆ˜ 있습니다" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "CPU파티í´ë¡œ 변환" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "ìƒì„± 시간 (ì´ˆ):" @@ -6312,10 +6342,6 @@ msgstr "AABB 만드는 중" msgid "Generate Visibility AABB" msgstr "가시성 AABB 만들기" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "AABB 만들기" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "ê³¡ì„ ì—서 ì ì‚ì œ" @@ -6908,6 +6934,14 @@ msgstr "문서 닫기" msgid "Run" msgstr "실행" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "검색" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "í”„ë¡œì‹œì € 단위 실행" @@ -6961,16 +6995,6 @@ msgstr "" "해당 파ì¼ì€ 디스í¬ì— 있는 게 ë” ìµœì‹ ìž…ë‹ˆë‹¤.\n" "어떻게 í• ê±´ê°€ìš”?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "ìƒˆë¡œê³ ì¹¨" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "다시 ì €ìž¥" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "디버거" @@ -7066,8 +7090,8 @@ msgstr "중단ì " msgid "Go To" msgstr "ì´ë™" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "잘ë¼ë‚´ê¸°" @@ -7290,6 +7314,11 @@ msgid "Yaw" msgstr "ìš”" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "í¬ê¸°: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ê·¸ë ¤ì§„ ê°ì²´" @@ -9945,6 +9974,11 @@ msgid "Projects" msgstr "프로ì 트" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "미러를 검색 중입니다. ê¸°ë‹¤ë ¤ì£¼ì„¸ìš”..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "마지막으로 ìˆ˜ì •ë¨" @@ -10561,6 +10595,16 @@ msgid "Instance Child Scene" msgstr "ìžì‹ 씬 ì¸ìŠ¤í„´ìŠ¤í™”" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "다른 씬ì—서 ìˆ˜í–‰í• ìˆ˜ 없는 작업입니다!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "노드 붙여넣기" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "스í¬ë¦½íЏ 떼기" @@ -10686,6 +10730,11 @@ msgid "Attach Script" msgstr "스í¬ë¦½íЏ ë¶™ì´ê¸°" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "노드 잘ë¼ë‚´ê¸°" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "노드 ì‚ì œ" @@ -11488,6 +11537,39 @@ msgstr "메시 í•„í„°" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "메시를 ì‚¬ìš©í•˜ë ¤ë©´ ì´ GridMapì— MeshLibrary 리소스를 주세요." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "AABB 만들기" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "ë°©í–¥" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "들여쓰기" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "후처리" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "구분하는 조명:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "í´ëž˜ìФ ì´ë¦„ì€ í‚¤ì›Œë“œê°€ ë 수 없습니다" @@ -11999,12 +12081,16 @@ msgid "Select device from the list" msgstr "목ë¡ì—서 기기 ì„ íƒ" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB 실행 파ì¼ì„ 편집기 ì„¤ì •ì—서 ì„¤ì •í•˜ì§€ 않았습니다." +msgid "Unable to find the 'apksigner' tool." +msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner를 편집기 ì„¤ì •ì—서 ì„¤ì •í•˜ì§€ 않았습니다." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"프로ì íŠ¸ì— ì•ˆë“œë¡œì´ë“œ 빌드 í…œí”Œë¦¿ì„ ì„¤ì¹˜í•˜ì§€ 않았습니다. 프로ì 트 메뉴ì—서 설" +"치하세요." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12015,11 +12101,13 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "내보내기 í”„ë¦¬ì…‹ì— ë°°í¬ keystorkeê°€ 잘못 ì„¤ì •ë˜ì–´ 있습니다." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "맞춤 빌드ì—는 편집기 ì„¤ì •ì—서 올바른 안드로ì´ë“œ SDK 경로가 필요합니다." +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "편집기 ì„¤ì •ì—서 맞춤 ë¹Œë“œì— ìž˜ëª»ëœ ì•ˆë“œë¡œì´ë“œ SDK 경로입니다." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "편집기 ì„¤ì •ì—서 맞춤 ë¹Œë“œì— ìž˜ëª»ëœ ì•ˆë“œë¡œì´ë“œ SDK 경로입니다." #: platform/android/export/export.cpp @@ -12027,12 +12115,21 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "편집기 ì„¤ì •ì—서 맞춤 ë¹Œë“œì— ìž˜ëª»ëœ ì•ˆë“œë¡œì´ë“œ SDK 경로입니다." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"프로ì íŠ¸ì— ì•ˆë“œë¡œì´ë“œ 빌드 í…œí”Œë¦¿ì„ ì„¤ì¹˜í•˜ì§€ 않았습니다. 프로ì 트 메뉴ì—서 설" -"치하세요." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12481,28 +12578,32 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROriginì€ ìžì‹ìœ¼ë¡œ ARVRCamera 노드가 필요합니다." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(ë‚¨ì€ ì‹œê°„: %d:%02d ì´ˆ)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "형태 ë¶„ì„ ì¤‘..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "구분하는 메시: " +#, fuzzy +msgid "Preparing environment" +msgstr "환경 보기" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "구분하는 조명:" +#, fuzzy +msgid "Generating capture" +msgstr "ë¼ì´íŠ¸ë§µ ìƒì„± 중" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "구분 ë남" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "ë¼ì´íŠ¸ë§µ ìƒì„± 중" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "조명 메시: " +msgid "Done" +msgstr "완료" #: scene/3d/collision_object.cpp msgid "" @@ -12578,6 +12679,10 @@ msgid "Plotting Meshes" msgstr "메시 구분" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "구분 ë남" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12830,6 +12935,10 @@ msgstr "ê²½ê³ !" msgid "Please Confirm..." msgstr "확ì¸í•´ì£¼ì„¸ìš”..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "올바른 확장ìžë¥¼ 사용해야 합니다." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -12887,6 +12996,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "무엇ì´ë“ ë Œë”ë§í•˜ë ¤ë©´ ë·°í¬íЏ í¬ê¸°ê°€ 0보다 커야 합니다." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "미리 ë³´ê¸°ì— ìž˜ëª»ëœ ì†ŒìŠ¤." @@ -12914,6 +13029,34 @@ msgstr "Varyingì€ ê¼ì§“ì 함수ì—ë§Œ ì§€ì •í• ìˆ˜ 있습니다." msgid "Constants cannot be modified." msgstr "ìƒìˆ˜ëŠ” ìˆ˜ì •í• ìˆ˜ 없습니다." +#~ msgid "No" +#~ msgstr "아니오" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "ì´ ì”¬ì€ ì•„ì§ ì €ìž¥í•˜ì§€ 않았습니다. 실행하기 ì „ì— ì €ìž¥í• ê¹Œìš”?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ADB 실행 파ì¼ì„ 편집기 ì„¤ì •ì—서 ì„¤ì •í•˜ì§€ 않았습니다." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner를 편집기 ì„¤ì •ì—서 ì„¤ì •í•˜ì§€ 않았습니다." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "맞춤 빌드ì—는 편집기 ì„¤ì •ì—서 올바른 안드로ì´ë“œ SDK 경로가 필요합니다." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(ë‚¨ì€ ì‹œê°„: %d:%02d ì´ˆ)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "구분하는 메시: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "조명 메시: " + #~ msgid "Search complete" #~ msgstr "검색 완료" @@ -13253,9 +13396,6 @@ msgstr "ìƒìˆ˜ëŠ” ìˆ˜ì •í• ìˆ˜ 없습니다." #~ msgid "Failed to save solution." #~ msgstr "솔루션 ì €ìž¥ 실패." -#~ msgid "Done" -#~ msgstr "완료" - #~ msgid "Failed to create C# project." #~ msgstr "C# 프로ì 트 ìƒì„± 실패." diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 53f9b83536..313d6144e3 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -5,12 +5,12 @@ # Ignas Kiela <ignaskiela@super.lt>, 2017. # Kornelijus <kornelijus.github@gmail.com>, 2017, 2018. # Ignotas Gražys <ignotas.gr@gmail.com>, 2020. -# Kornelijus TvarijanaviÄius <kornelitvari@protonmail.com>, 2020. +# Kornelijus TvarijanaviÄius <kornelitvari@protonmail.com>, 2020, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-28 11:18+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: Kornelijus TvarijanaviÄius <kornelitvari@protonmail.com>\n" "Language-Team: Lithuanian <https://hosted.weblate.org/projects/godot-engine/" "godot/lt/>\n" @@ -20,7 +20,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n==1 ? 0 : n%10>=2 && (n%100<10 || n" "%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -650,7 +650,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1948,10 +1948,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2365,6 +2361,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2409,18 +2409,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2469,6 +2457,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2512,7 +2504,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2909,14 +2901,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3070,6 +3054,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3279,7 +3279,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4770,7 +4770,6 @@ msgstr "Naujas pavadinimas:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp -#, fuzzy msgid "Scale:" msgstr "SkalÄ—:" @@ -4972,7 +4971,7 @@ msgid "Got:" msgstr "Gauta:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5113,8 +5112,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5128,9 +5126,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Pasirinkite Nodus, kuriuos norite importuoti" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6208,6 +6226,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Keisti Poligono SkalÄ™" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6268,10 +6291,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6876,6 +6895,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6927,16 +6954,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7033,8 +7050,8 @@ msgstr "Sukurti" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7257,6 +7274,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9869,6 +9890,11 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Atsiųsti" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10478,6 +10504,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Duplikuoti" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Atidaryti Skriptų Editorių" @@ -10602,6 +10637,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Transition Nodas" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11409,6 +11449,35 @@ msgstr "Filtrai..." msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "ApraÅ¡ymas:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11920,11 +11989,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11936,11 +12007,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11948,9 +12019,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12348,27 +12429,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12428,6 +12509,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12648,6 +12733,10 @@ msgstr "Ä®spÄ—jimas!" msgid "Please Confirm..." msgstr "PraÅ¡ome Patvirtinti..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12693,6 +12782,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Netinkamas Å¡rifto dydis." @@ -12766,10 +12861,6 @@ msgstr "" #~ msgid "Path to Node:" #~ msgstr "Kelias iki Nodo:" -#, fuzzy -#~ msgid "Custom Node" -#~ msgstr "Transition Nodas" - #~ msgid "Line:" #~ msgstr "Linija:" diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 7c30135407..8f70ed94f7 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -649,7 +649,7 @@ msgstr "IzvÄ“lÄ“ties Celiņus ko KopÄ“t" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "KopÄ“t" @@ -1933,10 +1933,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2340,6 +2336,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2383,18 +2383,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2443,6 +2431,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2485,7 +2477,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2875,14 +2867,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3036,6 +3020,23 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "SekojoÅ¡ie faili netika izvilkti no paketes:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3238,7 +3239,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4869,7 +4870,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5004,8 +5005,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5019,9 +5019,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "IzvÄ“lÄ“ties Å ablona Failu" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6077,6 +6097,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Izveidot" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6137,10 +6162,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6730,6 +6751,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6781,16 +6810,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6887,8 +6906,8 @@ msgstr "Izveidot" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7114,6 +7133,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9692,6 +9715,11 @@ msgid "Projects" msgstr "Projekta DibinÄtÄji" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "IelÄdÄ“t..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10299,6 +10327,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "DublicÄ“t atslÄ“gvietnes" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Galvenais Skripts:" @@ -10422,6 +10459,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "DublicÄ“t atslÄ“gvietnes" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11219,6 +11261,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11722,11 +11792,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11738,11 +11810,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11750,9 +11822,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12149,27 +12231,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12229,6 +12311,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12443,6 +12529,10 @@ msgstr "BrÄ«dinÄjums!" msgid "Please Confirm..." msgstr "LÅ«dzu Apstipriniet..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12488,6 +12578,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "NederÄ«gs fonta izmÄ“rs." diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 2da7379e71..301383d787 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -619,7 +619,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1880,10 +1880,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2287,6 +2283,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2330,18 +2330,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2389,6 +2377,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2431,7 +2423,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2821,14 +2813,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2982,6 +2966,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3184,7 +3184,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4812,7 +4812,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4947,8 +4947,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4962,9 +4961,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6020,6 +6038,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6080,10 +6102,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6665,6 +6683,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6716,16 +6742,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6818,8 +6834,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7040,6 +7056,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9560,6 +9580,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10163,6 +10187,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10283,6 +10315,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11067,6 +11103,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11562,11 +11626,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11578,11 +11644,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11590,9 +11656,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11983,27 +12059,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12063,6 +12139,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12276,6 +12356,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12321,6 +12405,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/mk.po b/editor/translations/mk.po new file mode 100644 index 0000000000..1b01a6f792 --- /dev/null +++ b/editor/translations/mk.po @@ -0,0 +1,12446 @@ +# Macedonian translation of the Godot Engine editor +# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. +# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). +# This file is distributed under the same license as the Godot source code. +# +# Kristijan Fremen Velkovski <me@krisfremen.com>, 2021. +msgid "" +msgstr "" +"Project-Id-Version: Godot Engine editor\n" +"PO-Revision-Date: 2021-01-22 10:21+0000\n" +"Last-Translator: Kristijan Fremen Velkovski <me@krisfremen.com>\n" +"Language-Team: Macedonian <https://hosted.weblate.org/projects/godot-engine/" +"godot/mk/>\n" +"Language: mk\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" +"Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n" +"X-Generator: Weblate 4.5-dev\n" + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Invalid type argument to convert(), use TYPE_* constants." +msgstr "Погрешен тип на аргумент до convert(), кориÑтите TYPE_* конÑтанти." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +msgid "Expected a string of length 1 (a character)." +msgstr "Очекува Ñтринг од должина 1 (карактер)." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/mono/glue/gd_glue.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Not enough bytes for decoding bytes, or invalid format." +msgstr "Ðема доволно бајти за декодирање бајтови, или невалиден формат." + +#: core/math/expression.cpp +msgid "Invalid input %i (not passed) in expression" +msgstr "Ðевалидено внеÑување %i (не додадено) во израз" + +#: core/math/expression.cpp +msgid "self can't be used because instance is null (not passed)" +msgstr "self неможе да Ñе кориÑти зашто инÑтанцата е нула(не дадена)" + +#: core/math/expression.cpp +msgid "Invalid operands to operator %s, %s and %s." +msgstr "Ðевалиден операнд на операторите %s, %s и %s." + +#: core/math/expression.cpp +msgid "Invalid index of type %s for base type %s" +msgstr "Ðевалиден Ð¸Ð½Ð´ÐµÐºÑ Ð¾Ð´ тип %s за оÑновен тип %s" + +#: core/math/expression.cpp +msgid "Invalid named index '%s' for base type %s" +msgstr "Ðевалиден именуван Ð¸Ð½Ð´ÐµÐºÑ Ð¾Ð´ тип %s за оÑновен тип %s" + +#: core/math/expression.cpp +msgid "Invalid arguments to construct '%s'" +msgstr "Ðевалидни аргументи на конÑтрукт '%s'" + +#: core/math/expression.cpp +msgid "On call to '%s':" +msgstr "Ðа јавување до '%s':" + +#: core/ustring.cpp +msgid "B" +msgstr "Б" + +#: core/ustring.cpp +msgid "KiB" +msgstr "КиБ" + +#: core/ustring.cpp +msgid "MiB" +msgstr "МиБ" + +#: core/ustring.cpp +msgid "GiB" +msgstr "ГиБ" + +#: core/ustring.cpp +msgid "TiB" +msgstr "ТиБ" + +#: core/ustring.cpp +msgid "PiB" +msgstr "ПиБ" + +#: core/ustring.cpp +msgid "EiB" +msgstr "ЕиБ" + +#: editor/animation_bezier_editor.cpp +msgid "Free" +msgstr "Слободно" + +#: editor/animation_bezier_editor.cpp +msgid "Balanced" +msgstr "БаланÑирано" + +#: editor/animation_bezier_editor.cpp +msgid "Mirror" +msgstr "Огледало" + +#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp +msgid "Time:" +msgstr "Време:" + +#: editor/animation_bezier_editor.cpp +msgid "Value:" +msgstr "ВредноÑÑ‚:" + +#: editor/animation_bezier_editor.cpp +msgid "Insert Key Here" +msgstr "ВнеÑи клуч тука" + +#: editor/animation_bezier_editor.cpp +msgid "Duplicate Selected Key(s)" +msgstr "Дуплирај избран(и) клуч(еви)" + +#: editor/animation_bezier_editor.cpp +msgid "Delete Selected Key(s)" +msgstr "Избриши избран(и) клуч(еви)" + +#: editor/animation_bezier_editor.cpp +msgid "Add Bezier Point" +msgstr "Додади Безиер Точка" + +#: editor/animation_bezier_editor.cpp +msgid "Move Bezier Points" +msgstr "ПромеÑти Безиер Точка" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Duplicate Keys" +msgstr "Дуплицирај клучеви" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Delete Keys" +msgstr "Избриши Клучеви" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Time" +msgstr "Ðнимација Промени Време на клучниот кадар" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transition" +msgstr "Ðнимација Промени Прелаз" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transform" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Value" +msgstr "Ðнимација Промени Клучен Кадар ВредноÑÑ‚" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Call" +msgstr "Ðнимација Промени Позив" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Time" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transition" +msgstr "Ðнимација Многукратно Променување на Прелози" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transform" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Value" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Call" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Length" +msgstr "" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation Loop" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Property Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "3D Transform Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Call Method Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Bezier Curve Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Audio Playback Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation Playback Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation length (frames)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation length (seconds)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Add Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation Looping" +msgstr "" + +#: editor/animation_track_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Functions:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Audio Clips:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Clips:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Track Path" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Toggle this track on/off." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Update Mode (How this property is set)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Interpolation Mode" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Remove this track." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Time (s): " +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Toggle Track Enabled" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Continuous" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Discrete" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Trigger" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Capture" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Nearest" +msgstr "" + +#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp +#: editor/property_editor.cpp +msgid "Linear" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Cubic" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Clamp Loop Interp" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Wrap Loop Interp" +msgstr "" + +#: editor/animation_track_editor.cpp +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Key(s)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Delete Key(s)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Update Mode" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Interpolation Mode" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Loop Mode" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Remove Anim Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Create NEW track for %s and insert key?" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Create %d NEW tracks and insert keys?" +msgstr "" + +#: editor/animation_track_editor.cpp editor/create_dialog.cpp +#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/mesh_instance_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Create" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "AnimationPlayer can't animate itself, only other players." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Create & Insert" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Track & Key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Step" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Rearrange Tracks" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Transform tracks only apply to Spatial-based nodes." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "" +"Audio tracks can only point to nodes of type:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation tracks can only point to AnimationPlayer nodes." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "An animation player can't animate itself, only other players." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Not possible to add a new track without a root" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Invalid track for Bezier (no suitable sub-properties)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Add Bezier Track" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a key." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Track is not of type Spatial, can't insert key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Add Transform Track Key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Add Track Key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a method key." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Add Method Track Key" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Method not found in object: " +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Move Keys" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Clipboard is empty" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Paste Tracks" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim Scale Keys" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "" +"This option does not work for Bezier editing, as it's only a single track." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "" +"This animation belongs to an imported scene, so changes to imported tracks " +"will not be saved.\n" +"\n" +"To enable the ability to add custom tracks, navigate to the scene's import " +"settings and set\n" +"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks" +"\", then re-import.\n" +"Alternatively, use an import preset that imports animations to separate " +"files." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Warning: Editing imported animation" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select an AnimationPlayer node to create and edit animations." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Only show tracks from nodes selected in tree." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Group tracks by node or display them as plain list." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Snap:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation step value." +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Seconds" +msgstr "Секунди" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "FPS" +msgstr "ФПС" + +#: editor/animation_track_editor.cpp editor/editor_properties.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit" +msgstr "Уреди" + +#: editor/animation_track_editor.cpp +msgid "Animation properties." +msgstr "СвојÑтва на анимацијата." + +#: editor/animation_track_editor.cpp +msgid "Copy Tracks" +msgstr "Копирај Траки" + +#: editor/animation_track_editor.cpp +msgid "Scale Selection" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Scale From Cursor" +msgstr "" + +#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp +msgid "Duplicate Selection" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Transposed" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Delete Selection" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Go to Next Step" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Go to Previous Step" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Optimize Animation" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Pick the node that will be animated:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Use Bezier Curves" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Anim. Optimizer" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Max. Linear Error:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Max. Angular Error:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Max Optimizable Angle:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Optimize" +msgstr "Оптимизирај" + +#: editor/animation_track_editor.cpp +msgid "Remove invalid keys" +msgstr "Избриши невалидни клучеви" + +#: editor/animation_track_editor.cpp +msgid "Remove unresolved and empty tracks" +msgstr "Избриши нерешени и празни траки" + +#: editor/animation_track_editor.cpp +msgid "Clean-up all animations" +msgstr "ИÑчиÑти Ñите анимации" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation(s) (NO UNDO!)" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Scale Ratio:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select Tracks to Copy" +msgstr "" + +#: editor/animation_track_editor.cpp editor/editor_log.cpp +#: editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Copy" +msgstr "Копирај" + +#: editor/animation_track_editor.cpp +msgid "Select All/None" +msgstr "" + +#: editor/animation_track_editor_plugins.cpp +msgid "Add Audio Track Clip" +msgstr "" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip Start Offset" +msgstr "" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip End Offset" +msgstr "" + +#: editor/array_property_edit.cpp +msgid "Resize Array" +msgstr "" + +#: editor/array_property_edit.cpp +msgid "Change Array Value Type" +msgstr "" + +#: editor/array_property_edit.cpp +msgid "Change Array Value" +msgstr "" + +#: editor/code_editor.cpp +msgid "Go to Line" +msgstr "" + +#: editor/code_editor.cpp +msgid "Line Number:" +msgstr "" + +#: editor/code_editor.cpp +msgid "%d replaced." +msgstr "" + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d match." +msgstr "" + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d matches." +msgstr "" + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Match Case" +msgstr "" + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Whole Words" +msgstr "" + +#: editor/code_editor.cpp +msgid "Replace" +msgstr "" + +#: editor/code_editor.cpp +msgid "Replace All" +msgstr "" + +#: editor/code_editor.cpp +msgid "Selection Only" +msgstr "" + +#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp +#: editor/plugins/text_editor.cpp +msgid "Standard" +msgstr "" + +#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp +msgid "Toggle Scripts Panel" +msgstr "" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom In" +msgstr "" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Out" +msgstr "" + +#: editor/code_editor.cpp +msgid "Reset Zoom" +msgstr "" + +#: editor/code_editor.cpp +msgid "Warnings" +msgstr "" + +#: editor/code_editor.cpp +msgid "Line and column numbers." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Method in target node must be specified." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Method name must be a valid identifier." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "" +"Target method not found. Specify a valid method or attach a script to the " +"target node." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Connect to Node:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Connect to Script:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "From Signal:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Scene does not contain any script." +msgstr "" + +#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp +#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +msgid "Add" +msgstr "" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/editor_feature_profile.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp +msgid "Remove" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Add Extra Call Argument:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Extra Call Arguments:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Receiver Method:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Advanced" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Deferred" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "" +"Defers the signal, storing it in a queue and only firing it at idle time." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Oneshot" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Disconnects the signal after its first emission." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Cannot connect signal" +msgstr "" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/export_template_manager.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Close" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Connect" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Connect '%s' to '%s'" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Disconnect '%s' from '%s'" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Disconnect all from signal: '%s'" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Connect..." +msgstr "" + +#: editor/connections_dialog.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Disconnect" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Connect a Signal to a Method" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Edit Connection:" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from the \"%s\" signal?" +msgstr "" + +#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp +msgid "Signals" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Filter signals" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from this signal?" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Disconnect All" +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Edit..." +msgstr "" + +#: editor/connections_dialog.cpp +msgid "Go To Method" +msgstr "" + +#: editor/create_dialog.cpp +msgid "Change %s Type" +msgstr "" + +#: editor/create_dialog.cpp editor/project_settings_editor.cpp +msgid "Change" +msgstr "" + +#: editor/create_dialog.cpp +msgid "Create New %s" +msgstr "" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp +msgid "Favorites:" +msgstr "" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +msgid "Recent:" +msgstr "" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search:" +msgstr "" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Matches:" +msgstr "" + +#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp +#: editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Description:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Search Replacement For:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Dependencies For:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "" +"Scene '%s' is currently being edited.\n" +"Changes will only take effect when reloaded." +msgstr "" + +#: editor/dependency_editor.cpp +msgid "" +"Resource '%s' is in use.\n" +"Changes will only take effect when reloaded." +msgstr "" + +#: editor/dependency_editor.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dependencies" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Resource" +msgstr "" + +#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp +#: editor/project_manager.cpp editor/project_settings_editor.cpp +msgid "Path" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Dependencies:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Fix Broken" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Dependency Editor" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Search Replacement Resource:" +msgstr "" + +#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +#: scene/gui/file_dialog.cpp +msgid "Open" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Owners Of:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "" +"Remove selected files from the project? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" + +#: editor/dependency_editor.cpp +msgid "" +"The files being removed are required by other resources in order for them to " +"work.\n" +"Remove them anyway? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Cannot remove:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Error loading:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Load failed due to missing dependencies:" +msgstr "" + +#: editor/dependency_editor.cpp editor/editor_node.cpp +msgid "Open Anyway" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Which action should be taken?" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Fix Dependencies" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Errors loading!" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Permanently delete %d item(s)? (No undo!)" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Show Dependencies" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Orphan Resource Explorer" +msgstr "" + +#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp +msgid "Delete" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Owns" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Resources Without Explicit Ownership:" +msgstr "" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Key" +msgstr "" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Value" +msgstr "" + +#: editor/editor_about.cpp +msgid "Thanks from the Godot community!" +msgstr "" + +#: editor/editor_about.cpp +msgid "Godot Engine contributors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Project Founders" +msgstr "" + +#: editor/editor_about.cpp +msgid "Lead Developer" +msgstr "" + +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. +#: editor/editor_about.cpp +msgid "Project Manager " +msgstr "" + +#: editor/editor_about.cpp +msgid "Developers" +msgstr "" + +#: editor/editor_about.cpp +msgid "Authors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Platinum Sponsors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Gold Sponsors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Silver Sponsors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Bronze Sponsors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Mini Sponsors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Gold Donors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Silver Donors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Bronze Donors" +msgstr "" + +#: editor/editor_about.cpp +msgid "Donors" +msgstr "" + +#: editor/editor_about.cpp +msgid "License" +msgstr "" + +#: editor/editor_about.cpp +msgid "Third-party Licenses" +msgstr "" + +#: editor/editor_about.cpp +msgid "" +"Godot Engine relies on a number of third-party free and open source " +"libraries, all compatible with the terms of its MIT license. The following " +"is an exhaustive list of all such third-party components with their " +"respective copyright statements and license terms." +msgstr "" + +#: editor/editor_about.cpp +msgid "All Components" +msgstr "" + +#: editor/editor_about.cpp +msgid "Components" +msgstr "" + +#: editor/editor_about.cpp +msgid "Licenses" +msgstr "" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Error opening package file, not in ZIP format." +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "%s (Already Exists)" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "Uncompressing Assets" +msgstr "" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "The following files failed extraction from package:" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "And %s more files." +msgstr "" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Package installed successfully!" +msgstr "" + +#: editor/editor_asset_installer.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Success!" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "Package Contents:" +msgstr "" + +#: editor/editor_asset_installer.cpp editor/editor_node.cpp +msgid "Install" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "Package Installer" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Speakers" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Rename Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Change Audio Bus Volume" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Solo" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Mute" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Bypass Effects" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Select Audio Bus Send" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Move Bus Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Delete Bus Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Drag & drop to rearrange." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Solo" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Mute" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Bypass" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Bus options" +msgstr "" + +#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Duplicate" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Reset Volume" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Delete Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Audio" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Master bus can't be deleted!" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Delete Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Duplicate Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Reset Bus Volume" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Move Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Save Audio Bus Layout As..." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Location for New Layout..." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Open Audio Bus Layout" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "There is no '%s' file." +msgstr "" + +#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp +msgid "Layout" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Invalid file, not an audio bus layout." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Error saving file: %s" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add a new Audio Bus to this layout." +msgstr "" + +#: editor/editor_audio_buses.cpp editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Load" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Load an existing Bus Layout." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Save As" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Save this Bus Layout to a file." +msgstr "" + +#: editor/editor_audio_buses.cpp editor/import_dock.cpp +msgid "Load Default" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Load the default Bus Layout." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Create a new Bus Layout." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Invalid name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Valid characters:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing engine class name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing built-in type name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing global constant name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Keyword cannot be used as an autoload name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Autoload '%s' already exists!" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Rename Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Toggle AutoLoad Globals" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Move Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Remove Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp +msgid "Enable" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Rearrange Autoloads" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Can't add autoload:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Add AutoLoad" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp +msgid "Path:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Node Name:" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp +#: editor/editor_profiler.cpp editor/project_manager.cpp +#: editor/settings_config_dialog.cpp +msgid "Name" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Singleton" +msgstr "" + +#: editor/editor_data.cpp editor/inspector_dock.cpp +msgid "Paste Params" +msgstr "" + +#: editor/editor_data.cpp +msgid "Updating Scene" +msgstr "" + +#: editor/editor_data.cpp +msgid "Storing local changes..." +msgstr "" + +#: editor/editor_data.cpp +msgid "Updating scene..." +msgstr "" + +#: editor/editor_data.cpp editor/editor_properties.cpp +msgid "[empty]" +msgstr "" + +#: editor/editor_data.cpp +msgid "[unsaved]" +msgstr "" + +#: editor/editor_dir_dialog.cpp +msgid "Please select a base directory first." +msgstr "" + +#: editor/editor_dir_dialog.cpp +msgid "Choose a Directory" +msgstr "" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +#: scene/gui/file_dialog.cpp +msgid "Create Folder" +msgstr "" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp +#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp +msgid "Name:" +msgstr "" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp +msgid "Could not create folder." +msgstr "" + +#: editor/editor_dir_dialog.cpp +msgid "Choose" +msgstr "" + +#: editor/editor_export.cpp +msgid "Storing File:" +msgstr "" + +#: editor/editor_export.cpp +msgid "No export template found at the expected path:" +msgstr "" + +#: editor/editor_export.cpp +msgid "Packing" +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " +"Etc' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' texture compression for GLES3. Enable " +"'Import Etc 2' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for GLES2. Enable " +"'Import Pvrtc' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " +"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom debug template not found." +msgstr "" + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom release template not found." +msgstr "" + +#: editor/editor_export.cpp platform/javascript/export/export.cpp +msgid "Template file not found:" +msgstr "" + +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "3D Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Script Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Asset Library" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Scene Tree Editing" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Node Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "FileSystem Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Import Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Erase profile '%s'? (no undo)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Profile must be a valid filename and must not contain '.'" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Profile with this name already exists." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled, Properties Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Properties Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Class Options:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enable Contextual Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Properties:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Features:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Classes:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "File '%s' format is invalid, import aborted." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "" +"Profile '%s' already exists. Remove it first before importing, import " +"aborted." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Error saving profile to path: '%s'." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Unset" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Current Profile:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Make Current" +msgstr "" + +#: editor/editor_feature_profile.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "New" +msgstr "" + +#: editor/editor_feature_profile.cpp editor/editor_node.cpp +#: editor/project_manager.cpp +msgid "Import" +msgstr "" + +#: editor/editor_feature_profile.cpp editor/project_export.cpp +msgid "Export" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Available Profiles:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Class Options" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "New profile name:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Erase Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Godot Feature Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Import Profile(s)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Export Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Manage Editor Feature Profiles" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select Current Folder" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File Exists, Overwrite?" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select This Folder" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Copy Path" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Open in File Manager" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +msgid "Show in File Manager" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "New Folder..." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/find_in_files.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Refresh" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Recognized" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Files (*)" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open File(s)" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a Directory" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File or Directory" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/editor_properties.cpp editor/inspector_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp +msgid "Save" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Save a File" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Back" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Forward" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Up" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Hidden Files" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Favorite" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Mode" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Focus Path" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Up" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Down" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go to previous folder." +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go to next folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Go to parent folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Refresh files." +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "(Un)favorite current folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Toggle the visibility of hidden files." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a grid of thumbnails." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a list." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Directories & Files:" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp +#: editor/plugins/style_box_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Preview:" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File:" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "ScanSources" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "" +"There are multiple importers for different types pointing to file %s, import " +"aborted" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "(Re)Importing Assets" +msgstr "" + +#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp +msgid "Top" +msgstr "" + +#: editor/editor_help.cpp +msgid "Class:" +msgstr "" + +#: editor/editor_help.cpp editor/scene_tree_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Inherits:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Inherited by:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Description" +msgstr "" + +#: editor/editor_help.cpp +msgid "Online Tutorials" +msgstr "" + +#: editor/editor_help.cpp +msgid "Properties" +msgstr "" + +#: editor/editor_help.cpp +msgid "override:" +msgstr "" + +#: editor/editor_help.cpp +msgid "default:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Methods" +msgstr "" + +#: editor/editor_help.cpp +msgid "Theme Properties" +msgstr "" + +#: editor/editor_help.cpp +msgid "Enumerations" +msgstr "" + +#: editor/editor_help.cpp +msgid "Constants" +msgstr "" + +#: editor/editor_help.cpp +msgid "Property Descriptions" +msgstr "" + +#: editor/editor_help.cpp +msgid "(value)" +msgstr "" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this property. Please help us by " +"[color=$color][url=$url]contributing one[/url][/color]!" +msgstr "" + +#: editor/editor_help.cpp +msgid "Method Descriptions" +msgstr "" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this method. Please help us by [color=" +"$color][url=$url]contributing one[/url][/color]!" +msgstr "" + +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Help" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Case Sensitive" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Show Hierarchy" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Display All" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Classes Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Methods Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Signals Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Constants Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Properties Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Theme Properties Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Member Type" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Class" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Method" +msgstr "" + +#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp +msgid "Signal" +msgstr "" + +#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp +msgid "Constant" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Property" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Theme Property" +msgstr "" + +#: editor/editor_inspector.cpp editor/project_settings_editor.cpp +msgid "Property:" +msgstr "" + +#: editor/editor_inspector.cpp +msgid "Set" +msgstr "" + +#: editor/editor_inspector.cpp +msgid "Set Multiple:" +msgstr "" + +#: editor/editor_log.cpp +msgid "Output:" +msgstr "" + +#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Copy Selection" +msgstr "" + +#: editor/editor_log.cpp editor/editor_network_profiler.cpp +#: editor/editor_profiler.cpp editor/editor_properties.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/property_editor.cpp editor/scene_tree_dock.cpp +#: editor/script_editor_debugger.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Clear" +msgstr "" + +#: editor/editor_log.cpp +msgid "Clear Output" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +#: editor/editor_profiler.cpp +msgid "Stop" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp +#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp +msgid "Start" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "%s/s" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Down" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Up" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +msgid "Node" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RPC" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RSET" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RPC" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RSET" +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "New Window" +msgstr "" + +#: editor/editor_node.cpp +msgid "Imported resources can't be saved." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: scene/gui/dialogs.cpp +msgid "OK" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Error saving resource!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource can't be saved because it does not belong to the edited scene. " +"Make it unique first." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Save Resource As..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't open file for writing:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Requested file format unknown:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while saving." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Can't open '%s'. The file could have been moved or deleted." +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while parsing '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unexpected end of file '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Missing '%s' or its dependencies." +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while loading '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Saving Scene" +msgstr "Зачувување на Ñцената" + +#: editor/editor_node.cpp +msgid "Analyzing" +msgstr "" + +#: editor/editor_node.cpp +msgid "Creating Thumbnail" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a tree root." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This scene can't be saved because there is a cyclic instancing inclusion.\n" +"Please resolve it and then attempt to save again." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " +"be satisfied." +msgstr "" + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "Can't overwrite scene that is still open!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load MeshLibrary for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving MeshLibrary!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load TileSet for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving TileSet!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"An error occurred while trying to save the editor layout.\n" +"Make sure the editor's user data path is writable." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Default editor layout overridden.\n" +"To restore the Default layout to its base settings, use the Delete Layout " +"option and delete the Default layout." +msgstr "" + +#: editor/editor_node.cpp +msgid "Layout name not found!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Restored the Default layout to its base settings." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was imported, so it's not editable.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was instanced or inherited.\n" +"Changes to it won't be kept when saving the current scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource was imported, so it's not editable. Change its settings in the " +"import panel and then re-import." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This scene was imported, so changes to it won't be kept.\n" +"Instancing it or inheriting will allow making changes to it.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This is a remote object, so changes to it won't be kept.\n" +"Please read the documentation relevant to debugging to better understand " +"this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "There is no defined scene to run." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Could not start subprocess!" +msgstr "" + +#: editor/editor_node.cpp editor/filesystem_dock.cpp +msgid "Open Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Base Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open Script..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save & Close" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes to '%s' before closing?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Saved %s modified resource(s)." +msgstr "" + +#: editor/editor_node.cpp +msgid "A root node is required to save the scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Scene As..." +msgstr "" + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "This operation can't be done without a scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Mesh Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a root node." +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Tile Set" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a selected node." +msgstr "" + +#: editor/editor_node.cpp +msgid "Current scene not saved. Open anyway?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't reload a scene that was never saved." +msgstr "" + +#: editor/editor_node.cpp +msgid "Reload Saved Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The current scene has unsaved changes.\n" +"Reload the saved scene anyway? This action cannot be undone." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Run Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quit" +msgstr "" + +#: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp +msgid "Exit the editor?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Manager?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save & Quit" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes to the following scene(s) before quitting?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes the following scene(s) before opening Project Manager?" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This option is deprecated. Situations where refresh must be forced are now " +"considered a bug. Please report." +msgstr "" + +#: editor/editor_node.cpp +msgid "Pick a Main Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Reopen Closed Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to enable addon plugin at: '%s' parsing of config failed." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' There seems to be an error in " +"the code, please check the syntax." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' Base type is not EditorPlugin." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s' Script is not in tool mode." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Scene '%s' was automatically imported, so it can't be modified.\n" +"To make changes to it, a new inherited scene can be created." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Error loading scene, it must be inside the project path. Use 'Import' to " +"open the scene, then save it inside the project path." +msgstr "" + +#: editor/editor_node.cpp +msgid "Scene '%s' has broken dependencies:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Clear Recent Scenes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"No main scene has ever been defined, select one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' does not exist, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' is not a scene file, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Layout" +msgstr "" + +#: editor/editor_node.cpp +msgid "Delete Layout" +msgstr "" + +#: editor/editor_node.cpp editor/import_dock.cpp +#: editor/script_create_dialog.cpp +msgid "Default" +msgstr "" + +#: editor/editor_node.cpp editor/editor_properties.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp +msgid "Show in FileSystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play This Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Undo Close Tab" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Close Other Tabs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Tabs to the Right" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close All Tabs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Switch Scene Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files or folders" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more folders" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files" +msgstr "" + +#: editor/editor_node.cpp +msgid "Dock Position" +msgstr "" + +#: editor/editor_node.cpp +msgid "Distraction Free Mode" +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle distraction-free mode." +msgstr "" + +#: editor/editor_node.cpp +msgid "Add a new scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Go to previously opened scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Copy Text" +msgstr "" + +#: editor/editor_node.cpp +msgid "Next tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Previous tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Filter Files..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Operations with scene files." +msgstr "" + +#: editor/editor_node.cpp +msgid "New Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "New Inherited Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Scene..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Open Recent" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save All Scenes" +msgstr "" + +#: editor/editor_node.cpp +msgid "Convert To..." +msgstr "" + +#: editor/editor_node.cpp +msgid "MeshLibrary..." +msgstr "" + +#: editor/editor_node.cpp +msgid "TileSet..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Undo" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Redo" +msgstr "" + +#: editor/editor_node.cpp +msgid "Miscellaneous project or scene-wide tools." +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +#: editor/script_create_dialog.cpp +msgid "Project" +msgstr "" + +#: editor/editor_node.cpp +msgid "Project Settings..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Set Up Version Control" +msgstr "" + +#: editor/editor_node.cpp +msgid "Shut Down Version Control" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Install Android Build Template..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Data Folder" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp +msgid "Tools" +msgstr "" + +#: editor/editor_node.cpp +msgid "Orphan Resource Explorer..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quit to Project List" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/project_export.cpp +msgid "Debug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Deploy with Remote Debug" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy will make the executable " +"attempt to connect to this computer's IP so the running project can be " +"debugged.\n" +"This option is intended to be used for remote debugging (typically with a " +"mobile device).\n" +"You don't need to enable it to use the GDScript debugger locally." +msgstr "" + +#: editor/editor_node.cpp +msgid "Small Deploy with Network Filesystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy for Android will only " +"export an executable without the project data.\n" +"The filesystem will be provided from the project by the editor over the " +"network.\n" +"On Android, deploying will use the USB cable for faster performance. This " +"option speeds up testing for projects with large assets." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Collision Shapes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, collision shapes and raycast nodes (for 2D and " +"3D) will be visible in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Navigation" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, navigation meshes and polygons will be visible " +"in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Scene Changes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any changes made to the scene in the editor " +"will be replicated in the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Script Changes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any script that is saved will be reloaded in " +"the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" + +#: editor/editor_node.cpp editor/script_create_dialog.cpp +msgid "Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Editor Settings..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Editor Layout" +msgstr "" + +#: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle Fullscreen" +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Data/Settings Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Data Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Settings Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Editor Features..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Export Templates..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp +msgid "Help" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Online Docs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Q&A" +msgstr "" + +#: editor/editor_node.cpp +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp +msgid "Community" +msgstr "" + +#: editor/editor_node.cpp +msgid "About" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play the project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play" +msgstr "" + +#: editor/editor_node.cpp +msgid "Pause the scene execution for debugging." +msgstr "" + +#: editor/editor_node.cpp +msgid "Pause Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Stop the scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play the edited scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play custom scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play Custom Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Changing the video driver requires restarting the editor." +msgstr "" + +#: editor/editor_node.cpp editor/project_settings_editor.cpp +#: editor/settings_config_dialog.cpp +msgid "Save & Restart" +msgstr "" + +#: editor/editor_node.cpp +msgid "Spins when the editor window redraws." +msgstr "" + +#: editor/editor_node.cpp +msgid "Update Continuously" +msgstr "" + +#: editor/editor_node.cpp +msgid "Update When Changed" +msgstr "" + +#: editor/editor_node.cpp +msgid "Hide Update Spinner" +msgstr "" + +#: editor/editor_node.cpp +msgid "FileSystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "Inspector" +msgstr "" + +#: editor/editor_node.cpp +msgid "Expand Bottom Panel" +msgstr "" + +#: editor/editor_node.cpp +msgid "Output" +msgstr "" + +#: editor/editor_node.cpp +msgid "Don't Save" +msgstr "" + +#: editor/editor_node.cpp +msgid "Android build template is missing, please install relevant templates." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Templates" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This will set up your project for custom Android builds by installing the " +"source template to \"res://android/build\".\n" +"You can then apply modifications and build your own custom APK on export " +"(adding modules, changing the AndroidManifest.xml, etc.).\n" +"Note that in order to make custom builds instead of using pre-built APKs, " +"the \"Use Custom Build\" option should be enabled in the Android export " +"preset." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The Android build template is already installed in this project and it won't " +"be overwritten.\n" +"Remove the \"res://android/build\" directory manually before attempting this " +"operation again." +msgstr "" + +#: editor/editor_node.cpp +msgid "Import Templates From ZIP File" +msgstr "" + +#: editor/editor_node.cpp +msgid "Template Package" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "Merge With Existing" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open & Run a Script" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp +msgid "New Inherited" +msgstr "" + +#: editor/editor_node.cpp +msgid "Load Errors" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Select" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open 2D Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open 3D Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Script Editor" +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "Open Asset Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open the next Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open the previous Editor" +msgstr "" + +#: editor/editor_node.h +msgid "Warning!" +msgstr "" + +#: editor/editor_path.cpp +msgid "No sub-resources found." +msgstr "" + +#: editor/editor_plugin.cpp +msgid "Creating Mesh Previews" +msgstr "" + +#: editor/editor_plugin.cpp +msgid "Thumbnail..." +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Main Script:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Edit Plugin" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Installed Plugins:" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Update" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Version:" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Author:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Status:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Edit:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Measure:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame Time (sec)" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Average Time (sec)" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame %" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Physics Frame %" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Inclusive" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Self" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame #:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Time" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Calls" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Edit Text:" +msgstr "" + +#: editor/editor_properties.cpp editor/script_create_dialog.cpp +msgid "On" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Layer" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Bit %d, value %d" +msgstr "" + +#: editor/editor_properties.cpp +msgid "[Empty]" +msgstr "" + +#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp +msgid "Assign..." +msgstr "" + +#: editor/editor_properties.cpp +msgid "Invalid RID" +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"The selected resource (%s) does not match any type expected for this " +"property (%s)." +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on resources saved as a file.\n" +"Resource needs to belong to a scene." +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on this resource because it's not set as " +"local to scene.\n" +"Please switch on the 'local to scene' property on it (and all resources " +"containing it up to a node)." +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Pick a Viewport" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New Script" +msgstr "" + +#: editor/editor_properties.cpp editor/scene_tree_dock.cpp +msgid "Extend Script" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New %s" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Make Unique" +msgstr "" + +#: editor/editor_properties.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Paste" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Convert To %s" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Selected node is not a Viewport!" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Size: " +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Page: " +msgstr "" + +#: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "New Key:" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "New Value:" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Add Key/Value Pair" +msgstr "" + +#: editor/editor_run_native.cpp +msgid "" +"No runnable export preset found for this platform.\n" +"Please add a runnable preset in the Export menu or define an existing preset " +"as runnable." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Write your logic in the _run() method." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "There is an edited scene already." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Couldn't instance script:" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Did you forget the 'tool' keyword?" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Couldn't run script:" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Did you forget the '_run' method?" +msgstr "" + +#: editor/editor_spin_slider.cpp +msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Select Node(s) to Import" +msgstr "" + +#: editor/editor_sub_scene.cpp editor/project_manager.cpp +msgid "Browse" +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Scene Path:" +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Import From Node:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Redownload" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Uninstall" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Installed)" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Official export templates aren't available for development builds." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Missing)" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Current)" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Retrieving mirrors, please wait..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove template version '%s'?" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't open export templates zip." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Invalid version.txt format inside templates: %s." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "No version.txt found inside templates." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error creating path for templates:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Extracting Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Importing:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error getting the list of mirrors." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error parsing JSON of mirror list. Please report this issue!" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"No download links found for this version. Direct download is only available " +"for official releases." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Request Failed." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Redirect Loop." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Complete." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Cannot remove temporary file:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"Templates installation failed.\n" +"The problematic templates archives can be found at '%s'." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error requesting URL:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connecting to Mirror..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Disconnected" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Resolving" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't Resolve" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connecting..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't Connect" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connected" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Requesting..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Downloading" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connection Error" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "SSL Handshake Error" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Uncompressing Android Build Sources" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Current Version:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Installed Versions:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Install From File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove Template" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select Template File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Godot Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Export Template Manager" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select mirror from list: (Shift+Click: Open in Browser)" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Status: Import of file failed. Please fix file and reimport manually." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move/rename resources root." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move a folder into itself." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Error moving:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Error duplicating:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Unable to update dependencies:" +msgstr "" + +#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp +msgid "No name provided." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Provided name contains invalid characters." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "A file or folder with this name already exists." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Name contains invalid characters." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"The following files or folders conflict with items in the target location " +"'%s':\n" +"\n" +"%s\n" +"\n" +"Do you wish to overwrite them?" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Renaming file:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Renaming folder:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicating file:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicating folder:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Inherited Scene" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Set As Main Scene" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Open Scenes" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Instance" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Add to Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Remove from Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Edit Dependencies..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "View Owners..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move To..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Scene..." +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "New Script..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Resource..." +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Expand All" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Collapse All" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicate..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move to Trash" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Rename..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Previous Folder/File" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Next Folder/File" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Re-Scan Filesystem" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Toggle Split Mode" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Search files" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"Scanning Files,\n" +"Please Wait..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move" +msgstr "" + +#: editor/filesystem_dock.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/project_manager.cpp editor/rename_dialog.cpp +#: editor/scene_tree_dock.cpp +msgid "Rename" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Overwrite" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Create Scene" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "Create Script" +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +msgid "Find in Files" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Find:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Folder:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Filters:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "" +"Include the files with the following extensions. Add or remove them in " +"ProjectSettings." +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find..." +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp +msgid "Replace..." +msgstr "" + +#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp +msgid "Cancel" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Find: " +msgstr "" + +#: editor/find_in_files.cpp +msgid "Replace: " +msgstr "" + +#: editor/find_in_files.cpp +msgid "Replace all (no undo)" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Searching..." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d match in %d file." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d matches in %d file." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d matches in %d files." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Add to Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Remove from Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Group name already exists." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Invalid group name." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Rename Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Delete Group" +msgstr "" + +#: editor/groups_editor.cpp editor/node_dock.cpp +msgid "Groups" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Nodes Not in Group" +msgstr "" + +#: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp +msgid "Filter nodes" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Nodes in Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Empty groups will be automatically removed." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Group Editor" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Manage Groups" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Single Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes+Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Importing Scene..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating Lightmaps" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating for Mesh: " +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Running Custom Script..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Couldn't load post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Invalid/broken script for post-import (check console):" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Error running post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Did you return a Node-derived object in the `post_import()` method?" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Saving..." +msgstr "" + +#: editor/import_dock.cpp +msgid "%d Files" +msgstr "" + +#: editor/import_dock.cpp +msgid "Set as Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Clear Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Import As:" +msgstr "" + +#: editor/import_dock.cpp +msgid "Preset" +msgstr "" + +#: editor/import_dock.cpp +msgid "Reimport" +msgstr "" + +#: editor/import_dock.cpp +msgid "Save Scenes, Re-Import, and Restart" +msgstr "" + +#: editor/import_dock.cpp +msgid "Changing the type of an imported file requires editor restart." +msgstr "" + +#: editor/import_dock.cpp +msgid "" +"WARNING: Assets exist that use this resource, they may stop loading properly." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Failed to load resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Expand All Properties" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Collapse All Properties" +msgstr "" + +#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Save As..." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Params" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Edit Resource Clipboard" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Resource" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Built-In" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Sub-Resources Unique" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Open in Help" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Create a new resource in memory and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Load an existing resource from disk and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Save the currently edited resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the previous edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the next edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "History of recently edited objects." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Object properties." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Filter properties" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Changes may be lost!" +msgstr "" + +#: editor/multi_node_edit.cpp +msgid "MultiNode Set" +msgstr "" + +#: editor/node_dock.cpp +msgid "Select a single node to edit its signals and groups." +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Edit a Plugin" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Create a Plugin" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Plugin Name:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Subfolder:" +msgstr "" + +#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp +msgid "Language:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Script Name:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Activate now?" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create points." +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "" +"Edit points.\n" +"LMB: Move Point\n" +"RMB: Erase Point" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Erase points." +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Insert Point" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon (Remove Point)" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Remove Polygon And Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Animation" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Load..." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Move Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "This type of node can't be used. Only root nodes are allowed." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Animation Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Remove BlendSpace1D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Move BlendSpace1D Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"AnimationTree is inactive.\n" +"Activate to enable playback, check node warnings if activation fails." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Set the blending position within the space" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Select and move points, create points with RMB." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp +msgid "Enable snap and show grid." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Open Editor" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Open Animation Node" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Triangle already exists." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "BlendSpace2D does not belong to an AnimationTree node." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "No triangles exist, so no blending can take place." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Toggle Auto Triangles" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create triangles by connecting points." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Erase points and triangles." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Generate blend triangles automatically (instead of manually)" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Parameter Changed" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Filters" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Output node can't be added to the blend tree." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Add Node to BlendTree" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Node Moved" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Unable to connect, port may be in use or connection may be invalid." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Connected" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Disconnected" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Set Animation" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Node" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/scene_tree_dock.cpp +msgid "Delete Node(s)" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Toggle Filter On/Off" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Change Filter" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "No animation player set, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Player path set is invalid, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "" +"Animation player has no valid root node path, so unable to retrieve track " +"names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Anim Clips" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Audio Clips" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Functions" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Renamed" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node..." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Edit Filtered Tracks:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Enable Filtering" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Toggle Autoplay" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Anim" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Animation?" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Remove Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Invalid animation name!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation name already exists!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Rename Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Next Changed" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Blend Time" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Load Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Duplicate Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to copy!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation resource on clipboard!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pasted Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Paste Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to edit!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from current pos. (A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from end. (Shift+A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Stop animation playback. (S)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from start. (Shift+D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from current pos. (D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation position (in seconds)." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Scale animation playback globally for the node." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Tools" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Edit Transitions..." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Open in Inspector" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Display list of animations in player." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Autoplay on Load" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Enable Onion Skinning" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Onion Skinning Options" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Directions" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Past" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Future" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Depth" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "1 step" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "2 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "3 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Differences Only" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Force White Modulate" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Include Gizmos (3D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pin AnimationPlayer" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Create New Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +msgid "Error!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Times:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Next (Auto Queue):" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Cross-Animation Blend Times" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Move Node" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition exists!" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Add Transition" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "End" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Immediate" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Sync" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "At End" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Travel" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Start and end nodes are needed for a sub-transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "No playback resource set at path: %s." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Removed" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition Removed" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set Start Node (Autoplay)" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"Select and move nodes.\n" +"RMB to add new nodes.\n" +"Shift+LMB to create connections." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Create new nodes." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Connect nodes." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Remove selected node or transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Toggle autoplay this animation on start, restart or seek to zero." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set the end animation. This is useful for sub-transitions." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition: " +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Play Mode:" +msgstr "" + +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "AnimationTree" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "New name:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Scale:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade In (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade Out (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Auto Restart:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Random Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Start!" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Amount:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 0:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 1:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "X-Fade Time (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Current:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Clear Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Set Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Delete Input" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is valid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is invalid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "OneShot Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend2 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend3 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend4 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeScale Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeSeek Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Transition Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Import Animations..." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Node Filters" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Filters..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Contents:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "View Files" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connection error, please try again." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect to host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response from host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve hostname:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, return code:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Cannot save response to:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Write error." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, too many redirects" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Redirect loop." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, timeout" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Timeout." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Bad download hash, assuming file has been tampered with." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Expected:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Got:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed SHA-256 hash check" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Asset Download Error:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading (%s / %s)..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Resolving..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Error making request" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Idle" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Install..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Retry" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download Error" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download for this asset is already in progress!" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Least Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (A-Z)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (Z-A)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (A-Z)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (Z-A)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "First" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Previous" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Next" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Last" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "All" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No results for \"%s\"." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Import..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Plugins..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp +msgid "Sort:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/project_settings_editor.cpp +msgid "Category:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Site:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Support" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Official" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Testing" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Loading..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Assets ZIP File" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Can't determine a save path for lightmap images.\n" +"Save your scene and try again." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " +"Light' flag is on." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed creating lightmap images, make sure path is writable." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Bake Lightmaps" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + +#: editor/plugins/camera_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Preview" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Configure Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Primary Line Every:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "steps" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal and Vertical Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate CanvasItem \"%s\" to %d degrees" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Node2D \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Resize Control \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale CanvasItem \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Children of containers have their anchors and margins values overridden by " +"their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Presets for the anchors and margins values of a Control node." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"When active, moving Control nodes changes their anchors instead of their " +"margins." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Top" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Bottom" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Left Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Right Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "VCenter Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "HCenter Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Full Rect" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Keep Ratio" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Anchors only" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors and Margins" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"Overrides game camera with editor viewport camera." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"No game instance running." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Group Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Ungroup Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Paste Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Warning: Children of a container get their position and size determined only " +"by their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Reset" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Select Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Drag: Rotate" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+Drag: Move" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Move Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Show a list of all objects at the position clicked\n" +"(same as Alt+RMB in select mode)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Click to change object's rotation pivot." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Ruler Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle smart snapping." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Smart Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle grid snapping." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Grid Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snapping Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Rotation Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Scale Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap Relative" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Pixel Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Smart Snapping" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Configure Snap..." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Parent" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Sides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Center" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Other Nodes" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock the selected object in place (can't be moved)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock the selected object (can be moved)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Makes sure the object's children are not selectable." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Restores the object's children's ability to be selected." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Skeleton Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Custom Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Always Show Grid" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Helpers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Rulers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Origin" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Viewport" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Group And Lock Icons" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Frame Selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Preview Canvas Scale" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Translation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert keys (based on mask)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Auto insert keys when objects are translated, rotated or scaled (based on " +"mask).\n" +"Keys are only added to existing tracks, no new tracks will be created.\n" +"Keys must be inserted manually for the first time." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Auto Insert Key" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Animation Key and Pose Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key (Existing Tracks)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Copy Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Multiply grid step by 2" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Divide grid step by 2" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Add %s" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Adding %s..." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Cannot instantiate multiple nodes without root." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Create Node" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Error instancing scene from %s" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Default Type" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Drag & drop + Shift : Add node as sibling\n" +"Drag & drop + Alt : Change node type" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Create Polygon3D" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly (Remove Point)" +msgstr "" + +#: editor/plugins/collision_shape_2d_editor_plugin.cpp +msgid "Set Handle" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Load Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Clear Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Particles" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generated Point Count:" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Solid Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Directed Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Capture from Pixel" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Colors" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +msgid "CPUParticles" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Mesh" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Node" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 0" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 1" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease In" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease Out" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Smoothstep" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Curve Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Add Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Left Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Toggle Curve Linear Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Hold Shift to edit tangents individually" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right click to add point" +msgstr "" + +#: editor/plugins/gi_probe_editor_plugin.cpp +msgid "Bake GI Probe" +msgstr "" + +#: editor/plugins/gradient_editor_plugin.cpp +msgid "Gradient Edited" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item %d" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Items" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item List Editor" +msgstr "" + +#: editor/plugins/light_occluder_2d_editor_plugin.cpp +msgid "Create Occluder Polygon" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh is empty!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a Trimesh collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Static Trimesh Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "This doesn't work on scene root!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create a single convex collision shape for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a single convex collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create multiple convex collision shapes for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create any collision shapes." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Shapes" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Navigation Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Contained Mesh is not of type ArrayMesh." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Unwrap failed, mesh may not be manifold?" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "No mesh to debug." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Model has no UV in this layer" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "MeshInstance lacks a Mesh!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh has not surface to create outlines from!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Could not create outline!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a StaticBody and assigns a polygon-based collision shape to it " +"automatically.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a single convex collision shape.\n" +"This is the fastest (but least accurate) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Collision Siblings" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is a performance middle-ground between the two above options." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh..." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a static outline mesh. The outline mesh will have its normals " +"flipped automatically.\n" +"This can be used instead of the SpatialMaterial Grow property when using " +"that property isn't possible." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV1" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV2" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Unwrap UV2 for Lightmap/AO" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Outline Size:" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Channel Debug" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove item %d?" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "" +"Update from existing scene?:\n" +"%s" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Mesh Library" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove Selected Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import from Scene" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Update from Scene" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and no MultiMesh set in node)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and MultiMesh contains no Mesh)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (not a MeshInstance)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (contains no Mesh resource)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No surface source specified." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no geometry)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no faces)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate Surface" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate MultiMesh" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "X-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Y-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Z-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh Up Axis:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Rotation:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Tilt:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Scale:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate" +msgstr "" + +#: editor/plugins/navigation_polygon_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Navigation Polygon" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Convert to CPUParticles" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generating Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generate Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Can only set point into a ParticlesMaterial process material" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generation Time (sec):" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry's faces don't contain any area." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry doesn't contain any faces." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't inherit from Spatial." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain face geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emitter" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Points:" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points+Normal (Directed)" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Volume" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Source: " +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "A processor material of type 'ParticlesMaterial' is required." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generating AABB" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generate Visibility AABB" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Point from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Out-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove In-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point to Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Split Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Point in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move In-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Out-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Select Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Shift+Drag: Select Control Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Click: Add Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Left Click: Split Segment (in curve)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Right Click: Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Select Control Points (Shift+Drag)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point (in empty space)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Close Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp +msgid "Options" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Angles" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Lengths" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Curve Point #" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Point Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve In Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Out Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Path" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Path Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Out-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove In-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Segment (in curve)" +msgstr "" + +#: editor/plugins/physical_bone_plugin.cpp +msgid "Move Joint" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"The skeleton property of the Polygon2D does not point to a Skeleton2D node" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"No texture in this polygon.\n" +"Set a texture to be able to edit UV." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create UV Map" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Polygon 2D has internal vertices, so it can no longer be edited in the " +"viewport." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon & UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Invalid Polygon (need 3 different vertices)" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Add Custom Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Custom Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform UV Map" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint Bone Weights" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Open Polygon 2D UV editor." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygon 2D UV Editor" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Points" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygons" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Points" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Command: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift: Move All" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Command: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Ctrl: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Ctrl: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Rotate Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Scale Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create a custom polygon. Enables custom polygon rendering." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Remove a custom polygon. If none remain, custom polygon rendering is " +"disabled." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Unpaint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Radius:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy Polygon to UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy UV to Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Clear UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Settings" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Snap" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Enable Snap" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Show Grid" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Configure Grid:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones to Polygon" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ERROR: Couldn't load resource!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Add Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Rename Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Resource clipboard is empty!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Paste Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Load Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ResourcePreloader" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "AnimationTree has no path set to an AnimationPlayer" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Path to AnimationPlayer is invalid" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Files" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close and save changes?" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error writing TextFile:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Could not load file at:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving file!" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Saving" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error importing theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Importing" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "New Text File..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open File" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save File As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Can't obtain the script for running." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script failed reloading, check console for errors." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script is not in tool mode, will not be able to run." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"To run this script, it must inherit EditorScript and be set to tool mode." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "%s Class Reference" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Toggle alphabetical sorting of the method list." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Sort" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Up" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Down" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Next script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Previous script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "File" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reopen Closed Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save All" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Soft Reload Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Copy Script Path" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reload Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close All" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close Docs" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +msgid "Run" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Into" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Over" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Break" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +#: editor/script_editor_debugger.cpp +msgid "Continue" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Keep Debugger Open" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Debug with External Editor" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open Godot online documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search the reference documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to previous edited document." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to next edited document." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Discard" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Debugger" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Results" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Scripts" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Connections to method:" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp +msgid "Source" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Target" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "" +"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "[Ignore]" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Only resources from filesystem can be dropped." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't drop nodes because script '%s' is not used in this scene." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Lookup Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Pick Color" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Convert Case" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Uppercase" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Lowercase" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Capitalize" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Syntax Highlighter" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Bookmarks" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Cut" +msgstr "" + +#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Delete Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Left" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Right" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Comment" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold/Unfold Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold All Lines" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Unfold All Lines" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Complete Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Evaluate Selection" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Trim Trailing Whitespace" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Spaces" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Tabs" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Auto Indent" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Find in Files..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Contextual Help" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Bookmarks" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Line..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Toggle Breakpoint" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Breakpoint" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Breakpoint" +msgstr "" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "" +"This shader has been modified on on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "Shader" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "This skeleton has no bones, create some children Bone2D nodes." +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Create Rest Pose from Bones" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Rest Pose to Bones" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Skeleton2D" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Make Rest Pose (From Bones)" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Bones to Rest Pose" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical bones" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Skeleton" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical skeleton" +msgstr "" + +#: editor/plugins/skeleton_ik_editor_plugin.cpp +msgid "Play IK" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Orthogonal" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Aborted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "X-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Y-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Z-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Plane Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scaling: " +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translating: " +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotating %s degrees." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Keying is disabled (no key inserted)." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Animation Key Inserted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pitch" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Yaw" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Objects Drawn" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Material Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Shader Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Surface Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Draw Calls" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Vertices" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Transform with View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Rotation with View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "No parent to instance a child at." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "This operation requires a single selected node." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock View Rotation" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Normal" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Wireframe" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Overdraw" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Unshaded" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Environment" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Information" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View FPS" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Half Resolution" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Audio Listener" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Enable Doppler" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Cinematic Preview" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Not available when using the GLES2 renderer." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Forward" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Backwards" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Up" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Down" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Speed Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Slow Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "XForm Dialog" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Click to toggle between visibility states.\n" +"\n" +"Open eye: Gizmo is visible.\n" +"Closed eye: Gizmo is hidden.\n" +"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Nodes To Floor" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Couldn't find a solid floor to snap the selection to." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Drag: Rotate\n" +"Alt+Drag: Move\n" +"Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Local Space" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Snap" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Switch Perspective/Orthogonal View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Insert Animation Key" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Toggle Freelook" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Object to Floor" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Dialog..." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "1 Viewport" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports (Alt)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports (Alt)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "4 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Grid" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Settings..." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Settings" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate Snap:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Snap (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Snap (%):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Viewport Settings" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective FOV (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Near:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Far:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Change" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale (ratio):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Type" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pre" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Post" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Nameless gizmo" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Mesh2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Polygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Polygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "CollisionPolygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "LightOccluder2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite is empty!" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Can't convert a sprite using animation frames to mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't replace by mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Polygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create collision polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create light occluder." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Simplification: " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Shrink (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Grow (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Update Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Settings:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "No Frames Selected" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add %d Frame(s)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Unable to load images" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "ERROR: Couldn't load frame resource!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Resource clipboard is empty or not a texture!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Paste Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Empty" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation FPS" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "(empty)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animations:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "New Animation" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Speed:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Loop" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animation Frames:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add a Texture from File" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frames from a Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Horizontal:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Vertical:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select/Clear All Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Create Frames from Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "SpriteFrames" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Region Rect" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Margin" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Snap Mode:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +#: scene/resources/visual_shader.cpp +msgid "None" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Pixel Snap" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Grid Snap" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Auto Slice" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Offset:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Step:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Sep.:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "TextureRegion" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp +msgid "Remove All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Edit Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme editing menu." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Editor Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create From Current Editor Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Toggle Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Check Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Named Sep." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Submenu" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Many" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled LineEdit" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 3" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Editable Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subtree" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has,Many,Options" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Data Type:" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Style" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Font" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Color" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme File" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Fix Invalid Tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cut Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Line Draw" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Bucket Fill" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Find Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Transpose" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Disable Autotile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Enable Priority" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Filter tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Give a TileSet resource to this TileMap to use its tiles." +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Command+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Ctrl+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Pick Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Left" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Right" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Horizontally" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Vertically" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Clear Transform" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Add Texture(s) to TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected Texture from TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Single Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Autotile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Atlas" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Next Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the next shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Previous Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the previous shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Copy bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Erase bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new rectangle." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Rectangle" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete Selected Shape" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Keep polygon inside region Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Enable snap and show grid (configurable via the Inspector)." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Display Tile Names (Hold Alt Key)" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Add or select a texture on the left panel to edit the tiles bound to it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected texture? This will remove all tiles which use it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "You haven't selected a texture to remove." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from scene? This will overwrite all current tiles." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from scene?" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Texture" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "%s file(s) were not added because was already on the list." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Drag handles to edit Rect.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete selected Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select current edited sub-tile.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"LMB: Set bit on.\n" +"RMB: Set bit off.\n" +"Shift+LMB: Set wildcard bit.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to use as icon, this will be also used on invalid autotile " +"bindings.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its priority.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its z index.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Icon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Clear Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "This property can't be changed." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "TileSet" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No VCS addons are available." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Error" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No files added to stage" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "VCS Addon is not initialized" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control System" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Initialize" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Staging area" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage Selected" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage All" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Status" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View file diffs before committing them to the latest version" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No file diff is active" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect changes in file diff" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(GLES3 only)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Output" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sampler" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set expression" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Resize VisualShader node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Uniform Name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Input Default Port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node to Visual Shader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Node(s) Moved" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Duplicate Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Input Type Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "UniformRef Name Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vertex" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Fragment" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Light" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Show resulted shader code." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Create Shader Node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Grayscale function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts HSV vector to RGB equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts RGB vector to HSV equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sepia function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Burn operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Darken operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Difference operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Dodge operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "HardLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Lighten operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Overlay operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Screen operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "SoftLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the %s comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Equal (==)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than (>)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than or Equal (>=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided scalars are equal, greater or " +"less." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between NaN and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than (<)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than or Equal (<=)" +msgstr "Помалку или еднакво (<=)" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Not Equal (!=)" +msgstr "Ðееднакво" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated scalar if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF (or NaN) and a " +"scalar parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for all shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Input parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for light shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "E constant (2.718282). Represents the base of the natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Epsilon constant (0.00001). Smallest possible scalar number." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Phi constant (1.618034). Golden ratio." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/4 constant (0.785398) or 45 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/2 constant (1.570796) or 90 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi constant (3.141593) or 180 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Tau constant (6.283185) or 360 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sqrt2 constant (1.414214). Square root of 2." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the absolute value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Finds the nearest integer that is greater than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Constrains a value to lie between two further values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in radians to degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-e Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer less than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Computes the fractional part of the argument." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse of the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the greater of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the lesser of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the opposite value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the value of the first parameter raised to the power of the second." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in degrees to radians." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest even integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Clamps the value between 0.0 and 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Extracts the sign of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the truncated value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds scalar to scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts scalar from scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the cubic texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Cubic texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup with triplanar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Calculate the outer product of a pair of vectors.\n" +"\n" +"OuterProduct treats the first parameter 'c' as a column vector (matrix with " +"one column) and the second parameter 'r' as a row vector (matrix with one " +"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix " +"whose number of rows is the number of components in 'c' and whose number of " +"columns is the number of components in 'r'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes transform from four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes transform to four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the determinant of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the inverse of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the transpose of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies transform by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes vector from three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes vector to three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the cross product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the distance between two points." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the dot product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the same direction as a reference vector. " +"The function has three vector parameters : N, the vector to orient, I, the " +"incident vector, and Nref, the reference vector. If the dot product of I and " +"Nref is smaller than zero the return value is N. Otherwise -N is returned." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the length of a vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors using scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the normalize product of vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the direction of reflection ( a : incident " +"vector, b : normal vector )." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the vector that points in the direction of refraction." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( vector(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds vector to vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts vector from vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, with custom amount of input and " +"output ports. This is a direct injection of code into the vertex/fragment/" +"light function, do not use it to write the function declarations inside." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns falloff based on the dot product of surface normal and view " +"direction of camera (pass associated inputs to it)." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, which is placed on top of the " +"resulted shader. You can place various function definitions inside and call " +"it later in the Expressions. You can also declare varyings, uniforms and " +"constants." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "A reference to an existing uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Scalar derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Vector derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "VisualShader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Edit Visual Property" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Mode Changed" +msgstr "" + +#: editor/project_export.cpp +msgid "Runnable" +msgstr "" + +#: editor/project_export.cpp +msgid "Delete preset '%s'?" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"Export templates seem to be missing or invalid." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"This might be due to a configuration issue in the export preset or your " +"export settings." +msgstr "" + +#: editor/project_export.cpp +msgid "Release" +msgstr "" + +#: editor/project_export.cpp +msgid "Exporting All" +msgstr "" + +#: editor/project_export.cpp +msgid "The given export path doesn't exist:" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing/corrupted:" +msgstr "" + +#: editor/project_export.cpp +msgid "Presets" +msgstr "" + +#: editor/project_export.cpp editor/project_settings_editor.cpp +msgid "Add..." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"If checked, the preset will be available for use in one-click deploy.\n" +"Only one preset per platform may be marked as runnable." +msgstr "" + +#: editor/project_export.cpp +msgid "Export Path" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources" +msgstr "" + +#: editor/project_export.cpp +msgid "Export all resources in the project" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected scenes (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected resources (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources to export:" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to export non-resource files/folders\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to exclude files/folders from project\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "Features" +msgstr "" + +#: editor/project_export.cpp +msgid "Custom (comma-separated):" +msgstr "" + +#: editor/project_export.cpp +msgid "Feature List:" +msgstr "" + +#: editor/project_export.cpp +msgid "Script" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Text" +msgstr "" + +#: editor/project_export.cpp +msgid "Compiled" +msgstr "" + +#: editor/project_export.cpp +msgid "Encrypted (Provide Key Below)" +msgstr "" + +#: editor/project_export.cpp +msgid "Invalid Encryption Key (must be 64 characters long)" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Encryption Key (256-bits as hex):" +msgstr "" + +#: editor/project_export.cpp +msgid "Export PCK/Zip" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Project" +msgstr "" + +#: editor/project_export.cpp +msgid "Export mode?" +msgstr "" + +#: editor/project_export.cpp +msgid "Export All" +msgstr "" + +#: editor/project_export.cpp editor/project_manager.cpp +msgid "ZIP File" +msgstr "" + +#: editor/project_export.cpp +msgid "Godot Game Pack" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing:" +msgstr "" + +#: editor/project_export.cpp +msgid "Manage Export Templates" +msgstr "" + +#: editor/project_export.cpp +msgid "Export With Debug" +msgstr "" + +#: editor/project_manager.cpp +msgid "The path specified doesn't exist." +msgstr "" + +#: editor/project_manager.cpp +msgid "Error opening package file (it's not in ZIP format)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose an empty folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose a \"project.godot\" or \".zip\" file." +msgstr "" + +#: editor/project_manager.cpp +msgid "This directory already contains a Godot project." +msgstr "" + +#: editor/project_manager.cpp +msgid "New Game Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Imported Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Invalid Project Name." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't create folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "There is already a folder in this path with the specified name." +msgstr "" + +#: editor/project_manager.cpp +msgid "It would be a good idea to name your project." +msgstr "" + +#: editor/project_manager.cpp +msgid "Invalid project path (changed anything?)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't edit project.godot in project path." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't create project.godot in project path." +msgstr "" + +#: editor/project_manager.cpp +msgid "Rename Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Import Existing Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Import & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Create New Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Create & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Install Project:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Install & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Name:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Path:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Installation Path:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer:" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 3.0" +msgstr "" + +#: editor/project_manager.cpp +msgid "Not supported by your GPU drivers." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Higher visual quality\n" +"All features available\n" +"Incompatible with older hardware\n" +"Not recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 2.0" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Lower visual quality\n" +"Some features not available\n" +"Works on most hardware\n" +"Recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer can be changed later, but scenes may need to be adjusted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Unnamed Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Missing Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Error: Project is missing on the filesystem." +msgstr "" + +#: editor/project_manager.cpp +msgid "Can't open project at '%s'." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to open more than one project?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file does not specify the version of Godot " +"through which it was created.\n" +"\n" +"%s\n" +"\n" +"If you proceed with opening it, it will be converted to Godot's current " +"configuration file format.\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file was generated by an older engine " +"version, and needs to be converted for this version:\n" +"\n" +"%s\n" +"\n" +"Do you want to convert it?\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The project settings were created by a newer engine version, whose settings " +"are not compatible with this version." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Can't run project: no main scene defined.\n" +"Please edit the project and set the main scene in the Project Settings under " +"the \"Application\" category." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Can't run project: Assets need to be imported.\n" +"Please edit the project to trigger the initial import." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to run %d projects at once?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove %d projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove this project from the list?\n" +"The project folder's contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove all missing projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Language changed.\n" +"The interface will update after restarting the editor or project manager." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Are you sure to scan %s folders for existing Godot projects?\n" +"This could take a while." +msgstr "" + +#. TRANSLATORS: This refers to the application where users manage their Godot projects. +#: editor/project_manager.cpp +msgid "Project Manager" +msgstr "" + +#: editor/project_manager.cpp +msgid "Projects" +msgstr "" + +#: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp +msgid "Last Modified" +msgstr "" + +#: editor/project_manager.cpp +msgid "Scan" +msgstr "" + +#: editor/project_manager.cpp +msgid "Select a Folder to Scan" +msgstr "" + +#: editor/project_manager.cpp +msgid "New Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Remove Missing" +msgstr "" + +#: editor/project_manager.cpp +msgid "Templates" +msgstr "" + +#: editor/project_manager.cpp +msgid "Restart Now" +msgstr "" + +#: editor/project_manager.cpp +msgid "Can't run project" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"You currently don't have any projects.\n" +"Would you like to explore official example projects in the Asset Library?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Key " +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joy Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joy Axis" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "An action with the name '%s' already exists." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Rename Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Action deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "All Devices" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device" +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Press a Key..." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Left Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Right Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Middle Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Left Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Right Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "X Button 1" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "X Button 2" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joypad Axis Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Axis" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joypad Button Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Left Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Right Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Middle Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Global Property" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Select a setting item first!" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "No property '%s' exists." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Setting '%s' is internal, and it can't be deleted." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Delete Item" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Error saving settings." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Settings saved OK." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Moved Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Override for Feature" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Translation" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Translation" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Remapped Path" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resource Remap Add Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Resource Remap Language" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap Option" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter Mode" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Project Settings (project.godot)" +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "General" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Override For..." +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "The editor must be restarted for changes to take effect." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Input Map" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Action:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Localization" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Translations" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Translations:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remaps" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resources:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remaps by Locale:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locale" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locales Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Show All Locales" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Show Selected Locales Only" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Filter mode:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locales:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "AutoLoad" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Plugins" +msgstr "" + +#: editor/property_editor.cpp +msgid "Preset..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Zero" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing In-Out" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing Out-In" +msgstr "" + +#: editor/property_editor.cpp +msgid "File..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Dir..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Assign" +msgstr "" + +#: editor/property_editor.cpp +msgid "Select Node" +msgstr "" + +#: editor/property_editor.cpp +msgid "Error loading file: Not a resource!" +msgstr "" + +#: editor/property_editor.cpp +msgid "Pick a Node" +msgstr "" + +#: editor/property_editor.cpp +msgid "Bit %d, val %d." +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Property" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Virtual Method" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Method" +msgstr "" + +#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp +msgid "Batch Rename" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Replace:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Prefix:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Suffix:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Use Regular Expressions" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Advanced Options" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Substitute" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node's parent name, if available" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node type" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Current scene name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Root node name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Sequential integer counter.\n" +"Compare counter options." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Per-level Counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "If set, the counter restarts for each group of child nodes." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Initial value for the counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Step" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Amount by which counter is incremented for each node" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Padding" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Minimum number of digits for the counter.\n" +"Missing digits are padded with leading zeros." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Post-Process" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Keep" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "PascalCase to snake_case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "snake_case to PascalCase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Lowercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Uppercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Reset" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Regular Expression Error:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "At character %s" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent Node" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Reparent Location (Select new Parent):" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Keep Global Transform" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Run Mode:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Current Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene Arguments:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Scene Run Settings" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "No parent to instance the scenes at." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error loading scene from %s" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot instance the scene '%s' because the current scene exists within one " +"of its nodes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Scene(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Replace with Branch Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Child Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on the tree root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Node In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Nodes In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Duplicate Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Node must belong to the edited scene to become root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instantiated scenes can't become root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make node as Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes and any children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete the root node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\" and its children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can not perform with the root node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on instanced scenes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Save New Scene As..." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Disabling \"editable_instance\" will cause all properties of the node to be " +"reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and " +"cause all properties of the node to be reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "New Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Create Root Node:" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "2D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "3D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "User Interface" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Other Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes from a foreign scene!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes the current scene inherits from!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remove Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change type of node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Couldn't save new scene. Likely dependencies (instances) couldn't be " +"satisfied." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error saving scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error duplicating scene to save it." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Sub-Resources" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Editable Children" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Load As Placeholder" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Open Documentation" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot attach a script: there are no languages registered.\n" +"This is probably because this editor was built with all language modules " +"disabled." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add Child Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change Type" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Reparent to New Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Merge From Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Save Branch as Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Copy Node Path" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete (No Confirm)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add/Create a New Node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Instance a scene file as a Node. Creates an inherited scene if no root node " +"exists." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach a new or existing script to the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach the script from the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remote" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance? (No Undo!)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visible" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Unlock Node" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Button Group" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "(Connecting From)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node configuration warning:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s) and %s group(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is in %s group(s).\n" +"Click to show groups dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Open Script:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is locked.\n" +"Click to unlock it." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Children are not selectable.\n" +"Click to make selectable." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visibility" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"AnimationPlayer is pinned.\n" +"Click to unpin." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Invalid node name, the following characters are not allowed:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Rename Node" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Scene Tree (Nodes):" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node Configuration Warning!" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Select a Node" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Path is empty." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Filename is empty." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Path is not local." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid base path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "A directory with the same name exists." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "File does not exist." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid extension." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Wrong extension chosen." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error loading template '%s'" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error - Could not create script in filesystem." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error loading script from %s" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Overrides" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "N/A" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Open Script / Choose Location" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Open Script" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "File exists, it will be reused." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid class name." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid inherited parent name or path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Script path/name is valid." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Allowed: a-z, A-Z, 0-9, _ and ." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Built-in script (into scene file)." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Will create a new script file." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Will load an existing script file." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Script file already exists." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Class Name:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Template:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Built-in Script:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Attach Node Script" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Remote " +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Bytes:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Warning:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Error:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Source:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Trace" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Errors" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Child process connected." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Copy Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Video RAM" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Skip Breakpoints" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Previous Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Next Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Frames" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Profiler" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Network Profiler" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Monitor" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Value" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Monitors" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Pick one or more items from the list to display the graph." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "List of Video Memory Usage by Resource:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Total:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Resource Path" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Type" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Format" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Usage" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Misc" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control Type:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Live Edit Root:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Set From Tree" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export measures as CSV" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Erase Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Restore Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Change Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Editor Settings" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Shortcuts" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Binding" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Light Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change AudioStreamPlayer3D Emission Angle" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera FOV" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera Size" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Notifier AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Particles AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Probe Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Sphere Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Box Shape Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Ray Shape Length" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Height" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Inner Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Outer Radius" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select the dynamic library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select dependencies of the library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Remove current entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Double click to create a new entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform:" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dynamic Library" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Add an architecture entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "GDNativeLibrary" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Enabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Disabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Library" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Libraries: " +msgstr "Библиотеки: " + +#: modules/gdnative/register_types.cpp +msgid "GDNative" +msgstr "GDNative(ГДДомороден)" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Step argument is zero!" +msgstr "Корак аргумент е нула!" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not a script with an instance" +msgstr "Ðе е Ñкрипта Ñо инÑтанца" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a script" +msgstr "Ðе е оÑновано на Ñкрипта" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a resource file" +msgstr "Ðе е оÑновано на реÑÑƒÑ€Ñ Ñ„Ð°Ñ˜Ð»" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (missing @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (can't load script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (invalid script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary (invalid subclasses)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Object can't provide a length." +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Delete Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paste Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paint" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Disabled" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Above" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Below" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit X Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Y Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Z Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Clear Rotation" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Paste Selects" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clear Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Settings" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Pick Distance:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Filter meshes" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Give a MeshLibrary resource to this GridMap to use its meshes." +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + +#: modules/mono/csharp_script.cpp +msgid "Class name can't be a reserved keyword" +msgstr "" + +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Bake NavMesh" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Clear the navigation mesh." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Setting up Configuration..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Calculating grid size..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Marking walkable triangles..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Constructing compact heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Eroding walkable area..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Partitioning..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating contours..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating polymesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Converting to native navigation mesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Navigation Mesh Generator Setup:" +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Parsing Geometry..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Done!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"A node yielded without working memory, please read the docs on how to yield " +"properly!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Node yielded, but did not return a function state in the first working " +"memory." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Return value must be assigned to first element of node working memory! Fix " +"your node please." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Node returned an invalid sequence output: " +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Found sequence bit but not the node in the stack, report bug!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Stack overflow with stack depth: " +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Signal Arguments" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Default Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Override an existing built-in function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Variables:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new variable." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Signals:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new signal." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name is not a valid identifier:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name already in use by another func/var/signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete input port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Expression" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Duplicate VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Preload Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node(s) From Tree" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "" +"Can't drop properties because script '%s' is not used in this scene.\n" +"Drop holding 'Shift' to just copy the signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Getter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Setter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Move Node(s)" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Disconnect Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Data" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Sequence" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Script already has function '%s'" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Input Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Resize Comment" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't copy the function node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Clipboard is empty!" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function with a function node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function of nodes from nodes of multiple functions." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select at least one node with sequence port." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Try to only have one sequence input in selection." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Variable:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Tool:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Members:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Nodes..." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function..." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "function_name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select or create a function to edit its graph." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete Selected" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Find Node Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Copy Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Cut Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Refresh Graph" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit Member" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Input type not iterable: " +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid: " +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name." +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Base object is not a Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Path does not lead Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name '%s' in node %s." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid argument of type: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid arguments: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableGet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableSet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Custom node has no _step() method, can't process graph." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "" +"Invalid return value from _step(), must be integer (seq out), or string " +"(error)." +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search VisualScript" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Set %s" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package name is missing." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package segments must be of non-zero length." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' is not allowed in Android application package names." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A digit cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The package must have at least one '.' separator." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Select device from the list" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find the 'apksigner' tool." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Debug keystore not configured in the Editor Settings nor in the preset." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Release keystore incorrectly configured in the export preset." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid Android SDK path in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'platform-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid public key for APK expansion." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid package name:" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" " +"project setting (changed in Godot 3.2.2).\n" +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Use Custom Build\" must be enabled to use the plugins." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR" +"\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android App Bundle requires the *.aab extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "APK Expansion not compatible with Android App Bundle." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android APK requires the *.apk extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Trying to build from a custom built template, but no version info for it " +"exists. Please reinstall from the 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build version mismatch:\n" +" Template installed: %s\n" +" Godot Version: %s\n" +"Please reinstall Android build template from 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Building Android Project (gradle)" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Building of Android project failed, check output for the error.\n" +"Alternatively visit docs.godotengine.org for Android build documentation." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Moving output" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Unable to copy and rename export file, check gradle project directory for " +"outputs." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Identifier is missing." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "The character '%s' is not allowed in Identifier." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "App Store Team ID not specified - cannot configure the project." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Invalid Identifier:" +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Required icon is not specified in the preset." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Stop HTTP Server" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run in Browser" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run exported HTML in the system's default browser." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not write file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not open template for export:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Invalid export template:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read custom HTML shell:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read boot splash image file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Using default boot splash image." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package short name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package unique name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package publisher display name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid product GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid publisher GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid background color." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid Store Logo image dimensions (should be 50x50)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid splash screen image dimensions (should be 620x300)." +msgstr "" + +#: scene/2d/animated_sprite.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite to display frames." +msgstr "" + +#: scene/2d/canvas_modulate.cpp +msgid "" +"Only one visible CanvasModulate is allowed per scene (or set of instanced " +"scenes). The first created one will work, while the rest will be ignored." +msgstr "" + +#: scene/2d/collision_object_2d.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " +"define its shape." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "" +"CollisionPolygon2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "An empty CollisionPolygon2D has no effect on collision." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"CollisionShape2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"A shape must be provided for CollisionShape2D to function. Please create a " +"shape resource for it!" +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"Polygon-based shapes are not meant be used nor edited directly through the " +"CollisionShape2D node. Please use the CollisionPolygon2D node instead." +msgstr "" + +#: scene/2d/cpu_particles_2d.cpp +msgid "" +"CPUParticles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be PhysicsBody2Ds" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A must be a PhysicsBody2D" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node B must be a PhysicsBody2D" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Joint is not connected to two PhysicsBody2Ds" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be different PhysicsBody2Ds" +msgstr "" + +#: scene/2d/light_2d.cpp +msgid "" +"A texture with the shape of the light must be supplied to the \"Texture\" " +"property." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "" +"An occluder polygon must be set (or drawn) for this occluder to take effect." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"A NavigationPolygon resource must be set or created for this node to work. " +"Please set a property or draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"NavigationPolygonInstance must be a child or grandchild to a Navigation2D " +"node. It only provides navigation data." +msgstr "" + +#: scene/2d/parallax_layer.cpp +msgid "" +"ParallaxLayer node only works when set as child of a ParallaxBackground node." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles2D node instead. You can use the \"Convert to " +"CPUParticles\" option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp scene/3d/particles.cpp +msgid "" +"A material to process the particles is not assigned, so no behavior is " +"imprinted." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"Particles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/path_2d.cpp +msgid "PathFollow2D only works when set as a child of a Path2D node." +msgstr "" + +#: scene/2d/physics_body_2d.cpp +msgid "" +"Size changes to RigidBody2D (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/2d/remote_transform_2d.cpp +msgid "Path property must point to a valid Node2D node to work." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "This Bone2D chain should end at a Skeleton2D node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "" +"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." +msgstr "" + +#: scene/2d/tile_map.cpp +msgid "" +"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes " +"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " +"KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/visibility_notifier_2d.cpp +msgid "" +"VisibilityEnabler2D works best when used with the edited scene root directly " +"as parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRCamera must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRController must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The controller ID must not be 0 or this controller won't be bound to an " +"actual controller." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRAnchor must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The anchor ID must not be 0 or this anchor won't be bound to an actual " +"anchor." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVROrigin requires an ARVRCamera child node." +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Finding meshes and lights" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing geometry (%d/%d)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing environment" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Generating capture" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Done" +msgstr "" + +#: scene/3d/collision_object.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape or CollisionPolygon as a child to define " +"its shape." +msgstr "" + +#: scene/3d/collision_polygon.cpp +msgid "" +"CollisionPolygon only serves to provide a collision shape to a " +"CollisionObject derived node. Please only use it as a child of Area, " +"StaticBody, RigidBody, KinematicBody, etc. to give them a shape." +msgstr "" + +#: scene/3d/collision_polygon.cpp +msgid "An empty CollisionPolygon has no effect on collision." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"CollisionShape only serves to provide a collision shape to a CollisionObject " +"derived node. Please only use it as a child of Area, StaticBody, RigidBody, " +"KinematicBody, etc. to give them a shape." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"A shape must be provided for CollisionShape to function. Please create a " +"shape resource for it." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"Plane shapes don't work well and will be removed in future versions. Please " +"don't use them." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"ConcavePolygonShape doesn't support RigidBody in another mode than static." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "Nothing is visible because no mesh has been assigned." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "" +"CPUParticles animation requires the usage of a SpatialMaterial whose " +"Billboard Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Plotting Meshes" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "" +"GIProbes are not supported by the GLES2 video driver.\n" +"Use a BakedLightmap instead." +msgstr "" + +#: scene/3d/interpolated_camera.cpp +msgid "" +"InterpolatedCamera has been deprecated and will be removed in Godot 4.0." +msgstr "" + +#: scene/3d/light.cpp +msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "A NavigationMesh resource must be set or created for this node to work." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "" +"NavigationMeshInstance must be a child or grandchild to a Navigation node. " +"It only provides navigation data." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" +"\" option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Nothing is visible because meshes have not been assigned to draw passes." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Particles animation requires the usage of a SpatialMaterial whose Billboard " +"Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/path.cpp +msgid "PathFollow only works when set as a child of a Path node." +msgstr "" + +#: scene/3d/path.cpp +msgid "" +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." +msgstr "" + +#: scene/3d/physics_body.cpp +msgid "" +"Size changes to RigidBody (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A must be a PhysicsBody" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node B must be a PhysicsBody" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Joint is not connected to any PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be different PhysicsBodies" +msgstr "" + +#: scene/3d/remote_transform.cpp +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "This body will be ignored until you set a mesh." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "" +"Size changes to SoftBody will be overridden by the physics engine when " +"running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/3d/sprite_3d.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite3D to display frames." +msgstr "" + +#: scene/3d/vehicle_body.cpp +msgid "" +"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " +"it as a child of a VehicleBody." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " +"this environment's Background Mode to Canvas (for 2D scenes)." +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "On BlendTree node '%s', animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "Animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "In node '%s', invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Nothing connected to input '%s' of node '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "No root AnimationNode for the graph is set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path to an AnimationPlayer node containing animations is not set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "The AnimationPlayer root node is not a valid node." +msgstr "" + +#: scene/animation/animation_tree_player.cpp +msgid "This node has been deprecated. Use AnimationTree instead." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "" +"Color: #%s\n" +"LMB: Set color\n" +"RMB: Remove preset" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Pick a color from the editor window." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Switch between hexadecimal and code values." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Add current color as a preset." +msgstr "" + +#: scene/gui/container.cpp +msgid "" +"Container by itself serves no purpose unless a script configures its " +"children placement behavior.\n" +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" + +#: scene/gui/control.cpp +msgid "" +"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to " +"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"." +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Alert!" +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Please Confirm..." +msgstr "" + +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + +#: scene/gui/graph_edit.cpp +msgid "Enable grid minimap." +msgstr "" + +#: scene/gui/popup.cpp +msgid "" +"Popups will hide by default unless you call popup() or any of the popup*() " +"functions. Making them visible for editing is fine, but they will hide upon " +"running." +msgstr "" + +#: scene/gui/range.cpp +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." +msgstr "" + +#: scene/gui/scroll_container.cpp +msgid "" +"ScrollContainer is intended to work with a single child control.\n" +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " +"minimum size manually." +msgstr "" + +#: scene/gui/tree.cpp +msgid "(Other)" +msgstr "" + +#: scene/main/scene_tree.cpp +msgid "" +"Default Environment as specified in Project Settings (Rendering -> " +"Environment -> Default Environment) could not be loaded." +msgstr "" + +#: scene/main/viewport.cpp +msgid "" +"This viewport is not set as render target. If you intend for it to display " +"its contents directly to the screen, make it a child of a Control so it can " +"obtain a size. Otherwise, make it a RenderTarget and assign its internal " +"texture to some node for display." +msgstr "" + +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for preview." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for shader." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid comparison function for that type." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to uniform." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Varyings can only be assigned in vertex function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Constants cannot be modified." +msgstr "КонÑтантите неможат да Ñе променат." diff --git a/editor/translations/ml.po b/editor/translations/ml.po index e3ed585a4a..71693f68dd 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -629,7 +629,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1890,10 +1890,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2299,6 +2295,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2342,18 +2342,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2401,6 +2389,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2443,7 +2435,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2833,14 +2825,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2994,6 +2978,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3196,7 +3196,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4827,7 +4827,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4962,8 +4962,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4977,9 +4976,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6036,6 +6054,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6096,10 +6118,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6681,6 +6699,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6732,16 +6758,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6834,8 +6850,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7056,6 +7072,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9577,6 +9597,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10180,6 +10204,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10300,6 +10332,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11084,6 +11120,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11580,11 +11644,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11596,11 +11662,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11608,9 +11674,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12001,27 +12077,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12081,6 +12157,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12294,6 +12374,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12339,6 +12423,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index e9a759c4d8..a07cd2a007 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -626,7 +626,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1887,10 +1887,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2294,6 +2290,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2337,18 +2337,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2396,6 +2384,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2438,7 +2430,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2828,14 +2820,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2989,6 +2973,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3191,7 +3191,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4819,7 +4819,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4954,8 +4954,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4969,9 +4968,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6027,6 +6045,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6087,10 +6109,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6672,6 +6690,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6723,16 +6749,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6825,8 +6841,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7047,6 +7063,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9568,6 +9588,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10171,6 +10195,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10291,6 +10323,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11075,6 +11111,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11570,11 +11634,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11586,11 +11652,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11598,9 +11664,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11991,27 +12067,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12071,6 +12147,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12284,6 +12364,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12329,6 +12413,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index f2f18b9a22..9019b6b0e4 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -8,12 +8,12 @@ # Nafis Ibrahim <thepreciousnafis@gmail.com>, 2018. # Muhammad Hazim bin Hafizalshah <muhammadhazimhafizalshah@gmail.com>, 2020. # keviinx <keviinx@yahoo.com>, 2020. -# Keviindran Ramachandran <keviinx@yahoo.com>, 2020. +# Keviindran Ramachandran <keviinx@yahoo.com>, 2020, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-02 09:52+0000\n" +"PO-Revision-Date: 2021-01-12 13:32+0000\n" "Last-Translator: Keviindran Ramachandran <keviinx@yahoo.com>\n" "Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/" "ms/>\n" @@ -22,7 +22,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.4.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -649,7 +649,7 @@ msgstr "Pilih Trek untuk Disalin" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Salin" @@ -1957,10 +1957,6 @@ msgstr "Pratonton:" msgid "File:" msgstr "Fail:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Mesti menggunakan sambungan yang sah." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Sumber Imbas" @@ -2323,6 +2319,8 @@ msgid "" "An error occurred while trying to save the editor layout.\n" "Make sure the editor's user data path is writable." msgstr "" +"Ralat berlaku semasa cubaan menyimpan susun atur editor.\n" +"Pastikan laluan data pengguna editor dapat ditulis." #: editor/editor_node.cpp msgid "" @@ -2330,6 +2328,9 @@ msgid "" "To restore the Default layout to its base settings, use the Delete Layout " "option and delete the Default layout." msgstr "" +"Susun atur editor lalai diganti.\n" +"Untuk mengembalikan susun atur Lalai ke tetapan asasnya, gunakan pilihan " +"Hapus Tata Letak dan hapus susun atur Lalai." #: editor/editor_node.cpp msgid "Layout name not found!" @@ -2394,6 +2395,10 @@ msgid "There is no defined scene to run." msgstr "Tiada adegan yang didefinisikan untuk dijalankan." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Tidak dapat memulakan subproses!" @@ -2437,18 +2442,6 @@ msgstr "Nod akar diperlukan untuk menyimpan adegan." msgid "Save Scene As..." msgstr "Simpan Adegan Sebagai..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Tidak" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ya" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Adegan ini tidak pernah disimpan. Simpan sebelum menjalankan?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Operasi ini tidak boleh dilakukan tanpa adegan." @@ -2499,6 +2492,10 @@ msgid "Quit" msgstr "Keluar" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ya" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Keluar dari editor?" @@ -2541,49 +2538,64 @@ msgstr "Buka Semula Adegan Tertutup" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" +"Tidak dapat mengaktifkan pemalam addon pada: penghuraian konfigurasi '%s' " +"gagal." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" +"Tidak dapat mencari medan skrip untuk pemalam addon di: 'res://addons/%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "" +msgstr "Tidak dapat memuatkan skrip addon dari laluan: '%s'." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' There seems to be an error in " "the code, please check the syntax." msgstr "" +"Tidak dapat memuat skrip addon dari laluan: '%s' Nampaknya terdapat ralat " +"dalam kod, sila periksa sintaksnya." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" +"Tidak dapat memuatkan skrip addon dari laluan: '%s' Jenis Asas bukan " +"EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" +"Tidak dapat memuat skrip addon dari laluan: Skrip '%s' tidak berada dalam " +"mod alat." #: editor/editor_node.cpp msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" +"Adegan '%s' diimport secara automatik, maka ia tidak dapat diubah.\n" +"Untuk membuat perubahan, pemandangan baru yang diwarisi dapat dibuat." #: editor/editor_node.cpp msgid "" "Error loading scene, it must be inside the project path. Use 'Import' to " "open the scene, then save it inside the project path." msgstr "" +"Ralat memuatkan adegan, ia mesti berada di dalam laluan projek. Gunakan " +"'Import' untuk membuka adegan, kemudian simpan di dalam laluan projek." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "" +msgstr "Adegan '%s' mengandungi kebergantungan yang pecah:" #: editor/editor_node.cpp +#, fuzzy msgid "Clear Recent Scenes" -msgstr "" +msgstr "Kosongkan Adegan Terbaru" #: editor/editor_node.cpp msgid "" @@ -2591,13 +2603,20 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Tiada adegan utama yang pernah didefinasikan, pilih satu?\n" +"Anda boleh mengubahnya kemudian dalam \"Tetapan Projek\" di bawah kategori " +"'aplikasi'." #: editor/editor_node.cpp +#, fuzzy msgid "" "Selected scene '%s' does not exist, select a valid one?\n" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Adegan terpilih '%s' tidak wujud, pilih satu yang sah?\n" +"Anda boleh mengubahnya kemudian dalam \"Tetapan Projek\" di bawah kategori " +"'aplikasi'." #: editor/editor_node.cpp msgid "" @@ -2605,88 +2624,106 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Adegan terpilih '%s' bukan fail adegan, pilih satu yang sah?\n" +"Anda boleh mengubahnya kemudian dalam \"Tetapan Projek\" di bawah kategori " +"'aplikasi'." #: editor/editor_node.cpp msgid "Save Layout" -msgstr "" +msgstr "Simpan Susun Atur" #: editor/editor_node.cpp msgid "Delete Layout" -msgstr "" +msgstr "Padam Susun Atur" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "" +msgstr "Lalai" #: editor/editor_node.cpp editor/editor_properties.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp msgid "Show in FileSystem" -msgstr "" +msgstr "Tunjukkan dalam FileSystem" #: editor/editor_node.cpp +#, fuzzy msgid "Play This Scene" -msgstr "" +msgstr "Mainkan Adegan Ini" #: editor/editor_node.cpp +#, fuzzy msgid "Close Tab" -msgstr "" +msgstr "Tutup Tab" #: editor/editor_node.cpp +#, fuzzy msgid "Undo Close Tab" -msgstr "" +msgstr "Buat Asal Tutup Tab" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Close Other Tabs" -msgstr "" +msgstr "Tutup Tab Lain" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Tutup Tab-tab ke Kanan" #: editor/editor_node.cpp +#, fuzzy msgid "Close All Tabs" -msgstr "" +msgstr "Tutup Semua Tab" #: editor/editor_node.cpp +#, fuzzy msgid "Switch Scene Tab" -msgstr "" +msgstr "Tukar Tab Adegan" #: editor/editor_node.cpp +#, fuzzy msgid "%d more files or folders" -msgstr "" +msgstr "%d lebih banyak fail atau folder" #: editor/editor_node.cpp +#, fuzzy msgid "%d more folders" -msgstr "" +msgstr "%d lebih banyak folder" #: editor/editor_node.cpp +#, fuzzy msgid "%d more files" -msgstr "" +msgstr "%d lebih banyak fail" #: editor/editor_node.cpp +#, fuzzy msgid "Dock Position" -msgstr "" +msgstr "Kedudukan Dok" #: editor/editor_node.cpp +#, fuzzy msgid "Distraction Free Mode" -msgstr "" +msgstr "Mod Bebas Gangguan" #: editor/editor_node.cpp +#, fuzzy msgid "Toggle distraction-free mode." -msgstr "" +msgstr "Togol mod bebas gangguan." #: editor/editor_node.cpp +#, fuzzy msgid "Add a new scene." -msgstr "" +msgstr "Tambah adegan baru." #: editor/editor_node.cpp +#, fuzzy msgid "Scene" -msgstr "" +msgstr "Adegan" #: editor/editor_node.cpp +#, fuzzy msgid "Go to previously opened scene." -msgstr "" +msgstr "Pergi ke adegan yang dibuka sebelum ini." #: editor/editor_node.cpp #, fuzzy @@ -2694,124 +2731,142 @@ msgid "Copy Text" msgstr "Semua Pilihan" #: editor/editor_node.cpp +#, fuzzy msgid "Next tab" -msgstr "" +msgstr "Tab seterusnya" #: editor/editor_node.cpp +#, fuzzy msgid "Previous tab" -msgstr "" +msgstr "Tab terdahulu" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "" +msgstr "Tapis Fail-fail..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "" +msgstr "Operasi dengan fail adegan." #: editor/editor_node.cpp +#, fuzzy msgid "New Scene" -msgstr "" +msgstr "Adegan Baru" #: editor/editor_node.cpp +#, fuzzy msgid "New Inherited Scene..." -msgstr "" +msgstr "Adegan Baru Diwarisi..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "" +msgstr "Buka Adegan..." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Open Recent" -msgstr "" +msgstr "Buka Terkini" #: editor/editor_node.cpp +#, fuzzy msgid "Save Scene" -msgstr "" +msgstr "Simpan Adegan" #: editor/editor_node.cpp +#, fuzzy msgid "Save All Scenes" -msgstr "" +msgstr "Simpan Semua Adegan" #: editor/editor_node.cpp +#, fuzzy msgid "Convert To..." -msgstr "" +msgstr "Tukar Kepada..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "PerpustakaanMesh..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "" +msgstr "SetJubin..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Undo" -msgstr "" +msgstr "Buat Asal" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#, fuzzy msgid "Redo" -msgstr "" +msgstr "Buat Semula" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "" +msgstr "Pelbagai projek atau alatan seluruh adegan." #: editor/editor_node.cpp editor/project_manager.cpp #: editor/script_create_dialog.cpp +#, fuzzy msgid "Project" -msgstr "" +msgstr "Projek" #: editor/editor_node.cpp msgid "Project Settings..." -msgstr "" +msgstr "Tetapan Projek..." #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Version Control" -msgstr "" +msgstr "Kawalan Versi" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +#, fuzzy msgid "Set Up Version Control" -msgstr "" +msgstr "Sediakan Kawalan Versi" #: editor/editor_node.cpp +#, fuzzy msgid "Shut Down Version Control" -msgstr "" +msgstr "Tutup Kawalan Versi" #: editor/editor_node.cpp +#, fuzzy msgid "Export..." -msgstr "" +msgstr "Eksport..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "Pasang Templat Binaan Android..." #: editor/editor_node.cpp +#, fuzzy msgid "Open Project Data Folder" -msgstr "" +msgstr "Buka Folder Data Projek" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" -msgstr "" +msgstr "Alatan" #: editor/editor_node.cpp msgid "Orphan Resource Explorer..." -msgstr "" +msgstr "Penjelajah Sumber Yatim..." #: editor/editor_node.cpp +#, fuzzy msgid "Quit to Project List" -msgstr "" +msgstr "Keluar ke Senarai Projek" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp +#, fuzzy msgid "Debug" -msgstr "" +msgstr "Nyahpepijat" #: editor/editor_node.cpp +#, fuzzy msgid "Deploy with Remote Debug" -msgstr "" +msgstr "Gunakan Nyahpepijat Jauh" #: editor/editor_node.cpp msgid "" @@ -2822,12 +2877,20 @@ msgid "" "mobile device).\n" "You don't need to enable it to use the GDScript debugger locally." msgstr "" +"Apabila pilihan ini diaktifkan, penggunaan satu klik akan membuat percubaan " +"yang dapat dilaksanakan untuk menyambung ke IP komputer ini sehingga projek " +"yang sedang berjalan dapat dinyahpepijat.\n" +"Pilihan ini bertujuan untuk digunakan untuk penyahpepijatan jauh (biasanya " +"dengan peranti mudah alih).\n" +"Anda tidak perlu mengaktifkannya untuk menggunakan debugger GDScript secara " +"tempatan." #: editor/editor_node.cpp msgid "Small Deploy with Network Filesystem" -msgstr "" +msgstr "Penggunaan Kecil dengan Sistem Fail Rangkaian" #: editor/editor_node.cpp +#, fuzzy msgid "" "When this option is enabled, using one-click deploy for Android will only " "export an executable without the project data.\n" @@ -2836,30 +2899,43 @@ msgid "" "On Android, deploying will use the USB cable for faster performance. This " "option speeds up testing for projects with large assets." msgstr "" +"Apabila pilihan ini diaktifkan, menggunakan satu klik untuk Android hanya " +"akan mengeksport yang dapat dilaksanakan tanpa data projek.\n" +"Sistem fail akan disediakan dari projek oleh editor melalui rangkaian.\n" +"Pada Android, penggunaan akan menggunakan kabel USB untuk prestasi yang " +"lebih pantas. Pilihan ini mempercepat pengujian untuk projek dengan aset " +"besar." #: editor/editor_node.cpp +#, fuzzy msgid "Visible Collision Shapes" -msgstr "" +msgstr "Bentuk Perlanggaran Yang Boleh Dilihat" #: editor/editor_node.cpp msgid "" "When this option is enabled, collision shapes and raycast nodes (for 2D and " "3D) will be visible in the running project." msgstr "" +"Apabila pilihan ini diaktifkan, bentuk perlanggaran dan nod raycast (untuk " +"2D dan 3D) akan dapat dilihat dalam projek yang sedang berjalan." #: editor/editor_node.cpp +#, fuzzy msgid "Visible Navigation" -msgstr "" +msgstr "Navigasi Yang Boleh Dilihat" #: editor/editor_node.cpp +#, fuzzy msgid "" "When this option is enabled, navigation meshes and polygons will be visible " "in the running project." msgstr "" +"Apabila pilihan ini diaktifkan, jejaring navigasi dan poligon akan kelihatan " +"dalam projek yang sedang berjalan." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" -msgstr "" +msgstr "Segerakkan Perubahan Adegan" #: editor/editor_node.cpp msgid "" @@ -2868,10 +2944,15 @@ msgid "" "When used remotely on a device, this is more efficient when the network " "filesystem option is enabled." msgstr "" +"Apabila pilihan ini diaktifkan, setiap perubahan yang dibuat ke adegan di " +"editor akan direplikasi dalam projek yang sedang berjalan.\n" +"Apabila digunakan dari jauh pada peranti, ini lebih efisien apabila pilihan " +"sistem fail rangkaian diaktifkan." #: editor/editor_node.cpp +#, fuzzy msgid "Synchronize Script Changes" -msgstr "" +msgstr "Segerakkan Perubahan Skrip" #: editor/editor_node.cpp msgid "" @@ -2880,10 +2961,15 @@ msgid "" "When used remotely on a device, this is more efficient when the network " "filesystem option is enabled." msgstr "" +"Apabila pilihan ini diaktifkan, skrip yang disimpan akan dimuat semula dalam " +"projek yang sedang berjalan.\n" +"Apabila digunakan dari jauh pada peranti, ini lebih efisien apabila pilihan " +"sistem fail rangkaian diaktifkan." #: editor/editor_node.cpp editor/script_create_dialog.cpp +#, fuzzy msgid "Editor" -msgstr "" +msgstr "Editor" #: editor/editor_node.cpp msgid "Editor Settings..." @@ -2891,72 +2977,71 @@ msgstr "Tetapan Editor..." #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "" +msgstr "Editor Susun Atur" #: editor/editor_node.cpp +#, fuzzy msgid "Take Screenshot" -msgstr "" +msgstr "Ambil Tangkapan Skrin" #: editor/editor_node.cpp msgid "Screenshots are stored in the Editor Data/Settings Folder." -msgstr "" +msgstr "Tangkapan skrin disimpan dalam Folder Data/Tetapan Editor." #: editor/editor_node.cpp +#, fuzzy msgid "Toggle Fullscreen" -msgstr "" +msgstr "Togol Skrin Penuh" #: editor/editor_node.cpp msgid "Toggle System Console" -msgstr "" +msgstr "Togol Konsol Sistem" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "" +msgstr "Buka Folder Data/Tetapan Editor" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "" +msgstr "Buka Folder Data Editor" #: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Settings Folder" -msgstr "" +msgstr "Buka Folder Tetapan Editor" #: editor/editor_node.cpp msgid "Manage Editor Features..." -msgstr "" +msgstr "Urus Ciri-ciri Penyunting..." #: editor/editor_node.cpp msgid "Manage Export Templates..." -msgstr "" +msgstr "Urus Templat-templat Eksport..." #: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp msgid "Help" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" +msgstr "Bantuan" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp +#, fuzzy msgid "Online Docs" -msgstr "" +msgstr "Dokumen Dalam Talian" #: editor/editor_node.cpp +#, fuzzy msgid "Q&A" -msgstr "" +msgstr "Soal Jawab" #: editor/editor_node.cpp +#, fuzzy msgid "Report a Bug" -msgstr "" +msgstr "Laporkan Pepijat" #: editor/editor_node.cpp +#, fuzzy msgid "Send Docs Feedback" -msgstr "" +msgstr "Hantar Maklum Balas Dokumen" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -2967,93 +3052,102 @@ msgid "About" msgstr "Tentang" #: editor/editor_node.cpp +#, fuzzy msgid "Play the project." -msgstr "" +msgstr "Main projek." #: editor/editor_node.cpp +#, fuzzy msgid "Play" -msgstr "" +msgstr "Main" #: editor/editor_node.cpp msgid "Pause the scene execution for debugging." -msgstr "" +msgstr "Jeda pelaksanaan adegan untuk nyahpepijat." #: editor/editor_node.cpp +#, fuzzy msgid "Pause Scene" -msgstr "" +msgstr "Jeda Adegan" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "" +msgstr "Hentikan adegan." #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "" +msgstr "Mainkan adegan yang diedit." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "" +msgstr "Main Adegan" #: editor/editor_node.cpp +#, fuzzy msgid "Play custom scene" -msgstr "" +msgstr "Main adegan tersuai" #: editor/editor_node.cpp +#, fuzzy msgid "Play Custom Scene" -msgstr "" +msgstr "Main Adegan Tersuai" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "Menukar pemacu video memerlukan editor dimulakan semula." #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp msgid "Save & Restart" -msgstr "" +msgstr "Simpan & Mula Semula" #: editor/editor_node.cpp msgid "Spins when the editor window redraws." -msgstr "" +msgstr "Berputar apabila tingkap editor dilukis semula." #: editor/editor_node.cpp msgid "Update Continuously" -msgstr "" +msgstr "Kemas Kini Secara Berterusan" #: editor/editor_node.cpp msgid "Update When Changed" -msgstr "" +msgstr "Kemas Kini Apabila Diubah" #: editor/editor_node.cpp +#, fuzzy msgid "Hide Update Spinner" -msgstr "" +msgstr "Sembunyi Spinner Kemas Kini" #: editor/editor_node.cpp msgid "FileSystem" -msgstr "" +msgstr "SistemFail" #: editor/editor_node.cpp +#, fuzzy msgid "Inspector" -msgstr "" +msgstr "Pemeriksa" #: editor/editor_node.cpp +#, fuzzy msgid "Expand Bottom Panel" -msgstr "" +msgstr "Kembangkan Panel Bawah" #: editor/editor_node.cpp msgid "Output" -msgstr "" +msgstr "Keluaran" #: editor/editor_node.cpp +#, fuzzy msgid "Don't Save" -msgstr "" +msgstr "Jangan Simpan" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "Templat binaan Android hilang, sila pasang templat yang berkaitan." #: editor/editor_node.cpp msgid "Manage Templates" -msgstr "" +msgstr "Urus Templat-templat" #: editor/editor_node.cpp msgid "" @@ -3065,6 +3159,14 @@ msgid "" "the \"Use Custom Build\" option should be enabled in the Android export " "preset." msgstr "" +"Ini akan menyiapkan projek anda untuk binaan Android khas dengan memasang " +"templat sumber pada \"res://android/build\".\n" +"Anda kemudian boleh menerapkan pengubahsuaian dan membina APK tersuai anda " +"sendiri pada eksport (menambah modul, menukar AndroidManifest.xml, dan lain-" +"lain).\n" +"Perhatikan bahawa untuk membuat binaan tersuai dan bukannya menggunakan APK " +"pra-dibina, pilihan \"Gunakan Bina Tersuai\" harus diaktifkan dalam pratetap " +"eksport Android." #: editor/editor_node.cpp msgid "" @@ -3073,191 +3175,251 @@ msgid "" "Remove the \"res://android/build\" directory manually before attempting this " "operation again." msgstr "" +"Templat binaan Android telah dipasang dalam projek ini dan ia tidak akan " +"ditimpa.\n" +"Keluarkan direktori \"res://android/build\" secara manual sebelum mencuba " +"operasi ini semula." #: editor/editor_node.cpp +#, fuzzy msgid "Import Templates From ZIP File" -msgstr "" +msgstr "Import Templat Dari Fail ZIP" #: editor/editor_node.cpp +#, fuzzy msgid "Template Package" -msgstr "" +msgstr "Pakej Templat" #: editor/editor_node.cpp +#, fuzzy msgid "Export Library" -msgstr "" +msgstr "Eksport Perpustakaan" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "" +msgstr "Gabung Dengan Sedia Ada" #: editor/editor_node.cpp +#, fuzzy msgid "Open & Run a Script" +msgstr "Buka & Jalankan Skrip" + +#: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "Fail berikut gagal diekstrak dari pakej:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" msgstr "" #: editor/editor_node.cpp +#, fuzzy msgid "New Inherited" -msgstr "" +msgstr "Baru Diwarisi" #: editor/editor_node.cpp msgid "Load Errors" -msgstr "" +msgstr "Muatkan Ralat-ralat" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +#, fuzzy msgid "Select" -msgstr "" +msgstr "Pilih" #: editor/editor_node.cpp +#, fuzzy msgid "Open 2D Editor" -msgstr "" +msgstr "Buka Editor 2D" #: editor/editor_node.cpp +#, fuzzy msgid "Open 3D Editor" -msgstr "" +msgstr "Buka Editor 3D" #: editor/editor_node.cpp +#, fuzzy msgid "Open Script Editor" -msgstr "" +msgstr "Buka Editor Skrip" #: editor/editor_node.cpp editor/project_manager.cpp +#, fuzzy msgid "Open Asset Library" -msgstr "" +msgstr "Buka Perpustakaan Aset" #: editor/editor_node.cpp +#, fuzzy msgid "Open the next Editor" -msgstr "" +msgstr "Buka Editor seterusnya" #: editor/editor_node.cpp +#, fuzzy msgid "Open the previous Editor" -msgstr "" +msgstr "Buka Editor terdahulu" #: editor/editor_node.h +#, fuzzy msgid "Warning!" -msgstr "" +msgstr "Amaran!" #: editor/editor_path.cpp msgid "No sub-resources found." -msgstr "" +msgstr "Tiada sub-sumber dijumpai." #: editor/editor_plugin.cpp +#, fuzzy msgid "Creating Mesh Previews" -msgstr "" +msgstr "Mencipta Pratonton Mesh" #: editor/editor_plugin.cpp msgid "Thumbnail..." -msgstr "" +msgstr "Gambar kecil..." #: editor/editor_plugin_settings.cpp +#, fuzzy msgid "Main Script:" -msgstr "" +msgstr "Skrip Utama:" #: editor/editor_plugin_settings.cpp msgid "Edit Plugin" -msgstr "" +msgstr "Sunting Plugin" #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" -msgstr "" +msgstr "Plugin yang Dipasang:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#, fuzzy msgid "Update" -msgstr "" +msgstr "Kemas kini" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Version:" -msgstr "" +msgstr "Versi:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#, fuzzy msgid "Author:" -msgstr "" +msgstr "Pengarang:" #: editor/editor_plugin_settings.cpp +#, fuzzy msgid "Status:" -msgstr "" +msgstr "Status:" #: editor/editor_plugin_settings.cpp msgid "Edit:" -msgstr "" +msgstr "Sunting:" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "Ukur:" #: editor/editor_profiler.cpp +#, fuzzy msgid "Frame Time (sec)" -msgstr "" +msgstr "Masa Bingkai (saat)" #: editor/editor_profiler.cpp +#, fuzzy msgid "Average Time (sec)" -msgstr "" +msgstr "Masa Purata (saat)" #: editor/editor_profiler.cpp +#, fuzzy msgid "Frame %" -msgstr "" +msgstr "Bingkai %" #: editor/editor_profiler.cpp +#, fuzzy msgid "Physics Frame %" -msgstr "" +msgstr "Bingkai Fizik %" #: editor/editor_profiler.cpp +#, fuzzy msgid "Inclusive" -msgstr "" +msgstr "Inklusif" #: editor/editor_profiler.cpp +#, fuzzy msgid "Self" -msgstr "" +msgstr "Diri" #: editor/editor_profiler.cpp +#, fuzzy msgid "Frame #:" -msgstr "" +msgstr "Bingkai #:" #: editor/editor_profiler.cpp +#, fuzzy msgid "Time" -msgstr "" +msgstr "Masa" #: editor/editor_profiler.cpp +#, fuzzy msgid "Calls" -msgstr "" +msgstr "Panggilan" #: editor/editor_properties.cpp msgid "Edit Text:" -msgstr "" +msgstr "Sunting Teks:" #: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" -msgstr "" +msgstr "Hidupkan" #: editor/editor_properties.cpp +#, fuzzy msgid "Layer" -msgstr "" +msgstr "Lapisan" #: editor/editor_properties.cpp +#, fuzzy msgid "Bit %d, value %d" -msgstr "" +msgstr "Bit %d, nilai %d" #: editor/editor_properties.cpp +#, fuzzy msgid "[Empty]" -msgstr "" +msgstr "[Kosong]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp +#, fuzzy msgid "Assign..." -msgstr "" +msgstr "Menguntukkan..." #: editor/editor_properties.cpp +#, fuzzy msgid "Invalid RID" -msgstr "" +msgstr "RID tidak sah" #: editor/editor_properties.cpp msgid "" "The selected resource (%s) does not match any type expected for this " "property (%s)." msgstr "" +"Sumber yang dipilih (%s) tidak sesuai dengan jenis yang diharapkan untuk " +"sifat ini (%s)." #: editor/editor_properties.cpp +#, fuzzy msgid "" "Can't create a ViewportTexture on resources saved as a file.\n" "Resource needs to belong to a scene." msgstr "" +"Tidak dapat mencipta ViewportTexture pada sumber yang disimpan sebagai " +"fail.\n" +"Sumber perlu tergolong dalam adegan." #: editor/editor_properties.cpp msgid "" @@ -3266,26 +3428,34 @@ msgid "" "Please switch on the 'local to scene' property on it (and all resources " "containing it up to a node)." msgstr "" +"Tidak dapat mencipta ViewportTexture pada sumber ini kerana ia tidak " +"disetkan sebagai adegan tempatan.\n" +"Sila hidupkan sifat 'tempatan ke tempat kejadian' di atasnya (dan semua " +"sumber yang mengandunginya sehingga ke nod)." #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" -msgstr "" +msgstr "Pilih Viewport" #: editor/editor_properties.cpp editor/property_editor.cpp +#, fuzzy msgid "New Script" -msgstr "" +msgstr "Skrip Baru" #: editor/editor_properties.cpp editor/scene_tree_dock.cpp +#, fuzzy msgid "Extend Script" -msgstr "" +msgstr "Lanjutkan Skrip" #: editor/editor_properties.cpp editor/property_editor.cpp +#, fuzzy msgid "New %s" -msgstr "" +msgstr "%s baru" #: editor/editor_properties.cpp editor/property_editor.cpp +#, fuzzy msgid "Make Unique" -msgstr "" +msgstr "Buat Unik" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3297,42 +3467,49 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#, fuzzy msgid "Paste" -msgstr "" +msgstr "Tampal" #: editor/editor_properties.cpp editor/property_editor.cpp +#, fuzzy msgid "Convert To %s" -msgstr "" +msgstr "Tukar Kepada %s" #: editor/editor_properties.cpp editor/property_editor.cpp +#, fuzzy msgid "Selected node is not a Viewport!" -msgstr "" +msgstr "Node yang dipilih bukan Viewport!" #: editor/editor_properties_array_dict.cpp +#, fuzzy msgid "Size: " -msgstr "" +msgstr "Saiz: " #: editor/editor_properties_array_dict.cpp +#, fuzzy msgid "Page: " -msgstr "" +msgstr "Halaman: " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Item" -msgstr "" +msgstr "Keluarkan Item" #: editor/editor_properties_array_dict.cpp +#, fuzzy msgid "New Key:" -msgstr "" +msgstr "Kunci Baru:" #: editor/editor_properties_array_dict.cpp +#, fuzzy msgid "New Value:" -msgstr "" +msgstr "Nilai Baru:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "" +msgstr "Tambah Pasangan Kunci/Nilai" #: editor/editor_run_native.cpp msgid "" @@ -3340,157 +3517,189 @@ msgid "" "Please add a runnable preset in the Export menu or define an existing preset " "as runnable." msgstr "" +"Tiada pratetap eksport yang dapat dijalankan untuk platform ini.\n" +"Sila tambah pratetap yang dapat dijalankan di menu Eksport atau tentukan " +"pratetap yang ada sebagai yang dapat dijalankan." #: editor/editor_run_script.cpp +#, fuzzy msgid "Write your logic in the _run() method." -msgstr "" +msgstr "Tulis logik anda dalam kaedah _run()." #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "" +msgstr "Sudah ada adegan yang diedit." #: editor/editor_run_script.cpp msgid "Couldn't instance script:" -msgstr "" +msgstr "Tidak dapat meng-instance skrip:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "" +msgstr "Adakah anda lupa kata kunci 'tool'?" #: editor/editor_run_script.cpp +#, fuzzy msgid "Couldn't run script:" -msgstr "" +msgstr "Tidak dapat menjalankan skrip:" #: editor/editor_run_script.cpp +#, fuzzy msgid "Did you forget the '_run' method?" -msgstr "" +msgstr "Adakah anda lupa kaedah '_run'?" #: editor/editor_spin_slider.cpp msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." msgstr "" +"Tahan Ctrl untuk bundarkan ke integer. Tahan Shift untuk perubahan yang " +"lebih tepat." #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "" +msgstr "Pilih Nod(Nod-nod) untuk Diimport" #: editor/editor_sub_scene.cpp editor/project_manager.cpp +#, fuzzy msgid "Browse" -msgstr "" +msgstr "Layari" #: editor/editor_sub_scene.cpp +#, fuzzy msgid "Scene Path:" -msgstr "" +msgstr "Laluan Adegan:" #: editor/editor_sub_scene.cpp +#, fuzzy msgid "Import From Node:" -msgstr "" +msgstr "Import Dari Nod:" #: editor/export_template_manager.cpp +#, fuzzy msgid "Redownload" -msgstr "" +msgstr "Muat turun semula" #: editor/export_template_manager.cpp +#, fuzzy msgid "Uninstall" -msgstr "" +msgstr "Nyahpasang" #: editor/export_template_manager.cpp +#, fuzzy msgid "(Installed)" -msgstr "" +msgstr "(Dipasang)" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Download" -msgstr "" +msgstr "Muat turun" #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." -msgstr "" +msgstr "Templat eksport rasmi tidak tersedia untuk binaan pembangunan." #: editor/export_template_manager.cpp +#, fuzzy msgid "(Missing)" -msgstr "" +msgstr "(Hilang)" #: editor/export_template_manager.cpp +#, fuzzy msgid "(Current)" -msgstr "" +msgstr "(Semasa)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait..." -msgstr "" +msgstr "Mengambil maklumat cermin, sila tunggu..." #: editor/export_template_manager.cpp +#, fuzzy msgid "Remove template version '%s'?" -msgstr "" +msgstr "Alih keluar versi templat '%s'?" #: editor/export_template_manager.cpp +#, fuzzy msgid "Can't open export templates zip." -msgstr "" +msgstr "Tidak dapat membuka zip templat eksport." #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates: %s." -msgstr "" +msgstr "Format version.txt tidak sah di dalam templat: %s." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "" +msgstr "Tiada version.txt dijumpai di dalam templat." #: editor/export_template_manager.cpp +#, fuzzy msgid "Error creating path for templates:" -msgstr "" +msgstr "Ralat mencipta laluan untuk templat:" #: editor/export_template_manager.cpp +#, fuzzy msgid "Extracting Export Templates" -msgstr "" +msgstr "Mengekstrak Templat Eksport" #: editor/export_template_manager.cpp +#, fuzzy msgid "Importing:" -msgstr "" +msgstr "Mengimport:" #: editor/export_template_manager.cpp +#, fuzzy msgid "Error getting the list of mirrors." -msgstr "" +msgstr "Ralat mendapatkan senarai cermin." #: editor/export_template_manager.cpp +#, fuzzy msgid "Error parsing JSON of mirror list. Please report this issue!" -msgstr "" +msgstr "Ralat menghuraikan JSON senarai cermin. Sila laporkan isu ini!" #: editor/export_template_manager.cpp msgid "" "No download links found for this version. Direct download is only available " "for official releases." msgstr "" +"Tiada pautan muat turun ditemui untuk versi ini. Muat turun langsung hanya " +"tersedia untuk siaran rasmi." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Can't resolve." -msgstr "" +msgstr "Tidak dapat menyelesaikan." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Can't connect." -msgstr "" +msgstr "Tidak dapat menyambung." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "No response." -msgstr "" +msgstr "Tiada jawapan." #: editor/export_template_manager.cpp +#, fuzzy msgid "Request Failed." -msgstr "" +msgstr "Permintaan Gagal." #: editor/export_template_manager.cpp msgid "Redirect Loop." -msgstr "" +msgstr "Ubah Hala Gelung." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Failed:" -msgstr "" +msgstr "Gagal:" #: editor/export_template_manager.cpp +#, fuzzy msgid "Download Complete." -msgstr "" +msgstr "Muat turun Selesai." #: editor/export_template_manager.cpp msgid "Cannot remove temporary file:" @@ -4933,7 +5142,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5070,8 +5279,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5085,9 +5293,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6149,6 +6376,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6209,10 +6440,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6794,6 +7021,15 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +#, fuzzy +msgid "Search" +msgstr "Cari" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6845,16 +7081,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6947,8 +7173,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7170,6 +7396,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Saiz: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9706,6 +9937,11 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Mengambil maklumat cermin, sila tunggu..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10128,9 +10364,8 @@ msgid "Batch Rename" msgstr "Ubah Nama Trek Anim" #: editor/rename_dialog.cpp -#, fuzzy msgid "Replace:" -msgstr "Ganti" +msgstr "Ganti:" #: editor/rename_dialog.cpp msgid "Prefix:" @@ -10311,6 +10546,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Anim Menduakan Kunci" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10432,6 +10676,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Anim Menduakan Kunci" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11220,6 +11469,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11719,11 +11996,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11735,11 +12014,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11747,9 +12026,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12140,27 +12429,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12220,6 +12509,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12433,6 +12726,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Mesti menggunakan sambungan yang sah." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12478,6 +12775,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12505,6 +12808,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "Tidak" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Adegan ini tidak pernah disimpan. Simpan sebelum menjalankan?" + #~ msgid "Error trying to save layout!" #~ msgstr "Ralat semasa menyimpan susun atur!" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 86a6c618b6..1289275b3d 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2,7 +2,7 @@ # Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. -# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019, 2020. +# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019, 2020, 2021. # Anonymous <GentleSaucepan@protonmail.com>, 2017. # Elias <eliasnykrem@gmail.com>, 2018. # flesk <eivindkn@gmail.com>, 2017, 2019. @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-10-09 05:49+0000\n" +"PO-Revision-Date: 2021-01-12 13:32+0000\n" "Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n" "Language-Team: Norwegian BokmÃ¥l <https://hosted.weblate.org/projects/godot-" "engine/godot/nb_NO/>\n" @@ -28,7 +28,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.3-dev\n" +"X-Generator: Weblate 4.4.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -680,7 +680,7 @@ msgstr "Velg spor Ã¥ kopiere:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Lim inn" @@ -2059,10 +2059,6 @@ msgstr "ForhÃ¥ndsvisning:" msgid "File:" msgstr "Fil:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "MÃ¥ ha en gyldig filutvidelse." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Gjennomsøk kilder" @@ -2521,6 +2517,10 @@ msgid "There is no defined scene to run." msgstr "Det er ingen definert scene Ã¥ kjøre." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Kunne ikke starta subprosess!" @@ -2566,18 +2566,6 @@ msgstr "En rotnode kreves for Ã¥ lagre scenen." msgid "Save Scene As..." msgstr "Lagre Scene Som..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nei" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ja" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Denne scene har aldri blitt lagret. Lagre før kjøring?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Denne operasjonen kan ikke gjøres uten en scene." @@ -2626,6 +2614,10 @@ msgid "Quit" msgstr "Avslutt" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ja" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Avslutt editoren?" @@ -2674,7 +2666,8 @@ msgstr "" "mislyktes." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Kunne ikke finne skriptfelt for addon-plugin i: 'res://addons/%s'." #: editor/editor_node.cpp @@ -2745,14 +2738,14 @@ msgstr "" "'applikasjon'." #: editor/editor_node.cpp +#, fuzzy msgid "" "Selected scene '%s' is not a scene file, select a valid one?\n" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Valgte scene '%s' er ikke en scenefil, velg en gyldig én?\n" -"Du kan endre dette senere i \"Prosjekt Instillinger\" under 'applikasjon' " -"kategorien." +"Den valgte scenen «%s» er ikke en scenefil, velg en gyldig scenefil?\n" +"Du kan endre dette senere i «Prosjektinnstillinger» i «program»-kategorien." #: editor/editor_node.cpp msgid "Save Layout" @@ -3071,9 +3064,8 @@ msgid "Editor" msgstr "Redigeringsverktøy" #: editor/editor_node.cpp -#, fuzzy msgid "Editor Settings..." -msgstr "Redigeringsverktøy-instillinger" +msgstr "Innstillinger for redigeringsverktøy …" #: editor/editor_node.cpp msgid "Editor Layout" @@ -3085,9 +3077,8 @@ msgid "Take Screenshot" msgstr "Lagre Scene" #: editor/editor_node.cpp -#, fuzzy msgid "Screenshots are stored in the Editor Data/Settings Folder." -msgstr "Redigeringsverktøy-instillinger" +msgstr "Skjermavbildninger lagres i redigeringsdata/innstillingsmappen." #: editor/editor_node.cpp msgid "Toggle Fullscreen" @@ -3099,18 +3090,16 @@ msgid "Toggle System Console" msgstr "Veksle modus" #: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" -msgstr "Redigeringsverktøy-instillinger" +msgstr "Ã…pne data for redigeringsverktøy/innstillingsmappe" #: editor/editor_node.cpp msgid "Open Editor Data Folder" msgstr "Ã…pne Redigererdatamappen" #: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Settings Folder" -msgstr "Redigeringsverktøy-instillinger" +msgstr "Ã…pne mappe for redigeringsverktøyinnstillinger" #: editor/editor_node.cpp #, fuzzy @@ -3127,14 +3116,6 @@ msgid "Help" msgstr "Hjelp" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Søk" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online Dokumentasjon" @@ -3299,6 +3280,23 @@ msgstr "Ã…pne & Kjør et Skript" #: editor/editor_node.cpp #, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "De følgende filene feilet ekstrahering fra pakke:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Gjeninnlat" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Lagre pÃ¥ nytt" + +#: editor/editor_node.cpp +#, fuzzy msgid "New Inherited" msgstr "Ny Arvet" @@ -3518,7 +3516,7 @@ msgstr "Gjør Unik" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Lim inn" @@ -5310,7 +5308,8 @@ msgid "Got:" msgstr "Fikk:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Feilet sha256 hash-sjekk" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5458,8 +5457,7 @@ msgstr "Assets ZIP-Fil" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5473,9 +5471,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "Laging av lysmapbilder feilet, forsikre om at stien er skrivbar." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Velg malfil" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6624,6 +6642,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Konverter til store versaler" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6684,10 +6707,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6999,9 +7018,8 @@ msgid "Clear UV" msgstr "Fjern UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Settings" -msgstr "Redigeringsverktøy-instillinger" +msgstr "Rutenettsinnstillinger" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Snap" @@ -7321,6 +7339,14 @@ msgstr "Lukk Dokumentasjon" msgid "Run" msgstr "Kjør" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Søk" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Tre inn i" @@ -7374,16 +7400,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Gjeninnlat" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Lagre pÃ¥ nytt" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Feilsøking" @@ -7484,8 +7500,8 @@ msgstr "Slett punkter" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Klipp ut" @@ -7725,6 +7741,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Størrelse: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -8050,9 +8071,8 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Settings..." -msgstr "Redigeringsverktøy-instillinger" +msgstr "Innstillinger …" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" @@ -8222,9 +8242,8 @@ msgid "Update Preview" msgstr "ForhÃ¥ndsvis" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Settings:" -msgstr "Redigeringsverktøy-instillinger" +msgstr "Innstillinger:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -10433,6 +10452,11 @@ msgid "Projects" msgstr "Prosjekter" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Henter fillager, vennligst vent..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -11063,6 +11087,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Lim inn Noder" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Nytt Skript" @@ -11192,6 +11225,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Kutt Noder" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11725,7 +11763,7 @@ msgstr "Endre Anker" #: editor/settings_config_dialog.cpp msgid "Editor Settings" -msgstr "Redigeringsverktøy-instillinger" +msgstr "Innstillinger for redigeringsverktøy" #: editor/settings_config_dialog.cpp msgid "Shortcuts" @@ -12042,6 +12080,38 @@ msgstr "Lim inn Noder" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Retninger" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Innrykk Høyre" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Gjeldende Versjon:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Genererer Lyskart" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12577,11 +12647,13 @@ msgid "Select device from the list" msgstr "Velg enhet fra listen" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12593,11 +12665,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12605,9 +12677,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -13011,28 +13093,31 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Genererer Lyskart" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Genererer Lyskart" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "" +#, fuzzy +msgid "Done" +msgstr "Ferdig!" #: scene/3d/collision_object.cpp msgid "" @@ -13091,6 +13176,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13309,6 +13398,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "MÃ¥ ha en gyldig filutvidelse." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -13355,6 +13448,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Ugyldig fontstørrelse." @@ -13384,6 +13483,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstanter kan ikke endres." +#~ msgid "No" +#~ msgstr "Nei" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Denne scene har aldri blitt lagret. Lagre før kjøring?" + #, fuzzy #~ msgid "Search complete" #~ msgstr "Søk Tekst" @@ -13614,10 +13719,6 @@ msgstr "Konstanter kan ikke endres." #~ msgstr "Kunne ikke laste ressurs." #, fuzzy -#~ msgid "Done" -#~ msgstr "Ferdig!" - -#, fuzzy #~ msgid "Failed to create C# project." #~ msgstr "Kunne ikke laste ressurs." diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 15a47ab682..1202219ee6 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -28,7 +28,7 @@ # rxadmin <r.van.eeghem@gmail.com>, 2018. # Peter Goelst <muis24@gmail.com>, 2019. # Wouter Buckens <wou.buc@gmail.com>, 2019. -# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2019, 2020. +# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2019, 2020, 2021. # jef dered <themen098s@vivaldi.net>, 2019. # Alex H. <sandertjeh13@hotmail.com>, 2019. # edouardgr <edouard.gruyters@gmail.com>, 2019. @@ -47,7 +47,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-25 12:29+0000\n" +"PO-Revision-Date: 2021-02-05 23:44+0000\n" "Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -56,7 +56,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -686,7 +686,7 @@ msgstr "Selecteer sporen om te kopieren" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopiëren" @@ -1703,7 +1703,7 @@ msgstr "Script Editor" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "Asset bibliotheek" +msgstr "Materiaalbibliotheek" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" @@ -1991,10 +1991,6 @@ msgstr "Voorbeeld:" msgid "File:" msgstr "Bestand:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Een geldige extensie moet gebruikt worden." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Scan Bronnen" @@ -2433,6 +2429,10 @@ msgid "There is no defined scene to run." msgstr "Er is geen startscène ingesteld." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Scène opslaan voor het afspelen..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Kon het subproces niet opstarten!" @@ -2476,18 +2476,6 @@ msgstr "Een wortelknoop is nodig om de scène op te slaan." msgid "Save Scene As..." msgstr "Scène opslaan als..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nee" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ja" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Deze scene is nooit opgeslagen. Sla op voor het uitvoeren?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Deze operatie kan niet uitgevoerd worden zonder scène." @@ -2538,6 +2526,10 @@ msgid "Quit" msgstr "Afsluiten" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ja" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Editor afsluiten?" @@ -2585,7 +2577,8 @@ msgstr "" "mislukt." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Onmogelijk om scriptveld te vinden voor de plugin op: 'res://addons/%s'." @@ -2909,7 +2902,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Visible Collision Shapes" -msgstr "Toon collision shapes" +msgstr "Botsingsvormen tonen" #: editor/editor_node.cpp #, fuzzy @@ -3019,14 +3012,6 @@ msgid "Help" msgstr "Help" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Zoeken" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online Documentatie" @@ -3193,6 +3178,25 @@ msgid "Open & Run a Script" msgstr "Voer Een Script Uit" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"De volgende bestanden zijn nieuwer op de schijf.\n" +"Welke aktie moet worden genomen?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Herladen" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Heropslaan" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nieuw afgeleid type" @@ -3218,7 +3222,7 @@ msgstr "Open Script Bewerker" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "Open Asset Bibliotheek" +msgstr "Open Materiaalbibliotheek" #: editor/editor_node.cpp msgid "Open the next Editor" @@ -3404,7 +3408,7 @@ msgstr "Maak Uniek" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Plakken" @@ -3766,6 +3770,11 @@ msgid "" "\n" "Do you wish to overwrite them?" msgstr "" +"De volgende bestanden of mappen conflicteren met elementen in '%s':\n" +"\n" +"%s\n" +"\n" +"Wil je deze overschrijven?" #: editor/filesystem_dock.cpp msgid "Renaming file:" @@ -3958,19 +3967,16 @@ msgid "Searching..." msgstr "Aan het zoeken..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d overeenkomst(en) gevonden." +msgstr "%d overeenkomst in %d bestand." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d overeenkomst(en) gevonden." +msgstr "%d overeenkomsten in %d bestand." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d overeenkomst(en) gevonden." +msgstr "%d overeenkomsten in %d bestanden." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5074,7 +5080,8 @@ msgid "Got:" msgstr "Gekregen:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "SHA256-proef mislukt" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5207,10 +5214,10 @@ msgid "Assets ZIP File" msgstr "Assets ZIP Bestand" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Kan geen opslag pad voor de lichtmappen bepalen.\n" "Sla jouw scène op (om lichtmappen op te slaan in dezelfde map) of kies een " @@ -5231,9 +5238,28 @@ msgstr "" "beschrijfbaar is." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Bak Lichtmappen" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Selecteer lightmap bake-bestand" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -5301,7 +5327,7 @@ msgstr "Maak nieuwe horizontale en verticale gidsen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" -msgstr "" +msgstr "Draaipuntverschuiving van het CanvasItem „%s“ op (%d, %d) zetten" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate %d CanvasItems" @@ -5324,24 +5350,20 @@ msgid "Resize Control \"%s\" to (%d, %d)" msgstr "Control \"%s\" vergrootten tot (%d, %d)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale %d CanvasItems" -msgstr "Schaal CanvasItem" +msgstr "Schaal %d CanvasItems" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale CanvasItem \"%s\" to (%s, %s)" -msgstr "Schaal CanvasItem" +msgstr "Schaal CanvasItem \"%s\" naar (%s, %s)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move %d CanvasItems" -msgstr "Verplaats CanvasItem" +msgstr "Verplaats %d CanvasItems" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move CanvasItem \"%s\" to (%d, %d)" -msgstr "Verplaats CanvasItem" +msgstr "CanvasItem \"%s\" naar (%d, %d) verplaatsen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -6335,6 +6357,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Kan punt alleen plaatsen in een PartikelsMateriaal proces materiaal" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Omzetten naar CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Genereer Tijd (sec):" @@ -6395,10 +6421,6 @@ msgstr "AABB Genereren" msgid "Generate Visibility AABB" msgstr "Genereer Zichtbaarheid AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Genereer AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Verwijder Punt van Curve" @@ -6627,9 +6649,8 @@ msgid "Move Points" msgstr "Beweeg Punten" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Command: Rotate" -msgstr "Sleep: Roteer" +msgstr "Ctrl: Roteer" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" @@ -6687,14 +6708,12 @@ msgid "Radius:" msgstr "Radius:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Copy Polygon to UV" -msgstr "Creëer Polygon & UV" +msgstr "Kopieer Polygon naar UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Copy UV to Polygon" -msgstr "Naar Polygon2D omzetten" +msgstr "Kopieer UV naar Polygon2D" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Clear UV" @@ -6996,6 +7015,14 @@ msgstr "Sluit Docs" msgid "Run" msgstr "Uitvoeren" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Zoeken" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Stap In" @@ -7049,16 +7076,6 @@ msgstr "" "De volgende bestanden zijn nieuwer op de schijf.\n" "Welke aktie moet worden genomen?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Herladen" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Heropslaan" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Debugger" @@ -7152,8 +7169,8 @@ msgstr "Breekpunten" msgid "Go To" msgstr "Ga Naar" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Knippen" @@ -7376,6 +7393,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Grootte: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objecten Getekend" @@ -7788,7 +7810,7 @@ msgstr "Polygon2D Voorbeeldweergave" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create CollisionPolygon2D" -msgstr "Creëer CollisionPolygon2D" +msgstr "CollisionPolygon2D aanmaken" #: editor/plugins/sprite_editor_plugin.cpp msgid "CollisionPolygon2D Preview" @@ -7830,11 +7852,11 @@ msgstr "Naar Polygon2D omzetten" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "Ongeldige geometrie, kan geen collision polygoon creëren." +msgstr "Ongeldige geometrie, kan geen botsingspolygoon aanmaken." #: editor/plugins/sprite_editor_plugin.cpp msgid "Create CollisionPolygon2D Sibling" -msgstr "Creëer CollisionPolygon2D Sibling" +msgstr "CollisionPolygon2D aanmaken" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create light occluder." @@ -8240,13 +8262,12 @@ msgid "Paint Tile" msgstr "Teken Tegel" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "" "Shift+LMB: Line Draw\n" "Shift+Command+LMB: Rectangle Paint" msgstr "" -"Shift+LMB: Lijn Tekenen\n" -"Shift+Ctrl+LMB: Vierkant Tekenen" +"Shift+LMB: Lijn tekenen\n" +"Shift+Ctrl+LMB: Vierkant tekenen" #: editor/plugins/tile_map_editor_plugin.cpp msgid "" @@ -8401,23 +8422,20 @@ msgid "Create a new rectangle." msgstr "Creëer nieuwe driehoek." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "New Rectangle" -msgstr "Teken Driehoek" +msgstr "Nieuwe rechthoek" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create a new polygon." msgstr "Nieuwe veelhoek aanmaken." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "New Polygon" -msgstr "Beweeg Polygon" +msgstr "Nieuwe veelhoek" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete Selected Shape" -msgstr "Geselecteerde Verwijderen" +msgstr "Geselecteerde vormen verwijderen" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." @@ -8544,7 +8562,7 @@ msgstr "Tegelbitmasker bewerken" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Collision Polygon" -msgstr "Bewerk Collision Polygon" +msgstr "Botsingspolygoon aanpassen" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Occlusion Polygon" @@ -8576,7 +8594,7 @@ msgstr "Verwijder Tile" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Collision Polygon" -msgstr "Verwijder Collision Polygon" +msgstr "Botsingsvorm verwijderen" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Occlusion Polygon" @@ -8604,7 +8622,7 @@ msgstr "Maak concaaf" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Collision Polygon" -msgstr "Creëer Collision Polygon" +msgstr "Botsingsvorm aanmaken" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Occlusion Polygon" @@ -8782,9 +8800,8 @@ msgid "Add Node to Visual Shader" msgstr "VisualShader-knoop toevoegen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Node(s) Moved" -msgstr "Knoop verplaatst" +msgstr "Knoop/knopen verplaatst" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Duplicate Nodes" @@ -8804,9 +8821,8 @@ msgid "Visual Shader Input Type Changed" msgstr "Visuele Shader Invoertype Gewijzigd" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "UniformRef Name Changed" -msgstr "Uniforme naam instellen" +msgstr "UniformRef naam veranderd" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" @@ -9534,7 +9550,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "A reference to an existing uniform." -msgstr "" +msgstr "Een verwijzing naar een bestaande uniform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(Fragment/Light mode only) Scalar derivative function." @@ -9901,7 +9917,7 @@ msgstr "OpenGL ES 3.0" #: editor/project_manager.cpp msgid "Not supported by your GPU drivers." -msgstr "" +msgstr "Niet ondersteund door de GPU drivers op dit systeem." #: editor/project_manager.cpp msgid "" @@ -10080,6 +10096,11 @@ msgid "Projects" msgstr "Projecten" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Mirrors ophalen, even wachten a.u.b..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Laatst bewerkt" @@ -10117,7 +10138,7 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" "U heeft momenteel geen projecten.\n" -"Wilt u de officiële voorbeeldprojecten verkennen in de Asset Library?" +"Wilt u officiële voorbeeldprojecten verkennen in de Materiaalbibliotheek?" #: editor/project_manager.cpp msgid "" @@ -10511,19 +10532,16 @@ msgid "Batch Rename" msgstr "Bulk hernoemen" #: editor/rename_dialog.cpp -#, fuzzy msgid "Replace:" -msgstr "Vervangen: " +msgstr "Vervangen:" #: editor/rename_dialog.cpp -#, fuzzy msgid "Prefix:" -msgstr "Voorvoegsel" +msgstr "Voorvoegsel:" #: editor/rename_dialog.cpp -#, fuzzy msgid "Suffix:" -msgstr "Achtervoegsel" +msgstr "Achtervoegsel:" #: editor/rename_dialog.cpp msgid "Use Regular Expressions" @@ -10570,11 +10588,10 @@ msgid "Per-level Counter" msgstr "Per niveau teller" #: editor/rename_dialog.cpp -#, fuzzy msgid "If set, the counter restarts for each group of child nodes." msgstr "" -"Indien ingesteld: herstart de teller voor iedere groep van onderliggende " -"knopen" +"Indien ingesteld, zal de teller voor iedere groep van onderliggende knopen " +"opnieuw starten." #: editor/rename_dialog.cpp msgid "Initial value for the counter" @@ -10633,9 +10650,8 @@ msgid "Reset" msgstr "Resetten" #: editor/rename_dialog.cpp -#, fuzzy msgid "Regular Expression Error:" -msgstr "Fout in reguliere expressie" +msgstr "Fout in reguliere expressie:" #: editor/rename_dialog.cpp msgid "At character %s" @@ -10706,6 +10722,16 @@ msgid "Instance Child Scene" msgstr "Scène instantiëren" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Kan deze operatie niet uitvoeren op knopen uit een vreemde scène!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Knopen plakken" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Script losmaken" @@ -10833,6 +10859,11 @@ msgid "Attach Script" msgstr "Script toevoegen" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Knopen knippen" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Verwijder knoop/knopen" @@ -11638,6 +11669,34 @@ msgstr "Filter Meshes" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Voeg een MeshLibrary aan deze GridMap toe om meshes te gebruiken." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Begin lichtberekening" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Datastructuren worden voorbereid" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Genereer buffers" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Directe verlichting" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Indirecte verlichting" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Nabewerking" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Lightmaps plotten" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Klassennaam kan geen gereserveerd sleutelwoord zijn" @@ -12155,12 +12214,16 @@ msgid "Select device from the list" msgstr "Selecteer apparaat uit de lijst" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB niet ingesteld in Editor Settings." +msgid "Unable to find the 'apksigner' tool." +msgstr "Het hulpmiddel 'apksigner' kon niet gevonden worden." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK niet ingesteld in Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Geen Android bouwsjabloon geïnstalleerd in dit project. Vanuit het " +"projectmenu kan het geïnstalleerd worden." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12171,25 +12234,34 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "Release-Keystore is verkeerd ingesteld in de exportinstelingen." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Eigen build vereist een geldige Android SDK pad in de Editorinstellingen." +"Een geldig Android SDK-pad moet in de Editorinstellingen ingesteld zijn." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "Ongeldig Android SDK pad voor custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Ongeldig Android SDK-pad in Editorinstellingen." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" +msgstr "'platform-tools' map ontbreekt!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "Ongeldig Android SDK pad voor custom build in Editor Settings." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"Geen Android bouwsjabloon geïnstalleerd in dit project. Vanuit het " -"projectmenu kan het geïnstalleerd worden." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12431,10 +12503,10 @@ msgid "" "Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " "define its shape." msgstr "" -"Deze knoop heeft geen vorm (Shape), dus kan het niet met andere objecten " -"botsen of interactie hebben.\n" -"Overweeg om een CollisionShape2D of CollisionPolygon2D als kind toe te " -"voegen om de vorm ervan vast te leggen." +"Deze knoop heeft geen botsingsvorm als onderliggende knoop en kan dus niet " +"met andere objecten botsen of interageren.\n" +"Plaats hieronder een knoop als CollisionShape2D of CollisionPolygon2D om " +"deze vorm vast te leggen." #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -12442,13 +12514,14 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" -"CollisionPolygon2D dient enkel om een botsingsvorm te koppelen aan een knoop " -"afgeleid van CollisionObject2D. Plaats hem onder een Area2D-, StaticBody2D-, " -"RigidBody2D- of KinematicBody2D-knoop." +"Een knooppunt van het type CollisionPolygon2D kan alleen een botsingsvorm " +"keveren aan knopen die zijn afgeleid van CollisionObject2D. Plaats het dus " +"alleen onder een knoop als Area2D, StaticBody2D, RigidBody2D of " +"KinematicBody2D." #: scene/2d/collision_polygon_2d.cpp msgid "An empty CollisionPolygon2D has no effect on collision." -msgstr "Een lege CollisionPolygon2D heeft geen effect op botsingen." +msgstr "Lege CollisionPolygon2D hebben geen botsingsfunctie." #: scene/2d/collision_shape_2d.cpp msgid "" @@ -12456,15 +12529,16 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" -"CollisionShape2D dient enkel om een botsingsvorm te koppelen aan een knoop " -"afgeleid van CollisionObject2D. Plaats hem onder een Area2D-, StaticBody2D-, " -"RigidBody2D- of KinematicBody2D-knoop." +"Een knooppunt van het type CollisionShape2D kan alleen een botsingsvorm " +"keveren aan knopen die zijn afgeleid van CollisionObject2D. Plaats het dus " +"alleen onder een knoop als Area2D, StaticBody2D, RigidBody2D of " +"KinematicBody2D." #: scene/2d/collision_shape_2d.cpp msgid "" "A shape must be provided for CollisionShape2D to function. Please create a " "shape resource for it!" -msgstr "Een CollisionShape2D heeft een vorm nodig in de Shape-eigenschap!" +msgstr "Een CollisionShape2D heeft een vorm nodig." #: scene/2d/collision_shape_2d.cpp msgid "" @@ -12580,9 +12654,9 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" -"Grootteveranderingen van een RigidBody2D (in Character- of Rigidmodus) zal " -"overschreven worden door de physics engine als het spel start.\n" -"Verander in plaats daarvan de grootte van CollisionShapes in de kinderen." +"De grootte van een RigidBody2D (in Character- of Rigidmodus) wordt " +"overschreven wanneer het spel start.\n" +"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen." #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -12611,10 +12685,9 @@ msgid "" "to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " "KinematicBody2D, etc. to give them a shape." msgstr "" -"TileMap met de optie \"Use Parent\" aan heeft een CollisionShape2D-ouder " -"nodig om vormen aan te geven. De TileMap hoort een kind van een Area2D, " -"StaticBody2D, RigidBody2D, KinematicBody2D enz. knoop te zijn om ze een vorm " -"te geven." +"Een TileMap met de optie \"Use Parent\" ingeschakeld moet knoop afgeleid van " +"CollisionObject2D (Area2D, StaticBody2D, RigidBody2D of KinematicBody2D) als " +"ouder hebben." #: scene/2d/visibility_notifier_2d.cpp msgid "" @@ -12657,28 +12730,33 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin heeft een ARVRCamera nodig als kind." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Tijd resterend: %d:%02d s)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Geometrie aan het ontleden..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Plotten Meshes: " +#, fuzzy +msgid "Preparing environment" +msgstr "Bekijk Omgeving" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Plotten Light:" +#, fuzzy +msgid "Generating capture" +msgstr "Bouw Lightmappen" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Plotten Voltooid" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Bouw Lightmappen" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Light Meshes: " +#, fuzzy +msgid "Done" +msgstr "Klaar!" #: scene/3d/collision_object.cpp msgid "" @@ -12686,10 +12764,10 @@ msgid "" "Consider adding a CollisionShape or CollisionPolygon as a child to define " "its shape." msgstr "" -"Deze knoop heeft geen vorm (Shape), dus het kan niet met andere objecten " -"botsen of interactie hebben.\n" -"Overweeg om een CollisionShape of CollisionPolygon als kind toe te voegen om " -"de vorm ervan vast te leggen." +"Deze knoop heeft geen botsingsvorm als onderliggende knoop en kan dus niet " +"met andere objecten botsen of interageren.\n" +"Plaats hieronder een knoop als CollisionShape of CollisionPolygon om deze " +"vorm vast te leggen." #: scene/3d/collision_polygon.cpp msgid "" @@ -12697,13 +12775,13 @@ msgid "" "CollisionObject derived node. Please only use it as a child of Area, " "StaticBody, RigidBody, KinematicBody, etc. to give them a shape." msgstr "" -"CollisionPolygon dient enkel om een botsingsvorm te koppelen aan een knoop " -"afgeleid van CollisionObject. Plaats hem onder een Area-, StaticBody-, " -"RigidBody- of KinematicBody-knoop." +"Een knooppunt van het type CollisionPolygon kan alleen een botsingsvorm " +"keveren aan knopen die zijn afgeleid van CollisionObject. Plaats het dus " +"alleen onder een knoop als Area, StaticBody, RigidBody of KinematicBody." #: scene/3d/collision_polygon.cpp msgid "An empty CollisionPolygon has no effect on collision." -msgstr "Een lege CollisionPolygon heeft geen effect op botsingen." +msgstr "Lege CollisionPolygon hebben geen botsingsfunctie." #: scene/3d/collision_shape.cpp msgid "" @@ -12711,17 +12789,15 @@ msgid "" "derived node. Please only use it as a child of Area, StaticBody, RigidBody, " "KinematicBody, etc. to give them a shape." msgstr "" -"CollisionShape dient enkel om een botsingsvorm te koppelen aan een knoop " -"afgeleid van CollisionObject. Plaats hem onder een Area-, StaticBody-, " -"RigidBody- of KinematicBody-knoop." +"Een knooppunt van het type CollisionShape kan alleen een botsingsvorm " +"keveren aan knopen die zijn afgeleid van CollisionObject2D. Plaats het dus " +"alleen onder een knoop als Area, StaticBody, RigidBody of KinematicBody." #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " "shape resource for it." -msgstr "" -"Om CollisionShape te laten werken, hoort het een Shape te hebben. Maak " -"hiervoor alstublieft een Shape bron aan." +msgstr "Een CollisionShape heeft een vorm nodig." #: scene/3d/collision_shape.cpp msgid "" @@ -12753,6 +12829,10 @@ msgid "Plotting Meshes" msgstr "Plotten van Meshes" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Plotten Voltooid" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12826,9 +12906,9 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" -"Grootteveranderingen van een RigidBody (in Character- of Rigidmodus) zal " -"overschreven worden door de physics engine als het spel start.\n" -"Verander in plaats daarvan de grootte van CollisionShapes in de kinderen." +"De grootte van een RigidBody (in Character- of Rigidmodus) wordt " +"overschreven wanneer het spel start.\n" +"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen." #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be PhysicsBodies" @@ -12868,9 +12948,8 @@ msgid "" "running.\n" "Change the size in children collision shapes instead." msgstr "" -"Grootteveranderingen van een SoftBody (in Character- of Rigidmodus) zal " -"overschreven worden door de physics engine als het spel start.\n" -"Verander de grootte van CollisionShapes in de kinderen." +"De grootte van een SoftBody wordt overschreven wanneer het spel start.\n" +"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen." #: scene/3d/sprite_3d.cpp msgid "" @@ -13010,10 +13089,13 @@ msgstr "Alarm!" msgid "Please Confirm..." msgstr "Bevestig alstublieft..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Een geldige extensie moet gebruikt worden." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Aan raster kleven" +msgstr "Rasteroverzicht inschakelen." #: scene/gui/popup.cpp msgid "" @@ -13069,6 +13151,12 @@ msgstr "" "De grootte van een Viewport moet groter zijn dan 0 om iets weer te geven." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ongeldige bron voor voorvertoning." @@ -13096,6 +13184,34 @@ msgstr "Varyings kunnen alleen worden toegewezenin vertex functies." msgid "Constants cannot be modified." msgstr "Constanten kunnen niet worden aangepast." +#~ msgid "No" +#~ msgstr "Nee" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Deze scene is nooit opgeslagen. Sla op voor het uitvoeren?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ADB niet ingesteld in Editor Settings." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK niet ingesteld in Editor Settings." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Eigen build vereist een geldige Android SDK pad in de Editorinstellingen." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Tijd resterend: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Plotten Meshes: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Light Meshes: " + #~ msgid "Search complete" #~ msgstr "Zoek Compleet" diff --git a/editor/translations/or.po b/editor/translations/or.po index 9c03d588f9..269276221d 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -625,7 +625,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1886,10 +1886,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2293,6 +2289,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2336,18 +2336,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2395,6 +2383,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2437,7 +2429,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2827,14 +2819,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2988,6 +2972,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3190,7 +3190,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4818,7 +4818,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4953,8 +4953,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4968,9 +4967,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6026,6 +6044,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6086,10 +6108,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6671,6 +6689,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6722,16 +6748,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6824,8 +6840,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7046,6 +7062,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9566,6 +9586,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10169,6 +10193,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10289,6 +10321,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11073,6 +11109,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11568,11 +11632,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11584,11 +11650,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11596,9 +11662,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11989,27 +12065,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12069,6 +12145,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12282,6 +12362,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12327,6 +12411,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 0d525439eb..3cf039dd3b 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -24,7 +24,7 @@ # Sebastian Pasich <sebastian.pasich@gmail.com>, 2017, 2019, 2020. # siatek papieros <sbigneu@gmail.com>, 2016. # Zatherz <zatherz@linux.pl>, 2017, 2020. -# Tomek <kobewi4e@gmail.com>, 2018, 2019, 2020. +# Tomek <kobewi4e@gmail.com>, 2018, 2019, 2020, 2021. # Wojcieh Er Zet <wojcieh.rzepecki@gmail.com>, 2018. # Dariusz Siek <dariuszynski@gmail.com>, 2018, 2019, 2020. # Szymon Nowakowski <smnbdg13@gmail.com>, 2019. @@ -45,11 +45,13 @@ # Piotr Grodzki <ziemniakglados@gmail.com>, 2020. # Dzejkop <jakubtrad@gmail.com>, 2020. # Mateusz Grzonka <alpinus4@gmail.com>, 2020. +# gnu-ewm <gnu.ewm@protonmail.com>, 2021. +# vrid <patryksoon@live.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -59,7 +61,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -687,7 +689,7 @@ msgstr "Wybierz Å›cieżki do skopiowania" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopiuj" @@ -903,7 +905,7 @@ msgstr "SygnaÅ‚:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" -msgstr "Połącz \"%s\" z \"%s\"" +msgstr "Połącz '%s' z '%s'" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" @@ -1981,10 +1983,6 @@ msgstr "PodglÄ…d:" msgid "File:" msgstr "Plik:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Rozszerzenie musi być poprawne." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Przeszukaj źródÅ‚a" @@ -2419,6 +2417,10 @@ msgid "There is no defined scene to run." msgstr "Nie ma zdefiniowanej sceny do uruchomienia." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Zapisz scenÄ™ przed uruchomieniem..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Nie można byÅ‚o uruchomić podprocesu!" @@ -2462,18 +2464,6 @@ msgstr "Scena musi posiadać korzeÅ„, by jÄ… zapisać." msgid "Save Scene As..." msgstr "Zapisz scenÄ™ jako..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nie" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Tak" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Ta scena nie zostaÅ‚a zapisana. Zapisać przed uruchomieniem?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ta operacja nie może zostać wykonana bez sceny." @@ -2523,6 +2513,10 @@ msgid "Quit" msgstr "Wyjdź" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Tak" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Zamknąć edytor?" @@ -2569,7 +2563,8 @@ msgstr "" "Nie można włączyć dodatku: \"%s\" - parsowanie konfiguracji nie powiodÅ‚o siÄ™." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Nie można odnaleźć pola skryptu w dodatku: \"res://addons/%s\"." #: editor/editor_node.cpp @@ -3000,14 +2995,6 @@ msgid "Help" msgstr "Pomoc" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Szukaj" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Dokumentacja online" @@ -3171,6 +3158,24 @@ msgid "Open & Run a Script" msgstr "Otwórz i Uruchom Skrypt" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"NastÄ™pujÄ…ce pliki sÄ… nowsze na dysku.\n" +"Jakie dziaÅ‚anie powinno zostać podjÄ™te?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "PrzeÅ‚aduj" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Zapisz ponownie" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Nowa dziedziczÄ…ca scena" @@ -3381,7 +3386,7 @@ msgstr "Zrób unikalny" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Wklej" @@ -3940,19 +3945,16 @@ msgid "Searching..." msgstr "Wyszukiwanie..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d dopasowaÅ„." +msgstr "%d dopasowanie w %d pliku." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d dopasowaÅ„." +msgstr "%d dopasowaÅ„ w %d pliku." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d dopasowaÅ„." +msgstr "%d dopasowaÅ„ w %d plikach." #: editor/groups_editor.cpp msgid "Add to Group" @@ -4208,7 +4210,7 @@ msgstr "Zmiany mogÄ… zostać utracone!" #: editor/multi_node_edit.cpp msgid "MultiNode Set" -msgstr "Zestaw wielowÄ™zÅ‚owy" +msgstr "Ustaw wielu wÄ™zÅ‚om" #: editor/node_dock.cpp msgid "Select a single node to edit its signals and groups." @@ -5058,7 +5060,8 @@ msgid "Got:" msgstr "Otrzymano:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Nie udaÅ‚o się przeprowadzić testu integralnoÅ›ci sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5193,12 +5196,10 @@ msgstr "Plik ZIP assetów" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"Nie można okreÅ›lić Å›cieżki zapisu dla lightmapy obrazu.\n" -"Zapisz scenÄ™ (obrazy bÄ™dÄ… zapisane w tym samym katalogu), lub przepisz " -"Å›cieżkÄ™ zapisu z wÅ‚aÅ›ciwoÅ›ci BakedLightmap." +"Nie można okreÅ›lić Å›cieżki zapisu dla obrazów mapy Å›wiatÅ‚a.\n" +"Zapisz scenÄ™ i spróbuj ponownie." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5215,9 +5216,34 @@ msgstr "" "jedynie do odczytu." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Nie udaÅ‚o siÄ™ okreÅ›lić rozmiaru mapy Å›wiatÅ‚a. Maksymalny rozmiar jest za " +"maÅ‚y?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"JakaÅ› siatka jest nieprawidÅ‚owa. Upewnij siÄ™, że wartoÅ›ci kanaÅ‚u UV2 " +"mieszczÄ… siÄ™ w kwadratowym obszarze [0.0, 1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Godot zostaÅ‚ zbudowany bez wsparcia ray tracingu, mapy Å›wiatÅ‚a nie mogÄ… być " +"wypalone." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Stwórz Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Wybierz plik wypalenia mapy Å›wiatÅ‚a:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6313,6 +6339,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Punkt można wstawić tylko w materiaÅ‚ przetwarzania ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Przekonwertuj na CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Czas generowania (sek):" @@ -6373,10 +6403,6 @@ msgstr "Generowanie AABB" msgid "Generate Visibility AABB" msgstr "Generuj AABB widocznoÅ›ci" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Generuj AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "UsuÅ„ punkt z krzywej" @@ -6966,6 +6992,14 @@ msgstr "Zamknij pliki pomocy" msgid "Run" msgstr "Uruchom" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Szukaj" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Krok w" @@ -7019,16 +7053,6 @@ msgstr "" "NastÄ™pujÄ…ce pliki sÄ… nowsze na dysku.\n" "Jakie dziaÅ‚ania powinny zostać podjÄ™te?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "PrzeÅ‚aduj" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Zapisz ponownie" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Debugger" @@ -7124,8 +7148,8 @@ msgstr "Punkty wstrzymania" msgid "Go To" msgstr "Idź do" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Wytnij" @@ -7348,6 +7372,10 @@ msgid "Yaw" msgstr "Odchylenie" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Rozmiar" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Narysowane obiekty" @@ -10033,6 +10061,10 @@ msgid "Projects" msgstr "Projekty" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Wczytywanie, proszÄ™ czekać..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Data modyfikacji" @@ -10141,15 +10173,15 @@ msgstr "Indeks przycisku myszy:" #: editor/project_settings_editor.cpp msgid "Left Button" -msgstr "Lewy guzik" +msgstr "Lewy przycisk" #: editor/project_settings_editor.cpp msgid "Right Button" -msgstr "Prawy guzik" +msgstr "Prawy przycisk" #: editor/project_settings_editor.cpp msgid "Middle Button" -msgstr "Åšrodkowy guzik" +msgstr "Åšrodkowy przycisk" #: editor/project_settings_editor.cpp msgid "Wheel Up Button" @@ -10652,6 +10684,16 @@ msgid "Instance Child Scene" msgstr "Dodaj instancjÄ™ sceny" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Nie można operować wÄ™zÅ‚ami z innej sceny!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Wklej wÄ™zÅ‚y" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Odłącz skrypt" @@ -10778,6 +10820,11 @@ msgid "Attach Script" msgstr "Dołącz skrypt" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Wytnij wÄ™zÅ‚y" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "UsuÅ„ wÄ™zeÅ‚(y)" @@ -11585,6 +11632,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "Przypisz temu wÄ™zÅ‚owi GridMap zasób MeshLibrary, aby korzystać z jego siatek." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Zacznij wypalanie" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Przygotowywanie struktur danych" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Generuj bufory" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "OÅ›wietlenie bezpoÅ›rednie" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "OÅ›wietlenie poÅ›rednie" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Przetwarzanie koÅ„cowe" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "KreÅ›lenie map Å›wiatÅ‚a" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Nazwa klasy nie może być sÅ‚owem zastrzeżonym" @@ -12096,12 +12171,16 @@ msgid "Select device from the list" msgstr "Wybierz urzÄ…dzenie z listy" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Plik wykonywalny ADB nie skonfigurowany w Ustawieniach Edytora." +msgid "Unable to find the 'apksigner' tool." +msgstr "Nie udaÅ‚o siÄ™ znaleźć narzÄ™dzia \"apksigner\"." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "Jarsigner OpenJDK nie skonfigurowany w Ustawieniach Edytora." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Szablon budowania Androida nie jest zainstalowany dla projektu. Zainstaluj " +"go z menu Projekt." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12115,27 +12194,33 @@ msgstr "" "Wydaniowy keystore jest niepoprawnie skonfigurowany w profilu eksportu." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "" -"WÅ‚asny build wymaga poprawnej Å›cieżki do SDK Androida w Ustawieniach Edytora." +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "Wymagana jest poprawna Å›cieżka SDK Androida w Ustawieniach Edytora." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Niepoprawna Å›cieżka do SDK Androida dla wÅ‚asnego builda w Ustawieniach " -"Edytora." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Niepoprawna Å›cieżka do SDK Androida w Ustawieniach Edytora." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Folder \"platform-tools\" nie istnieje!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" -"Szablon budowania Androida nie jest zainstalowany dla projektu. Zainstaluj " -"go z menu Projekt." +"Nie udaÅ‚o siÄ™ znaleźć komendy adb z narzÄ™dzi platformowych SDK Androida." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "Sprawdź w folderze SDK Androida podanych w Ustawieniach Edytora." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Brakuje folderu \"build-tools\"!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "Nie udaÅ‚o siÄ™ znaleźć komendy apksigner z narzÄ™dzi SDK Androida." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12612,28 +12697,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin wymaga wÄ™zÅ‚a potomnego typu ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Szukanie siatek i Å›wiateÅ‚" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(PozostaÅ‚y czas: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "Przygotowywanie geometrii (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "KreÅ›lenie siatek: " +msgid "Preparing environment" +msgstr "Przygotowywanie Å›rodowiska" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "KreÅ›lenie Å›wiateÅ‚:" +msgid "Generating capture" +msgstr "Generowanie przechwycenia" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "KoÅ„czenie kreÅ›lenia" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Zapisywanie map Å›wiatÅ‚a" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "OÅ›wietlanie siatek: " +msgid "Done" +msgstr "Gotowe" #: scene/3d/collision_object.cpp msgid "" @@ -12711,6 +12796,10 @@ msgid "Plotting Meshes" msgstr "KreÅ›lenie siatek" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "KoÅ„czenie kreÅ›lenia" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12967,10 +13056,13 @@ msgstr "Alarm!" msgid "Please Confirm..." msgstr "ProszÄ™ potwierdzić..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Rozszerzenie musi być poprawne." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Włączyć przyciÄ…ganie" +msgstr "Włącz minimapÄ™ siatki." #: scene/gui/popup.cpp msgid "" @@ -13025,6 +13117,14 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Rozmiar wÄ™zÅ‚a Viewport musi być wiÄ™kszy niż 0, by coÅ› wyrenderować." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Port samplera jest podłączony, ale nieużyty. Rozważ zmianÄ™ źródÅ‚a na " +"\"SamplerPort\"." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "NieprawidÅ‚owe źródÅ‚o do podglÄ…du." @@ -13052,6 +13152,35 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchoÅ‚ków." msgid "Constants cannot be modified." msgstr "StaÅ‚e nie mogÄ… być modyfikowane." +#~ msgid "No" +#~ msgstr "Nie" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ta scena nie zostaÅ‚a zapisana. Zapisać przed uruchomieniem?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Plik wykonywalny ADB nie skonfigurowany w Ustawieniach Edytora." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "Jarsigner OpenJDK nie skonfigurowany w Ustawieniach Edytora." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "WÅ‚asny build wymaga poprawnej Å›cieżki do SDK Androida w Ustawieniach " +#~ "Edytora." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(PozostaÅ‚y czas: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "KreÅ›lenie siatek: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "OÅ›wietlanie siatek: " + #~ msgid "Search complete" #~ msgstr "Wyszukiwanie zakoÅ„czone" @@ -13064,12 +13193,6 @@ msgstr "StaÅ‚e nie mogÄ… być modyfikowane." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "W tej lokalizacji istnieje już plik lub folder o podanej nazwie." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Brakuje folderu \"build-tools\"!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Nie udaÅ‚o siÄ™ znaleźć narzÄ™dzia zipalign." - #~ msgid "Aligning APK..." #~ msgstr "Uzgadnianie APK..." @@ -13411,9 +13534,6 @@ msgstr "StaÅ‚e nie mogÄ… być modyfikowane." #~ msgid "Failed to save solution." #~ msgstr "Nie udaÅ‚o siÄ™ zapisać solucji." -#~ msgid "Done" -#~ msgstr "Gotowe" - #~ msgid "Failed to create C# project." #~ msgstr "Nie udaÅ‚o siÄ™ utworzyć projektu jÄ™zyka C#." diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 3f83414fb6..ca53ec3af2 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -656,7 +656,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1956,10 +1956,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2373,6 +2369,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2416,18 +2416,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2476,6 +2464,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2518,7 +2510,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2919,14 +2911,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3083,6 +3067,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3291,7 +3291,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4987,7 +4987,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5122,8 +5122,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5137,9 +5136,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Slit th' Node" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6223,6 +6242,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Discharge ye' Function" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6283,10 +6307,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6889,6 +6909,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6941,16 +6969,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7047,8 +7065,8 @@ msgstr "Yar, Blow th' Selected Down!" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7281,6 +7299,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9899,6 +9921,10 @@ msgid "Projects" msgstr "Rename Function" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10513,6 +10539,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Paste yer Node" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Discharge ye' Variable" @@ -10638,6 +10673,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Slit th' Node" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11461,6 +11501,36 @@ msgstr "Paste yer Node" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Yer functions:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Swap yer Expression" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12002,11 +12072,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12018,11 +12090,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12030,9 +12102,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12430,27 +12512,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12510,6 +12592,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12724,6 +12810,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12769,6 +12859,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Yer Calligraphy be wrongly sized." diff --git a/editor/translations/pt.po b/editor/translations/pt.po index 772e3858b7..939735e8da 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -6,7 +6,7 @@ # Carlos Vieira <carlos.vieira@gmail.com>, 2017. # João <joao@nogordio.com>, 2018. # João Graça <jgraca95@gmail.com>, 2017. -# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020. +# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020, 2021. # Miguel Gomes <miggas09@gmail.com>, 2017. # Paulo Caldeira <paucal@gmail.com>, 2018. # Pedro Gomes <pedrogomes1698@gmail.com>, 2017. @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-01-26 03:28+0000\n" "Last-Translator: João Lopes <linux-man@hotmail.com>\n" "Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/" "godot/pt/>\n" @@ -31,7 +31,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -566,7 +566,7 @@ msgstr "Copiar Pistas" #: editor/animation_track_editor.cpp msgid "Scale Selection" -msgstr "Escalar Selecção" +msgstr "Escalar Seleção" #: editor/animation_track_editor.cpp msgid "Scale From Cursor" @@ -622,7 +622,7 @@ msgstr "Máximo de Erros Angulares:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "Angulo Máximo Otimizável:" +msgstr "Ângulo Máximo Otimizável:" #: editor/animation_track_editor.cpp msgid "Optimize" @@ -630,7 +630,7 @@ msgstr "Otimizar" #: editor/animation_track_editor.cpp msgid "Remove invalid keys" -msgstr "Remover Chaves inválidas" +msgstr "Remover chaves inválidas" #: editor/animation_track_editor.cpp msgid "Remove unresolved and empty tracks" @@ -661,7 +661,7 @@ msgstr "Selecionar Pistas a Copiar" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copiar" @@ -1132,7 +1132,7 @@ msgstr "Agradecimentos da Comunidade Godot!" #: editor/editor_about.cpp msgid "Godot Engine contributors" -msgstr "Contribuidores da engine Godot" +msgstr "Contribuidores do Godot Engine" #: editor/editor_about.cpp msgid "Project Founders" @@ -1959,10 +1959,6 @@ msgstr "Pré-visualização:" msgid "File:" msgstr "Ficheiro:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Deve usar uma extensão válida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Analisar fontes" @@ -2272,7 +2268,7 @@ msgstr "A guardar Cena" #: editor/editor_node.cpp msgid "Analyzing" -msgstr "A analizar" +msgstr "A analisar" #: editor/editor_node.cpp msgid "Creating Thumbnail" @@ -2400,6 +2396,10 @@ msgid "There is no defined scene to run." msgstr "Não existe cena definida para execução." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Guardar cena antes de executar..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Não consegui iniciar o subprocesso!" @@ -2443,18 +2443,6 @@ msgstr "É necessário um nó raiz para guardar a cena." msgid "Save Scene As..." msgstr "Guardar Cena Como..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Não" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Sim" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Esta cena nunca foi guardada. Guardar antes de executar?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Esta operação não pode ser efetuada sem uma cena." @@ -2504,6 +2492,10 @@ msgid "Quit" msgstr "Sair" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Sim" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Sair do Editor?" @@ -2550,7 +2542,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "Incapaz de ativar plugin em: '%s' falha de análise ou configuração." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Incapaz de localizar campo Script para plugin em: 'res://addons/%s'." #: editor/editor_node.cpp @@ -2764,7 +2757,7 @@ msgstr "Converter Para..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "Bib. de Meshes..." +msgstr "MeshLibrary..." #: editor/editor_node.cpp msgid "TileSet..." @@ -2894,7 +2887,7 @@ msgid "" "When this option is enabled, navigation meshes and polygons will be visible " "in the running project." msgstr "" -"Com esta opção ativa, Meshes e PolÃgonos de navegação serão visÃveis no " +"Com esta opção ativa, malhas de navegação e polÃgonos serão visÃveis no " "projeto em execução." #: editor/editor_node.cpp @@ -2915,7 +2908,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Synchronize Script Changes" -msgstr "Sicronizar alterações de script" +msgstr "Sincronizar Alterações de Script" #: editor/editor_node.cpp msgid "" @@ -2983,14 +2976,6 @@ msgid "Help" msgstr "Ajuda" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Procurar" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentação Online" @@ -3155,6 +3140,25 @@ msgid "Open & Run a Script" msgstr "Abrir & Executar um Script" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Os seguintes Ficheiros são mais recentes no disco.\n" +"Que ação deve ser tomada?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Recarregar" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Guardar novamente" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Novo Herdado" @@ -3200,7 +3204,7 @@ msgstr "Sub-recurso não encontrado." #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "A criar pré-visualizações de Malha" +msgstr "A criar Pré-visualizações de Malha" #: editor/editor_plugin.cpp msgid "Thumbnail..." @@ -3365,7 +3369,7 @@ msgstr "Fazer único" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Colar" @@ -3435,7 +3439,7 @@ msgstr "Não consegui executar o script:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "Esqueceu-se do médodo '_run'?" +msgstr "Esqueceu-se do método '_run'?" #: editor/editor_spin_slider.cpp msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." @@ -3729,7 +3733,7 @@ msgid "" "\n" "Do you wish to overwrite them?" msgstr "" -"Os seguintes ficheiros ou pastas estão em conflito com os items na " +"Os seguintes ficheiros ou pastas estão em conflito com os itens na " "localização '%s':\n" "\n" "%s\n" @@ -3927,19 +3931,16 @@ msgid "Searching..." msgstr "A procurar..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d correspondências." +msgstr "Correspondência de %d no ficheiro %d." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d correspondências." +msgstr "Correspondências de %d no ficheiro %d." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d correspondências." +msgstr "Correspondências de %d em %d ficheiros." #: editor/groups_editor.cpp msgid "Add to Group" @@ -4330,7 +4331,7 @@ msgid "" "Activate to enable playback, check node warnings if activation fails." msgstr "" "AnimationTree está inativa.\n" -"Active-a para permitir a reprodução, verifique avisos do nó se a ativação " +"Ative-a para permitir a reprodução, verifique avisos do nó se a ativação " "falhar." #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -5030,7 +5031,7 @@ msgstr "Tempo expirado." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." -msgstr "Mau hash na transferência, assume-se que o Ficheiro foi manipulado." +msgstr "Mau hash na transferência, assume-se que o ficheiro foi manipulado." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Expected:" @@ -5041,7 +5042,8 @@ msgid "Got:" msgstr "Obtido:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Verificação hash sha256 falhada" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5176,19 +5178,17 @@ msgstr "Ficheiro ZIP de Ativos" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Não consigo determinar um caminho para guardar imagens lightmap.\n" -"Guarde a sua cena (para as imagens serem guardadas na mesma diretoria), ou " -"escolha um caminho nas propriedades BakedLightmap." +"Guarde a sua cena e tente novamente." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " "Light' flag is on." msgstr "" -"Não há Meshes para consolidar. Assegure-se que contêm um canal UV2 e que a " +"Não há malhas para consolidar. Assegure-se que contêm um canal UV2 e que a " "referência 'Bake Light' flag está on." #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5196,9 +5196,34 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "Falha ao criar imagens lightmap, assegure-se que o caminho é gravável." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Falha na determinação do tamanho do lightmap. Tamanho máximo do lightmap " +"demasiado pequeno?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Alguma malha é inválida. Certifique-se que os valores do canal UV2 estão " +"contidos na região quadrada [0.0,1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Editor Godot foi compilado sem suporte para ray tracing, lightmaps não podem " +"ser consolidados." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Consolidar Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Selecionar ficheiro de consolidação de lightmap:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -5310,7 +5335,7 @@ msgid "" "their parent." msgstr "" "As âncoras e margens de filhos de um contentores são sobrescritas pelo seu " -"pai." +"progenitor." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Presets for the anchors and margins values of a Control node." @@ -5410,8 +5435,8 @@ msgid "" "Game Camera Override\n" "Overrides game camera with editor viewport camera." msgstr "" -"Sobreposição de Câmara de Jogo\n" -"Sobrepõe câmara de jogo com câmara viewport do editor." +"Sobreposição de Câmera de Jogo\n" +"Sobrepõe câmara de jogo com câmera viewport do editor." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5419,7 +5444,7 @@ msgid "" "Game Camera Override\n" "No game instance running." msgstr "" -"Sobreposição de Câmara de Jogo\n" +"Sobreposição de Câmera de Jogo\n" "Nenhuma instância de jogo em execução." #: editor/plugins/canvas_item_editor_plugin.cpp @@ -5472,7 +5497,7 @@ msgid "" "by their parent." msgstr "" "Atenção: as crianças de um contentor obtêm a sua posição e tamanho " -"determinados apenas pelos seus pais." +"determinados apenas pelos seus progenitores." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -5585,7 +5610,7 @@ msgstr "Configurar Ajuste..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to Parent" -msgstr "Ajustar ao Parente" +msgstr "Ajustar ao Progenitor" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to Node Anchor" @@ -5973,7 +5998,7 @@ msgstr "Não consegui criar uma forma de colisão Trimesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "Criar corpo estático Trimesh" +msgstr "Criar Corpo Estático Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" @@ -6018,7 +6043,7 @@ msgstr "Malha contida não é do tipo ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "Falhou o desempacotamento UV, a Malha pode não ser múltipla?" +msgstr "Falhou o desempacotamento UV, a malha pode não ser múltipla?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." @@ -6038,7 +6063,7 @@ msgstr "A Malha não tem superfÃcie para criar contornos!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "Tipo primitivo de Malha não é PRIMITIVE_TRIANGLES!" +msgstr "Tipo primitivo de malha não é PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" @@ -6054,7 +6079,7 @@ msgstr "Malha" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" -msgstr "Criar corpo estático Trimesh" +msgstr "Criar Corpo Estático Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -6140,7 +6165,7 @@ msgstr "Tamanho do contorno:" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Channel Debug" -msgstr "Debug Canal UV" +msgstr "Depuração Canal UV" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove item %d?" @@ -6156,7 +6181,7 @@ msgstr "" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Mesh Library" -msgstr "Bib. de Meshes" +msgstr "Bib. de Malhas" #: editor/plugins/mesh_library_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -6177,11 +6202,11 @@ msgstr "Atualizar a partir da Cena" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." -msgstr "Fonte da Malha não especificada (nem MultiMesh no nó)." +msgstr "Fonte da malha não especificada (nem MultiMesh definido no nó)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." -msgstr "Fonte da Malha não especificada (e MultiMesh não contêm Malha)." +msgstr "Fonte da malha não especificada (e MultiMesh não contêm Malha)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." @@ -6213,7 +6238,7 @@ msgstr "A fonte de superfÃcie é inválida (sem faces)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "Selecione uma fonte Malha:" +msgstr "Selecione uma Fonte Malha:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" @@ -6290,6 +6315,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Só pode definir um Ponto num Material ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Converter em CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Tempo de geração (s):" @@ -6350,10 +6379,6 @@ msgstr "A gerar AABB" msgid "Generate Visibility AABB" msgstr "Gerar visibilidade AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Gerar AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Remover Ponto da curva" @@ -6511,7 +6536,7 @@ msgstr "Criar mapa UV" msgid "" "Polygon 2D has internal vertices, so it can no longer be edited in the " "viewport." -msgstr "Polygon 2D tem vértices internos, não poder ser editado no viewport." +msgstr "PolÃgono 2D tem vértices internos, não pode ser editado no viewport." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Polygon & UV" @@ -6551,7 +6576,7 @@ msgstr "Pintar pesos dos ossos" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Open Polygon 2D UV editor." -msgstr "Abrir editor UV de Polygon2D." +msgstr "Abrir editor UV de PolÃgono 2D." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon 2D UV Editor" @@ -6803,7 +6828,7 @@ msgstr "Não consigo obter o script para executar." #: editor/plugins/script_editor_plugin.cpp msgid "Script failed reloading, check console for errors." -msgstr "Falhou a re-leitura do script, analise os erros na consola." +msgstr "Falhou a releitura do script, analise os erros na consola." #: editor/plugins/script_editor_plugin.cpp msgid "Script is not in tool mode, will not be able to run." @@ -6943,6 +6968,14 @@ msgstr "Fechar documentos" msgid "Run" msgstr "Executar" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Procurar" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Passar Dentro" @@ -6996,16 +7029,6 @@ msgstr "" "Os seguintes Ficheiros são mais recentes no disco.\n" "Que ação deve ser tomada?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Recarregar" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Reguardar" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Depurador" @@ -7020,7 +7043,7 @@ msgstr "Limpar Scripts Recentes" #: editor/plugins/script_text_editor.cpp msgid "Connections to method:" -msgstr "Conecções ao método:" +msgstr "Conexões ao método:" #: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp msgid "Source" @@ -7098,8 +7121,8 @@ msgstr "Pontos de paragem" msgid "Go To" msgstr "Ir Para" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Cortar" @@ -7322,6 +7345,11 @@ msgid "Yaw" msgstr "Direção" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamanho: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos desenhados" @@ -7399,7 +7427,7 @@ msgstr "Alinhar Rotação com Vista" #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "No parent to instance a child at." -msgstr "Sem parente para criar instância de filho." +msgstr "Sem progenitor para criar instância de filho." #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "This operation requires a single selected node." @@ -7419,7 +7447,7 @@ msgstr "Vista normal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Wireframe" -msgstr "Vista wireframe" +msgstr "Vista Wireframe" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Overdraw" @@ -7971,7 +7999,7 @@ msgstr "TextureRegion" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All Items" -msgstr "Adicionar todos os itens" +msgstr "Adicionar Todos os Itens" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All" @@ -7979,7 +8007,7 @@ msgstr "Adicionar tudo" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove All Items" -msgstr "Remover todos os itens" +msgstr "Remover Todos os Itens" #: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp msgid "Remove All" @@ -7995,11 +8023,11 @@ msgstr "Menu edição de tema." #: editor/plugins/theme_editor_plugin.cpp msgid "Add Class Items" -msgstr "Adicionar itens de classe" +msgstr "Adicionar Itens de Classe" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Class Items" -msgstr "Remover itens de classe" +msgstr "Remover Itens de Classe" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Template" @@ -8413,7 +8441,7 @@ msgstr "" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Delete selected Rect." -msgstr "Eliminar Rect seleccionado." +msgstr "Eliminar Rect selecionado." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -9139,8 +9167,8 @@ msgstr "" "Função SmoothStep( escalar(limite0), escalar(limite1), escalar(x) ).\n" "\n" "Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que " -"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 " -"a usar polinomiais Hermite." +"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 e 1.0 " +"usando polinomiais Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9357,8 +9385,8 @@ msgstr "" "Função SmoothStep( vetor(limite0), vetor(limite1), vetor(x) ).\n" "\n" "Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que " -"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 " -"a usar polinomiais Hermite." +"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 e 1.0 " +"usando polinomiais Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9371,8 +9399,8 @@ msgstr "" "Função SmoothStep( escalar(limite0), escalar(limite1), vetor(x) ).\n" "\n" "Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que " -"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 " -"a usar polinomiais Hermite." +"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 e 1.0 " +"usando polinomiais Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9439,7 +9467,7 @@ msgid "" "direction of camera (pass associated inputs to it)." msgstr "" "Devolve queda baseada no produto escalar da normal à superfÃcie e da direção " -"da câmara (passa entradas associadas)." +"da câmera (passa entradas associadas)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -10001,6 +10029,11 @@ msgid "Projects" msgstr "Projetos" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "A readquirir servidores, espere por favor..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Última modificação" @@ -10461,7 +10494,7 @@ msgstr "Nome do nó" #: editor/rename_dialog.cpp msgid "Node's parent name, if available" -msgstr "Nome do parente do nó, se disponÃvel" +msgstr "Nome do progenitor do nó, se disponÃvel" #: editor/rename_dialog.cpp msgid "Node type" @@ -10557,11 +10590,11 @@ msgstr "No carácter %s" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent Node" -msgstr "Repôr Nó" +msgstr "Reassociar Nó" #: editor/reparent_dialog.cpp msgid "Reparent Location (Select new Parent):" -msgstr "Repôr localização (selecionar novo Parente):" +msgstr "Reassociar Localização (Selecionar novo Progenitor):" #: editor/reparent_dialog.cpp msgid "Keep Global Transform" @@ -10569,7 +10602,7 @@ msgstr "Manter transformação global" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent" -msgstr "Repôr" +msgstr "Reassociar" #: editor/run_settings_dialog.cpp msgid "Run Mode:" @@ -10593,7 +10626,7 @@ msgstr "Configurações de Execução da Cena" #: editor/scene_tree_dock.cpp msgid "No parent to instance the scenes at." -msgstr "Nenhum parente para instância das cenas." +msgstr "Nenhum progenitor para instância das cenas." #: editor/scene_tree_dock.cpp msgid "Error loading scene from %s" @@ -10620,6 +10653,16 @@ msgid "Instance Child Scene" msgstr "Instanciar Cena Filha" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Não consigo operar em nós de uma cena externa!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Colar Nós" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Separar Script" @@ -10629,11 +10672,11 @@ msgstr "Esta operação não pode ser feita na raiz da árvore." #: editor/scene_tree_dock.cpp msgid "Move Node In Parent" -msgstr "Mover Nó no Parente" +msgstr "Mover Nó no Progenitor" #: editor/scene_tree_dock.cpp msgid "Move Nodes In Parent" -msgstr "Mover Nós no Parente" +msgstr "Mover Nós no Progenitor" #: editor/scene_tree_dock.cpp msgid "Duplicate Node(s)" @@ -10642,7 +10685,7 @@ msgstr "Duplicar Nó(s)" #: editor/scene_tree_dock.cpp msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." msgstr "" -"Não consigo mudar nó em cenas herdadas, a ordem dos nós não pode mudar." +"Não consigo reassociar nós em cenas herdadas, a ordem dos nós não pode mudar." #: editor/scene_tree_dock.cpp msgid "Node must belong to the edited scene to become root." @@ -10746,6 +10789,11 @@ msgid "Attach Script" msgstr "Anexar Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Cortar Nós" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Remover Nó(s)" @@ -10813,7 +10861,7 @@ msgstr "Mudar tipo" #: editor/scene_tree_dock.cpp msgid "Reparent to New Node" -msgstr "Repôr o Novo Nó" +msgstr "Reassociar a Novo Nó" #: editor/scene_tree_dock.cpp msgid "Make Scene Root" @@ -11037,7 +11085,7 @@ msgstr "Nome de classe inválido." #: editor/script_create_dialog.cpp msgid "Invalid inherited parent name or path." -msgstr "Nome ou caminho de parente herdado inválido." +msgstr "Nome ou caminho herdado do progenitor inválido." #: editor/script_create_dialog.cpp msgid "Script path/name is valid." @@ -11161,11 +11209,11 @@ msgstr "Empilhar Frames" #: editor/script_editor_debugger.cpp msgid "Profiler" -msgstr "Profiler" +msgstr "Analisador" #: editor/script_editor_debugger.cpp msgid "Network Profiler" -msgstr "Traçador de Rede" +msgstr "Analisador de Rede" #: editor/script_editor_debugger.cpp msgid "Monitor" @@ -11269,11 +11317,11 @@ msgstr "Mudar ângulo de emissão de AudioStreamPlayer3D" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" -msgstr "Mudar FOV da câmara" +msgstr "Mudar FOV da Câmera" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera Size" -msgstr "Mudar tamanho da câmara" +msgstr "Mudar tamanho da Câmera" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -11321,7 +11369,7 @@ msgstr "Mudar Raio do Cilindro" #: modules/csg/csg_gizmos.cpp msgid "Change Cylinder Height" -msgstr "Mudar Altura do CIlindro" +msgstr "Mudar Altura do Cilindro" #: modules/csg/csg_gizmos.cpp msgid "Change Torus Inner Radius" @@ -11547,11 +11595,39 @@ msgstr "Distância de escolha:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Filter meshes" -msgstr "Meshes de filtro" +msgstr "Filtrar malhas" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Give a MeshLibrary resource to this GridMap to use its meshes." -msgstr "Dá um recurso MeshLibrary a este GridMap para usar os seus meshes." +msgstr "Dê um recurso MeshLibrary a este GridMap para usar as suas malhas." + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Começar Consolidação" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "A preparar estruturas de dados" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Gerar buffers" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Iluminação direta" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Iluminação indireta" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "Pós-processamento" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "A Traçar lightmaps" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -11567,7 +11643,7 @@ msgstr "Consolidar NavMesh" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "Limpar a Malha de navegação." +msgstr "Limpar a malha de navegação." #: modules/recast/navigation_mesh_generator.cpp msgid "Setting up Configuration..." @@ -11591,7 +11667,7 @@ msgstr "A construir heightfield compacto..." #: modules/recast/navigation_mesh_generator.cpp msgid "Eroding walkable area..." -msgstr "A corroer a Ãrea caminhável..." +msgstr "A corroer a área caminhável..." #: modules/recast/navigation_mesh_generator.cpp msgid "Partitioning..." @@ -11607,11 +11683,11 @@ msgstr "A criar polymesh..." #: modules/recast/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." -msgstr "A converter para Malha de navegação nativa..." +msgstr "A converter para malha de navegação nativa..." #: modules/recast/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "Configuração do gerador da Malha de navegação:" +msgstr "Configuração do Gerador da Malha de Navegação:" #: modules/recast/navigation_mesh_generator.cpp msgid "Parsing Geometry..." @@ -12067,17 +12143,21 @@ msgid "Select device from the list" msgstr "Selecionar aparelho da lista" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "O executável ADB não está configurado nas Configurações do Editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "Incapaz de localizar a ferramenta 'apksigner'." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "O jarsigner do OpenJDK não está configurado nas Definições do Editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Modelo de compilação Android não está instalado neste projeto. Instale-o no " +"menu Projeto." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." msgstr "" -"Depuração de keystore não configurada nas Configurações do Editor e nem na " +"Keystore de depuração não configurada nas Configurações do Editor e nem na " "predefinição." #: platform/android/export/export.cpp @@ -12086,28 +12166,35 @@ msgstr "" "Lançamento de keystore configurado incorretamente na predefinição exportada." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Compilação personalizada necessita de um caminho válido para Android SDK no " -"Editor de Configurações." +"É necessário um caminho válido para o Android SDK no Editor de Configurações." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Caminho inválido de Android SDK para compilação personalizada no Editor de " -"Configurações." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Caminho inválido para o Android SDK no Editor de Configurações." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Diretoria 'platform-tools' em falta!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "Incapaz de encontrar o comando adb das ferramentas Android SDK." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Modelo de compilação Android não está instalado neste projeto. Instale-o no " -"menu Projeto." +"Por favor confirme a pasta do Android SDK especificada no Editor de " +"Configurações." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Diretoria 'build-tools' em falta!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "Incapaz de encontrar o comando apksigner das ferramentas Android SDK." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12299,7 +12386,7 @@ msgstr "Cor de fundo inválida." #: platform/uwp/export/export.cpp msgid "Invalid Store Logo image dimensions (should be 50x50)." -msgstr "Inválidas dimensões da imagem do logotipo do Store (deve ser 50x50)." +msgstr "Dimensões inválidas da imagem do logotipo do Store (deve ser 50x50)." #: platform/uwp/export/export.cpp msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." @@ -12420,7 +12507,7 @@ msgstr "Nó B tem de ser um PhysicsBody2D" #: scene/2d/joints_2d.cpp msgid "Joint is not connected to two PhysicsBody2Ds" -msgstr "Junção não está conetada a dois PhysicsBody2Ds" +msgstr "Junção não está conectada a dois PhysicsBody2Ds" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be different PhysicsBody2Ds" @@ -12521,7 +12608,7 @@ msgstr "Esta corrente de Bone2D deve terminar num nó Skeleton2D." #: scene/2d/skeleton_2d.cpp msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." -msgstr "Um Bone2D só funciona com um nó parente Skeleton2D ou Bone2D." +msgstr "Um Bone2D só funciona com um nó progenitor Skeleton2D ou Bone2D." #: scene/2d/skeleton_2d.cpp msgid "" @@ -12534,25 +12621,25 @@ msgid "" "to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " "KinematicBody2D, etc. to give them a shape." msgstr "" -"TileMap com Usar Parente ativo precisa de um parente CollisionObject2D para " -"lhe dar formas. Use-o como um filho de Area2D, StaticBody2D, RigidBody2D, " -"KinematicBody2D, etc. para lhes dar uma forma." +"TileMap com Usar Progenitor ativo precisa de um progenitor CollisionObject2D " +"para lhe dar formas. Use-o como um filho de Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D, etc. para lhes dar uma forma." #: scene/2d/visibility_notifier_2d.cpp msgid "" "VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" -"VisibilityEnabler2D funciona melhor quando usado diretamente como parente na " -"cena raiz editada." +"VisibilityEnabler2D funciona melhor quando usado diretamente como progenitor " +"na cena raiz editada." #: scene/3d/arvr_nodes.cpp msgid "ARVRCamera must have an ARVROrigin node as its parent." -msgstr "ARVRCamera precisa de um nó ARVROrigin como parente." +msgstr "ARVRCamera precisa de um nó ARVROrigin como progenitor." #: scene/3d/arvr_nodes.cpp msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "ARVRController precisa de um nó ARVROrigin como parente." +msgstr "ARVRController precisa de um nó ARVROrigin como progenitor." #: scene/3d/arvr_nodes.cpp msgid "" @@ -12564,7 +12651,7 @@ msgstr "" #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor precisa de um nó ARVROrigin como parente." +msgstr "ARVRAnchor precisa de um nó ARVROrigin como progenitor." #: scene/3d/arvr_nodes.cpp msgid "" @@ -12579,28 +12666,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin exige um nó filho ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "A procurar malhas e luzes" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Tempo restante: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" +msgstr "A preparar geometria (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "A traçar Meshes: " +msgid "Preparing environment" +msgstr "A preparar ambiente" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "A traçar Luzes:" +msgid "Generating capture" +msgstr "A gerar captura" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "A concluir desenho" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "A guardar lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "A iluminar Meshes: " +msgid "Done" +msgstr "Feito" #: scene/3d/collision_object.cpp msgid "" @@ -12659,7 +12746,7 @@ msgstr "ConcavePolygonShape apenas suporta RigidBody no modo estático." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." -msgstr "Nada é visÃvel porque nenhuma Malha foi atribuÃda." +msgstr "Nada é visÃvel porque nenhuma malha foi atribuÃda." #: scene/3d/cpu_particles.cpp msgid "" @@ -12671,7 +12758,11 @@ msgstr "" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" -msgstr "A desenhar Meshes" +msgstr "A Traçar Malhas" + +#: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "A concluir desenho" #: scene/3d/gi_probe.cpp msgid "" @@ -12684,7 +12775,7 @@ msgstr "" #: scene/3d/interpolated_camera.cpp msgid "" "InterpolatedCamera has been deprecated and will be removed in Godot 4.0." -msgstr "A InterpolatedCamerda foi deprecada e será removida no Godot 4.0." +msgstr "InterpolatedCamerda foi descontinuada e será removida no Godot 4.0." #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." @@ -12718,7 +12809,7 @@ msgstr "" msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" -"Nada é visÃvel porque não foram atribuÃdas Meshes aos passos de desenho." +"Nada é visÃvel porque não foram atribuÃdas malhas aos passos de desenho." #: scene/3d/particles.cpp msgid "" @@ -12738,7 +12829,7 @@ msgid "" "parent Path's Curve resource." msgstr "" "ROTATION_ORIENTED de PathFollow requer \"Up Vector\" ativado no recurso de " -"Curva do Caminho do seu pai." +"Curva do Caminho do seu progenitor." #: scene/3d/physics_body.cpp msgid "" @@ -12764,7 +12855,7 @@ msgstr "Nó B tem de ser um PhysicsBody" #: scene/3d/physics_joint.cpp msgid "Joint is not connected to any PhysicsBodies" -msgstr "Junção não está conetada a quaisquer PhysicsBodies" +msgstr "Junção não está conectada a quaisquer PhysicsBodies" #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be different PhysicsBodies" @@ -12828,7 +12919,7 @@ msgid "" "This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " "this environment's Background Mode to Canvas (for 2D scenes)." msgstr "" -"Este WorldEnvironment Ä— ignorado. Pode adicionar uma Camera (para cenas 3D) " +"Este WorldEnvironment é ignorado. Pode adicionar uma Câmera (para cenas 3D) " "ou definir o Modo Background deste ambiente como Canvas (para cenas 2D)." #: scene/animation/animation_blend_tree.cpp @@ -12930,10 +13021,13 @@ msgstr "Alerta!" msgid "Please Confirm..." msgstr "Confirme por favor..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Deve usar uma extensão válida." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Ativar Ajuste" +msgstr "Ativar grelha do minimapa." #: scene/gui/popup.cpp msgid "" @@ -12988,6 +13082,14 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "O tamanho do viewport tem de ser maior do que 0 para renderizar." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"A porta coletora está conectada mas não é usada. Considere mudar a origem " +"para 'SamplerPort'." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fonte inválida para pré-visualização." @@ -13015,6 +13117,36 @@ msgstr "Variações só podem ser atribuÃdas na função vértice." msgid "Constants cannot be modified." msgstr "Constantes não podem ser modificadas." +#~ msgid "No" +#~ msgstr "Não" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Esta cena nunca foi guardada. Guardar antes de executar?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "O executável ADB não está configurado nas Configurações do Editor." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "" +#~ "O jarsigner do OpenJDK não está configurado nas Definições do Editor." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Compilação personalizada necessita de um caminho válido para Android SDK " +#~ "no Editor de Configurações." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Tempo restante: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "A traçar Meshes: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "A iluminar Meshes: " + #~ msgid "Search complete" #~ msgstr "Pesquisa completa" @@ -13027,12 +13159,6 @@ msgstr "Constantes não podem ser modificadas." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "Já existe um ficheiro ou pasta com o mesmo nome nesta localização." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Diretoria 'build-tools' em falta!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Incapaz de localizar a ferramenta zipalign." - #~ msgid "Aligning APK..." #~ msgstr "A alinhar APK..." @@ -13375,9 +13501,6 @@ msgstr "Constantes não podem ser modificadas." #~ msgid "Failed to save solution." #~ msgstr "Falha ao guardar solução." -#~ msgid "Done" -#~ msgstr "Feito" - #~ msgid "Failed to create C# project." #~ msgstr "Falha ao criar projeto C#." diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 509d1833b1..f4535819c2 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -105,12 +105,19 @@ # Elton <eltondeoliveira@outlook.com>, 2020. # ThiagoCTN <thiagocampostn@gmail.com>, 2020. # Alec Santos <alecsantos96@gmail.com>, 2020. +# Augusto Milão <augusto.milao01@gmail.com>, 2021. +# Gabriel Gavazzi Felix <mutcholoko32@gmail.com>, 2021. +# Lucas Dantas <lucas.lucantas38@gmail.com>, 2021. +# Carlos Bonifacio <carlosboni.sa@gmail.com>, 2021. +# Lucas Castro <castroclucas@gmail.com>, 2021. +# Ricardo Zamarrenho Carvalho Correa <ricardozcc17@gmail.com>, 2021. +# Diego dos Reis Macedo <diego_dragon97@hotmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2020-12-19 04:29+0000\n" -"Last-Translator: ThiagoCTN <thiagocampostn@gmail.com>\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" +"Last-Translator: Carlos Bonifacio <carlosboni.sa@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -118,7 +125,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -746,7 +753,7 @@ msgstr "Selecionar Trilhas para Copiar" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copiar" @@ -1855,7 +1862,7 @@ msgstr "Novo" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "Import" +msgstr "Importar" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -2044,10 +2051,6 @@ msgstr "Previsualização:" msgid "File:" msgstr "Arquivo:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Deve usar uma extensão válida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "BuscarFontes" @@ -2484,6 +2487,10 @@ msgid "There is no defined scene to run." msgstr "Não há cena definida para rodar." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Salvar a cena antes de executar..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Não se pôde iniciar sub-processo!" @@ -2527,18 +2534,6 @@ msgstr "Um nó raiz é requerido para salvar a cena." msgid "Save Scene As..." msgstr "Salvar Cena Como..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Não" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Sim" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Esta cena nunca foi salva. Salvar antes de rodar?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Essa operação não pode ser realizada sem uma cena." @@ -2588,6 +2583,10 @@ msgid "Quit" msgstr "Sair" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Sim" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Sair do editor?" @@ -2636,7 +2635,8 @@ msgstr "" "falhou." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Não foi possÃvel encontrar o campo de script para o plugin em: 'res://addons/" "%s'." @@ -3071,14 +3071,6 @@ msgid "Help" msgstr "Ajuda" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Pesquisar" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Documentação Online" @@ -3244,6 +3236,25 @@ msgid "Open & Run a Script" msgstr "Abrir e Rodar um Script" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Os seguintes arquivos são mais recentes no disco.\n" +"Que ação deve ser tomada?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Recarregar" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Salve novamente" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Novo Herdado" @@ -3455,7 +3466,7 @@ msgstr "Tornar Único" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Colar" @@ -4017,19 +4028,16 @@ msgid "Searching..." msgstr "Procurando..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d correspondências." +msgstr "%d correspondência em %d arquivo." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d correspondências." +msgstr "%d correspondências em %d arquivo." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d correspondências." +msgstr "%d correspondências em %d arquivos." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5137,7 +5145,8 @@ msgid "Got:" msgstr "Obtido:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Falha na verificação da hash sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5272,12 +5281,10 @@ msgstr "Arquivo ZIP de Assets" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Não foi possÃvel determinar um caminho para salvar as imagens do lightmap.\n" -"Salve sua cena (para que as imagens sejam salvas no mesmo diretório), ou " -"escolha um caminho nas propriedades do BakedLightmap." +"Salve sua cena e tente novamente." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5294,8 +5301,33 @@ msgstr "" "permissões de escrita." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Falha ao determinar o tamanho do lightmap. Tamanho máximo do lightmap é " +"muito baixo?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Alguma malha é inválida. Certifique-se de que os valores do canal UV2 estão " +"contidos na região quadrada [0.0,1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"O editor Godot foi construÃdo sem suporte à ray tracing, os lightmaps não " +"podem ser bakeados." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" -msgstr "Preparar Lightmaps" +msgstr "Bake Lightmaps" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Selecione o arquivo de lightmap bake:" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6391,6 +6423,10 @@ msgstr "" "Só é permitido colocar um ponto em um material processador ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Converter para CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Gerando Tempo (seg):" @@ -6451,10 +6487,6 @@ msgstr "Gerando AABB" msgid "Generate Visibility AABB" msgstr "Gerar AABB de Visibilidade" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Gerar AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Remover Ponto da Curva" @@ -7046,6 +7078,14 @@ msgstr "Fechar Docs" msgid "Run" msgstr "Rodar" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Pesquisar" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Passo para dentro" @@ -7099,16 +7139,6 @@ msgstr "" "Os seguintes arquivos são mais recentes no disco.\n" "Que ação deve ser tomada?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Recarregar" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Salve novamente" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Depurador" @@ -7202,8 +7232,8 @@ msgstr "Breakpoints" msgid "Go To" msgstr "Ir Para" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Recortar" @@ -7426,6 +7456,11 @@ msgid "Yaw" msgstr "Guinada" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamanho: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Desenhados" @@ -8844,9 +8879,8 @@ msgid "Visual Shader Input Type Changed" msgstr "Tipo de Entrada de Shader Visual Alterado" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "UniformRef Name Changed" -msgstr "Definir Nome Uniforme" +msgstr "UniformRef Name foi altearado" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" @@ -9561,7 +9595,6 @@ msgstr "" "uniformes e constantes." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "A reference to an existing uniform." msgstr "Uma referência a um uniforme existente." @@ -10111,6 +10144,11 @@ msgid "Projects" msgstr "Projetos" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Reconectando, por favor aguarde." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Ultima Modificação" @@ -10730,6 +10768,16 @@ msgid "Instance Child Scene" msgstr "Instânciar Cena Filha" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Não é possÃvel operar em nós de uma cena externa!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Colar Nodes" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Remover Script" @@ -10856,6 +10904,11 @@ msgid "Attach Script" msgstr "Adicionar Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Recortar Nós" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Remover Nó(s)" @@ -11663,6 +11716,36 @@ msgstr "Filtrar malhas" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Atribua um recurso MeshLibrary a este GridMap para usar seus meshes." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Iniciar pré-cálculo" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Preparando estruturas de dados" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Gerar buffers" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "Direct lightning" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Iluminação indireta" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Pós-processamento" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Traçando mapas de luz" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Nome da classe não pode ser uma palavra reservada" @@ -12179,12 +12262,16 @@ msgid "Select device from the list" msgstr "Selecione um dispositivo da lista" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Executável ADB não configurado nas opções do Editor." +msgid "Unable to find the 'apksigner' tool." +msgstr "Não foi possÃvel encontrar a ferramenta 'apksigner'." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner não configurado nas opções do Editor." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"O modelo de compilação do Android não foi instalado no projeto. Instale " +"através do menu Projeto." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12199,28 +12286,37 @@ msgstr "" "exportação." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "Um caminho Android SDK é necessário nas Configurações do Editor." + +#: platform/android/export/export.cpp +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Caminho do Android SDK está inválido para Configurações do Editor." + +#: platform/android/export/export.cpp +msgid "Missing 'platform-tools' directory!" +msgstr "Diretório 'ferramentas-da-plataforma' ausente!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" -"Build personalizada precisa de um caminho Android SDK válido em " -"Configurações do Editor." +"Não foi possÃvel encontrar o comando adb nas ferramentas do Android SDK." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Caminho do Android SDK inválido para o build personalizado em Configurações " +"Por favor, verifique o caminho do Android SDK especificado nas Configurações " "do Editor." #: platform/android/export/export.cpp -msgid "Missing 'platform-tools' directory!" -msgstr "Diretório 'ferramentas-da-plataforma' ausente!" +msgid "Missing 'build-tools' directory!" +msgstr "Diretório 'ferramentas-da-plataforma' está faltando !" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"O modelo de compilação do Android não foi instalado no projeto. Instale " -"através do menu Projeto." +"Não foi possÃvel encontrar o comando apksigner nas ferramentas de build do " +"Android SDK." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12273,11 +12369,11 @@ msgstr "" #: platform/android/export/export.cpp msgid "Invalid filename! Android App Bundle requires the *.aab extension." -msgstr "" +msgstr "Nome de arquivo invalido! Android App Bunlde requer a extensão *.aab." #: platform/android/export/export.cpp msgid "APK Expansion not compatible with Android App Bundle." -msgstr "" +msgstr "A expansão APK não é compatÃvel com o Android App Bundle." #: platform/android/export/export.cpp msgid "Invalid filename! Android APK requires the *.apk extension." @@ -12326,6 +12422,8 @@ msgid "" "Unable to copy and rename export file, check gradle project directory for " "outputs." msgstr "" +"Não foi possÃvel copiar e renomear o arquivo de exportação, verifique o " +"diretório do projeto gradle por saÃdas." #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -12514,23 +12612,23 @@ msgstr "" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be PhysicsBody2Ds" -msgstr "" +msgstr "O Nó A e o Nó B devem ser PhysicsBody2Ds" #: scene/2d/joints_2d.cpp msgid "Node A must be a PhysicsBody2D" -msgstr "" +msgstr "O Nó A deve ser um PhysicsBody2D" #: scene/2d/joints_2d.cpp msgid "Node B must be a PhysicsBody2D" -msgstr "" +msgstr "O Nó A deve ser um PhysicsBody2D" #: scene/2d/joints_2d.cpp msgid "Joint is not connected to two PhysicsBody2Ds" -msgstr "" +msgstr "A Junta não está conectada a dois PhysicsBody2Ds" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be different PhysicsBody2Ds" -msgstr "" +msgstr "O Nó A e o Nó B devem ser diferentes PhysicsBody2Ds" #: scene/2d/light_2d.cpp msgid "" @@ -12687,28 +12785,30 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin necessita um nó ARVRCamera como filho." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Encontrando malhas e luzes" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Tempo Restante: %d:%02d s)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Analisando Geometria..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Planejando Malhas: " +msgid "Preparing environment" +msgstr "Preparando ambiente" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Planejando Luzes:" +msgid "Generating capture" +msgstr "Gerando captura" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Terminando de Plotar" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Salvando mapas de luz" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Iluminando Malhas: " +msgid "Done" +msgstr "Pronto" #: scene/3d/collision_object.cpp msgid "" @@ -12784,6 +12884,10 @@ msgid "Plotting Meshes" msgstr "Planejando Malhas" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Terminando de Plotar" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12862,23 +12966,23 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be PhysicsBodies" -msgstr "" +msgstr "Nó A e Nó B devem ser PhysicsBodys" #: scene/3d/physics_joint.cpp msgid "Node A must be a PhysicsBody" -msgstr "" +msgstr "Nó A deve ser PhysicsBody" #: scene/3d/physics_joint.cpp msgid "Node B must be a PhysicsBody" -msgstr "" +msgstr "Nó B deve ser um PhysicsBody" #: scene/3d/physics_joint.cpp msgid "Joint is not connected to any PhysicsBodies" -msgstr "" +msgstr "A junta não está conectada a nenhum PhysicsBody" #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be different PhysicsBodies" -msgstr "" +msgstr "Nó A e Nó B devem ser diferente PhysicsBodies" #: scene/3d/remote_transform.cpp msgid "" @@ -13041,10 +13145,13 @@ msgstr "Alerta!" msgid "Please Confirm..." msgstr "Confirme Por Favor..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Deve usar uma extensão válida." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Ativar Snap" +msgstr "Ativar minimapa de grade." #: scene/gui/popup.cpp msgid "" @@ -13101,6 +13208,14 @@ msgstr "" "O tamanho da Viewport deve ser maior do que 0 para renderizar qualquer coisa." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"A porta sampler está conectada mas não está sendo usada. Considere alterar a " +"fonte para 'SamplerPort'." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fonte inválida para a prévia." @@ -13128,6 +13243,35 @@ msgstr "Variáveis só podem ser atribuÃdas na função de vértice." msgid "Constants cannot be modified." msgstr "Constantes não podem serem modificadas." +#~ msgid "No" +#~ msgstr "Não" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Esta cena nunca foi salva. Salvar antes de rodar?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Executável ADB não configurado nas opções do Editor." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner não configurado nas opções do Editor." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Build personalizada precisa de um caminho Android SDK válido em " +#~ "Configurações do Editor." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Tempo Restante: %d:%02d s)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Planejando Malhas: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Iluminando Malhas: " + #~ msgid "Search complete" #~ msgstr "Pesquisa concluÃda" @@ -13471,9 +13615,6 @@ msgstr "Constantes não podem serem modificadas." #~ msgid "Failed to save solution." #~ msgstr "Falha ao salvar solução." -#~ msgid "Done" -#~ msgstr "Pronto" - #~ msgid "Failed to create C# project." #~ msgstr "Falha ao criar projeto C#." diff --git a/editor/translations/ro.po b/editor/translations/ro.po index c0337a3413..1843f25bf0 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -661,7 +661,7 @@ msgstr "Selectează Pistele de Copiat" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Copiază" @@ -1966,10 +1966,6 @@ msgstr "PrevizualizaÈ›i:" msgid "File:" msgstr "FiÈ™ier:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Trebuie să utilizaÅ£i o extensie valida." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "SurseScan" @@ -2404,6 +2400,10 @@ msgid "There is no defined scene to run." msgstr "Nu există nici o scenă definită pentru a execuÈ›ie." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Nu s-a putut porni subprocesul!" @@ -2447,18 +2447,6 @@ msgstr "Un nod rădăcină este necesar pentru a salva scena." msgid "Save Scene As..." msgstr "Salvează scena ca..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nu" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Da" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Această scenă nu a fost salvată niciodata. SalvaÈ›i înainte de rulare?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Această operaÈ›ie nu se poate face fără o scenă." @@ -2508,6 +2496,10 @@ msgid "Quit" msgstr "ÃŽnchide" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Da" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "IeÈ™i din editor?" @@ -2556,7 +2548,8 @@ msgstr "" "Nu se poate iniÈ›ializa plugin-ul la: '%s' analizarea configuraÈ›iei a eÈ™uat." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Nu a putut fi găsit câmpul scriptului pentru plugin la: 'res://addons/%s'." @@ -2993,14 +2986,6 @@ msgid "Help" msgstr "Ajutor" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Căutare" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "DocumentaÈ›ie Online" @@ -3156,6 +3141,23 @@ msgid "Open & Run a Script" msgstr "Deschide È™i Execută un Script" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "Următoarele file au eÈ™uat extragerea din pachet:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Derivare Nouă" @@ -3358,7 +3360,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -5041,7 +5043,8 @@ msgid "Got:" msgstr "Primit:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Verificare hash sha256 eÈ™uată" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5179,10 +5182,10 @@ msgid "Assets ZIP File" msgstr "FiÈ™ier ZIP cu Asset-uri" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Nu se poate determina p cale de salvare pentru imaginile lightmap.\n" "Salvează scena (imaginile vor fi salvate în acelasi director), sau alege o " @@ -5203,9 +5206,29 @@ msgstr "" "ele." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Procesează Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Selectare fiÈ™ier È™ablon" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6338,6 +6361,11 @@ msgstr "" "ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Conversie în Mesh2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Timp de Generare (sec):" @@ -6401,10 +6429,6 @@ msgstr "Generare AABB" msgid "Generate Visibility AABB" msgstr "Generare Vizibilitate AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Generare AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Ștergere Punt din Curbă" @@ -7018,6 +7042,14 @@ msgstr "" msgid "Run" msgstr "Execută" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Căutare" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7070,16 +7102,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7180,8 +7202,8 @@ msgstr "Șterge puncte" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7414,6 +7436,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10052,6 +10078,11 @@ msgid "Projects" msgstr "Proiect" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Se recuperează oglinzile, te rog aÈ™teaptă..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10669,6 +10700,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "LipeÈ™te Postura" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Curăță Scriptul" @@ -10798,6 +10838,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Creează Nod" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11615,6 +11660,38 @@ msgstr "Filtru meshuri" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "Generare AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "DirecÈ›ii" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Setare expresie" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Se Genereaza Lightmaps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12127,11 +12204,13 @@ msgid "Select device from the list" msgstr "Selectează un dispozitiv din listă" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12143,11 +12222,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12155,9 +12234,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12554,28 +12643,33 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "Analiza geometriei..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "" +#, fuzzy +msgid "Preparing environment" +msgstr "Analiza geometriei..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Se Genereaza Lightmaps" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Se Genereaza Lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "" +#, fuzzy +msgid "Done" +msgstr "Efectuat!" #: scene/3d/collision_object.cpp msgid "" @@ -12634,6 +12728,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12850,6 +12948,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Trebuie să utilizaÅ£i o extensie valida." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -12896,6 +12998,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12923,6 +13031,13 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "Nu" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Această scenă nu a fost salvată niciodata. SalvaÈ›i înainte de rulare?" + #~ msgid "Search complete" #~ msgstr "Căutare completă" @@ -13171,10 +13286,6 @@ msgstr "" #~ msgstr "Creează un Corp Static Convex" #, fuzzy -#~ msgid "Custom Node" -#~ msgstr "Creează Nod" - -#, fuzzy #~ msgid "Snap (s): " #~ msgstr "Pas (s):" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index c16d7a8e59..a38646e2e8 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -56,7 +56,7 @@ # КонÑтантин Рин <email.to.rean@gmail.com>, 2019, 2020. # Maxim Samburskiy <alpacones@outlook.com>, 2019. # Dima Koshel <form.eater@gmail.com>, 2019. -# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020. +# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020, 2021. # Ravager <al.porkhunov@gmail.com>, 2019. # ÐлекÑандр <akonn7@mail.ru>, 2019. # Rei <clxgamer12@gmail.com>, 2019. @@ -90,11 +90,13 @@ # Cube Show <griiv.06@gmail.com>, 2020. # Roman Tolkachyov <roman@tolkachyov.name>, 2020. # Igor Grachev <igorecha.9999@gmail.com>, 2020. +# Dmytro Meleshko <dmytro.meleshko@gmail.com>, 2021. +# narrnika <narr13niki@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-21 00:29+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -104,7 +106,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -732,7 +734,7 @@ msgstr "Выбрать треки Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Копировать" @@ -2029,10 +2031,6 @@ msgstr "ПредпроÑмотр:" msgid "File:" msgstr "Файл:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Ðужно иÑпользовать доÑтупное раÑширение." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Сканировать иÑходники" @@ -2470,6 +2468,10 @@ msgid "There is no defined scene to run." msgstr "Ðет открытой Ñцены Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Сохранение Ñцены перед запуÑком..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить подпроцеÑÑ!" @@ -2513,18 +2515,6 @@ msgstr "Ð”Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñцены требуетÑÑ ÐºÐ¾Ñ€Ð½ÐµÐ²Ð¾ msgid "Save Scene As..." msgstr "Сохранить Ñцену как..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ðет" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Да" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Ðта Ñцена никогда не была Ñохранена. Сохранить перед запуÑком?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ðта Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ðµ может быть выполнена без Ñцены." @@ -2574,6 +2564,10 @@ msgid "Quit" msgstr "Выход" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Да" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Выйти из редактора?" @@ -2621,7 +2615,8 @@ msgstr "" "конфигурации." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Ðе удаётÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ поле script Ð´Ð»Ñ Ð¿Ð»Ð°Ð³Ð¸Ð½Ð°: «res://addons/%s»." #: editor/editor_node.cpp @@ -3052,14 +3047,6 @@ msgid "Help" msgstr "Справка" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "ПоиÑк" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Онлайн документациÑ" @@ -3226,6 +3213,24 @@ msgid "Open & Run a Script" msgstr "Открыть и запуÑтить Ñкрипт" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Следующие файлы изменены на диÑке.\n" +"Какое дейÑтвие Ñледует выполнить?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Перезагрузить" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "ПереÑохранить" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "ÐÐ¾Ð²Ð°Ñ ÑƒÐ½Ð°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñцена" @@ -3436,7 +3441,7 @@ msgstr "Сделать уникальным" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Ð’Ñтавить" @@ -3560,7 +3565,7 @@ msgstr "(Текущий)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait..." -msgstr "Получение зеркал, пожалуйÑта подождите..." +msgstr "Получение зеркал, пожалуйÑта, подождите..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" @@ -3994,19 +3999,16 @@ msgid "Searching..." msgstr "ПоиÑк..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d ÑовпадениÑ(ий)." +msgstr "%d Ñовпадение в %d файле." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d ÑовпадениÑ(ий)." +msgstr "%d ÑовпадениÑ(ий) в %d файле." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d ÑовпадениÑ(ий)." +msgstr "%d ÑовпадениÑ(ий) в %d файле(ах)." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5109,7 +5111,8 @@ msgid "Got:" msgstr "Получено:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Ðе удалоÑÑŒ проверить sha256 Ñ…Ñш" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5244,12 +5247,10 @@ msgstr "ZIP файл аÑÑетов" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"Ðе удаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ путь Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ lightmap.\n" -"Сохраните ваши Ñцены (чтобы Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ Ñохранены в том же разделе), " -"или выберите путь ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð² ÑвойÑтвах BakedLightmap." +"Ðе удалоÑÑŒ определить путь Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ карты оÑвещениÑ.\n" +"Сохраните Ñцену и попробуйте ещё раз." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5265,9 +5266,34 @@ msgstr "" "Сбой ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ оÑвещенноÑти, убедитеÑÑŒ, что путь доÑтупен Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Ðе удалоÑÑŒ определить размер карты оÑвещениÑ. МакÑимальный размер карты " +"оÑÐ²ÐµÑ‰ÐµÐ½Ð¸Ñ Ñлишком мал?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"ÐÐµÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñетка некорректна. УбедитеÑÑŒ, что Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð° UV2 " +"находÑÑ‚ÑÑ Ð² квадратной облаÑти [0.0,1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Редактор Godot был Ñобран без поддержки траÑÑировки лучей, карты оÑÐ²ÐµÑ‰ÐµÐ½Ð¸Ñ " +"невозможно запечь." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Запекать карты оÑвещениÑ" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Выберите файл Ð·Ð°Ð¿ÐµÐºÐ°Ð½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ оÑвещениÑ:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -5714,7 +5740,7 @@ msgstr "ОчиÑтить пользовательÑкие коÑти" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "Обзор" +msgstr "Вид" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Always Show Grid" @@ -5754,7 +5780,7 @@ msgstr "Кадрировать выбранное" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "ПроÑмотреть Canvas Scale" +msgstr "ПредпроÑмотр Canvas Scale" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -6358,6 +6384,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Возможно уÑтановить точку только в ParticlesMaterial материал" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Преобразовать в CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ (Ñек):" @@ -6418,10 +6448,6 @@ msgstr "Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ AABB" msgid "Generate Visibility AABB" msgstr "Генерировать AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Генерировать AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Удалить точку Ñ ÐºÑ€Ð¸Ð²Ð¾Ð¹" @@ -6726,7 +6752,7 @@ msgstr "ПривÑзка" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "Ðктивировать привÑзку" +msgstr "Включить привÑзку" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" @@ -7012,6 +7038,14 @@ msgstr "Закрыть документацию" msgid "Run" msgstr "ЗапуÑтить" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "ПоиÑк" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Шаг в" @@ -7065,16 +7099,6 @@ msgstr "" "Следующие файлы новее на диÑке.\n" "Какие меры должны быть принÑты?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Перезагрузить" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "ПереÑохранить" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Отладчик" @@ -7171,8 +7195,8 @@ msgstr "Точки оÑтанова" msgid "Go To" msgstr "Перейти к" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Вырезать" @@ -7395,8 +7419,12 @@ msgid "Yaw" msgstr "Ð Ñ‹Ñкание" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Размер" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" -msgstr "ÐариÑовано обьектов" +msgstr "ÐариÑовано объектов" #: editor/plugins/spatial_editor_plugin.cpp msgid "Material Changes" @@ -10078,6 +10106,10 @@ msgid "Projects" msgstr "Проекты" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Загрузка, пожалуйÑта, ждите..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "ПоÑледнее изменение" @@ -10698,6 +10730,16 @@ msgid "Instance Child Scene" msgstr "Добавить дочернюю Ñцену" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Ðе могу работать Ñ ÑƒÐ·Ð»Ð°Ð¼Ð¸ из внешней Ñцены!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Ð’Ñтавить узлы" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Открепить Ñкрипт" @@ -10825,6 +10867,11 @@ msgid "Attach Script" msgstr "Прикрепить Ñкрипт" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Вырезать узлы" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Удалить узел(узлы)" @@ -11633,6 +11680,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "ПредоÑтавьте реÑÑƒÑ€Ñ MeshLibrary Ñтой GridMap, чтобы иÑпользовать его Ñетки." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Ðачать запекание" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Подготовка Ñтруктур данных" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Генерировать буфферы" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "ПрÑмое оÑвещение" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "ÐепрÑмое оÑвещение" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "ПоÑтобработка" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "ПоÑтроение карт оÑвещениÑ" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Ð˜Ð¼Ñ ÐºÐ»Ð°ÑÑа не может быть зарезервированным ключевым Ñловом" @@ -12145,12 +12220,15 @@ msgid "Select device from the list" msgstr "Выберите уÑтройÑтво из ÑпиÑка" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ИÑполнÑемый файл ADB не Ñконфигурирован в наÑтройках редактора." +msgid "Unable to find the 'apksigner' tool." +msgstr "Ðе удалоÑÑŒ найти инÑтрумент «apksigner»." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner не наÑтроен в ÐаÑтройках Редактора." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Шаблон Ñборки Android не уÑтановлен в проекте. УÑтановите его в меню проекта." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12164,27 +12242,34 @@ msgstr "" "Хранилище ключей не наÑтроено ни в наÑтройках редактора, ни в предуÑтановках." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"ПользовательÑÐºÐ°Ñ Ñборка требует Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð³Ð¾ пути к Android SDK в " -"наÑтройках редактора." +"ТребуетÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ дейÑтвительный путь к Android SDK в ÐаÑтройках редактора." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Ðеправильный путь к Android SDK Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑкой Ñборки в наÑтройках " -"редактора." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "ÐедейÑтвительный путь Android SDK в ÐаÑтройках редактора." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Â«platform-tools» отÑутÑтвует!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "Ðе удалоÑÑŒ найти команду adb в Android SDK platform-tools." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Шаблон Ñборки Android не уÑтановлен в проекте. УÑтановите его в меню проекта." +"ПожалуйÑта, проверьте каталог Android SDK, указанный в ÐаÑтройках редактора." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Â«build-tools» отÑутÑтвует!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "Ðе удалоÑÑŒ найти команду apksigner в Android SDK build-tools." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12656,28 +12741,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin требует дочерний узел ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "ПоиÑк полиÑеток и иÑточников Ñвета" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(ОÑталоÑÑŒ: %d:%02d Ñек)" +msgid "Preparing geometry (%d/%d)" +msgstr "Подготовка геометрии (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "ПоÑтроение полиÑетки: " +msgid "Preparing environment" +msgstr "Подготовка окружениÑ" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "ПоÑтроение Ñвета:" +msgid "Generating capture" +msgstr "Создание захвата" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Завершение поÑтроениÑ" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Сохранение карт оÑвещениÑ" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "ОÑвещение полиÑетки: " +msgid "Done" +msgstr "Готово" #: scene/3d/collision_object.cpp msgid "" @@ -12752,6 +12837,10 @@ msgid "Plotting Meshes" msgstr "ПоÑтроение полиÑетки" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Завершение поÑтроениÑ" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13006,10 +13095,13 @@ msgstr "Внимание!" msgid "Please Confirm..." msgstr "Подтверждение..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Ðужно иÑпользовать доÑтупное раÑширение." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Ðктивировать привÑзку" +msgstr "Включить миникарту Ñетки." #: scene/gui/popup.cpp msgid "" @@ -13066,6 +13158,14 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Размер окна проÑмотра должен быть больше 0 Ð´Ð»Ñ Ñ€ÐµÐ½Ð´ÐµÑ€Ð¸Ð½Ð³Ð°." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Порт ÑÑмплера подключен, но не иÑпользуетÑÑ. РаÑÑмотрите возможноÑть " +"Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ñточника на «SamplerPort»." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ðеверный иÑточник Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра." @@ -13093,6 +13193,35 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð msgid "Constants cannot be modified." msgstr "КонÑтанты не могут быть изменены." +#~ msgid "No" +#~ msgstr "Ðет" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ðта Ñцена никогда не была Ñохранена. Сохранить перед запуÑком?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ИÑполнÑемый файл ADB не Ñконфигурирован в наÑтройках редактора." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner не наÑтроен в ÐаÑтройках Редактора." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "ПользовательÑÐºÐ°Ñ Ñборка требует Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð³Ð¾ пути к Android SDK в " +#~ "наÑтройках редактора." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(ОÑталоÑÑŒ: %d:%02d Ñек)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "ПоÑтроение полиÑетки: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "ОÑвещение полиÑетки: " + #~ msgid "Search complete" #~ msgstr "ПоиÑк завершен" @@ -13105,12 +13234,6 @@ msgstr "КонÑтанты не могут быть изменены." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "По Ñтому пути уже ÑущеÑтвует файл или папка Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ð¼ именем." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Â«build-tools» отÑутÑтвует!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Ðе удалоÑÑŒ найти инÑтрумент zipalign." - #~ msgid "Aligning APK..." #~ msgstr "Выравнивание APK..." @@ -13453,9 +13576,6 @@ msgstr "КонÑтанты не могут быть изменены." #~ msgid "Failed to save solution." #~ msgstr "Ðе удалоÑÑŒ Ñохранить решение." -#~ msgid "Done" -#~ msgstr "Готово" - #~ msgid "Failed to create C# project." #~ msgstr "Ðе удалоÑÑŒ Ñоздать C# проект." diff --git a/editor/translations/si.po b/editor/translations/si.po index e7f0199198..062cf64646 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -3,12 +3,13 @@ # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. # Yohan Sandun <Yohan99ysk@gmail.com>, 2018. +# thushariii <thusharipahalage@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-12-13 14:42+0100\n" -"Last-Translator: Yohan Sandun <Yohan99ysk@gmail.com>\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" +"Last-Translator: thushariii <thusharipahalage@gmail.com>\n" "Language-Team: Sinhala <https://hosted.weblate.org/projects/godot-engine/" "godot/si/>\n" "Language: si\n" @@ -16,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -103,11 +104,11 @@ msgstr "à¶šà·à¶©à¶´à¶" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" -msgstr "" +msgstr "à¶šà·à¶½à¶º:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "වටිනà·à¶šà¶¸:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -190,7 +191,7 @@ msgstr "සජීවීකරණ පුනරà·à·€à¶»à·Šà¶®à¶±à¶º" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation Loop" -msgstr "" +msgstr "සජීවිකරණ ලූපය වෙනස් කරන්න" #: editor/animation_track_editor.cpp msgid "Property Track" @@ -249,7 +250,7 @@ msgstr "Anim පසුරු:" #: editor/animation_track_editor.cpp msgid "Change Track Path" -msgstr "" +msgstr "පථය වෙනස් කරන්න" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." @@ -331,7 +332,7 @@ msgstr "යà¶à·”රු මක෠දමන්න" #: editor/animation_track_editor.cpp msgid "Change Animation Update Mode" -msgstr "" +msgstr "සජීවිකරණ යà·à·€à¶à·Šà¶šà·à¶½à·“à¶± à¶´à·Šâ€à¶»à¶šà·à¶»à¶º වෙනස් කරන්න" #: editor/animation_track_editor.cpp #, fuzzy @@ -435,7 +436,7 @@ msgstr "ලුහුබදින්නෙක් à¶‘à¶šà·Š කරන්න" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "" +msgstr "පථය අවලංගු à¶¶à·à·€à·’න් යà¶à·”රක් à¶‘à¶šà·Š à¶šà·… නොහà·à¶š." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" @@ -646,7 +647,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1909,10 +1910,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2317,6 +2314,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2360,18 +2361,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2420,6 +2409,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2462,7 +2455,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2852,14 +2845,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3014,6 +2999,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3216,7 +3217,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4857,7 +4858,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4992,8 +4993,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5007,9 +5007,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6078,6 +6097,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6138,10 +6161,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6723,6 +6742,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6774,16 +6801,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6877,8 +6894,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7099,6 +7116,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9644,6 +9665,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10247,6 +10272,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "යà¶à·”රු à¶´à·’à¶§à¶´à¶à·Š කරන්න" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10371,6 +10405,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "යà¶à·”රු à¶´à·’à¶§à¶´à¶à·Š කරන්න" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11157,6 +11196,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11663,11 +11730,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11679,11 +11748,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11691,9 +11760,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12084,27 +12163,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12164,6 +12243,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12377,6 +12460,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12422,6 +12509,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index ebeb0fd387..9c179f743b 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -647,7 +647,7 @@ msgstr "VybraÅ¥ Track-y na skopÃrovanie" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "KopÃrovaÅ¥" @@ -1943,10 +1943,6 @@ msgstr "PredzobraziÅ¥:" msgid "File:" msgstr "Súbor:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "MusÃte použiÅ¥ platné rozÅ¡Ãrenie." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "SkenZdrojov" @@ -2378,6 +2374,10 @@ msgid "There is no defined scene to run." msgstr "Nieje definovaná žiadna scéna na spustenie." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Subprocess sa nedá spustiÅ¥!" @@ -2421,20 +2421,6 @@ msgstr "Na uloženie scény je potrebný root node." msgid "Save Scene As..." msgstr "UložiÅ¥ Scénu Ako..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nie" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "ÃNO" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" -"Táto scéna eÅ¡te nikdy nebola uložená. Chcete ju uložiÅ¥ predtým ako ju " -"zapnete?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez scény." @@ -2484,6 +2470,10 @@ msgid "Quit" msgstr "OdÃsÅ¥" #: editor/editor_node.cpp +msgid "Yes" +msgstr "ÃNO" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "OdÃsÅ¥ z editora?" @@ -2529,7 +2519,8 @@ msgstr "" "Addon plugin nie je možné povoliÅ¥ pri: '% s' analýze konfigurácie zlyhalo." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Nepodarilo sa nájsÅ¥ script field pre addon plugin v: 'res://addons/%s'." @@ -2960,14 +2951,6 @@ msgid "Help" msgstr "Pomoc" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "VyhľadaÅ¥" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Online Dokumentácie" @@ -3132,6 +3115,23 @@ msgid "Open & Run a Script" msgstr "OtvoriÅ¥ a vykonaÅ¥ skript" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "Nasledovné súbory sa nepodarilo extrahovaÅ¥ z balÃka:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Novo Zdedené" @@ -3341,7 +3341,7 @@ msgstr "SpraviÅ¥ JedineÄným" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "VložiÅ¥" @@ -5004,7 +5004,8 @@ msgid "Got:" msgstr "Má:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Zlyhalo sha256 hash check" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5137,10 +5138,10 @@ msgid "Assets ZIP File" msgstr "Prostriedky Súboru ZIP" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Nedá sa urÄiÅ¥ cesta pre uloženie lightmap obrázkov.\n" "Uložte svoju scénu (Aby sa obrázky na to isté miesto), alebo vyberte cestu " @@ -5161,9 +5162,29 @@ msgstr "" "zapisovateľná." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Bake Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "VybraÅ¥ Súbor Å ablóny" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6252,6 +6273,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "VÅ¡etky vybrané" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6312,10 +6338,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6921,6 +6943,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "VyhľadaÅ¥" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6973,16 +7003,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7081,8 +7101,8 @@ msgstr "VÅ¡etky vybrané" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7310,6 +7330,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "VeľkosÅ¥: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9947,6 +9972,11 @@ msgid "Projects" msgstr "Zakladatelia Projektu" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "NaÄÃtavanie zrkadiel, prosÃm Äakajte..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10561,6 +10591,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "VložiÅ¥" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Popis:" @@ -10685,6 +10724,11 @@ msgid "Attach Script" msgstr "Popis:" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "VložiÅ¥" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11503,6 +11547,36 @@ msgstr "Filter:" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Smery" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Generovanie Lightmaps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12022,11 +12096,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12038,11 +12114,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12050,9 +12126,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12463,27 +12549,29 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Generovanie Lightmaps" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Generovanie Lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12545,6 +12633,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12759,6 +12851,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "MusÃte použiÅ¥ platné rozÅ¡Ãrenie." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -12805,6 +12901,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Neplatný zdroj pre predzobrazenie." @@ -12834,6 +12936,14 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "Nie" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "" +#~ "Táto scéna eÅ¡te nikdy nebola uložená. Chcete ju uložiÅ¥ predtým ako ju " +#~ "zapnete?" + #~ msgid "Search complete" #~ msgstr "Vyhľadávanie bolo dokonÄené" @@ -12963,10 +13073,6 @@ msgstr "" #~ msgstr "VytvoriÅ¥ adresár" #, fuzzy -#~ msgid "Custom Node" -#~ msgstr "VložiÅ¥" - -#, fuzzy #~ msgid "Create Area" #~ msgstr "VytvoriÅ¥ adresár" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 4b542f4daa..1c6d1c566b 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -12,12 +12,13 @@ # Arnold Marko <arnold.marko@gmail.com>, 2019. # Alex <alexrixhardson@gmail.com>, 2019. # Andrew Poženel <andrej.pozenel@outlook.com>, 2020. +# Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-07-15 02:42+0000\n" -"Last-Translator: Andrew Poženel <andrej.pozenel@outlook.com>\n" +"PO-Revision-Date: 2021-02-01 20:54+0000\n" +"Last-Translator: Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>\n" "Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/" "godot/sl/>\n" "Language: sl\n" @@ -26,7 +27,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" "%100==4 ? 2 : 3;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -370,7 +371,7 @@ msgstr "Odstrani animacijsko sled" #: editor/animation_track_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "Ustvarim NOVO sled za %s in vstavim kljuÄ?" +msgstr "Ustvarim NOVO sled za %s in vstavi kljuÄ?" #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" @@ -680,7 +681,7 @@ msgstr "Izberi Lastnost" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -2035,10 +2036,6 @@ msgstr "Predogled:" msgid "File:" msgstr "Datoteka:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Uporabiti moraÅ¡ valjavno razÅ¡iritev." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "BranjeVirov" @@ -2488,6 +2485,10 @@ msgid "There is no defined scene to run." msgstr "Ni doloÄene scene za zagon." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Nemorem zaÄeti podprocesa!" @@ -2533,18 +2534,6 @@ msgstr "" msgid "Save Scene As..." msgstr "Shrani Sceno Kot..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ne" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Da" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Ta scena ni bila nikoli shranjena. Shranim pred zagonom?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ta operacija ni mogoÄa brez scene." @@ -2593,6 +2582,10 @@ msgid "Quit" msgstr "Zapri" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Da" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Zaprem urejevalnik?" @@ -2641,7 +2634,8 @@ msgstr "" "konfiguracije ni uspelo." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Ni mogoÄe najti polja skripte za dodatni vtiÄnik na: 'res://addons/%s'." @@ -3093,14 +3087,6 @@ msgid "Help" msgstr "PomoÄ" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Iskanje" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Spletna Dokumentacija" @@ -3263,6 +3249,22 @@ msgid "Open & Run a Script" msgstr "Odpri & Zaženi Skripto" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Novo Podedovano" @@ -3471,7 +3473,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -5232,7 +5234,8 @@ msgid "Got:" msgstr "Dobil:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "NeuspeÅ¡no preverjanje preizkusa sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5377,10 +5380,10 @@ msgid "Assets ZIP File" msgstr "Dodatki v ZIP Datoteki" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Ni mogoÄe doloÄiti poti shranjevanja slik svetlobnih kart.\n" "Shrani prizor (za slike, da bodo shranjene v isti mapi), ali izberi pot za " @@ -5400,9 +5403,29 @@ msgstr "" "Napaka pri izdelavi slik, svetlobnih kart. Poskrbite, da je pot zapisljiva." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "ZapeÄi Svetlobne karte" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Izberi datoteko predloge" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6531,6 +6554,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Pretvori V..." + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6591,10 +6619,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -7214,6 +7238,14 @@ msgstr "" msgid "Run" msgstr "Zaženi" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Iskanje" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7267,16 +7299,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "RazhroÅ¡Äevalnik" @@ -7377,8 +7399,8 @@ msgstr "IzbriÅ¡i toÄke" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7613,6 +7635,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10288,6 +10314,11 @@ msgid "Projects" msgstr "Projekt" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Pridobivanje virov, poÄakajte..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10911,6 +10942,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Prilepi Pozicijo" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Odstrani Gradnik VizualnaSkripta" @@ -11041,6 +11081,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Gradnik Prehod" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11878,6 +11923,37 @@ msgstr "Lastnosti objekta." msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Smeri" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Trenutna RazliÄica:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Ustvarjanje Svetlobnih Kart" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12406,11 +12482,13 @@ msgid "Select device from the list" msgstr "Izberite napravo s seznama" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12422,11 +12500,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12434,9 +12512,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12854,27 +12942,29 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Ustvarjanje Svetlobnih Kart" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Ustvarjanje Svetlobnih Kart" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12934,6 +13024,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13157,6 +13251,10 @@ msgstr "Opozorilo!" msgid "Please Confirm..." msgstr "Prosimo Potrdite..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Uporabiti moraÅ¡ valjavno razÅ¡iritev." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -13206,6 +13304,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Neveljaven vir za shader." @@ -13235,6 +13339,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstante ni možno spreminjati." +#~ msgid "No" +#~ msgstr "Ne" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ta scena ni bila nikoli shranjena. Shranim pred zagonom?" + #, fuzzy #~ msgid "Search complete" #~ msgstr "IÅ¡Äi Besedilo" @@ -13486,10 +13596,6 @@ msgstr "Konstante ni možno spreminjati." #~ msgid "Create folder" #~ msgstr "Ustvarite mapo" -#, fuzzy -#~ msgid "Custom Node" -#~ msgstr "Gradnik Prehod" - #~ msgid "Invalid Path" #~ msgstr "Neveljavna Pot" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index ca29161155..09b3b2af2e 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -632,7 +632,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1983,10 +1983,6 @@ msgstr "Shikim paraprak:" msgid "File:" msgstr "Skedar:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Duhet të perdorësh një shtesë të lejuar." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "SkanoBurimet" @@ -2432,6 +2428,10 @@ msgid "There is no defined scene to run." msgstr "Nuk ka një skenë të përcaktuar për të filluar." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Nuk mund të fillojë subprocess-in!" @@ -2476,18 +2476,6 @@ msgstr "Një nyje rrënjë është e kërkuar para se të ruash skenën." msgid "Save Scene As..." msgstr "Ruaje Skenën Si..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Jo" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Po" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Kjo skenë nuk është ruajtur më parë. Ruaje para se të fillosh?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ky veprim nuk mund të kryhet pa një skenë." @@ -2536,6 +2524,10 @@ msgid "Quit" msgstr "Dil" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Po" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Dil nga editori?" @@ -2585,7 +2577,8 @@ msgstr "" "dështoi." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "I paaftë te gjej fushën e shkrimit për shtojcën në: 'res://addons/%s'." #: editor/editor_node.cpp @@ -3031,14 +3024,6 @@ msgid "Help" msgstr "Ndihmë" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Kërko" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Dokumentimi Online" @@ -3199,6 +3184,22 @@ msgid "Open & Run a Script" msgstr "Hap & Fillo një Shkrim" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "E Trashëguar e Re" @@ -3412,7 +3413,7 @@ msgstr "Bëje Unik" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Ngjit" @@ -5096,7 +5097,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5237,8 +5238,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5252,9 +5252,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Zgjidh skedarin e shabllonit" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6332,6 +6352,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Konverto në %s" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6392,10 +6417,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6984,6 +7005,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Kërko" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7035,16 +7064,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7141,8 +7160,8 @@ msgstr "Krijo pika." msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7368,6 +7387,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Madhësia: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9946,6 +9970,11 @@ msgid "Projects" msgstr "Projekti" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Duke marrë pasqyrat, ju lutem prisni..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10555,6 +10584,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Dyfisho Nyjet" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Shkrim i Ri" @@ -10680,6 +10718,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Dyfisho Nyjet" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11497,6 +11540,36 @@ msgstr "Nyjet filtruese" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Versioni Aktual:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Duke Gjeneruar Hartat e Dritës" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12008,11 +12081,13 @@ msgid "Select device from the list" msgstr "Zgjidh paisjen nga lista" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12024,11 +12099,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12036,9 +12111,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12431,27 +12516,29 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Duke Gjeneruar Hartat e Dritës" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Duke Gjeneruar Hartat e Dritës" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12511,6 +12598,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12724,6 +12815,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Duhet të perdorësh një shtesë të lejuar." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12769,6 +12864,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12796,6 +12897,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "Jo" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Kjo skenë nuk është ruajtur më parë. Ruaje para se të fillosh?" + #~ msgid "Search complete" #~ msgstr "Kërkimi u kompletua" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 369e0d1c05..26c5abcbc8 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -720,7 +720,7 @@ msgstr "ПоÑтави прелаз на:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Копирај" @@ -2130,10 +2130,6 @@ msgstr "Преглед:" msgid "File:" msgstr "Датотека:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Мора Ñе кориÑтити важећа екÑтензија." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Скенирање извора" @@ -2609,6 +2605,10 @@ msgid "There is no defined scene to run." msgstr "Ðе поÑтоји дефиниÑана Ñцена за покретање." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Ðе могу покренути подпроцеÑ!" @@ -2655,18 +2655,6 @@ msgstr "За памћене Ñцене неопходан је корени но msgid "Save Scene As..." msgstr "Сачувај Ñцену као..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Ðе" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Да" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Ова Ñцена није Ñачувана. Сачувај пре покретања?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ова операција Ñе не може обавити без Ñцене." @@ -2715,6 +2703,10 @@ msgid "Quit" msgstr "Изађи" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Да" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Изађи из уредника?" @@ -2760,7 +2752,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "ÐеуÑпех при прикључивању додатка због конфигурационе датотеке: '%s'." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "ÐеуÑпех при налажењу поља за Ñкриптицу у додатку „res://addons/%s“." #: editor/editor_node.cpp @@ -3221,14 +3214,6 @@ msgid "Help" msgstr "Помоћ" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Тражи" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Онлајн документација" @@ -3408,6 +3393,25 @@ msgid "Open & Run a Script" msgstr "Отвори и покрени Ñкриптицу" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Следеће датотеке Ñу нове на диÑку.\n" +"Која акција Ñе треба предузети?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "ОÑвежи" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Поново Ñачувај" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Ðова наÑлеђена" @@ -3639,7 +3643,7 @@ msgstr "Учини ЈединÑтвеним" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Ðалепи" @@ -5488,7 +5492,8 @@ msgid "Got:" msgstr "Добијено:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "ÐеуÑпела провера sha256 Ñуме" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5641,8 +5646,7 @@ msgstr "РеÑурÑи ЗИП датотека" #, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "ÐеуÑпело одређивање путање памћења за Ñлике МапеСенчења.\n" "Упамти Ñцену (за Ñлике да буду Ñачуване у иÑтом директоријуму), или одабери " @@ -5664,10 +5668,30 @@ msgstr "" "ÐеуÑпешно креирање Ñлике МапеСенчења, провери да ли могуће упиÑивање путање." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp #, fuzzy msgid "Bake Lightmaps" msgstr "Изпеци МапеСенчења" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Одабери шаблонÑку датотеку" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6878,6 +6902,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Тачка Ñе Ñамо може поÑтавити у ParticlesMaterial процеÑни материјал" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Претвори у CPU чеÑтице" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Време генериÑања (Ñек.):" @@ -6943,10 +6972,6 @@ msgstr "ГенериÑање оÑног поравнаног граничниоРmsgid "Generate Visibility AABB" msgstr "Генериши оÑно поравнан гранични оквир (AABB) видљивоÑти" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Генериши оÑно поравнан гранични оквир (AABB)" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Обриши тачку из криве" @@ -7607,6 +7632,14 @@ msgstr "Затвори документацију" msgid "Run" msgstr "Покрени" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Тражи" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Корак у" @@ -7662,16 +7695,6 @@ msgstr "" "Следеће датотеке Ñу нове на диÑку.\n" "Која акција Ñе треба предузети?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "ОÑвежи" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Поново Ñачувај" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Дебагер" @@ -7779,8 +7802,8 @@ msgstr "Тачке прекида" msgid "Go To" msgstr "Иди Ðа" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "ИÑеци" @@ -8029,6 +8052,11 @@ msgid "Yaw" msgstr "Горе-Доле" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Величина:" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Ðацртани објекти" @@ -11130,6 +11158,11 @@ msgstr "Пројекти" #: editor/project_manager.cpp #, fuzzy +msgid "Loading, please wait..." +msgstr "Прихватам одредишта, молим Ñачекајте..." + +#: editor/project_manager.cpp +#, fuzzy msgid "Last Modified" msgstr "Задњи Измењен" @@ -11890,6 +11923,16 @@ msgstr "ИнÑтанца Сцена Дете" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Ðемогуће опериÑати на чвору из Ñтране Ñцене!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Ðалепи Чворове" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Detach Script" msgstr "Припој Скрипту" @@ -12045,6 +12088,11 @@ msgstr "Припој Скрипту" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Cut Node(s)" +msgstr "Ðаправи чвор" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Remove Node(s)" msgstr "Уклони Чвор/ове" @@ -13029,6 +13077,39 @@ msgstr "Пробери мреже" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Дај БиблиотециМрежа реÑÑƒÑ€Ñ Ð¾Ð²Ðµ МапеМреже да кориÑти њене мреже." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "Генериши оÑно поравнан гранични оквир (AABB)" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Смерови" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "Увучи деÑно" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Ðакон-Обраде" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Скована Светла:" + #: modules/mono/csharp_script.cpp #, fuzzy msgid "Class name can't be a reserved keyword" @@ -13593,14 +13674,17 @@ msgid "Select device from the list" msgstr "Одабери уређај Ñа лиÑте" #: platform/android/export/export.cpp -#, fuzzy -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB извршна датотека није подешена у Подешавањима Уредника." +msgid "Unable to find the 'apksigner' tool." +msgstr "" #: platform/android/export/export.cpp #, fuzzy -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jar потпиÑник није подешен у Подешавањима Уредника." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Android нацрт изградње није инÑталиран у пројекат. ИнÑталирај га из Пројекат " +"менија." #: platform/android/export/export.cpp #, fuzzy @@ -13618,14 +13702,13 @@ msgstr "" #: platform/android/export/export.cpp #, fuzzy -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Произвољна изградња захтева важећу путању до Android SDK у Подешавањима " -"Уредника." +"Ðеважећа Android SDK путања за произвољну изградњу у Подешавањима Уредника." #: platform/android/export/export.cpp #, fuzzy -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" "Ðеважећа Android SDK путања за произвољну изградњу у Подешавањима Уредника." @@ -13634,13 +13717,22 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp #, fuzzy -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Ðеважећа Android SDK путања за произвољну изградњу у Подешавањима Уредника." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"Android нацрт изградње није инÑталиран у пројекат. ИнÑталирај га из Пројекат " -"менија." #: platform/android/export/export.cpp #, fuzzy @@ -14149,34 +14241,33 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin захтева ARVRCamera дете чвор." #: scene/3d/baked_lightmap.cpp -#, fuzzy -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "(Time Left: %d:%02d s)" -msgstr "(Време преоÑтало: %d:%02d Ñ)" +msgid "Preparing geometry (%d/%d)" +msgstr "Ðнализирање геометрије..." #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Plotting Meshes: " -msgstr "Сковане Мреже:" +msgid "Preparing environment" +msgstr "Прикажи околину" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Plotting Lights:" -msgstr "Скована Светла:" +msgid "Generating capture" +msgstr "ГенериÑање оÑног поравнаног граничниог оквира (AABB)" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp +#: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Finishing Plot" -msgstr "Завршни Ков" +msgid "Saving lightmaps" +msgstr "ГенериÑање оÑног поравнаног граничниог оквира (AABB)" #: scene/3d/baked_lightmap.cpp #, fuzzy -msgid "Lighting Meshes: " -msgstr "СветлоÑне Мреже:" +msgid "Done" +msgstr "Готово!" #: scene/3d/collision_object.cpp #, fuzzy @@ -14263,6 +14354,11 @@ msgstr "Сковане Мреже" #: scene/3d/gi_probe.cpp #, fuzzy +msgid "Finishing Plot" +msgstr "Завршни Ков" + +#: scene/3d/gi_probe.cpp +#, fuzzy msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -14547,6 +14643,10 @@ msgstr "Узбуна!" msgid "Please Confirm..." msgstr "Молимо Потврди..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Мора Ñе кориÑтити важећа екÑтензија." + #: scene/gui/graph_edit.cpp #, fuzzy msgid "Enable grid minimap." @@ -14613,6 +14713,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Величина Viewport-а мора бити већа од 0 да би Ñе нешто иÑцртало." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Ðеважећи извор за преглед." @@ -14647,6 +14753,42 @@ msgstr "Варијације могу Ñамо бити одређене у фу msgid "Constants cannot be modified." msgstr "КонÑтанте није могуће мењати." +#~ msgid "No" +#~ msgstr "Ðе" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ова Ñцена није Ñачувана. Сачувај пре покретања?" + +#, fuzzy +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ADB извршна датотека није подешена у Подешавањима Уредника." + +#, fuzzy +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jar потпиÑник није подешен у Подешавањима Уредника." + +#, fuzzy +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Произвољна изградња захтева важећу путању до Android SDK у Подешавањима " +#~ "Уредника." + +#, fuzzy +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#, fuzzy +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Време преоÑтало: %d:%02d Ñ)" + +#, fuzzy +#~ msgid "Plotting Meshes: " +#~ msgstr "Сковане Мреже:" + +#, fuzzy +#~ msgid "Lighting Meshes: " +#~ msgstr "СветлоÑне Мреже:" + #, fuzzy #~ msgid "Search complete" #~ msgstr "Потражи текÑÑ‚" @@ -14923,10 +15065,6 @@ msgstr "КонÑтанте није могуће мењати." #~ msgstr "Грешка при учитавању реÑурÑа." #, fuzzy -#~ msgid "Done" -#~ msgstr "Готово!" - -#, fuzzy #~ msgid "Failed to create C# project." #~ msgstr "Грешка при учитавању реÑурÑа." @@ -14985,10 +15123,6 @@ msgstr "КонÑтанте није могуће мењати." #~ msgstr "CheckBox Radio2" #, fuzzy -#~ msgid "Custom Node" -#~ msgstr "Ðаправи чвор" - -#, fuzzy #~ msgid "Snap (s): " #~ msgstr "Један корак (Ñек.):" diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index 1a4dcff362..47cb13691e 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -654,7 +654,7 @@ msgstr "Postavi tranzicije na:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1921,10 +1921,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2331,6 +2327,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2374,18 +2374,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2434,6 +2422,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2476,7 +2468,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2868,14 +2860,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3030,6 +3014,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3233,7 +3233,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4881,7 +4881,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5016,8 +5016,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5031,9 +5030,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6109,6 +6127,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Napravi" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6169,10 +6192,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6760,6 +6779,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6811,16 +6838,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6915,8 +6932,8 @@ msgstr "Napravi" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7142,6 +7159,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9722,6 +9743,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10329,6 +10354,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Animacija Uduplaj KljuÄeve" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10453,6 +10487,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Animacija Uduplaj KljuÄeve" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11246,6 +11285,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11754,11 +11821,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11770,11 +11839,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11782,9 +11851,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12175,27 +12254,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12255,6 +12334,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12468,6 +12551,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12513,6 +12600,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index fdd3cfa116..420918548f 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -662,7 +662,7 @@ msgstr "Välj SpÃ¥r att Kopiera" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopiera" @@ -1996,10 +1996,6 @@ msgstr "Förhandsvisning:" msgid "File:" msgstr "Fil:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "MÃ¥ste använda en giltigt filändelse." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "ScanSources" @@ -2451,6 +2447,10 @@ msgid "There is no defined scene to run." msgstr "Det finns ingen definierad scen att köra." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Kunde inte starta underprocess!" @@ -2498,18 +2498,6 @@ msgstr "" msgid "Save Scene As..." msgstr "Spara Scen Som..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Nej" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Ja" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Denna scenen har aldrig sparats. Spara innan körning?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ã…tgärden kan inte göras utan en scen." @@ -2559,6 +2547,10 @@ msgid "Quit" msgstr "Avsluta" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Ja" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Stäng redigeraren?" @@ -2606,7 +2598,8 @@ msgstr "" "Kunde inte aktivera addon plugin vid: '%s' parsning av config misslyckades." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Kan inte hitta skriptfältet för addon plugin vid: 'res://addons/%s'." #: editor/editor_node.cpp @@ -3034,14 +3027,6 @@ msgid "Help" msgstr "Hjälp" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Sök" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Dokumentation Online" @@ -3201,6 +3186,23 @@ msgid "Open & Run a Script" msgstr "Öppna & Kör ett Skript" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "Följande filer gick inte att packa upp frÃ¥n tillägget:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Ladda om" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Spara om" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3413,7 +3415,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Klistra in" @@ -5160,7 +5162,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5295,8 +5297,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5310,9 +5311,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Välj mall-fil" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6423,6 +6444,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Konvertera till Versaler" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6483,10 +6509,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -7102,6 +7124,14 @@ msgstr "" msgid "Run" msgstr "Kör" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Sök" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7154,16 +7184,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Ladda om" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Spara om" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7264,8 +7284,8 @@ msgstr "Radera punkter" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Klipp" @@ -7503,6 +7523,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10180,6 +10204,11 @@ msgid "Projects" msgstr "Projekt" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "Laddar..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Senast Ändrad" @@ -10804,6 +10833,15 @@ msgid "Instance Child Scene" msgstr "Instansiera Barn-Scen" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Klistra in Noder" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "Fäst Skript" @@ -10934,6 +10972,11 @@ msgid "Attach Script" msgstr "Fäst Skript" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Klipp ut Noder" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Ta bort Nod(er)" @@ -11774,6 +11817,37 @@ msgstr "Filtrera noder" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Sektioner:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Nuvarande Version:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "Genererar Lightmaps" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12293,11 +12367,13 @@ msgid "Select device from the list" msgstr "Välj enhet frÃ¥n listan" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12309,11 +12385,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12321,9 +12397,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12740,28 +12826,31 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin kräver en ARVRCamera Barn-Node" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "Genererar Lightmaps" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "Genererar Lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "" +#, fuzzy +msgid "Done" +msgstr "Klar!" #: scene/3d/collision_object.cpp msgid "" @@ -12826,6 +12915,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13047,6 +13140,10 @@ msgstr "Varning!" msgid "Please Confirm..." msgstr "Vänligen Bekräfta..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "MÃ¥ste använda en giltigt filändelse." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -13092,6 +13189,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "Ogiltig teckenstorlek." @@ -13122,6 +13225,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "Nej" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Denna scenen har aldrig sparats. Spara innan körning?" + #, fuzzy #~ msgid "Search complete" #~ msgstr "Söktext" @@ -13313,10 +13422,6 @@ msgstr "" #~ msgstr "Misslyckades att ladda resurs." #, fuzzy -#~ msgid "Done" -#~ msgstr "Klar!" - -#, fuzzy #~ msgid "Failed to create C# project." #~ msgstr "Misslyckades att ladda resurs." diff --git a/editor/translations/ta.po b/editor/translations/ta.po index 4e7f9d7d26..d1bc762e93 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -650,7 +650,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1915,10 +1915,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2323,6 +2319,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2366,18 +2366,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2425,6 +2413,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2467,7 +2459,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2859,14 +2851,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3020,6 +3004,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3223,7 +3223,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4866,7 +4866,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5001,8 +5001,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5016,9 +5015,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6081,6 +6099,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6141,10 +6163,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6728,6 +6746,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6779,16 +6805,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6881,8 +6897,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7104,6 +7120,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9644,6 +9664,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10249,6 +10273,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•ளà¯" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10373,6 +10406,11 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•ளà¯" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11162,6 +11200,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11663,11 +11729,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11679,11 +11747,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11691,9 +11759,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12084,27 +12162,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12164,6 +12242,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12377,6 +12459,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12422,6 +12508,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/te.po b/editor/translations/te.po index 643c89a036..02a7a33269 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -628,7 +628,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1889,10 +1889,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2296,6 +2292,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2339,18 +2339,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2398,6 +2386,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2440,7 +2432,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2830,14 +2822,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2991,6 +2975,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3193,7 +3193,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4821,7 +4821,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4956,8 +4956,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4971,9 +4970,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6029,6 +6047,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6089,10 +6111,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6674,6 +6692,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6725,16 +6751,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6827,8 +6843,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7049,6 +7065,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9570,6 +9590,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10173,6 +10197,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10293,6 +10325,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11077,6 +11113,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11572,11 +11636,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11588,11 +11654,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11600,9 +11666,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11993,27 +12069,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12073,6 +12149,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12286,6 +12366,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12331,6 +12415,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index a81720a35a..2026248122 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -7,12 +7,12 @@ # Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020. # Anonymous <noreply@weblate.org>, 2020. # Lon3r <mptube.p@gmail.com>, 2020. -# Kongfa Warorot <gongpha@hotmail.com>, 2020. +# Kongfa Warorot <gongpha@hotmail.com>, 2020, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-02-15 10:51+0000\n" "Last-Translator: Kongfa Warorot <gongpha@hotmail.com>\n" "Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/" "th/>\n" @@ -21,7 +21,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -643,7 +643,7 @@ msgstr "เลืà¸à¸à¹à¸—ร็à¸à¸—ี่จะคัดลà¸à¸" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "คัดลà¸à¸" @@ -1928,10 +1928,6 @@ msgstr "ตัวà¸à¸¢à¹ˆà¸²à¸‡:" msgid "File:" msgstr "ไฟล์:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "นามสà¸à¸¸à¸¥à¹„ฟล์ไม่ถูà¸à¸•้à¸à¸‡" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "สà¹à¸à¸™à¸•้นฉบับ" @@ -2350,6 +2346,10 @@ msgid "There is no defined scene to run." msgstr "ยังไม่ได้เลืà¸à¸à¸‰à¸²à¸à¸—ี่จะเล่น" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "บันทึà¸à¸‰à¸²à¸à¸à¹ˆà¸à¸™à¸—ี่จะทำงาน..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "ไม่สามารถเริ่มขั้นตà¸à¸™à¸¢à¹ˆà¸à¸¢!" @@ -2393,18 +2393,6 @@ msgstr "โหนดà¹à¸¡à¹ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¸—ำà¸à¸²à¸£à¸šà¸± msgid "Save Scene As..." msgstr "บันทึà¸à¸‰à¸²à¸à¹€à¸›à¹‡à¸™..." -#: editor/editor_node.cpp -msgid "No" -msgstr "ไม่" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "ใช่" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "ฉาà¸à¸™à¸µà¹‰à¸¢à¸±à¸‡à¹„ม่ได้บันทึภบันทึà¸à¸à¹ˆà¸à¸™à¹€à¸£à¸´à¹ˆà¸¡?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "ทำไม่ได้ถ้าไม่มีฉาà¸" @@ -2454,6 +2442,10 @@ msgid "Quit" msgstr "à¸à¸à¸" #: editor/editor_node.cpp +msgid "Yes" +msgstr "ใช่" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "à¸à¸à¸à¹‚ปรà¹à¸à¸£à¸¡?" @@ -2497,7 +2489,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "ไม่สามารถเปิดใช้งานปลั๊à¸à¸à¸´à¸™: '%s'" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "ไม่พบชื่à¸à¸ªà¸„ริปต์ในปลั๊à¸à¸à¸´à¸™: 'res://addons/%s'" #: editor/editor_node.cpp @@ -2915,14 +2908,6 @@ msgid "Help" msgstr "ช่วยเหลืà¸" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "ค้นหา" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "คู่มืà¸" @@ -3084,6 +3069,25 @@ msgid "Open & Run a Script" msgstr "เปิดà¹à¸¥à¸°à¸£à¸±à¸™à¸ªà¸„ริปต์" #: editor/editor_node.cpp +#, fuzzy +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"ไฟล์ต่à¸à¹„ปนี้ในดิสà¸à¹Œà¹ƒà¸«à¸¡à¹ˆà¸à¸§à¹ˆà¸²\n" +"จะทำà¸à¸¢à¹ˆà¸²à¸‡à¹„รต่à¸à¹„ป?:" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "โหลดใหม่" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "บันทึà¸à¸à¸µà¸à¸„รั้ง" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "สืบทà¸à¸”" @@ -3290,7 +3294,7 @@ msgstr "ไม่ใช้ร่วมà¸à¸±à¸šà¸§à¸±à¸•ถุà¸à¸·à¹ˆà¸™" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "วาง" @@ -3838,19 +3842,16 @@ msgid "Searching..." msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„้นหา..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d ตรงà¸à¸±à¸™" +msgstr "%d ตรงà¸à¸±à¸šà¹„ฟล์ %d" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d ตรงà¸à¸±à¸™" +msgstr "%d ตรงà¸à¸±à¸šà¹„ฟล์ %d" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d ตรงà¸à¸±à¸™" +msgstr "%d ตรงà¸à¸±à¸šà¹„ฟล์ %d" #: editor/groups_editor.cpp msgid "Add to Group" @@ -4941,7 +4942,8 @@ msgid "Got:" msgstr "ที่ได้รับ:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "ผิดพลาดในà¸à¸²à¸£à¸•รวจสà¸à¸šà¹à¸®à¸Š SHA256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5074,10 +5076,10 @@ msgid "Assets ZIP File" msgstr "ทรัพยาà¸à¸£à¹„ฟล์ ZIP" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "ไม่สามารถเลืà¸à¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่จะบันทึà¸à¸ าพ lightmap\n" "à¸à¸£à¸¸à¸“าบันทึà¸à¸‰à¸²à¸ (เพื่à¸à¸šà¸±à¸™à¸—ึà¸à¸ าพในโฟลเดà¸à¸£à¹Œà¹€à¸”ียวà¸à¸±à¸™) หรืà¸à¸£à¸°à¸šà¸¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¹ƒà¸™à¸„ุณสมบัติขà¸à¸‡ BakedLightmap" @@ -5094,9 +5096,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "ผิดพลาดขณะสร้างภาพ lightmap à¸à¸£à¸¸à¸“าตรวจสà¸à¸šà¸§à¹ˆà¸²à¸ªà¸²à¸¡à¸²à¸£à¸–เขียนไฟล์ในตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่บันทึà¸à¹„ด้" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "สร้าง Lightmaps" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "เลืà¸à¸à¹„ฟล์เทมเพลต" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6175,6 +6197,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "สามารถà¸à¸³à¸«à¸™à¸”จุดให้à¹à¸à¹ˆ ParticlesMaterial เท่านั้น" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "เวลาในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡ (วินาที):" @@ -6235,10 +6262,6 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ AABB" msgid "Generate Visibility AABB" msgstr "สร้างà¸à¸²à¸£à¸¡à¸à¸‡à¹€à¸«à¹‡à¸™ AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "สร้าง AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "ลบจุดในเส้นโค้ง" @@ -6824,6 +6847,14 @@ msgstr "ปิดคู่มืà¸" msgid "Run" msgstr "เริ่ม" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "ค้นหา" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "คำสั่งต่à¸à¹„ป" @@ -6877,16 +6908,6 @@ msgstr "" "ไฟล์ต่à¸à¹„ปนี้ในดิสà¸à¹Œà¹ƒà¸«à¸¡à¹ˆà¸à¸§à¹ˆà¸²\n" "จะทำà¸à¸¢à¹ˆà¸²à¸‡à¹„รต่à¸à¹„ป?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "โหลดใหม่" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "บันทึà¸à¸à¸µà¸à¸„รั้ง" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "ตัวดีบัà¸" @@ -6979,8 +7000,8 @@ msgstr "เบรà¸à¸žà¸à¸¢à¸•์" msgid "Go To" msgstr "ไปยัง" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "ตัด" @@ -7203,6 +7224,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "ขนาด: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "à¸à¸à¸šà¹€à¸ˆà¸à¸•์ที่วาด" @@ -9836,6 +9862,11 @@ msgid "Projects" msgstr "โปรเจà¸à¸•์" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸£à¸µà¸¢à¸à¸‚้à¸à¸¡à¸¹à¸¥ โปรดรà¸..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "à¹à¸à¹‰à¹„ขล่าสุด" @@ -10447,6 +10478,16 @@ msgid "Instance Child Scene" msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์ฉาà¸à¸¥à¸¹à¸" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "ทำà¸à¸±à¸šà¹‚หนดขà¸à¸‡à¸‰à¸²à¸à¸à¸·à¹ˆà¸™à¹„ม่ได้!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "วางโหนด" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "ค้นพบสคริปต์" @@ -10572,6 +10613,11 @@ msgid "Attach Script" msgstr "à¹à¸™à¸šà¸ªà¸„ริปต์" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "ตัดโหนด" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "ลบโหนด" @@ -11370,6 +11416,39 @@ msgstr "ตัวà¸à¸£à¸à¸‡ mesh" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "มà¸à¸šà¸—รัพยาà¸à¸£ MeshLibrary ให้à¸à¸±à¸š GridMap นี้เพื่à¸à¹ƒà¸Šà¹‰ mesh" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Generate buffers" +msgstr "สร้าง AABB" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "ทิศทาง" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Indirect lighting" +msgstr "ย่à¸à¸«à¸™à¹‰à¸²à¸‚วา" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "หลังประมวลผล" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "วางà¹à¸™à¸§à¹à¸ªà¸‡:" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "ชื่à¸à¸„ลาสไม่สามารถมีคีย์เวิร์ดได้" @@ -11868,12 +11947,15 @@ msgid "Select device from the list" msgstr "เลืà¸à¸à¸à¸¸à¸›à¸à¸£à¸“์จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "ADB executable ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" +#, fuzzy +msgid "Unable to find the 'apksigner' tool." +msgstr "ไม่สามารถหา zipalign tool" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "เทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸à¸™à¸”รà¸à¸¢à¸”์ไม่ถูà¸à¸•ิดตั้ง สามารถติดตั้งจาà¸à¹€à¸¡à¸™à¸¹à¹‚ปรเจà¸à¸•์" #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -11884,11 +11966,13 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "Release keystore à¸à¸³à¸«à¸™à¸”ค่าไว้à¸à¸¢à¹ˆà¸²à¸‡à¹„ม่ถูà¸à¸•้à¸à¸‡à¹ƒà¸™à¸žà¸£à¸µà¹€à¸‹à¹‡à¸•สำหรับà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "à¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡à¸•้à¸à¸‡à¸¡à¸µà¸—ี่à¸à¸¢à¸¹à¹ˆ Android SDK ในà¸à¸²à¸£à¸•ั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" +#, fuzzy +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "ที่à¸à¸¢à¸¹à¹ˆ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡à¹ƒà¸™à¸à¸²à¸£à¸•ั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +#, fuzzy +msgid "Invalid Android SDK path in Editor Settings." msgstr "ที่à¸à¸¢à¸¹à¹ˆ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡à¹ƒà¸™à¸à¸²à¸£à¸•ั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" #: platform/android/export/export.cpp @@ -11896,10 +11980,21 @@ msgid "Missing 'platform-tools' directory!" msgstr "ไดเร็à¸à¸—à¸à¸£à¸µ 'platform-tools' หายไป!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." -msgstr "เทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸à¸™à¸”รà¸à¸¢à¸”์ไม่ถูà¸à¸•ิดตั้ง สามารถติดตั้งจาà¸à¹€à¸¡à¸™à¸¹à¹‚ปรเจà¸à¸•์" +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +#, fuzzy +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "ที่à¸à¸¢à¸¹à¹ˆ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡à¹ƒà¸™à¸à¸²à¸£à¸•ั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "ไดเร็à¸à¸—à¸à¸£à¸µ 'build-tools' หายไป!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12331,28 +12426,32 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin จำเป็นต้à¸à¸‡à¸¡à¸µ ARVRCamera เป็นโหนดลูà¸" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(เหลืà¸à¸à¸µà¸: %d:%02d วิ)" +#, fuzzy +msgid "Preparing geometry (%d/%d)" +msgstr "วิเคราะห์พื้นผิว..." #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "วางà¹à¸™à¸§ meshes: " +#, fuzzy +msgid "Preparing environment" +msgstr "à¹à¸ªà¸”งสภาพà¹à¸§à¸”ล้à¸à¸¡" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "วางà¹à¸™à¸§à¹à¸ªà¸‡:" +#, fuzzy +msgid "Generating capture" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ Lightmaps" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "เสร็จสิ้นà¸à¸²à¸£à¸§à¸²à¸‡à¹à¸™à¸§" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ Lightmaps" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "ส่à¸à¸‡à¹à¸ªà¸‡à¸šà¸™à¸žà¸·à¹‰à¸™à¸œà¸´à¸§: " +msgid "Done" +msgstr "เสร็จสิ้น" #: scene/3d/collision_object.cpp msgid "" @@ -12419,6 +12518,10 @@ msgid "Plotting Meshes" msgstr "วางà¹à¸™à¸§ meshes" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "เสร็จสิ้นà¸à¸²à¸£à¸§à¸²à¸‡à¹à¸™à¸§" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12660,10 +12763,13 @@ msgstr "à¹à¸ˆà¹‰à¸‡à¹€à¸•ืà¸à¸™!" msgid "Please Confirm..." msgstr "à¸à¸£à¸¸à¸“ายืนยัน..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "นามสà¸à¸¸à¸¥à¹„ฟล์ไม่ถูà¸à¸•้à¸à¸‡" + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸„ลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" +msgstr "เปิดเส้นà¸à¸£à¸´à¸”มินิà¹à¸¡à¸ž" #: scene/gui/popup.cpp msgid "" @@ -12715,6 +12821,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "ขนาดวิวพà¸à¸£à¹Œà¸•จะต้à¸à¸‡à¸¡à¸²à¸à¸à¸§à¹ˆà¸² 0 เพื่à¸à¸—ี่จะเรนเดà¸à¸£à¹Œà¹„ด้" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "à¹à¸«à¸¥à¹ˆà¸‡à¸—ี่มาไม่ถูà¸à¸•้à¸à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¹à¸ªà¸”งตัวà¸à¸¢à¹ˆà¸²à¸‡" @@ -12742,6 +12854,33 @@ msgstr "Varyings สามารถà¸à¸³à¸«à¸™à¸”ในังà¸à¹Œà¸Šà¸±à¸™à¹€ msgid "Constants cannot be modified." msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได้" +#~ msgid "No" +#~ msgstr "ไม่" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "ฉาà¸à¸™à¸µà¹‰à¸¢à¸±à¸‡à¹„ม่ได้บันทึภบันทึà¸à¸à¹ˆà¸à¸™à¹€à¸£à¸´à¹ˆà¸¡?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "ADB executable ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarsigner ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "à¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡à¸•้à¸à¸‡à¸¡à¸µà¸—ี่à¸à¸¢à¸¹à¹ˆ Android SDK ในà¸à¸²à¸£à¸•ั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(เหลืà¸à¸à¸µà¸: %d:%02d วิ)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "วางà¹à¸™à¸§ meshes: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "ส่à¸à¸‡à¹à¸ªà¸‡à¸šà¸™à¸žà¸·à¹‰à¸™à¸œà¸´à¸§: " + #~ msgid "Search complete" #~ msgstr "ค้นหาสำเร็จ" @@ -12754,12 +12893,6 @@ msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "มีไฟล์หรืà¸à¹‚ฟลเดà¸à¸£à¹Œà¸Šà¸·à¹ˆà¸à¹€à¸”ียวà¸à¸±à¸™à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "ไดเร็à¸à¸—à¸à¸£à¸µ 'build-tools' หายไป!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "ไม่สามารถหา zipalign tool" - #~ msgid "Aligning APK..." #~ msgstr "จัดเรียง APK..." @@ -13077,9 +13210,6 @@ msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได #~ msgid "Failed to save solution." #~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸šà¸±à¸™à¸—ึภsolution" -#~ msgid "Done" -#~ msgstr "เสร็จสิ้น" - #~ msgid "Failed to create C# project." #~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจà¸à¸•์ C#" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 9cb688c727..568265764b 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -46,7 +46,7 @@ # Kaan Genç <kaan@kaangenc.me>, 2020. # Anonymous <noreply@weblate.org>, 2020. # GüneÅŸ Gümüş <gunes.gumus.001@gmail.com>, 2020. -# OÄŸuz Ersen <oguzersen@protonmail.com>, 2020. +# OÄŸuz Ersen <oguzersen@protonmail.com>, 2020, 2021. # Vedat Günel <gunel15@itu.edu.tr>, 2020. # Ahmet Elgün <ahmetelgn@gmail.com>, 2020. # Efruz Yıldırır <efruzyildirir@gmail.com>, 2020. @@ -55,12 +55,14 @@ # Yusuf Osman YILMAZ <wolfkan4219@gmail.com>, 2020. # furkan atalar <fatalar55@gmail.com>, 2020. # Suleyman Poyraz <zaryob.dev@gmail.com>, 2020. +# ÇaÄŸlar KOPARIR <ckoparir@gmail.com>, 2021. +# Cem Eren Fukara <cefukara@hotmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" -"Last-Translator: OÄŸuz Ersen <oguzersen@protonmail.com>\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" +"Last-Translator: Cem Eren Fukara <cefukara@hotmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -68,7 +70,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -697,7 +699,7 @@ msgstr "Kopyalanacak izleri seç" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Kopyala" @@ -1994,10 +1996,6 @@ msgstr "Önizleme:" msgid "File:" msgstr "Dosya:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Geçerli bir uzantı kullanılmalı." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "KaynaklarıTara" @@ -2041,7 +2039,7 @@ msgstr "Çevrimiçi Rehberler" #: editor/editor_help.cpp msgid "Properties" -msgstr "Özellikler" +msgstr "Özellikleri" #: editor/editor_help.cpp msgid "override:" @@ -2053,7 +2051,7 @@ msgstr "varsayılan:" #: editor/editor_help.cpp msgid "Methods" -msgstr "Yöntemler" +msgstr "Metotlar" #: editor/editor_help.cpp msgid "Theme Properties" @@ -2433,6 +2431,10 @@ msgid "There is no defined scene to run." msgstr "Çalıştırmak için herhangi bir sahne seçilmedi." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Çalıştırmadan önce sahneyi kaydedin..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Alt iÅŸlem baÅŸlatılamadı!" @@ -2476,18 +2478,6 @@ msgstr "Sahneyi kaydedilmesi için kök düğüm gerekiyor." msgid "Save Scene As..." msgstr "Sahneyi Farklı Kaydet..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Hayır" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Evet" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Sahne hiç kaydedilmedi. Çalıştırmadan önce kaydedilsin mi?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Bu iÅŸlem bir sahne olmadan yapılamaz." @@ -2537,6 +2527,10 @@ msgid "Quit" msgstr "Çıkış" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Evet" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Düzenleyiciden çık?" @@ -2585,7 +2579,8 @@ msgstr "" "baÅŸarısız oldu." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "Eklentideki betik alanı bulunamıyor: 'res://addons/%s'." #: editor/editor_node.cpp @@ -3016,14 +3011,6 @@ msgid "Help" msgstr "Yardım" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Ara" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Çevrimiçi Belgeler" @@ -3189,6 +3176,24 @@ msgid "Open & Run a Script" msgstr "Aç & Bir Betik Çalıştır" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"AÅŸağıdaki dosyalar diskte daha yeni.\n" +"Hangi eylem yapılsın?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Yeniden Yükle" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "Yeniden Kaydet" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Yeni Örnekleme" @@ -3400,7 +3405,7 @@ msgstr "Benzersiz Yap" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Yapıştır" @@ -3959,19 +3964,16 @@ msgid "Searching..." msgstr "Aranıyor..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d eÅŸleÅŸme." +msgstr "%d eÅŸleÅŸme %d dosyada." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d eÅŸleÅŸme." +msgstr "%d eÅŸleÅŸme %d dosyada." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d eÅŸleÅŸme." +msgstr "%d eÅŸleÅŸme %d dosyada." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5076,7 +5078,8 @@ msgid "Got:" msgstr "Alınan:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "BaÅŸarısız sha256 hash sınaması" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5211,12 +5214,10 @@ msgstr "Varlıkların ZIP Dosyası" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" -"Lightmap resimleri için kaydetme yolu belirlenemiyor.\n" -"Sahneni kaydet (resimler aynı klasöre kaydedilmeli), ya da BakedLightmap " -"özelliklerinden bir kayıt yolu seçin." +"Lightmap dosyaları için kaydetme yolu belirlenemiyor.\n" +"Sahneyi kaydedip tekrar deneyin." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5233,9 +5234,32 @@ msgstr "" "olduÄŸundan emin olun." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "Lightmap boyutu belirlenemedi. Lightmap boyutu mu çok küçuk?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"Bazı örgüler geçersiz. [0.0,1.0] bölgesinin UV2 kanal deÄŸerlerini " +"içerdiÄŸinden emin olun." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Godot editör ışın yansıma desteÄŸi olmadan derlenmiÅŸ, ışık haritaları " +"piÅŸirilemez." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Işık-Haritalarını PiÅŸir" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Işık Haritası piÅŸirme dosyası seçiniz:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6326,6 +6350,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Nokta sadece ParçacıkMateryal iÅŸlem materyalinin içinde ayarlanabilir" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "2BİşlemciPartikül'e dönüştür" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Nesil Süresi (sn):" @@ -6386,10 +6414,6 @@ msgstr "AABB Üretimi" msgid "Generate Visibility AABB" msgstr "Görünebilirlik AABB'si Üret" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "AABB Üret" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Noktayı EÄŸriden Kaldır" @@ -6979,6 +7003,14 @@ msgstr "Belgeleri Kapat" msgid "Run" msgstr "Çalıştır" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Ara" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "İçeri Adımla" @@ -7032,16 +7064,6 @@ msgstr "" "AÅŸağıdaki dosyalar diskte daha yeni.\n" "Hangi eylem yapılsın?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Yeniden Yükle" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "Yeniden Kaydet" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Hata Ayıklayıcı" @@ -7136,8 +7158,8 @@ msgstr "Hata ayıklama noktaları" msgid "Go To" msgstr "Åžuna Git" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Kes" @@ -7360,6 +7382,10 @@ msgid "Yaw" msgstr "Yalpala" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Boyut" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ÇizilmiÅŸ Nesneler" @@ -10040,6 +10066,10 @@ msgid "Projects" msgstr "Projeler" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "Yükleniyor, lütfen bekleyin..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "Son DeÄŸiÅŸiklik" @@ -10658,6 +10688,16 @@ msgid "Instance Child Scene" msgstr "Çocuk Sahnesini Örnekle" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Yad bir sahnedeki düğümler üzerinde çalışamaz!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Düğümleri Yapıştır" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "BetiÄŸi Ayır" @@ -10785,6 +10825,11 @@ msgid "Attach Script" msgstr "Betik İliÅŸtir" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Düğümleri Kes" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Düğümleri Kaldır" @@ -11588,6 +11633,34 @@ msgstr "Modelleri Süz" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Model olarak kullanması için bu GridMap'e MeshLibrary kaynağı atayın." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "PiÅŸirmeye BaÅŸla" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Veri yapıları hazırlanıyor" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Arabellek OluÅŸtur" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "DoÄŸrudan aydınlatma" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "Dolaylı aydınlatma" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "RötuÅŸ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "Işık haritalarını çizme" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Sınıf ismi ayrılmış anahtar kelime olamaz" @@ -12098,12 +12171,15 @@ msgid "Select device from the list" msgstr "Listeden aygıt seç" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "Editör Ayarlarında ADB uygulaması tayin edilmemiÅŸ." +msgid "Unable to find the 'apksigner' tool." +msgstr "'apksigner' aracı bulunamıyor." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarimzalayıcı Editör Ayarlarında yapılandırılmamış." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"Android derleme ÅŸablonu projede yüklü deÄŸil. Proje menüsünden yükleyin." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12118,24 +12194,33 @@ msgstr "" "serbest bırakın." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "" -"Özel derleme için Editör Ayarları'nda geçerli bir Android SDK yolu gerekir." +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "Editör Ayarlarında geçerli bir Android SDK yolu gerekli." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "Editör Ayarlarında özel derleme için geçersiz Android SDK yolu." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Editör Ayarlarında geçersiz Android SDK yolu." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Eksik 'platform araçları' dizini!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "Android SDK platform-tools'un adb komutu bulunamıyor." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Android derleme ÅŸablonu projede yüklü deÄŸil. Proje menüsünden yükleyin." +"Lütfen Editör Ayarlarında girilen Android SDK klasörünü kontrol ediniz." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Eksik 'inÅŸa-araçları' dizini!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "Android SDK platform-tools'un apksigner komutu bulunamıyor." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12606,28 +12691,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin bir ARVRCamera alt düğümü gerektirir." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Örgü ve ışıkları bulmak" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(Kalan Zaman:%d:%02d sn)" +msgid "Preparing geometry (%d/%d)" +msgstr "Geometri hazırlanıyor (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Örüntüler Haritalanıyor: " +msgid "Preparing environment" +msgstr "Ortam hazırlanıyor" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Örüntüler Haritalanıyor:" +msgid "Generating capture" +msgstr "Yakalama oluÅŸturuluyor" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Haritalama Bitiriliyor" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Işık-haritaları kaydediliyor" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "Örüntüler Haritalanıyor: " +msgid "Done" +msgstr "Oldu" #: scene/3d/collision_object.cpp msgid "" @@ -12703,6 +12788,10 @@ msgid "Plotting Meshes" msgstr "Örüntüler Haritalanıyor" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Haritalama Bitiriliyor" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12963,10 +13052,13 @@ msgstr "Uyarı!" msgid "Please Confirm..." msgstr "Lütfen DoÄŸrulayın..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Geçerli bir uzantı kullanılmalı." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Yapışmayı EnkinleÅŸtir" +msgstr "Izgara haritasını etkinleÅŸtir." #: scene/gui/popup.cpp msgid "" @@ -13022,6 +13114,14 @@ msgstr "" "Herhangi bir ÅŸeyi iÅŸlemek için görüntükapısı boyutu 0'dan büyük olmalıdır." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Örnekleyici baÄŸlantı noktası baÄŸlandı ama kullanılmadı. Kaynağı " +"'ÖrnekleyiciBaÄŸlantıNoktası' olarak deÄŸiÅŸtirmeyi düşünün." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Önizleme için geçersiz kaynak." @@ -13049,6 +13149,35 @@ msgstr "varyings yalnızca vertex iÅŸlevinde atanabilir." msgid "Constants cannot be modified." msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez." +#~ msgid "No" +#~ msgstr "Hayır" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Sahne hiç kaydedilmedi. Çalıştırmadan önce kaydedilsin mi?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "Editör Ayarlarında ADB uygulaması tayin edilmemiÅŸ." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "OpenJDK jarimzalayıcı Editör Ayarlarında yapılandırılmamış." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Özel derleme için Editör Ayarları'nda geçerli bir Android SDK yolu " +#~ "gerekir." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(Kalan Zaman:%d:%02d sn)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Örüntüler Haritalanıyor: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "Örüntüler Haritalanıyor: " + #~ msgid "Search complete" #~ msgstr "Arama tamamlandı" @@ -13061,12 +13190,6 @@ msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "Bu konumda zaten aynı ada sahip bir dosya veya klasör var." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Eksik 'inÅŸa-araçları' dizini!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Zipalign aracı bulunamıyor." - #~ msgid "Aligning APK..." #~ msgstr "APK hizalanıyor ..." @@ -13394,9 +13517,6 @@ msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez." #~ msgid "Failed to save solution." #~ msgstr "Çözüm kaydetme baÅŸarısız." -#~ msgid "Done" -#~ msgstr "Oldu" - #~ msgid "Failed to create C# project." #~ msgstr "C# projesi oluÅŸturma baÅŸarısız." diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po index 52babb0305..67b5af0d44 100644 --- a/editor/translations/tzm.po +++ b/editor/translations/tzm.po @@ -626,7 +626,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1887,10 +1887,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2294,6 +2290,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2337,18 +2337,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2396,6 +2384,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2438,7 +2430,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2828,14 +2820,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -2989,6 +2973,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "" @@ -3191,7 +3191,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4819,7 +4819,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -4954,8 +4954,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -4969,9 +4968,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6027,6 +6045,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6087,10 +6109,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6672,6 +6690,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6723,16 +6749,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6825,8 +6841,8 @@ msgstr "" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7047,6 +7063,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9567,6 +9587,10 @@ msgid "Projects" msgstr "" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10170,6 +10194,14 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "" @@ -10290,6 +10322,10 @@ msgid "Attach Script" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11074,6 +11110,34 @@ msgstr "" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11569,11 +11633,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11585,11 +11651,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11597,9 +11663,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -11990,27 +12066,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12070,6 +12146,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12283,6 +12363,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12328,6 +12412,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index ea13d5c532..74f5becfea 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -3,7 +3,7 @@ # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. # Aleksandr <XpycT.TOP@gmail.com>, 2017. -# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020. +# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020, 2021. # Ðндрій Бандура <andriykopanytsia@gmail.com>, 2018. # Гидеон Теон <t.kudely94@gmail.com>, 2017. # МакÑим Якимчук <xpinovo@gmail.com>, 2018, 2019. @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-14 11:03+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -30,7 +30,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -666,7 +666,7 @@ msgstr "Виберіть доріжки Ð´Ð»Ñ ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Копіювати" @@ -1965,10 +1965,6 @@ msgstr "Попередній переглÑд:" msgid "File:" msgstr "Файл:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Ðеобхідно викориÑтовувати допуÑтиме розширеннÑ." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Сканувати Ñирці" @@ -2404,6 +2400,10 @@ msgid "There is no defined scene to run." msgstr "Ðемає визначеної Ñцени Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "Зберегти Ñцену перед запуÑком…" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити підпроцеÑ!" @@ -2447,18 +2447,6 @@ msgstr "Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб можна було зберегти Ñцену, msgid "Save Scene As..." msgstr "Зберегти Ñцену Ñк..." -#: editor/editor_node.cpp -msgid "No" -msgstr "ÐÑ–" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Так" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Ð¦Ñ Ñцена ніколи не була збережена. Зберегти перед запуÑком?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ може бути виконана без Ñцени." @@ -2509,6 +2497,10 @@ msgid "Quit" msgstr "Вийти" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Так" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Вийти з редактора?" @@ -2556,7 +2548,8 @@ msgstr "" "налаштуваннÑ." #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ поле Ñкрипт Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð»Ð°Ð³Ñ–Ð½Ñƒ в: 'res://addons/%s'." @@ -2992,14 +2985,6 @@ msgid "Help" msgstr "Довідка" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Пошук" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Онлайн документаціÑ" @@ -3165,6 +3150,24 @@ msgid "Open & Run a Script" msgstr "Відкрити Ñ– запуÑтити Ñкрипт" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"Ðа диÑку зберігаютьÑÑ Ð½Ð¾Ð²Ñ–ÑˆÑ– верÑÑ–Ñ— вказаних нижче файлів.\n" +"Що Ñлід зробити?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "Перезавантажити" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "ПерезапиÑати" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Ðовий уÑпадкований" @@ -3376,7 +3379,7 @@ msgstr "Зробити унікальним" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Ð’Ñтавити" @@ -3936,19 +3939,16 @@ msgid "Searching..." msgstr "Шукаємо…" #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d відповідників." +msgstr "%d відповдіник у %d файлі." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d відповідників." +msgstr "%d відповідників у %d файлі." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d відповідників." +msgstr "%d відповідників у %d файлах." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5056,7 +5056,8 @@ msgid "Got:" msgstr "Отримав:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "Помилка перевірки Ñ…ÐµÑˆÑƒÐ²Ð°Ð½Ð½Ñ sha256" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5191,12 +5192,10 @@ msgstr "ZIP файл реÑурÑів" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "Ðе вдаєтьÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ шлÑÑ… Ð´Ð»Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚ оÑвітленнÑ.\n" -"Збережіть вашу Ñцену (щоб Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¸ збережені в одній теці), або " -"виберіть шлÑÑ… Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñƒ влаÑтивоÑÑ‚ÑÑ… BakedLightmap." +"Збережіть вашу Ñцену Ñ– повторіть Ñпробу." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5213,9 +5212,34 @@ msgstr "" "запиÑу." #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ розмір карти оÑвітленнÑ. МакÑимальний розмір карти " +"оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñ” надто малим?" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" +"ЧаÑтина Ñітки Ñ” некоректною. ПереконайтеÑÑ, що Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñ–Ð² UV2 " +"потраплÑють до квадратної облаÑті [0.0,1.0]." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Редактор Godot було зібрано без підтримки траÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ–Ð². Карти " +"оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ð½Ðµ вдаÑтьÑÑ Ð¿Ð¾Ð±ÑƒÐ´ÑƒÐ²Ð°Ñ‚Ð¸." + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Запікати карти оÑвітленнÑ" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "Виберіть файл Ð¿Ñ€Ð¸Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸ оÑвітленнÑ:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6309,6 +6333,10 @@ msgstr "" "ПоÑтавити точку можна тільки в процедурному матеріалі ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "Перетворити на CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "Ð§Ð°Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ— (Ñек):" @@ -6369,10 +6397,6 @@ msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ AABB" msgid "Generate Visibility AABB" msgstr "Генерувати AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "Генерувати AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "Видалити точку з кривої" @@ -6965,6 +6989,14 @@ msgstr "Закрити документацію" msgid "Run" msgstr "ЗапуÑтити" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Пошук" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "Крок в" @@ -7018,16 +7050,6 @@ msgstr "" "Такі файли на диÑку новіші.\n" "Що робити?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "Перезавантажити" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "ПерезапиÑати" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "Зневаджувач" @@ -7124,8 +7146,8 @@ msgstr "Точки зупину" msgid "Go To" msgstr "Перейти" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Вирізати" @@ -7348,6 +7370,10 @@ msgid "Yaw" msgstr "ВідхиленнÑ" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Розмір" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Ðамальовано об'єктів" @@ -10039,6 +10065,10 @@ msgid "Projects" msgstr "Проєкти" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "ЗавантаженнÑ. Будь лаÑка, зачекайте..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "ВоÑтаннє змінено" @@ -10659,6 +10689,16 @@ msgid "Instance Child Scene" msgstr "Створити екземплÑÑ€ дочірньої Ñцени" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Ðе можна працювати із вузлами зі Ñторонньої Ñцени!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Ð’Ñтавити вузли" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "Від'єднати Ñкрипт" @@ -10785,6 +10825,11 @@ msgid "Attach Script" msgstr "Долучити Ñкрипт" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Вирізати вузли" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Вилучити вузли" @@ -11593,6 +11638,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" "Додайте реÑÑƒÑ€Ñ MeshLibrary до цього GridMap, щоб ÑкориÑтатиÑÑ Ð¹Ð¾Ð³Ð¾ Ñітками." +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "Почати обробку" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "Готуємо Ñтруктури даних" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "Створити буфери" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "БезпоÑереднє оÑвітленнÑ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "ОпоÑередковане оÑвітленнÑ" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "ПоÑÑ‚-обробка" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "КреÑÐ»ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚ оÑвітленнÑ" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "Ðазвою клаÑу не може бути зарезервоване ключове Ñлово" @@ -12107,12 +12180,16 @@ msgid "Select device from the list" msgstr "Вибрати приÑтрій зі ÑпиÑку" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "У параметрах редактора не налаштовано виконуваного файла ADB." +msgid "Unable to find the 'apksigner' tool." +msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програму apksigner." #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "У параметрах редактора не налаштовано jarsigner з OpenJDK." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" +"У проєкті не вÑтановлено шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android. Ð’Ñтановіть його за " +"допомогою меню «Проєкт»." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12126,28 +12203,37 @@ msgstr "" "У шаблоні екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ налаштовано Ñховище ключів випуÑку." #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Ðетипове Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” коректного шлÑху до SDK Ð´Ð»Ñ Android у параметрах " -"редактора." +"У параметрах редактора має бути вказано коректний шлÑÑ… до SDK Ð´Ð»Ñ Android." #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" -"Ðекоректний шлÑÑ… до SDK Ð´Ð»Ñ Android Ð´Ð»Ñ Ð½ÐµÑ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñƒ параметрах " -"редактора." +msgid "Invalid Android SDK path in Editor Settings." +msgstr "Ðекоректний шлÑÑ… до SDK Ð´Ð»Ñ Android у параметрах редактора." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "Ðе знайдено каталогу «platform-tools»!" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" -"У проєкті не вÑтановлено шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android. Ð’Ñтановіть його за " -"допомогою меню «Проєкт»." +"Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програми adb із інÑтрументів платформи SDK Ð´Ð»Ñ Android." + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" +"Будь лаÑка, перевірте, чи правильно вказано каталог SDK Ð´Ð»Ñ Android у " +"параметрах редактора." + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "Ðе знайдено каталогу «build-tools»!" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" +"Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програми apksigner з інÑтрументів Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ SDK Ð´Ð»Ñ Android." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12634,28 +12720,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin повинен мати дочірній вузол ARVRCamera." #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "Пошук Ñіток та джерел Ñвітла" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(ЛишилоÑÑ Ñ‡Ð°Ñу: %d:%02d Ñ)" +msgid "Preparing geometry (%d/%d)" +msgstr "ÐŸÑ€Ð¸Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ñ–Ñ— (%d з %d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "Побудова Ñітки: " +msgid "Preparing environment" +msgstr "ÐŸÑ€Ð¸Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñередовища" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "Побудова Ñвітла:" +msgid "Generating capture" +msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "Завершальна ділÑнка" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚ оÑвітленнÑ" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "ОÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñітки: " +msgid "Done" +msgstr "Зроблено" #: scene/3d/collision_object.cpp msgid "" @@ -12732,6 +12818,10 @@ msgid "Plotting Meshes" msgstr "Побудова Ñітки" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "Завершальна ділÑнка" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12991,10 +13081,13 @@ msgstr "Увага!" msgid "Please Confirm..." msgstr "Будь лаÑка, підтвердьте..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Ðеобхідно викориÑтовувати допуÑтиме розширеннÑ." + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Дозволити прилипаннÑ" +msgstr "Увімкнути мінікарту ґратки." #: scene/gui/popup.cpp msgid "" @@ -13052,6 +13145,14 @@ msgstr "" "за 0." #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" +"Порт заÑобу ÑÐµÐ¼Ð¿Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð·'єднано, але не викориÑтано. Вам варто змінити " +"джерело на «SamplerPort»." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ðекоректне джерело Ð´Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду." @@ -13079,6 +13180,35 @@ msgstr "Змінні величини можна пов'Ñзувати лише msgid "Constants cannot be modified." msgstr "Сталі не можна змінювати." +#~ msgid "No" +#~ msgstr "ÐÑ–" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Ð¦Ñ Ñцена ніколи не була збережена. Зберегти перед запуÑком?" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "У параметрах редактора не налаштовано виконуваного файла ADB." + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "У параметрах редактора не налаштовано jarsigner з OpenJDK." + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "" +#~ "Ðетипове Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” коректного шлÑху до SDK Ð´Ð»Ñ Android у " +#~ "параметрах редактора." + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(ЛишилоÑÑ Ñ‡Ð°Ñу: %d:%02d Ñ)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "Побудова Ñітки: " + +#~ msgid "Lighting Meshes: " +#~ msgstr "ОÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñітки: " + #~ msgid "Search complete" #~ msgstr "Пошук завершено" @@ -13091,12 +13221,6 @@ msgstr "Сталі не можна змінювати." #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "У вказаному каталозі вже міÑтитьÑÑ Ñ‚ÐµÐºÐ° або файл із вказано назвою." -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "Ðе знайдено каталогу «build-tools»!" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програму zipalign." - #~ msgid "Aligning APK..." #~ msgstr "Вирівнюємо APK..." @@ -13444,9 +13568,6 @@ msgstr "Сталі не можна змінювати." #~ msgid "Failed to save solution." #~ msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ розв'Ñзок." -#~ msgid "Done" -#~ msgstr "Зроблено" - #~ msgid "Failed to create C# project." #~ msgstr "Ðе вдалоÑÑ Ñтворити проєкт C#." diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 599ee5e6af..eccfc5f710 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -636,7 +636,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "" @@ -1926,10 +1926,6 @@ msgstr "" msgid "File:" msgstr "" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2341,6 +2337,10 @@ msgid "There is no defined scene to run." msgstr "" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2384,18 +2384,6 @@ msgstr "" msgid "Save Scene As..." msgstr "" -#: editor/editor_node.cpp -msgid "No" -msgstr "" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2444,6 +2432,10 @@ msgid "Quit" msgstr "" #: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "" @@ -2488,7 +2480,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2882,14 +2874,6 @@ msgid "Help" msgstr "" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "" @@ -3045,6 +3029,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp #, fuzzy msgid "New Inherited" msgstr "سب سکریپشن بنائیں" @@ -3252,7 +3252,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "" @@ -4921,7 +4921,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5058,8 +5058,7 @@ msgstr "Ø§Ø«Ø§Ø«Û Ú©ÛŒ زپ ÙØ§Ø¦Ù„" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5073,9 +5072,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr ".تمام کا انتخاب" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6160,6 +6179,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr ".تمام کا انتخاب" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6220,10 +6244,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6823,6 +6843,14 @@ msgstr "" msgid "Run" msgstr "" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -6874,16 +6902,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -6980,8 +6998,8 @@ msgstr ".تمام کا انتخاب" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "" @@ -7206,6 +7224,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -9810,6 +9832,10 @@ msgid "Projects" msgstr ".تمام کا انتخاب" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10418,6 +10444,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "ایکشن منتقل کریں" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "سب سکریپشن بنائیں" @@ -10545,6 +10580,11 @@ msgid "Attach Script" msgstr "سب سکریپشن بنائیں" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "ایکشن منتقل کریں" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11356,6 +11396,35 @@ msgstr "سب سکریپشن بنائیں" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "سب سکریپشن بنائیں" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -11870,11 +11939,13 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -11886,11 +11957,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -11898,9 +11969,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12292,27 +12373,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12372,6 +12453,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12585,6 +12670,10 @@ msgstr "" msgid "Please Confirm..." msgstr "" +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12630,6 +12719,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 64f38b6d19..3d01339f40 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -654,7 +654,7 @@ msgstr "Chá»n các Track để sao chép:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "Sao chép" @@ -1971,10 +1971,6 @@ msgstr "Xem thá»:" msgid "File:" msgstr "Tệp tin:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "Sá» dụng phần mở rá»™ng hợp lệ." - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "Quét nguồn" @@ -2410,6 +2406,10 @@ msgid "There is no defined scene to run." msgstr "Không có cảnh được xác định để chạy." #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "Không thể bắt đầu quá trình nhá»!" @@ -2453,18 +2453,6 @@ msgstr "Yêu cầu má»™t nút gốc khi lưu cảnh." msgid "Save Scene As..." msgstr "Lưu Scene vá»›i tên..." -#: editor/editor_node.cpp -msgid "No" -msgstr "Không" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "Có" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "Scene nà y chưa được lưu. Lưu trước khi chạy?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "Thao tác nà y phải có scene má»›i là m được." @@ -2513,6 +2501,10 @@ msgid "Quit" msgstr "Thoát" #: editor/editor_node.cpp +msgid "Yes" +msgstr "Có" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "Thoát trình biên táºp?" @@ -2558,7 +2550,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" #: editor/editor_node.cpp @@ -2974,14 +2966,6 @@ msgid "Help" msgstr "Trợ giúp" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "Tìm kiếm" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "Tà i liệu trá»±c tuyến" @@ -3148,6 +3132,22 @@ msgid "Open & Run a Script" msgstr "Mở & Chạy mã lệnh" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "Kế thừa má»›i" @@ -3355,7 +3355,7 @@ msgstr "Duy nhất" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "Dán" @@ -5035,7 +5035,7 @@ msgid "Got:" msgstr "Nháºn được:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5176,8 +5176,7 @@ msgstr "Tệp tin ZIP Nguyên liệu" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5191,9 +5190,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "Chá»n file template" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6293,6 +6312,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "Xóa Animation" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6354,10 +6378,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -6962,6 +6982,14 @@ msgstr "Äóng Docs" msgid "Run" msgstr "Chạy" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "Tìm kiếm" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7013,16 +7041,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7121,8 +7139,8 @@ msgstr "Tạo các Ä‘iểm." msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "Cắt" @@ -7354,6 +7372,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "KÃch thước: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10014,6 +10037,13 @@ msgid "Projects" msgstr "Dá»± án" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "" +"Äang quét các tệp tin,\n" +"Chá» má»™t chút ..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10638,6 +10668,16 @@ msgstr "" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "Không thể hoạt động trên các nút từ ngoại cảnh!" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "Dán các nút" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Detach Script" msgstr "ÄÃnh kèm Script" @@ -10765,6 +10805,11 @@ msgid "Attach Script" msgstr "ÄÃnh kèm Script" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "Cắt các nút" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "Xóa các nút" @@ -11593,6 +11638,36 @@ msgstr "Lá»c các nút" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "Hướng Ä‘i" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Post processing" +msgstr "Phiên bản hiện tại:" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12105,12 +12180,16 @@ msgid "Select device from the list" msgstr "" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" +"Mẫu xuất bản cho Android chưa được cà i đặt trong dá»± án. Cà i đặt nó từ menu " +"Dá»± Ãn." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12121,11 +12200,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12133,12 +12212,20 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" -"Mẫu xuất bản cho Android chưa được cà i đặt trong dá»± án. Cà i đặt nó từ menu " -"Dá»± Ãn." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12544,27 +12631,27 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" +msgid "Generating capture" msgstr "" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12624,6 +12711,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12839,6 +12930,10 @@ msgstr "Cảnh báo!" msgid "Please Confirm..." msgstr "Xin hãy xác nháºn..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "Sá» dụng phần mở rá»™ng hợp lệ." + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -12890,6 +12985,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "nguồn vô hiệu cho xem trước" @@ -12918,6 +13019,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Không thể chỉnh sá»a hằng số." +#~ msgid "No" +#~ msgstr "Không" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "Scene nà y chưa được lưu. Lưu trước khi chạy?" + #~ msgid "Search complete" #~ msgstr "Tìm kiếm hoà n tất" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index d8b4ddb0e6..3b0394b1d7 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -58,7 +58,7 @@ # idleman <1524328475@qq.com>, 2019. # king <wangding1992@126.com>, 2019. # silentbird <silentbird520@outlook.com>, 2019. -# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020. +# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021. # Revan Ji <jiruifancr@gmail.com>, 2020. # nieyuanhong <15625988003@163.com>, 2020. # binotaliu <binota@protonmail.ch>, 2020. @@ -71,13 +71,16 @@ # MintSoda <lionlxh@qq.com>, 2020. # Gardner Belgrade <hapenia@sina.com>, 2020. # godhidden <z2zz2zz@yahoo.com>, 2020. -# BinotaLIU <me@binota.org>, 2020. +# BinotaLIU <me@binota.org>, 2020, 2021. # TakWolf <takwolf@foxmail.com>, 2020. +# twoBornottwoB <305766341@qq.com>, 2021. +# Magian <magian1127@gmail.com>, 2021. +# Weiduo Xie <xwditfr@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2020-12-25 12:29+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" @@ -86,7 +89,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -707,7 +710,7 @@ msgstr "选择è¦å¤åˆ¶çš„轨é“" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "å¤åˆ¶" @@ -1987,10 +1990,6 @@ msgstr "预览:" msgid "File:" msgstr "文件:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "必须使用有效的扩展å。" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "æ‰«ææºæ–‡ä»¶" @@ -2413,6 +2412,10 @@ msgid "There is no defined scene to run." msgstr "没有设置è¦è¿è¡Œçš„场景。" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "è¿è¡Œå‰ä¿å˜åœºæ™¯..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "æ— æ³•å¯åЍå进程ï¼" @@ -2456,18 +2459,6 @@ msgstr "å¿…é¡»æœ‰æ ¹èŠ‚ç‚¹æ‰å¯ä¿å˜åœºæ™¯ã€‚" msgid "Save Scene As..." msgstr "场景å¦å˜ä¸º..." -#: editor/editor_node.cpp -msgid "No" -msgstr "å¦" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "是" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "æ¤åœºæ™¯å°šæœªä¿å˜ã€‚是å¦åœ¨è¿è¡Œå‰ä¿å˜ï¼Ÿ" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "必须先打开一个场景æ‰èƒ½å®Œæˆæ¤æ“作。" @@ -2517,6 +2508,10 @@ msgid "Quit" msgstr "退出" #: editor/editor_node.cpp +msgid "Yes" +msgstr "是" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "确定è¦é€€å‡ºç¼–辑器å—?" @@ -2559,7 +2554,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "æ— æ³•åœ¨ “%s†上å¯ç”¨åŠ è½½é¡¹æ’件:é…置解æžå¤±è´¥ã€‚" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "æ— æ³•åœ¨ “res://addons/%sâ€ ä¸æ‰¾åˆ°åŠ è½½é¡¹æ’ä»¶çš„è„šæœ¬å—æ®µã€‚" #: editor/editor_node.cpp @@ -2971,14 +2967,6 @@ msgid "Help" msgstr "帮助" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "æœç´¢" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "在线文档" @@ -3140,6 +3128,24 @@ msgid "Open & Run a Script" msgstr "打开并è¿è¡Œè„šæœ¬" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"ç£ç›˜ä¸çš„下列文件较新。\n" +"应该执行什么æ“作?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "釿–°åŠ è½½" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "釿–°ä¿å˜" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "新建继承" @@ -3346,7 +3352,7 @@ msgstr "唯一化" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "粘贴" @@ -3780,7 +3786,7 @@ msgstr "全部折å " #: editor/filesystem_dock.cpp msgid "Duplicate..." -msgstr "é‡å¤..." +msgstr "å¤åˆ¶ä¸º..." #: editor/filesystem_dock.cpp msgid "Move to Trash" @@ -3893,19 +3899,16 @@ msgid "Searching..." msgstr "æœç´¢ä¸..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d 个匹é…。" +msgstr "%d 处匹é…,共 %d 个文件。" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d 个匹é…。" +msgstr "%d 处匹é…,共 %d 个文件。" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d 个匹é…。" +msgstr "%d 处匹é…,共 %d 个文件。" #: editor/groups_editor.cpp msgid "Add to Group" @@ -4996,7 +4999,8 @@ msgid "Got:" msgstr "获得:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "SHA-256 å“ˆå¸Œå€¼æ ¡éªŒå¤±è´¥" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5131,8 +5135,7 @@ msgstr "ç´ æ ZIP 文件" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "æ— æ³•ç¡®å®šå…‰ç…§è´´å›¾çš„ä¿å˜è·¯å¾„。\n" "请先ä¿å˜åœºæ™¯ï¼ˆå…‰ç…§è´´å›¾å°†è¢«å˜åœ¨åŒä¸€ç›®å½•ä¸‹ï¼‰æˆ–ä»Žå±žæ€§é¢æ¿ä¸æ‰‹åЍä¿å˜ " @@ -5149,9 +5152,28 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "åˆ›å»ºå…‰ç…§è´´å›¾å¤±è´¥ï¼Œåˆ‡ç¡®ä¿æ–‡ä»¶æ˜¯å¯å†™çš„。" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "æ— æ³•ç¡®å®šå…‰ç…§è´´å›¾å¤§å°ã€‚最大光照贴图大å°å¤ªå°ï¼Ÿ" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "æŸäº›ç½‘æ ¼æ— æ•ˆã€‚ç¡®ä¿UV2通é“值包å«åœ¨[0.0,1.0]平方区域内。" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "Godot编辑器是在没有光线跟踪支æŒçš„æƒ…å†µä¸‹æž„å»ºçš„ï¼Œå…‰ç…§è´´å›¾æ— æ³•çƒ˜ç„™ã€‚" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "烘焙光照贴图" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "选择光照贴图烘焙文件:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -5803,7 +5825,7 @@ msgstr "å‘射色彩" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" -msgstr "CPUParticles" +msgstr "CPUç²’å" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -5817,11 +5839,11 @@ msgstr "从节点创建å‘射点" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 0" -msgstr "Flat 0" +msgstr "å¹³é¢ 0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 1" -msgstr "Flat 1" +msgstr "å¹³é¢ 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -6230,6 +6252,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "åªå¯è®¾ä¸ºæŒ‡å‘ ParticlesMaterial å¤„ç†ææ–™" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "转æ¢ä¸ºCPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "ç”Ÿæˆæ—¶é—´ï¼ˆç§’):" @@ -6290,10 +6316,6 @@ msgstr "æ£åœ¨ç”Ÿæˆ AABB" msgid "Generate Visibility AABB" msgstr "生æˆå¯è§çš„ AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "ç”Ÿæˆ AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "从曲线ä¸ç§»é™¤é¡¶ç‚¹" @@ -6877,6 +6899,14 @@ msgstr "关闿–‡æ¡£" msgid "Run" msgstr "è¿è¡Œ" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "æœç´¢" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "啿¥è¿›å…¥" @@ -6930,16 +6960,6 @@ msgstr "" "ç£ç›˜ä¸çš„下列文件已更新。\n" "请选择执行哪项æ“作?:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "釿–°åŠ è½½" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "釿–°ä¿å˜" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "调试器" @@ -7032,8 +7052,8 @@ msgstr "æ–点" msgid "Go To" msgstr "转到" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "剪切" @@ -7256,6 +7276,10 @@ msgid "Yaw" msgstr "å航角" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "大å°" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "绘制对象" @@ -9881,6 +9905,10 @@ msgid "Projects" msgstr "项目" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "æ£åœ¨åŠ è½½ï¼Œè¯·ç¨å€™..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "修改时间" @@ -10493,6 +10521,16 @@ msgid "Instance Child Scene" msgstr "实例化å场景" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "æ— æ³•æ“作外部场景的节点ï¼" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "粘贴节点" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "分离脚本" @@ -10615,6 +10653,11 @@ msgid "Attach Script" msgstr "æ·»åŠ è„šæœ¬" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "剪切节点" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "移除节点" @@ -11413,6 +11456,34 @@ msgstr "ç›é€‰ç½‘æ ¼" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "呿¤ GridMap æä¾›ç½‘æ ¼åº“èµ„æºä»¥ä½¿ç”¨å…¶ç½‘æ ¼ã€‚" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "开始烘焙" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "准备数æ®ç»“æž„" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "生æˆç¼“冲区" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "直接照明" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "间接照明" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "åŽå¤„ç†" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "绘制光照图" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "ç±»åä¸èƒ½æ˜¯ä¿ç•™å…³é”®å—" @@ -11912,12 +11983,14 @@ msgid "Select device from the list" msgstr "从列表ä¸é€‰æ‹©è®¾å¤‡" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "未在编辑器设置ä¸é…ç½® ADB 坿‰§è¡Œæ–‡ä»¶ã€‚" +msgid "Unable to find the 'apksigner' tool." +msgstr "找ä¸åˆ°â€œapksignerâ€å·¥å…·ã€‚" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "未在编辑器设置ä¸é…ç½® OpenJDK Jarsigner。" +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "未在项目ä¸å®‰è£… Android 构建模æ¿ã€‚从项目èœå•安装它。" #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -11928,22 +12001,32 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "用于å‘布的密钥å˜å‚¨åœ¨å¯¼å‡ºé¢„è®¾ä¸æœªè¢«æ£ç¡®è®¾ç½®ã€‚" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "自定义构建需è¦åœ¨ “编辑器设置†ä¸ä½¿ç”¨æœ‰æ•ˆçš„ Android SDK 路径。" +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "编辑器设置ä¸éœ€è¦æœ‰æ•ˆçš„Android SDK路径。" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "用于 “编辑器设置†ä¸è‡ªå®šä¹‰æž„建的 Android SDK è·¯å¾„æ˜¯æ— æ•ˆçš„ã€‚" +msgid "Invalid Android SDK path in Editor Settings." +msgstr "编辑器设置ä¸çš„Android SDKè·¯å¾„æ— æ•ˆã€‚" #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "缺失“platform-toolsâ€ç›®å½•ï¼" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." -msgstr "未在项目ä¸å®‰è£… Android 构建模æ¿ã€‚从项目èœå•安装它。" +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "找ä¸åˆ°Android SDKå¹³å°å·¥å…·çš„adb命令。" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "请ç¾å…¥ç¼–è¾‘å™¨è®¾ç½®ä¸æŒ‡å®šçš„Android SDK目录。" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "缺失“build-toolsâ€ç›®å½•ï¼" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "找ä¸åˆ°Android SDK生æˆå·¥å…·çš„apksigner命令。" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12372,28 +12455,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin 需è¦ä¸€ä¸ª ARVRCamera å节点。" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "æ£åœ¨æŸ¥æ‰¾ç½‘æ ¼å’Œç¯å…‰" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(剩余时间:%d:%02d 秒)" +msgid "Preparing geometry (%d/%d)" +msgstr "æ£åœ¨å‡†å¤‡å‡ 何体(%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼ï¼š " +msgid "Preparing environment" +msgstr "æ£åœ¨å‡†å¤‡çŽ¯å¢ƒ" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "æ£åœ¨ç»˜åˆ¶ç¯å…‰ï¼š" +msgid "Generating capture" +msgstr "æ£åœ¨ç”Ÿæˆæ•获" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "æ£åœ¨å®Œæˆåˆ’分" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "æ£åœ¨ä¿å˜å…‰ç…§è´´å›¾" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "æ£åœ¨å¯¹ç½‘æ ¼è¿›è¡Œç…§æ˜Ž " +msgid "Done" +msgstr "完æˆ" #: scene/3d/collision_object.cpp msgid "" @@ -12461,6 +12544,10 @@ msgid "Plotting Meshes" msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "æ£åœ¨å®Œæˆåˆ’分" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12705,10 +12792,13 @@ msgstr "è¦å‘Šï¼" msgid "Please Confirm..." msgstr "请确认..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "必须使用有效的扩展å。" + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "å¯ç”¨å¸é™„" +msgstr "å¯ç”¨ç½‘æ ¼å°åœ°å›¾ã€‚" #: scene/gui/popup.cpp msgid "" @@ -12761,6 +12851,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Viewport 大å°å¤§äºŽ 0 æ—¶æ‰èƒ½è¿›è¡Œæ¸²æŸ“。" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "é‡‡æ ·å™¨ç«¯å£å·²è¿žæŽ¥ä½†æœªä½¿ç”¨ã€‚è€ƒè™‘å°†æºæ›´æ”¹ä¸ºâ€œSamplerPortâ€ã€‚" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "预览的æºèµ„æºæ— 效。" @@ -12788,6 +12884,33 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸æŒ‡å®šã€‚" msgid "Constants cannot be modified." msgstr "ä¸å…许修改常é‡ã€‚" +#~ msgid "No" +#~ msgstr "å¦" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "æ¤åœºæ™¯å°šæœªä¿å˜ã€‚是å¦åœ¨è¿è¡Œå‰ä¿å˜ï¼Ÿ" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "未在编辑器设置ä¸é…ç½® ADB 坿‰§è¡Œæ–‡ä»¶ã€‚" + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "未在编辑器设置ä¸é…ç½® OpenJDK Jarsigner。" + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "自定义构建需è¦åœ¨ “编辑器设置†ä¸ä½¿ç”¨æœ‰æ•ˆçš„ Android SDK 路径。" + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(剩余时间:%d:%02d 秒)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼ï¼š " + +#~ msgid "Lighting Meshes: " +#~ msgstr "æ£åœ¨å¯¹ç½‘æ ¼è¿›è¡Œç…§æ˜Ž " + #~ msgid "Search complete" #~ msgstr "æœç´¢å®Œæ¯•" @@ -12800,12 +12923,6 @@ msgstr "ä¸å…许修改常é‡ã€‚" #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "当å‰ä½ç½®å·²å˜åœ¨åŒå文件或文件夹。" -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "缺失“build-toolsâ€ç›®å½•ï¼" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "未找到 zipalign 工具。" - #~ msgid "Aligning APK..." #~ msgstr "å¯¹é½ APK..." @@ -13139,9 +13256,6 @@ msgstr "ä¸å…许修改常é‡ã€‚" #~ msgid "Failed to save solution." #~ msgstr "ä¿å˜è§£å†³æ–¹æ¡ˆå¤±è´¥ã€‚" -#~ msgid "Done" -#~ msgstr "完æˆ" - #~ msgid "Failed to create C# project." #~ msgstr "创建C#项目失败。" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index b0dcffa7f1..728ecba4ba 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -682,7 +682,7 @@ msgstr "鏿“‡æ¨¡å¼" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "複製" @@ -2022,10 +2022,6 @@ msgstr "é 覽:" msgid "File:" msgstr "檔案:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "請用有效的副檔å。" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "" @@ -2452,6 +2448,10 @@ msgid "There is no defined scene to run." msgstr "沒有å¯ä»¥å·²å®šç¾©çš„å ´æ™¯å¯ä»¥é‹è¡Œã€‚" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "" @@ -2499,18 +2499,6 @@ msgstr "" msgid "Save Scene As..." msgstr "æŠŠå ´æ™¯å¦å˜ç‚º" -#: editor/editor_node.cpp -msgid "No" -msgstr "å¦" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "是" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "æ¤å ´æ™¯å¾žæœªå„²å˜ã€‚è¦åœ¨é‹è¡Œå‰å„²å˜å—Ž?" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "" @@ -2559,6 +2547,10 @@ msgid "Quit" msgstr "離開" #: editor/editor_node.cpp +msgid "Yes" +msgstr "是" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "è¦é›¢é–‹ç·¨è¼¯å™¨å—Ž?" @@ -2606,8 +2598,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." -msgstr "" +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "載入å—形出ç¾éŒ¯èª¤" #: editor/editor_node.cpp #, fuzzy @@ -3037,14 +3030,6 @@ msgid "Help" msgstr "幫助" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "æœå°‹" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp #, fuzzy msgid "Online Docs" @@ -3207,6 +3192,22 @@ msgid "Open & Run a Script" msgstr "" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp #, fuzzy msgid "New Inherited" msgstr "下一個腳本" @@ -3424,7 +3425,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "貼上" @@ -5198,7 +5199,7 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +msgid "Failed SHA-256 hash check" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5345,8 +5346,7 @@ msgstr "Assets ZIP 檔" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -5360,9 +5360,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy +msgid "Select lightmap bake file:" +msgstr "é¸å–Template檔案" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6469,6 +6489,11 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp +#, fuzzy +msgid "Convert to CPUParticles2D" +msgstr "轉為..." + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "" @@ -6529,10 +6554,6 @@ msgstr "" msgid "Generate Visibility AABB" msgstr "" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "" @@ -7152,6 +7173,14 @@ msgstr "é—œé–‰å ´æ™¯" msgid "Run" msgstr "é‹è¡Œ" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "æœå°‹" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "" @@ -7206,16 +7235,6 @@ msgid "" "What action should be taken?:" msgstr "" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "" @@ -7317,8 +7336,8 @@ msgstr "刪除" msgid "Go To" msgstr "" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "剪下" @@ -7557,6 +7576,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -10239,6 +10262,11 @@ msgid "Projects" msgstr "專案" #: editor/project_manager.cpp +#, fuzzy +msgid "Loading, please wait..." +msgstr "接收 mirrorsä¸, è«‹ç¨ä¾¯..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "" @@ -10873,6 +10901,15 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "貼上" + +#: editor/scene_tree_dock.cpp #, fuzzy msgid "Detach Script" msgstr "腳本" @@ -11007,6 +11044,11 @@ msgid "Attach Script" msgstr "腳本" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "貼上" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "" @@ -11852,6 +11894,36 @@ msgstr "篩é¸:" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Direct lighting" +msgstr "æè¿°ï¼š" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy +msgid "Plotting lightmaps" +msgstr "光照圖生æˆä¸" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "" @@ -12381,11 +12453,13 @@ msgid "Select device from the list" msgstr "從列表é¸å–è¨å‚™" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." +msgid "Unable to find the 'apksigner' tool." msgstr "" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." msgstr "" #: platform/android/export/export.cpp @@ -12397,11 +12471,11 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." +msgid "A valid Android SDK path is required in Editor Settings." msgstr "" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." +msgid "Invalid Android SDK path in Editor Settings." msgstr "" #: platform/android/export/export.cpp @@ -12409,9 +12483,19 @@ msgid "Missing 'platform-tools' directory!" msgstr "" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" #: platform/android/export/export.cpp @@ -12817,27 +12901,29 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" +msgid "Finding meshes and lights" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" +msgid "Preparing geometry (%d/%d)" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " +msgid "Preparing environment" msgstr "" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "" +#, fuzzy +msgid "Generating capture" +msgstr "光照圖生æˆä¸" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "" +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "Saving lightmaps" +msgstr "光照圖生æˆä¸" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " +msgid "Done" msgstr "" #: scene/3d/collision_object.cpp @@ -12897,6 +12983,10 @@ msgid "Plotting Meshes" msgstr "" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -13114,6 +13204,10 @@ msgstr "è¦å‘Š!" msgid "Please Confirm..." msgstr "請確èª..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "請用有效的副檔å。" + #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." msgstr "" @@ -13160,6 +13254,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "viewport大å°å¿…é ˆå¤§æ–¼ï¼ä»¥æ¸²æŸ“任何æ±è¥¿ã€‚" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." msgstr "é 覽來自無效來æºã€‚" @@ -13188,6 +13288,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "No" +#~ msgstr "å¦" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "æ¤å ´æ™¯å¾žæœªå„²å˜ã€‚è¦åœ¨é‹è¡Œå‰å„²å˜å—Ž?" + #~ msgid "Search complete" #~ msgstr "æœå°‹å®Œæˆ" @@ -13375,10 +13481,6 @@ msgstr "" #~ msgstr "新增資料夾" #, fuzzy -#~ msgid "Custom Node" -#~ msgstr "貼上" - -#, fuzzy #~ msgid "Invalid Path" #~ msgstr "有效的路徑" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 59b7ce53fa..7ac1142466 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -23,13 +23,13 @@ # binotaliu <binota@protonmail.ch>, 2020. # Allen H. <w84miracle@gmail.com>, 2020. # BinotaLIU <binota@protonmail.ch>, 2020. -# BinotaLIU <me@binota.org>, 2020. +# BinotaLIU <me@binota.org>, 2020, 2021. # MintSoda <lionlxh@qq.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-19 04:29+0000\n" +"PO-Revision-Date: 2021-02-21 10:51+0000\n" "Last-Translator: BinotaLIU <me@binota.org>\n" "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hant/>\n" @@ -38,7 +38,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4-dev\n" +"X-Generator: Weblate 4.5\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -659,7 +659,7 @@ msgstr "鏿“‡è»Œé“以複製" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" msgstr "複製" @@ -1943,10 +1943,6 @@ msgstr "é 覽:" msgid "File:" msgstr "檔案:" -#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -msgid "Must use a valid extension." -msgstr "å¿…é ˆä½¿ç”¨æœ‰æ•ˆçš„å‰¯æª”å。" - #: editor/editor_file_system.cpp msgid "ScanSources" msgstr "掃æåŽŸå§‹æª”" @@ -2367,6 +2363,10 @@ msgid "There is no defined scene to run." msgstr "æœªå®šç¾©æ¬²åŸ·è¡Œä¹‹å ´æ™¯ã€‚" #: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "執行å‰å…ˆä¿å˜å ´æ™¯..." + +#: editor/editor_node.cpp msgid "Could not start subprocess!" msgstr "無法啟動å處ç†ç¨‹åºï¼" @@ -2410,18 +2410,6 @@ msgstr "å¿…é ˆæœ‰æ ¹ç¯€é»žæ‰å¯ä¿å˜å ´æ™¯ã€‚" msgid "Save Scene As..." msgstr "å¦å˜å ´æ™¯ç‚ºâ€¦" -#: editor/editor_node.cpp -msgid "No" -msgstr "å¦" - -#: editor/editor_node.cpp -msgid "Yes" -msgstr "是" - -#: editor/editor_node.cpp -msgid "This scene has never been saved. Save before running?" -msgstr "æ¤å ´æ™¯å¾žæœªè¢«ä¿å˜ã€‚æ˜¯å¦æ–¼åŸ·è¡Œå‰å…ˆä¿å˜ï¼Ÿ" - #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." msgstr "å¿…é ˆè¦æœ‰å ´æ™¯æ‰å¯å®Œæˆè©²æ“作。" @@ -2471,6 +2459,10 @@ msgid "Quit" msgstr "離開" #: editor/editor_node.cpp +msgid "Yes" +msgstr "是" + +#: editor/editor_node.cpp msgid "Exit the editor?" msgstr "è¦çµæŸç·¨è¼¯å™¨å—Žï¼Ÿ" @@ -2513,7 +2505,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "無法在「%sã€ä¸Šå•Ÿç”¨æ“´å……功能,解æžçµ„æ…‹è¨å®šå¤±æ•—。" #: editor/editor_node.cpp -msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +#, fuzzy +msgid "Unable to find script field for addon plugin at: '%s'." msgstr "無法在擴充功能「res://addons/%sã€ä¸ç„¡æ³•找到腳本欄ä½ã€‚" #: editor/editor_node.cpp @@ -2925,14 +2918,6 @@ msgid "Help" msgstr "說明" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#: editor/plugins/script_text_editor.cpp -#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp -#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp -#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -msgid "Search" -msgstr "æœå°‹" - -#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" msgstr "線上說明文件" @@ -3094,6 +3079,24 @@ msgid "Open & Run a Script" msgstr "開啟並執行腳本" #: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" +"ç£ç¢Ÿä¸çš„下列檔案已更新。\n" +"è¦åŸ·è¡Œä»€éº¼æ“作?" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "釿–°è¼‰å…¥" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "釿–°ä¿å˜" + +#: editor/editor_node.cpp msgid "New Inherited" msgstr "新增繼承" @@ -3300,7 +3303,7 @@ msgstr "ç¨ç«‹åŒ–" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp -#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" msgstr "貼上" @@ -3847,19 +3850,16 @@ msgid "Searching..." msgstr "æ£åœ¨æœå°‹..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d 件相符åˆçš„çµæžœã€‚" +msgstr "%d 件相符åˆçš„çµæžœï¼ˆæ–¼ %d 個檔案內)。" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d 件相符åˆçš„çµæžœã€‚" +msgstr "%d 件相符åˆçš„çµæžœï¼ˆæ–¼ %d 個檔案內)。" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d 件相符åˆçš„çµæžœã€‚" +msgstr "%d 件相符åˆçš„çµæžœï¼ˆæ–¼ %d 個檔案內)。" #: editor/groups_editor.cpp msgid "Add to Group" @@ -4950,7 +4950,8 @@ msgid "Got:" msgstr "ç²å¾—:" #: editor/plugins/asset_library_editor_plugin.cpp -msgid "Failed sha256 hash check" +#, fuzzy +msgid "Failed SHA-256 hash check" msgstr "SHA-256 雜湊檢查失敗" #: editor/plugins/asset_library_editor_plugin.cpp @@ -5085,12 +5086,10 @@ msgstr "ç´ æ ZIP 檔" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Can't determine a save path for lightmap images.\n" -"Save your scene (for images to be saved in the same dir), or pick a save " -"path from the BakedLightmap properties." +"Save your scene and try again." msgstr "" "無法判斷光照圖的ä¿å˜è·¯å¾‘。\n" -"è«‹ä¿å˜å ´æ™¯ï¼ˆåœ–片將ä¿å˜æ–¼ç›¸åŒè³‡æ–™å¤¾ï¼‰ï¼Œæˆ–是在 BackedLightmap å±¬æ€§å…§é¸æ“‡ä¸€å€‹ä¿" -"å˜è·¯å¾‘。" +"è«‹ä¿å˜å ´æ™¯ä¸¦é‡è©¦ã€‚" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5104,9 +5103,29 @@ msgid "Failed creating lightmap images, make sure path is writable." msgstr "建立光照圖失敗,請確ä¿è©²è·¯å¾‘å¯å¯«å…¥ã€‚" #: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "無法判斷光照圖大å°ã€‚æœ€å¤§å…‰ç…§åœ–å¤§å°æ˜¯å¦éŽå°ï¼Ÿ" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "éƒ¨åˆ†ç¶²æ ¼ç„¡æ•ˆã€‚è«‹ç¢ºä¿ UV2 通é“çš„å€¼ä½æ–¼ [0.0,1.0] 矩形內。" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" +"Godot 編輯器在建制時未啟用光線追蹤 (Ray Tracing) 支æ´ï¼Œç„¡æ³•烘焙光照圖。" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "烘焙光照圖" +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "鏿“‡å…‰ç…§åœ–烘焙檔案:" + #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" @@ -6185,6 +6204,10 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "僅å¯è¨ç‚ºæŒ‡å‘ ProticlesMaterial è™•ç†ææ–™" #: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "轉æ›ç‚º CPUParticles2D" + +#: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" msgstr "產生時間(秒):" @@ -6245,10 +6268,6 @@ msgstr "æ£åœ¨ç”¢ç”Ÿ AABB" msgid "Generate Visibility AABB" msgstr "產生å¯è¦‹æ€§ AABB" -#: editor/plugins/particles_editor_plugin.cpp -msgid "Generate AABB" -msgstr "產生 AABB" - #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" msgstr "自曲線ä¸åˆªé™¤æŽ§åˆ¶é»ž" @@ -6832,6 +6851,14 @@ msgstr "關閉說明文件" msgid "Run" msgstr "執行" +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "æœå°‹" + #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" msgstr "逿¥åŸ·è¡Œ" @@ -6885,16 +6912,6 @@ msgstr "" "ç£ç¢Ÿä¸çš„下列檔案已更新。\n" "è«‹é¸æ“‡æ–¼åŸ·è¡Œä¹‹æ“作:" -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Reload" -msgstr "釿–°è¼‰å…¥" - -#: editor/plugins/script_editor_plugin.cpp -#: editor/plugins/shader_editor_plugin.cpp -msgid "Resave" -msgstr "釿–°ä¿å˜" - #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" msgstr "除錯工具" @@ -6987,8 +7004,8 @@ msgstr "䏿–·é»ž" msgid "Go To" msgstr "跳至" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Cut" msgstr "剪下" @@ -7211,6 +7228,10 @@ msgid "Yaw" msgstr "å航" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "大å°" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "繪製的物件" @@ -9837,6 +9858,10 @@ msgid "Projects" msgstr "專案" #: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "載入ä¸ï¼Œè«‹ç¨å¾Œ..." + +#: editor/project_manager.cpp msgid "Last Modified" msgstr "最後修改時間" @@ -10448,6 +10473,16 @@ msgid "Instance Child Scene" msgstr "實體化åå ´æ™¯" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Can't paste root node into the same scene." +msgstr "無法å°å¤–éƒ¨å ´æ™¯çš„ç¯€é»žé€²è¡Œæ“作ï¼" + +#: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Paste Node(s)" +msgstr "貼上節點" + +#: editor/scene_tree_dock.cpp msgid "Detach Script" msgstr "å–æ¶ˆé™„åŠ è…³æœ¬" @@ -10570,6 +10605,11 @@ msgid "Attach Script" msgstr "é™„åŠ è…³æœ¬" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Cut Node(s)" +msgstr "剪下節點" + +#: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "移除節點" @@ -11368,6 +11408,34 @@ msgstr "篩é¸ç¶²æ ¼" msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "æä¾› MeshLibrary 予該 GridMap ä»¥ä½¿ç”¨å…¶ç¶²æ ¼ã€‚" +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "開始烘焙" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "æ£åœ¨æº–å‚™è³‡æ–™çµæ§‹" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "產生緩è¡" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "呿€§å…‰ç…§" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "éžå‘性光照" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "後處ç†" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "æ£åœ¨ç¹ªè£½å…‰ç…§" + #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" msgstr "類別å稱ä¸èƒ½ç‚ºä¿ç•™é—œéµå—" @@ -11866,12 +11934,14 @@ msgid "Select device from the list" msgstr "自清單ä¸é¸æ“‡è£ç½®" #: platform/android/export/export.cpp -msgid "ADB executable not configured in the Editor Settings." -msgstr "尚未於編輯器è¨å®šä¸è¨å®š ADB å¯åŸ·è¡Œæª”。" +msgid "Unable to find the 'apksigner' tool." +msgstr "找ä¸åˆ°ã€Œapksignerã€å·¥å…·ã€‚" #: platform/android/export/export.cpp -msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "尚未於編輯器è¨å®šä¸è¨å®š OpenJDK Jarsigner。" +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "尚未於專案ä¸å®‰è£ Android 建置樣æ¿ã€‚請先於專案目錄ä¸é€²è¡Œå®‰è£ã€‚" #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -11882,22 +11952,32 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "發行金鑰儲å˜å€ä¸ä¸æ£ç¢ºä¹‹çµ„æ…‹è¨å®šè‡³åŒ¯å‡ºé è¨è¨å®šã€‚" #: platform/android/export/export.cpp -msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "è‡ªå®šå»ºç½®éœ€è¦æœ‰åœ¨ç·¨è¼¯å™¨è¨å®šä¸è¨å®šä¸€å€‹æœ‰æ•ˆçš„ Android SDK ä½ç½®ã€‚" +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "å¿…é ˆæ–¼ [編輯器è¨å®š] ä¸æä¾›ä¸€å€‹æœ‰æ•ˆçš„ Android SDK 路徑。" #: platform/android/export/export.cpp -msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "編輯器è¨å®šä¸ç”¨æ–¼è‡ªå®šç¾©è¨å®šä¹‹ Android SDK 路徑無效。" +msgid "Invalid Android SDK path in Editor Settings." +msgstr "[編輯器è¨å®š] 䏿‰€æŒ‡å®šçš„ Android SDK 路徑無效。" #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" msgstr "缺少「platform-toolsã€è³‡æ–™å¤¾ï¼" #: platform/android/export/export.cpp -msgid "" -"Android build template not installed in the project. Install it from the " -"Project menu." -msgstr "尚未於專案ä¸å®‰è£ Android 建置樣æ¿ã€‚請先於專案目錄ä¸é€²è¡Œå®‰è£ã€‚" +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "找ä¸åˆ° Android SDK platform-tools çš„ adb 指令。" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "請檢查 [編輯器è¨å®š] 䏿‰€æŒ‡å®šçš„ Android SDK 資料夾。" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "缺少「build-toolsã€è³‡æ–™å¤¾ï¼" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "找ä¸åˆ° Android SDK build-tools çš„ apksigner 指令。" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12331,28 +12411,28 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin å¿…é ˆæœ‰ä¸€å€‹ ARVRCamera å節點。" #: scene/3d/baked_lightmap.cpp -msgid "%d%%" -msgstr "%d%%" +msgid "Finding meshes and lights" +msgstr "æ£åœ¨å°‹æ‰¾ç¶²æ ¼èˆ‡å…‰ç…§" #: scene/3d/baked_lightmap.cpp -msgid "(Time Left: %d:%02d s)" -msgstr "(剩餘時間:%d:%02d 秒)" +msgid "Preparing geometry (%d/%d)" +msgstr "æ£åœ¨è§£æžå¹¾ä½• (%d/%d)" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Meshes: " -msgstr "æ£åœ¨ç¹ªè£½ç¶²æ ¼ï¼š " +msgid "Preparing environment" +msgstr "æ£åœ¨æº–備環境" #: scene/3d/baked_lightmap.cpp -msgid "Plotting Lights:" -msgstr "æ£åœ¨ç¹ªè£½å…‰ç…§ï¼š" +msgid "Generating capture" +msgstr "æ£åœ¨ç”¢ç”Ÿæ•æ‰" -#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -msgid "Finishing Plot" -msgstr "繪製完æˆ" +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "æ£åœ¨ä¿å˜å…‰ç…§åœ–" #: scene/3d/baked_lightmap.cpp -msgid "Lighting Meshes: " -msgstr "æ£åœ¨ç…§æ˜Žç¶²æ ¼ï¼š " +msgid "Done" +msgstr "完æˆ" #: scene/3d/collision_object.cpp msgid "" @@ -12419,6 +12499,10 @@ msgid "Plotting Meshes" msgstr "æ£åœ¨ç¹ªè£½ç¶²æ ¼" #: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "繪製完æˆ" + +#: scene/3d/gi_probe.cpp msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." @@ -12664,10 +12748,13 @@ msgstr "è¦å‘Šï¼" msgid "Please Confirm..." msgstr "請確èª..." +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "å¿…é ˆä½¿ç”¨æœ‰æ•ˆçš„å‰¯æª”å。" + #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "啟用å¸é™„" +msgstr "å•Ÿç”¨ç¶²æ ¼è¿·ä½ åœ°åœ–ã€‚" #: scene/gui/popup.cpp msgid "" @@ -12720,6 +12807,12 @@ msgid "Viewport size must be greater than 0 to render anything." msgstr "Viewport 大å°å¿…é ˆå¤§æ–¼ 0 æ‰å¯é€²è¡Œç®—繪。" #: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "å·²é€£ç·šè‡³å–æ¨£å™¨é€£çµåŸ 但並未使用。建è°å°‡ä¾†æºè¨ç‚ºã€ŒSamplerPortã€ã€‚" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "無效的é 覽來æºã€‚" @@ -12747,6 +12840,33 @@ msgstr "Varying 變數åªå¯åœ¨é ‚點函å¼ä¸æŒ‡æ´¾ã€‚" msgid "Constants cannot be modified." msgstr "ä¸å¯ä¿®æ”¹å¸¸æ•¸ã€‚" +#~ msgid "No" +#~ msgstr "å¦" + +#~ msgid "This scene has never been saved. Save before running?" +#~ msgstr "æ¤å ´æ™¯å¾žæœªè¢«ä¿å˜ã€‚æ˜¯å¦æ–¼åŸ·è¡Œå‰å…ˆä¿å˜ï¼Ÿ" + +#~ msgid "ADB executable not configured in the Editor Settings." +#~ msgstr "尚未於編輯器è¨å®šä¸è¨å®š ADB å¯åŸ·è¡Œæª”。" + +#~ msgid "OpenJDK jarsigner not configured in the Editor Settings." +#~ msgstr "尚未於編輯器è¨å®šä¸è¨å®š OpenJDK Jarsigner。" + +#~ msgid "Custom build requires a valid Android SDK path in Editor Settings." +#~ msgstr "è‡ªå®šå»ºç½®éœ€è¦æœ‰åœ¨ç·¨è¼¯å™¨è¨å®šä¸è¨å®šä¸€å€‹æœ‰æ•ˆçš„ Android SDK ä½ç½®ã€‚" + +#~ msgid "%d%%" +#~ msgstr "%d%%" + +#~ msgid "(Time Left: %d:%02d s)" +#~ msgstr "(剩餘時間:%d:%02d 秒)" + +#~ msgid "Plotting Meshes: " +#~ msgstr "æ£åœ¨ç¹ªè£½ç¶²æ ¼ï¼š " + +#~ msgid "Lighting Meshes: " +#~ msgstr "æ£åœ¨ç…§æ˜Žç¶²æ ¼ï¼š " + #~ msgid "Search complete" #~ msgstr "æœå°‹å®Œæˆ" @@ -12759,12 +12879,6 @@ msgstr "ä¸å¯ä¿®æ”¹å¸¸æ•¸ã€‚" #~ msgid "There is already file or folder with the same name in this location." #~ msgstr "該ä½ç½®å·²æœ‰ç›¸åŒå稱的檔案或資料夾。" -#~ msgid "Missing 'build-tools' directory!" -#~ msgstr "缺少「build-toolsã€è³‡æ–™å¤¾ï¼" - -#~ msgid "Unable to find the zipalign tool." -#~ msgstr "找ä¸åˆ° zipalign 工具。" - #~ msgid "Aligning APK..." #~ msgstr "æ£åœ¨å°é½Š APK…" diff --git a/main/main.cpp b/main/main.cpp index 25c559dac1..884caab1e9 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -71,7 +71,6 @@ #include "servers/physics_server_3d.h" #include "servers/register_server_types.h" #include "servers/rendering/rendering_server_default.h" -#include "servers/rendering/rendering_server_wrap_mt.h" #include "servers/text_server.h" #include "servers/xr_server.h" @@ -124,7 +123,9 @@ static bool _start_success = false; // Drivers +String tablet_driver = ""; String text_driver = ""; + static int text_driver_idx = -1; static int display_driver_idx = -1; static int audio_driver_idx = -1; @@ -171,6 +172,8 @@ static bool disable_render_loop = false; static int fixed_fps = -1; static bool print_fps = false; +bool profile_gpu = false; + /* Helper methods */ // Used by Mono module, should likely be registered in Engine singleton instead @@ -263,27 +266,27 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print("\n"); OS::get_singleton()->print("General options:\n"); - OS::get_singleton()->print(" -h, --help Display this help message.\n"); - OS::get_singleton()->print(" --version Display the version string.\n"); - OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n"); - OS::get_singleton()->print(" --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n"); + OS::get_singleton()->print(" -h, --help Display this help message.\n"); + OS::get_singleton()->print(" --version Display the version string.\n"); + OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n"); + OS::get_singleton()->print(" --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Run options:\n"); #ifdef TOOLS_ENABLED - OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n"); - OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n"); + OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n"); + OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n"); #endif - OS::get_singleton()->print(" -q, --quit Quit after the first iteration.\n"); - OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n"); - OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n"); - OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n"); - OS::get_singleton()->print(" --main-pack <file> Path to a pack (.pck) file to load.\n"); - OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n"); - OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n"); - OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n"); - - OS::get_singleton()->print(" --audio-driver <driver> Audio driver ["); + OS::get_singleton()->print(" -q, --quit Quit after the first iteration.\n"); + OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n"); + OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n"); + OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n"); + OS::get_singleton()->print(" --main-pack <file> Path to a pack (.pck) file to load.\n"); + OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n"); + OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n"); + OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n"); + + OS::get_singleton()->print(" --audio-driver <driver> Audio driver ["); for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) { if (i > 0) { OS::get_singleton()->print(", "); @@ -292,7 +295,7 @@ void Main::print_help(const char *p_binary) { } OS::get_singleton()->print("].\n"); - OS::get_singleton()->print(" --display-driver <driver> Display driver (and rendering driver) ["); + OS::get_singleton()->print(" --display-driver <driver> Display driver (and rendering driver) ["); for (int i = 0; i < DisplayServer::get_create_function_count(); i++) { if (i > 0) { OS::get_singleton()->print(", "); @@ -309,72 +312,68 @@ void Main::print_help(const char *p_binary) { } OS::get_singleton()->print("].\n"); - OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n"); + OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n"); - OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n"); + OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n"); OS::get_singleton()->print("\n"); #ifndef SERVER_ENABLED OS::get_singleton()->print("Display options:\n"); - OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n"); - OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n"); - OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n"); - OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n"); - OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); - OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); - OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n"); - OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n"); - OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n"); - OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n"); - OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); - OS::get_singleton()->print(" --tablet-driver Tablet input driver ("); - for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) { - if (i != 0) - OS::get_singleton()->print(", "); - OS::get_singleton()->print("'%s'", OS::get_singleton()->get_tablet_driver_name(i).utf8().get_data()); - } - OS::get_singleton()->print(") (Windows only).\n"); + OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n"); + OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n"); + OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n"); + OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n"); + OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); + OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); + OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n"); + OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n"); + OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n"); + OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n"); + OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); + OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n"); OS::get_singleton()->print("\n"); #endif OS::get_singleton()->print("Debug options:\n"); - OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); - OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n"); - OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n"); - OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n"); + OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); + OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n"); + OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n"); + OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n"); #if DEBUG_ENABLED - OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n"); + OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n"); #endif - OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n"); + OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n"); #if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED) - OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n"); - OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n"); + OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n"); + OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n"); #endif - OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n"); - OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n"); - OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n"); - OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n"); - OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n"); - OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n"); + OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n"); + OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n"); + OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n"); + OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n"); + OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n"); + OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n"); + OS::get_singleton()->print(" --profile-gpu Show a simple profile of the tasks that took more time during frame rendering.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Standalone tools:\n"); - OS::get_singleton()->print(" -s, --script <script> Run a script.\n"); - OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n"); + OS::get_singleton()->print(" -s, --script <script> Run a script.\n"); + OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n"); #ifdef TOOLS_ENABLED - OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n"); - OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n"); - OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n"); - OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n"); - OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n"); - OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); - OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n"); + OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n"); + OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n"); + OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n"); + OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n"); + OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n"); + OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); + OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n"); #ifdef DEBUG_METHODS_ENABLED - OS::get_singleton()->print(" --gdnative-generate-json-api Generate JSON dump of the Godot API for GDNative bindings.\n"); + OS::get_singleton()->print(" --gdnative-generate-json-api <path> Generate JSON dump of the Godot API for GDNative bindings and save it on the file specified in <path>.\n"); + OS::get_singleton()->print(" --gdnative-generate-json-builtin-api <path> Generate JSON dump of the Godot API of the builtin Variant types and utility functions for GDNative bindings and save it on the file specified in <path>.\n"); #endif #ifdef TESTS_ENABLED - OS::get_singleton()->print(" --test [--help] Run unit tests. Use --test --help for more information.\n"); + OS::get_singleton()->print(" --test [--help] Run unit tests. Use --test --help for more information.\n"); #endif OS::get_singleton()->print("\n"); #endif @@ -388,8 +387,6 @@ Error Main::test_setup() { engine = memnew(Engine); - ClassDB::init(); - register_core_types(); register_core_driver_types(); @@ -398,6 +395,8 @@ Error Main::test_setup() { GLOBAL_DEF("debug/settings/crash_handler/message", String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues")); + translation_server = memnew(TranslationServer); + // From `Main::setup2()`. preregister_module_types(); preregister_server_types(); @@ -405,6 +404,16 @@ Error Main::test_setup() { register_core_singletons(); register_server_types(); + + translation_server->setup(); //register translations, load them, etc. + if (locale != "") { + translation_server->set_locale(locale); + } + translation_server->load_translations(); + ResourceLoader::load_translation_remaps(); //load remaps for resources + + ResourceLoader::load_path_remaps(); + register_scene_types(); #ifdef TOOLS_ENABLED @@ -444,6 +453,9 @@ void Main::test_cleanup() { OS::get_singleton()->finalize(); + if (translation_server) { + memdelete(translation_server); + } if (globals) { memdelete(globals); } @@ -507,8 +519,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph engine = memnew(Engine); - ClassDB::init(); - MAIN_PRINT("Main: Initialize CORE"); register_core_types(); @@ -516,10 +526,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph MAIN_PRINT("Main: Initialize Globals"); - Thread::_main_thread_id = Thread::get_caller_id(); - - globals = memnew(ProjectSettings); input_map = memnew(InputMap); + globals = memnew(ProjectSettings); register_core_settings(); //here globals is present @@ -530,8 +538,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // Only flush stdout in debug builds by default, as spamming `print()` will // decrease performance if this is enabled. - GLOBAL_DEF("application/run/flush_stdout_on_print", false); - GLOBAL_DEF("application/run/flush_stdout_on_print.debug", true); + GLOBAL_DEF_RST("application/run/flush_stdout_on_print", false); + GLOBAL_DEF_RST("application/run/flush_stdout_on_print.debug", true); GLOBAL_DEF("debug/settings/crash_handler/message", String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues")); @@ -559,7 +567,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph String display_driver = ""; String audio_driver = ""; - String tablet_driver = ""; String project_path = "."; bool upwards = false; String debug_uri = ""; @@ -728,19 +735,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "--tablet-driver") { if (I->next()) { tablet_driver = I->next()->get(); - bool found = false; - for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) { - if (tablet_driver == OS::get_singleton()->get_tablet_driver_name(i)) { - found = true; - } - } - - if (!found) { - OS::get_singleton()->print("Unknown tablet driver '%s', aborting.\n", - tablet_driver.utf8().get_data()); - goto error; - } - N = I->next()->next(); } else { OS::get_singleton()->print("Missing tablet driver argument, aborting.\n"); @@ -880,7 +874,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph auto_build_solutions = true; editor = true; #ifdef DEBUG_METHODS_ENABLED - } else if (I->get() == "--gdnative-generate-json-api") { + } else if (I->get() == "--gdnative-generate-json-api" || I->get() == "--gdnative-generate-json-builtin-api") { // Register as an editor instance to use low-end fallback if relevant. editor = true; @@ -1010,6 +1004,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } else if (I->get() == "--print-fps") { print_fps = true; + } else if (I->get() == "--profile-gpu") { + profile_gpu = true; } else if (I->get() == "--disable-crash-handler") { OS::get_singleton()->disable_crash_handler(); } else if (I->get() == "--skip-breakpoints") { @@ -1126,29 +1122,29 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } #endif - GLOBAL_DEF("logging/file_logging/enable_file_logging", false); + GLOBAL_DEF("debug/file_logging/enable_file_logging", false); // Only file logging by default on desktop platforms as logs can't be // accessed easily on mobile/Web platforms (if at all). // This also prevents logs from being created for the editor instance, as feature tags // are disabled while in the editor (even if they should logically apply). - GLOBAL_DEF("logging/file_logging/enable_file_logging.pc", true); - GLOBAL_DEF("logging/file_logging/log_path", "user://logs/godot.log"); - GLOBAL_DEF("logging/file_logging/max_log_files", 5); - ProjectSettings::get_singleton()->set_custom_property_info("logging/file_logging/max_log_files", + GLOBAL_DEF("debug/file_logging/enable_file_logging.pc", true); + GLOBAL_DEF("debug/file_logging/log_path", "user://logs/godot.log"); + GLOBAL_DEF("debug/file_logging/max_log_files", 5); + ProjectSettings::get_singleton()->set_custom_property_info("debug/file_logging/max_log_files", PropertyInfo(Variant::INT, - "logging/file_logging/max_log_files", + "debug/file_logging/max_log_files", PROPERTY_HINT_RANGE, "0,20,1,or_greater")); //no negative numbers if (!project_manager && !editor && FileAccess::get_create_func(FileAccess::ACCESS_USERDATA) && - GLOBAL_GET("logging/file_logging/enable_file_logging")) { + GLOBAL_GET("debug/file_logging/enable_file_logging")) { // Don't create logs for the project manager as they would be written to // the current working directory, which is inconvenient. - String base_path = GLOBAL_GET("logging/file_logging/log_path"); - int max_files = GLOBAL_GET("logging/file_logging/max_log_files"); + String base_path = GLOBAL_GET("debug/file_logging/log_path"); + int max_files = GLOBAL_GET("debug/file_logging/max_log_files"); OS::get_singleton()->add_logger(memnew(RotatedFileLogger(base_path, max_files))); } - if (main_args.size() == 0 && String(GLOBAL_DEF("application/run/main_scene", "")) == "") { + if (main_args.size() == 0 && String(GLOBAL_GET("application/run/main_scene")) == "") { #ifdef TOOLS_ENABLED if (!editor && !project_manager) { #endif @@ -1178,30 +1174,32 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph _print_line_enabled = false; } + Logger::set_flush_stdout_on_print(ProjectSettings::get_singleton()->get("application/run/flush_stdout_on_print")); + OS::get_singleton()->set_cmdline(execpath, main_args); - GLOBAL_DEF("rendering/quality/driver/driver_name", "Vulkan"); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name", + GLOBAL_DEF("rendering/driver/driver_name", "Vulkan"); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/driver/driver_name", PropertyInfo(Variant::STRING, - "rendering/quality/driver/driver_name", + "rendering/driver/driver_name", PROPERTY_HINT_ENUM, "Vulkan")); if (display_driver == "") { - display_driver = GLOBAL_GET("rendering/quality/driver/driver_name"); + display_driver = GLOBAL_GET("rendering/driver/driver_name"); } - GLOBAL_DEF("display/window/size/width", 1024); + GLOBAL_DEF_BASIC("display/window/size/width", 1024); ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width", PropertyInfo(Variant::INT, "display/window/size/width", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution - GLOBAL_DEF("display/window/size/height", 600); + GLOBAL_DEF_BASIC("display/window/size/height", 600); ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height", PropertyInfo(Variant::INT, "display/window/size/height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution - GLOBAL_DEF("display/window/size/resizable", true); - GLOBAL_DEF("display/window/size/borderless", false); - GLOBAL_DEF("display/window/size/fullscreen", false); + GLOBAL_DEF_BASIC("display/window/size/resizable", true); + GLOBAL_DEF_BASIC("display/window/size/borderless", false); + GLOBAL_DEF_BASIC("display/window/size/fullscreen", false); GLOBAL_DEF("display/window/size/always_on_top", false); GLOBAL_DEF("display/window/size/test_width", 0); ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width", @@ -1249,7 +1247,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } - GLOBAL_DEF("display/window/force_right_to_left_layout_direction", false); + GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); if (!force_lowdpi) { OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false); @@ -1268,28 +1266,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor; - if (tablet_driver == "") { // specified in project.godot - tablet_driver = GLOBAL_DEF_RST_NOVAL("display/window/tablet_driver", OS::get_singleton()->get_tablet_driver_name(0)); - } - - for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) { - if (tablet_driver == OS::get_singleton()->get_tablet_driver_name(i)) { - OS::get_singleton()->set_current_tablet_driver(OS::get_singleton()->get_tablet_driver_name(i)); - break; - } - } - - if (tablet_driver == "") { - OS::get_singleton()->set_current_tablet_driver(OS::get_singleton()->get_tablet_driver_name(0)); - } - /* todo restore OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false); video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false); */ - GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2); - GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3); - if (editor || project_manager) { // The editor and project manager always detect and use hiDPI if needed OS::get_singleton()->_allow_hidpi = true; @@ -1298,7 +1278,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->_keep_screen_on = GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true); if (rtm == -1) { - rtm = GLOBAL_DEF("rendering/threads/thread_model", OS::RENDER_THREAD_SAFE); + rtm = GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE); } if (rtm >= 0 && rtm < 3) { @@ -1326,7 +1306,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } if (audio_driver == "") { // specified in project.godot - audio_driver = GLOBAL_DEF_RST_NOVAL("audio/driver", AudioDriverManager::get_driver(0)->get_name()); + audio_driver = GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name()); } for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) { @@ -1360,7 +1340,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } - Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60)); + Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF_BASIC("physics/common/physics_fps", 60)); ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_fps", PropertyInfo(Variant::INT, "physics/common/physics_fps", PROPERTY_HINT_RANGE, "1,120,1,or_greater")); @@ -1469,15 +1449,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // Print engine name and version print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); +#if !defined(NO_THREADS) if (p_main_tid_override) { - Thread::_main_thread_id = p_main_tid_override; + Thread::main_thread_id = p_main_tid_override; } +#endif /* Determine text driver */ - GLOBAL_DEF("display/window/text_name", ""); if (text_driver == "") { - text_driver = GLOBAL_GET("display/window/text_name"); + text_driver = GLOBAL_GET("internationalization/rendering/text_driver"); } if (text_driver != "") { @@ -1506,7 +1487,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } } } - printf("Using %s text server...\n", TextServerManager::get_interface_name(text_driver_idx).utf8().get_data()); + print_verbose("Using \"" + TextServerManager::get_interface_name(text_driver_idx) + "\" text server..."); /* Initialize Text Server */ @@ -1566,18 +1547,45 @@ Error Main::setup2(Thread::ID p_main_tid_override) { display_server->screen_set_orientation(window_orientation); } - /* Initialize Visual Server */ + /* Initialize Pen Table Driver */ + + { + GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver", ""); + GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver.windows", ""); + ProjectSettings::get_singleton()->set_custom_property_info("input_devices/pen_tablet/driver.windows", PropertyInfo(Variant::STRING, "input_devices/pen_tablet/driver.windows", PROPERTY_HINT_ENUM, "wintab,winink")); + } + + if (tablet_driver == "") { // specified in project.godot + tablet_driver = GLOBAL_GET("input_devices/pen_tablet/driver"); + if (tablet_driver == "") { + tablet_driver = DisplayServer::get_singleton()->tablet_get_driver_name(0); + } + } + + for (int i = 0; i < DisplayServer::get_singleton()->tablet_get_driver_count(); i++) { + if (tablet_driver == DisplayServer::get_singleton()->tablet_get_driver_name(i)) { + DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(i)); + break; + } + } - rendering_server = memnew(RenderingServerDefault); - if (OS::get_singleton()->get_render_thread_mode() != OS::RENDER_THREAD_UNSAFE) { - rendering_server = memnew(RenderingServerWrapMT(rendering_server, - OS::get_singleton()->get_render_thread_mode() == - OS::RENDER_SEPARATE_THREAD)); + if (DisplayServer::get_singleton()->tablet_get_current_driver() == "") { + DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(0)); } + print_verbose("Using \"" + tablet_driver + "\" pen tablet driver..."); + + /* Initialize Visual Server */ + + rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD)); + rendering_server->init(); rendering_server->set_render_loop_enabled(!disable_render_loop); + if (profile_gpu) { + rendering_server->set_print_gpu_profile(true); + } + OS::get_singleton()->initialize_joypads(); /* Initialize Audio Driver */ @@ -1602,7 +1610,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: Setup Logo"); -#ifdef JAVASCRIPT_ENABLED +#if defined(JAVASCRIPT_ENABLED) || defined(ANDROID_ENABLED) bool show_logo = false; #else bool show_logo = true; @@ -1628,9 +1636,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) { register_server_types(); - MAIN_PRINT("Main: Load Remaps"); + MAIN_PRINT("Main: Load Boot Image"); - Color clear = GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3)); + Color clear = GLOBAL_DEF("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3)); RenderingServer::get_singleton()->set_default_clear_color(clear); if (show_logo) { //boot logo! @@ -1683,8 +1691,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: DCC"); RenderingServer::get_singleton()->set_default_clear_color( - GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3))); - MAIN_PRINT("Main: END"); + GLOBAL_DEF("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3))); GLOBAL_DEF("application/config/icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", @@ -1722,7 +1729,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) { id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input_devices/pointing/emulate_mouse_from_touch", true))); } - MAIN_PRINT("Main: Load Remaps"); + MAIN_PRINT("Main: Load Translations and Remaps"); + + translation_server->setup(); //register translations, load them, etc. + if (locale != "") { + translation_server->set_locale(locale); + } + translation_server->load_translations(); + ResourceLoader::load_translation_remaps(); //load remaps for resources + + ResourceLoader::load_path_remaps(); MAIN_PRINT("Main: Load Scene Types"); @@ -1768,17 +1784,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // This loads global classes, so it must happen before custom loaders and savers are registered ScriptServer::init_languages(); - MAIN_PRINT("Main: Load Translations"); - - translation_server->setup(); //register translations, load them, etc. - if (locale != "") { - translation_server->set_locale(locale); - } - translation_server->load_translations(); - ResourceLoader::load_translation_remaps(); //load remaps for resources - - ResourceLoader::load_path_remaps(); - audio_server->load_default_bus_layout(); if (use_debug_profiler && EngineDebugger::is_active()) { @@ -1973,8 +1978,8 @@ bool Main::start() { #endif - if (script == "" && game_path == "" && String(GLOBAL_DEF("application/run/main_scene", "")) != "") { - game_path = GLOBAL_DEF("application/run/main_scene", ""); + if (script == "" && game_path == "" && String(GLOBAL_GET("application/run/main_scene")) != "") { + game_path = GLOBAL_GET("application/run/main_scene"); } MainLoop *main_loop = nullptr; @@ -1989,7 +1994,7 @@ bool Main::start() { if (check_only) { if (!script_res->is_valid()) { - OS::get_singleton()->set_exit_code(1); + OS::get_singleton()->set_exit_code(EXIT_FAILURE); } return false; } @@ -2146,18 +2151,13 @@ bool Main::start() { } #endif - { - int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size"); - RenderingServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size); - } - if (!editor && !project_manager) { //standard helpers that can be changed from main config - String stretch_mode = GLOBAL_DEF("display/window/stretch/mode", "disabled"); - String stretch_aspect = GLOBAL_DEF("display/window/stretch/aspect", "ignore"); - Size2i stretch_size = Size2i(GLOBAL_DEF("display/window/size/width", 0), - GLOBAL_DEF("display/window/size/height", 0)); + String stretch_mode = GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled"); + String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "ignore"); + Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/width", 0), + GLOBAL_DEF_BASIC("display/window/size/height", 0)); Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED; if (stretch_mode == "canvas_items") { @@ -2194,49 +2194,33 @@ bool Main::start() { DisplayServer::get_singleton()->window_set_title(appname); #endif - int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size"); - int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv"); - int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv"); - int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv"); - int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv"); - - sml->get_root()->set_shadow_atlas_size(shadow_atlas_size); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q0_subdiv)); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q1_subdiv)); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q2_subdiv)); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q3_subdiv)); - bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); sml->get_root()->set_snap_controls_to_pixels(snap_controls); - bool font_oversampling = GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true); + bool font_oversampling = GLOBAL_DEF("gui/fonts/dynamic_fonts/use_oversampling", true); sml->get_root()->set_use_font_oversampling(font_oversampling); - int texture_filter = GLOBAL_DEF("rendering/canvas_textures/default_texture_filter", 1); - int texture_repeat = GLOBAL_DEF("rendering/canvas_textures/default_texture_repeat", 0); + int texture_filter = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_filter", 1); + int texture_repeat = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_repeat", 0); sml->get_root()->set_default_canvas_item_texture_filter( Viewport::DefaultCanvasItemTextureFilter(texture_filter)); sml->get_root()->set_default_canvas_item_texture_repeat( Viewport::DefaultCanvasItemTextureRepeat(texture_repeat)); } else { - GLOBAL_DEF("display/window/stretch/mode", "disabled"); + GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled"); ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,canvas_items,viewport")); - GLOBAL_DEF("display/window/stretch/aspect", "ignore"); + GLOBAL_DEF_BASIC("display/window/stretch/aspect", "ignore"); ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand")); - GLOBAL_DEF("display/window/stretch/shrink", 1.0); + GLOBAL_DEF_BASIC("display/window/stretch/shrink", 1.0); ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::FLOAT, "display/window/stretch/shrink", @@ -2244,18 +2228,18 @@ bool Main::start() { "1.0,8.0,0.1")); sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); - GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); - GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true); + GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true); + GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true); - GLOBAL_DEF("rendering/canvas_textures/default_texture_filter", 1); + GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_filter", 1); ProjectSettings::get_singleton()->set_custom_property_info( - "rendering/canvas_textures/default_texture_filter", - PropertyInfo(Variant::INT, "rendering/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, + "rendering/textures/canvas_textures/default_texture_filter", + PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest")); - GLOBAL_DEF("rendering/canvas_textures/default_texture_repeat", 0); + GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_repeat", 0); ProjectSettings::get_singleton()->set_custom_property_info( - "rendering/canvas_textures/default_texture_repeat", - PropertyInfo(Variant::INT, "rendering/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, + "rendering/textures/canvas_textures/default_texture_repeat", + PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, "Disable,Enable,Mirror")); } @@ -2469,6 +2453,7 @@ bool Main::iteration() { for (int iters = 0; iters < advance.physics_steps; ++iters) { uint64_t physics_begin = OS::get_singleton()->get_ticks_usec(); + PhysicsServer3D::get_singleton()->sync(); PhysicsServer3D::get_singleton()->flush_queries(); PhysicsServer2D::get_singleton()->sync(); @@ -2483,6 +2468,7 @@ bool Main::iteration() { message_queue->flush(); + PhysicsServer3D::get_singleton()->end_sync(); PhysicsServer3D::get_singleton()->step(physics_step * time_scale); PhysicsServer2D::get_singleton()->end_sync(); @@ -2592,8 +2578,10 @@ void Main::force_redraw() { * so that the engine closes cleanly without leaking memory or crashing. * The order matters as some of those steps are linked with each other. */ -void Main::cleanup() { - ERR_FAIL_COND(!_start_success); +void Main::cleanup(bool p_force) { + if (!p_force) { + ERR_FAIL_COND(!_start_success); + } EngineDebugger::deinitialize(); @@ -2686,8 +2674,7 @@ void Main::cleanup() { //attempt to restart with arguments String exec = OS::get_singleton()->get_executable_path(); List<String> args = OS::get_singleton()->get_restart_on_exit_arguments(); - OS::ProcessID pid = 0; - OS::get_singleton()->execute(exec, args, false, &pid); + OS::get_singleton()->create_process(exec, args); OS::get_singleton()->set_restart_on_exit(false, List<String>()); //clear list (uses memory) } diff --git a/main/main.h b/main/main.h index 9e606c188d..f4fff6b97e 100644 --- a/main/main.h +++ b/main/main.h @@ -59,7 +59,7 @@ public: static bool is_iterating(); - static void cleanup(); + static void cleanup(bool p_force = false); }; // Test main override is for the testing behaviour. diff --git a/main/performance.cpp b/main/performance.cpp index 1a422dc499..a2e53f2ee2 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -119,7 +119,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const { "physics_3d/active_objects", "physics_3d/collision_pairs", "physics_3d/islands", - "audio/output_latency", + "audio/driver/output_latency", }; diff --git a/methods.py b/methods.py index 15eb82ae74..9b29eadc16 100644 --- a/methods.py +++ b/methods.py @@ -6,9 +6,11 @@ from collections import OrderedDict # We need to define our own `Action` method to control the verbosity of output # and whenever we need to run those commands in a subprocess on some platforms. -from SCons.Script import Action from SCons import Node +from SCons.Script import Action +from SCons.Script import ARGUMENTS from SCons.Script import Glob +from SCons.Variables.BoolVariable import _text2bool from platform_methods import run_in_subprocess @@ -145,34 +147,97 @@ def parse_cg_file(fname, uniforms, sizes, conditionals): fs.close() -def detect_modules(at_path): - module_list = OrderedDict() # name : path +def get_cmdline_bool(option, default): + """We use `ARGUMENTS.get()` to check if options were manually overridden on the command line, + and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings. + """ + cmdline_val = ARGUMENTS.get(option) + if cmdline_val is not None: + return _text2bool(cmdline_val) + else: + return default - modules_glob = os.path.join(at_path, "*") - files = glob.glob(modules_glob) - files.sort() # so register_module_types does not change that often, and also plugins are registered in alphabetic order - for x in files: - if not is_module(x): - continue - name = os.path.basename(x) - path = x.replace("\\", "/") # win32 - module_list[name] = path +def detect_modules(search_path, recursive=False): + """Detects and collects a list of C++ modules at specified path - return module_list + `search_path` - a directory path containing modules. The path may point to + a single module, which may have other nested modules. A module must have + "register_types.h", "SCsub", "config.py" files created to be detected. + + `recursive` - if `True`, then all subdirectories are searched for modules as + specified by the `search_path`, otherwise collects all modules under the + `search_path` directory. If the `search_path` is a module, it is collected + in all cases. + + Returns an `OrderedDict` with module names as keys, and directory paths as + values. If a path is relative, then it is a built-in module. If a path is + absolute, then it is a custom module collected outside of the engine source. + """ + modules = OrderedDict() + + def add_module(path): + module_name = os.path.basename(path) + module_path = path.replace("\\", "/") # win32 + modules[module_name] = module_path + + def is_engine(path): + # Prevent recursively detecting modules in self and other + # Godot sources when using `custom_modules` build option. + version_path = os.path.join(path, "version.py") + if os.path.exists(version_path): + with open(version_path) as f: + if 'short_name = "godot"' in f.read(): + return True + return False + + def get_files(path): + files = glob.glob(os.path.join(path, "*")) + # Sort so that `register_module_types` does not change that often, + # and plugins are registered in alphabetic order as well. + files.sort() + return files + + if not recursive: + if is_module(search_path): + add_module(search_path) + for path in get_files(search_path): + if is_engine(path): + continue + if is_module(path): + add_module(path) + else: + to_search = [search_path] + while to_search: + path = to_search.pop() + if is_module(path): + add_module(path) + for child in get_files(path): + if not os.path.isdir(child): + continue + if is_engine(child): + continue + to_search.insert(0, child) + return modules def is_module(path): - return os.path.isdir(path) and os.path.exists(os.path.join(path, "SCsub")) + if not os.path.isdir(path): + return False + must_exist = ["register_types.h", "SCsub", "config.py"] + for f in must_exist: + if not os.path.exists(os.path.join(path, f)): + return False + return True -def write_modules(module_list): +def write_modules(modules): includes_cpp = "" preregister_cpp = "" register_cpp = "" unregister_cpp = "" - for name, path in module_list.items(): + for name, path in modules.items(): try: with open(os.path.join(path, "register_types.h")): includes_cpp += '#include "' + path + '/register_types.h"\n' @@ -230,8 +295,6 @@ def convert_custom_modules_path(path): raise ValueError(err_msg % "point to an existing directory.") if path == os.path.realpath("modules"): raise ValueError(err_msg % "be a directory other than built-in `modules` directory.") - if is_module(path): - raise ValueError(err_msg % "point to a directory with modules, not a single module.") return path diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index de3cd07a93..535721f418 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -4,9 +4,8 @@ <meta charset='utf-8' /> <meta name='viewport' content='width=device-width, user-scalable=no' /> <link id='-gd-engine-icon' rel='icon' type='image/png' href='favicon.png' /> - <title></title> - <style type='text/css'> - + <title>Godot Engine Web Editor (@GODOT_VERSION@)</title> + <style> *:focus { /* More visible outline for better keyboard navigation. */ outline: 0.125rem solid hsl(220, 100%, 62.5%); @@ -40,13 +39,30 @@ filter: brightness(82.5%); } + #tabs-buttons { + /* Match the default background color of the editor window for a seamless appearance. */ + background-color: #202531; + } + + #tab-game { + /* Use a pure black background to better distinguish the running project */ + /* from the editor window, and to use a more neutral background color (no tint). */ + background-color: black; + /* Make the background span the entire page height. */ + min-height: 100vh; + } + #canvas, #gameCanvas { display: block; margin: 0; color: white; } - #canvas:focus, #gameCanvas:focus { + /* Don't show distracting focus outlines for the main tabs' contents. */ + #tab-editor canvas:focus, + #tab-game canvas:focus, + #canvas:focus, + #gameCanvas:focus { outline: none; } @@ -189,11 +205,22 @@ <br /> <img src="logo.svg" width="1024" height="414" style="width: auto; height: auto; max-width: 85%; max-height: 250px" /> <br /> + @GODOT_VERSION@ + <br /> + <a href="releases/">Need an old version?</a> + <br /> + <br /> + <br /> <label for="zip-file" style="margin-right: 1rem">Preload project ZIP:</label> <input id="zip-file" type="file" id="files" name="files" style="margin-bottom: 1rem"/> <br /> - <button id="startButton" class="btn" style="margin-bottom: 4rem">Start Godot editor</button> +<a href="demo.zip">(Try this for example)</a> <br /> - <button class="btn" onclick="clearPersistence()">Clear persistent data</button> + <br /> + <button id="startButton" class="btn" style="margin-bottom: 4rem; font-weight: 700">Start Godot editor</button> + <br /> + <button class="btn" onclick="clearPersistence()" style="margin-bottom: 1.5rem">Clear persistent data</button> + <br /> + <a href="https://docs.godotengine.org/en/latest/tutorials/editor/using_the_web_editor.html">Web editor documentation</a> </div> </div> <div id='tab-editor' style="display: none;"> @@ -224,10 +251,10 @@ </div> </div> - <script type='text/javascript' src='godot.tools.js'></script> - <script type='text/javascript'>//<![CDATA[ + <script src='godot.tools.js'></script> + <script>//<![CDATA[ - var engine = new Engine; + var editor = null; var game = null; var setStatusMode; var setStatusNotice; @@ -249,13 +276,11 @@ }); } - if (!window.confirm("Are you sure you want to delete all the locally stored files?")) { + if (!window.confirm("Are you sure you want to delete all the locally stored files?\nClicking \"OK\" will permanently remove your projects and editor settings!")) { return; } Promise.all([ - deleteDB("/home/web_user/projects"), - deleteDB("/home/web_user/.config"), - deleteDB("/home/web_user/.cache"), + deleteDB("/home/web_user"), ]).then(function(results) { alert("Done."); }).catch(function (err) { @@ -277,6 +302,10 @@ tabs.forEach(function (elem) { if (elem.id == 'tab-' + name) { elem.style.display = 'block'; + if (name == 'editor' || name == 'game') { + const canvas = document.getElementById(name + '-canvas'); + canvas.focus(); + } } else { elem.style.display = 'none'; } @@ -310,14 +339,14 @@ function closeEditor() { closeGame(); - if (engine) { - engine.requestQuit(); + if (editor) { + editor.requestQuit(); } } function startEditor(zip) { const INDETERMINATE_STATUS_STEP_MS = 100; - const persistentPaths = ['/home/web_user/.config', '/home/web_user/.cache', '/home/web_user/projects']; + const persistentPaths = ['/home/web_user']; var editorCanvas = document.getElementById('editor-canvas'); var gameCanvas = document.getElementById('game-canvas'); @@ -325,6 +354,7 @@ var statusProgressInner = document.getElementById('status-progress-inner'); var statusIndeterminate = document.getElementById('status-indeterminate'); var statusNotice = document.getElementById('status-notice'); + var headerDiv = document.getElementById('tabs-buttons'); var initializing = true; var statusMode = 'hidden'; @@ -338,16 +368,23 @@ } requestAnimationFrame(animate); + var lastScale = 0; + var lastWidth = 0; + var lastHeight = 0; function adjustCanvasDimensions() { var scale = window.devicePixelRatio || 1; - var header = document.getElementById('tabs-buttons'); - var headerHeight = header.offsetHeight + 1; + var headerHeight = headerDiv.offsetHeight + 1; var width = window.innerWidth; var height = window.innerHeight - headerHeight; - editorCanvas.width = width * scale; - editorCanvas.height = height * scale; - editorCanvas.style.width = width + "px"; - editorCanvas.style.height = height + "px"; + if (lastScale !== scale || lastWidth !== width || lastHeight !== height) { + editorCanvas.width = width * scale; + editorCanvas.height = height * scale; + editorCanvas.style.width = width + "px"; + editorCanvas.style.height = height + "px"; + lastScale = scale; + lastWidth = width; + lastHeight = height; + } } animationCallbacks.push(adjustCanvasDimensions); adjustCanvasDimensions(); @@ -401,24 +438,23 @@ }); }; - engine.setProgressFunc((current, total) => { - if (total > 0) { - statusProgressInner.style.width = current/total * 100 + '%'; - setStatusMode('progress'); - if (current === total) { - // wait for progress bar animation - setTimeout(() => { - setStatusMode('indeterminate'); - }, 100); - } - } else { - setStatusMode('indeterminate'); - } - }); - - engine.setPersistentPaths(persistentPaths); + const gameConfig = { + 'persistentPaths': persistentPaths, + 'unloadAfterInit': false, + 'canvas': gameCanvas, + 'canvasResizePolicy': 1, + 'onExit': function () { + setGameTabEnabled(false); + showTab('editor'); + game = null; + }, + }; - engine.setOnExecute(function(args) { + var OnEditorExit = function () { + showTab('loader'); + setLoaderEnabled(true); + }; + function Execute(args) { const is_editor = args.filter(function(v) { return v == '--editor' || v == '-e' }).length != 0; const is_project_manager = args.filter(function(v) { return v == '--project-manager' }).length != 0; const is_game = !is_editor && !is_project_manager; @@ -431,42 +467,60 @@ return; } setGameTabEnabled(true); - game = new Engine(); - game.setPersistentPaths(persistentPaths); - game.setUnloadAfterInit(false); - game.setOnExecute(engine.onExecute); - game.setCanvas(gameCanvas); - game.setCanvasResizedOnStart(true); - game.setOnExit(function() { - setGameTabEnabled(false); - showTab('editor'); - game = null; - }); + game = new Engine(gameConfig); showTab('game'); game.init().then(function() { requestAnimationFrame(function() { - game.start.apply(game, args).then(function() { + game.start({'args': args}).then(function() { gameCanvas.focus(); }); }); }); } else { // New editor instances will be run in the same canvas. We want to wait for it to exit. - engine.setOnExit(function(code) { + OnEditorExit = function(code) { setLoaderEnabled(true); setTimeout(function() { - engine.init().then(function() { + editor.init().then(function() { setLoaderEnabled(false); - engine.setOnExit(function() { + OnEditorExit = function() { showTab('loader'); setLoaderEnabled(true); - }); - engine.start.apply(engine, args); + }; + editor.start({'args': args}); }); }, 0); - engine.setOnExit(null); - }); + OnEditorExit = null; + }; } - }); + } + + const editorConfig = { + 'unloadAfterInit': false, + 'onProgress': function progressFunction (current, total) { + if (total > 0) { + statusProgressInner.style.width = current/total * 100 + '%'; + setStatusMode('progress'); + if (current === total) { + // wait for progress bar animation + setTimeout(() => { + setStatusMode('indeterminate'); + }, 100); + } + } else { + setStatusMode('indeterminate'); + } + }, + 'canvas': editorCanvas, + 'canvasResizePolicy': 0, + 'onExit': function() { + if (OnEditorExit) { + OnEditorExit(); + } + }, + 'onExecute': Execute, + 'persistentPaths': persistentPaths, + }; + editor = new Engine(editorConfig); function displayFailureNotice(err) { var msg = err.message || err; @@ -480,26 +534,20 @@ displayFailureNotice('WebGL not available'); } else { setStatusMode('indeterminate'); - engine.setCanvas(editorCanvas); - engine.setUnloadAfterInit(false); // Don't want to reload when starting game. - engine.init('godot.tools').then(function() { + editor.init('godot.tools').then(function() { if (zip) { - engine.copyToFS("/home/web_user/preload.zip", zip); + editor.copyToFS("/tmp/preload.zip", zip); } try { // Avoid user creating project in the persistent root folder. - engine.copyToFS("/home/web_user/projects/keep", new Uint8Array()); + editor.copyToFS("/home/web_user/keep", new Uint8Array()); } catch(e) { // File exists } //selectVideoMode(); showTab('editor'); setLoaderEnabled(false); - engine.setOnExit(function() { - showTab('loader'); - setLoaderEnabled(true); - }); - engine.start('--video-driver', video_driver).then(function() { + editor.start({'args': ['--video-driver', video_driver]}).then(function() { setStatusMode('hidden'); initializing = false; }); diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html index 85c5305b85..abc0479739 100644 --- a/misc/dist/html/full-size.html +++ b/misc/dist/html/full-size.html @@ -134,22 +134,14 @@ $GODOT_HEAD_INCLUDE <div id='status-notice' class='godot' style='display: none;'></div> </div> - <script type='text/javascript' src='$GODOT_BASENAME.js'></script> + <script type='text/javascript' src='$GODOT_URL'></script> <script type='text/javascript'>//<![CDATA[ - var engine = new Engine; - var setStatusMode; - var setStatusNotice; + const GODOT_CONFIG = $GODOT_CONFIG; + var engine = new Engine(GODOT_CONFIG); (function() { - const EXECUTABLE_NAME = '$GODOT_BASENAME'; - const MAIN_PACK = '$GODOT_BASENAME.pck'; - const EXTRA_ARGS = JSON.parse('$GODOT_ARGS'); - const GDNATIVE_LIBS = [$GODOT_GDNATIVE_LIBS]; const INDETERMINATE_STATUS_STEP_MS = 100; - const FULL_WINDOW = $GODOT_FULL_WINDOW; - - var canvas = document.getElementById('canvas'); var statusProgress = document.getElementById('status-progress'); var statusProgressInner = document.getElementById('status-progress-inner'); var statusIndeterminate = document.getElementById('status-indeterminate'); @@ -157,9 +149,6 @@ $GODOT_HEAD_INCLUDE var initializing = true; var statusMode = 'hidden'; - var lastWidth = 0; - var lastHeight = 0; - var lastScale = 0; var animationCallbacks = []; function animate(time) { @@ -168,26 +157,8 @@ $GODOT_HEAD_INCLUDE } requestAnimationFrame(animate); - function adjustCanvasDimensions() { - const scale = window.devicePixelRatio || 1; - if (lastWidth != window.innerWidth || lastHeight != window.innerHeight || lastScale != scale) { - lastScale = scale; - lastWidth = window.innerWidth; - lastHeight = window.innerHeight; - canvas.width = Math.floor(lastWidth * scale); - canvas.height = Math.floor(lastHeight * scale); - canvas.style.width = lastWidth + "px"; - canvas.style.height = lastHeight + "px"; - } - } - if (FULL_WINDOW) { - animationCallbacks.push(adjustCanvasDimensions); - adjustCanvasDimensions(); - } else { - engine.setCanvasResizedOnStart(true); - } + function setStatusMode(mode) { - setStatusMode = function setStatusMode(mode) { if (statusMode === mode || !initializing) return; [statusProgress, statusIndeterminate, statusNotice].forEach(elem => { @@ -213,7 +184,7 @@ $GODOT_HEAD_INCLUDE throw new Error('Invalid status mode'); } statusMode = mode; - }; + } function animateStatusIndeterminate(ms) { var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8); @@ -225,7 +196,7 @@ $GODOT_HEAD_INCLUDE } } - setStatusNotice = function setStatusNotice(text) { + function setStatusNotice(text) { while (statusNotice.lastChild) { statusNotice.removeChild(statusNotice.lastChild); } @@ -236,21 +207,6 @@ $GODOT_HEAD_INCLUDE }); }; - engine.setProgressFunc((current, total) => { - if (total > 0) { - statusProgressInner.style.width = current/total * 100 + '%'; - setStatusMode('progress'); - if (current === total) { - // wait for progress bar animation - setTimeout(() => { - setStatusMode('indeterminate'); - }, 500); - } - } else { - setStatusMode('indeterminate'); - } - }); - function displayFailureNotice(err) { var msg = err.message || err; console.error(msg); @@ -263,9 +219,22 @@ $GODOT_HEAD_INCLUDE displayFailureNotice('WebGL not available'); } else { setStatusMode('indeterminate'); - engine.setCanvas(canvas); - engine.setGDNativeLibraries(GDNATIVE_LIBS); - engine.startGame(EXECUTABLE_NAME, MAIN_PACK, EXTRA_ARGS).then(() => { + engine.startGame({ + 'onProgress': function (current, total) { + if (total > 0) { + statusProgressInner.style.width = current/total * 100 + '%'; + setStatusMode('progress'); + if (current === total) { + // wait for progress bar animation + setTimeout(() => { + setStatusMode('indeterminate'); + }, 500); + } + } else { + setStatusMode('indeterminate'); + } + }, + }).then(() => { setStatusMode('hidden'); initializing = false; }, displayFailureNotice); diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index bd21883259..b9ad431e6e 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -8,11 +8,11 @@ /* Begin PBXBuildFile section */ 1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; }; - DEADBEEF2F582BE20003B888 /* $binary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.a */; }; + DEADBEEF2F582BE20003B888 /* $binary.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.xcframework */; }; $modules_buildfile 1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */; }; D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; }; - 9039D3BE24C093AC0020482C /* MoltenVK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9039D3BD24C093AC0020482C /* MoltenVK.a */; }; + 9039D3BE24C093AC0020482C /* MoltenVK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9039D3BD24C093AC0020482C /* MoltenVK.xcframework */; }; 9073252C24BF980B0063BCD4 /* vulkan in Resources */ = {isa = PBXBuildFile; fileRef = 905036DC24BF932E00301046 /* vulkan */; }; D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; }; D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* $binary.pck */; }; @@ -35,11 +35,11 @@ /* Begin PBXFileReference section */ 1F1575711F582BE20003B888 /* dylibs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dylibs; path = "$binary/dylibs"; sourceTree = "<group>"; }; - DEADBEEF1F582BE20003B888 /* $binary.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot; path = "$binary.a"; sourceTree = "<group>"; }; + DEADBEEF1F582BE20003B888 /* $binary.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = godot; path = "$binary.xcframework"; sourceTree = "<group>"; }; $modules_fileref 1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; }; 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; }; - 9039D3BD24C093AC0020482C /* MoltenVK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = MoltenVK; path = MoltenVK.a; sourceTree = "<group>"; }; + 9039D3BD24C093AC0020482C /* MoltenVK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MoltenVK; path = MoltenVK.xcframework; sourceTree = "<group>"; }; 905036DC24BF932E00301046 /* vulkan */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vulkan; path = "$binary/vulkan"; sourceTree = "<group>"; }; D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; D0BCFE3418AEBDA2004A7AAE /* $binary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "$binary.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -56,8 +56,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9039D3BE24C093AC0020482C /* MoltenVK.a in Frameworks */, - DEADBEEF2F582BE20003B888 /* $binary.a */, + 9039D3BE24C093AC0020482C /* MoltenVK.xcframework in Frameworks */, + DEADBEEF2F582BE20003B888 /* $binary.xcframework */, $modules_buildphase $additional_pbx_frameworks_build ); @@ -90,8 +90,8 @@ D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = { isa = PBXGroup; children = ( - 9039D3BD24C093AC0020482C /* MoltenVK.a */, - DEADBEEF1F582BE20003B888 /* $binary.a */, + 9039D3BD24C093AC0020482C /* MoltenVK.xcframework */, + DEADBEEF1F582BE20003B888 /* $binary.xcframework */, $modules_buildgrp $additional_pbx_frameworks_refs ); diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.fat.a b/misc/dist/ios_xcode/libgodot.iphone.debug.fat.a deleted file mode 100644 index e69de29bb2..0000000000 --- a/misc/dist/ios_xcode/libgodot.iphone.debug.fat.a +++ /dev/null diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist new file mode 100644 index 0000000000..846533594f --- /dev/null +++ b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>AvailableLibraries</key> + <array> + <dict> + <key>LibraryIdentifier</key> + <string>ios-arm64</string> + <key>LibraryPath</key> + <string>libgodot.a</string> + <key>SupportedArchitectures</key> + <array> + <string>arm64</string> + </array> + <key>SupportedPlatform</key> + <string>ios</string> + </dict> + <dict> + <key>LibraryIdentifier</key> + <string>ios-arm64_x86_64-simulator</string> + <key>LibraryPath</key> + <string>libgodot.a</string> + <key>SupportedArchitectures</key> + <array> + <string>arm64</string> + <string>x86_64</string> + </array> + <key>SupportedPlatform</key> + <string>ios</string> + <key>SupportedPlatformVariant</key> + <string>simulator</string> + </dict> + </array> + <key>CFBundlePackageType</key> + <string>XFWK</string> + <key>XCFrameworkFormatVersion</key> + <string>1.0</string> +</dict> +</plist> diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty new file mode 100644 index 0000000000..bd3e894333 --- /dev/null +++ b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty @@ -0,0 +1 @@ +Dummy file to make dylibs folder exported diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty new file mode 100644 index 0000000000..bd3e894333 --- /dev/null +++ b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty @@ -0,0 +1 @@ +Dummy file to make dylibs folder exported diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.fat.a b/misc/dist/ios_xcode/libgodot.iphone.release.fat.a deleted file mode 100644 index e69de29bb2..0000000000 --- a/misc/dist/ios_xcode/libgodot.iphone.release.fat.a +++ /dev/null diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist new file mode 100644 index 0000000000..846533594f --- /dev/null +++ b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>AvailableLibraries</key> + <array> + <dict> + <key>LibraryIdentifier</key> + <string>ios-arm64</string> + <key>LibraryPath</key> + <string>libgodot.a</string> + <key>SupportedArchitectures</key> + <array> + <string>arm64</string> + </array> + <key>SupportedPlatform</key> + <string>ios</string> + </dict> + <dict> + <key>LibraryIdentifier</key> + <string>ios-arm64_x86_64-simulator</string> + <key>LibraryPath</key> + <string>libgodot.a</string> + <key>SupportedArchitectures</key> + <array> + <string>arm64</string> + <string>x86_64</string> + </array> + <key>SupportedPlatform</key> + <string>ios</string> + <key>SupportedPlatformVariant</key> + <string>simulator</string> + </dict> + </array> + <key>CFBundlePackageType</key> + <string>XFWK</string> + <key>XCFrameworkFormatVersion</key> + <string>1.0</string> +</dict> +</plist> diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty new file mode 100644 index 0000000000..bd3e894333 --- /dev/null +++ b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty @@ -0,0 +1 @@ +Dummy file to make dylibs folder exported diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty new file mode 100644 index 0000000000..bd3e894333 --- /dev/null +++ b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty @@ -0,0 +1 @@ +Dummy file to make dylibs folder exported diff --git a/misc/dist/linux/org.godotengine.Godot.xml b/misc/dist/linux/org.godotengine.Godot.xml new file mode 100644 index 0000000000..2f647f71a6 --- /dev/null +++ b/misc/dist/linux/org.godotengine.Godot.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> + <mime-type type="application/x-godot-project"> + <comment>Godot Engine project</comment> + <icon name="x-godot-project" /> + <glob pattern="*.godot"/> + </mime-type> + + <mime-type type="application/x-godot-resource"> + <comment>Godot Engine resource</comment> + <icon name="x-godot-resource" /> + <glob pattern="*.res"/> + <glob pattern="*.tres"/> + </mime-type> + + <mime-type type="application/x-godot-scene"> + <comment>Godot Engine scene</comment> + <icon name="x-godot-scene" /> + <glob pattern="*.scn"/> + <glob pattern="*.tscn"/> + <glob pattern="*.escn"/> + </mime-type> + + <mime-type type="application/x-gdscript"> + <comment>GDScript script</comment> + <icon name="x-gdscript" /> + <glob pattern="*.gd"/> + </mime-type> +</mime-info> diff --git a/misc/dist/linux/x-godot-project.xml b/misc/dist/linux/x-godot-project.xml deleted file mode 100644 index 9f28bab2ae..0000000000 --- a/misc/dist/linux/x-godot-project.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0"?> -<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> - <mime-type type="application/x-godot-project"> - <comment>Godot Engine project</comment> - <icon name="godot" /> - <glob pattern="*.godot" weight="100" /> - </mime-type> -</mime-info> diff --git a/misc/dist/osx_template.app/Contents/Info.plist b/misc/dist/osx_template.app/Contents/Info.plist index aad24935d0..aad24935d0 100755..100644 --- a/misc/dist/osx_template.app/Contents/Info.plist +++ b/misc/dist/osx_template.app/Contents/Info.plist diff --git a/misc/dist/osx_tools.app/Contents/Info.plist b/misc/dist/osx_tools.app/Contents/Info.plist index 1c682f339f..1c682f339f 100755..100644 --- a/misc/dist/osx_tools.app/Contents/Info.plist +++ b/misc/dist/osx_tools.app/Contents/Info.plist diff --git a/misc/dist/project_icon.svg b/misc/dist/project_icon.svg index cece381340..39a8cd6332 100644 --- a/misc/dist/project_icon.svg +++ b/misc/dist/project_icon.svg @@ -1 +1 @@ -<svg height="1024" width="1024" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -98.519719)"><rect fill="#1e1a21" height="1008" rx="176.28572" stroke="#2e2832" stroke-width="16" width="1008" x="8" y="106.51972"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164712 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426581-6.973693 9.2079704-13.9828879 13.621-19.449z" fill="#478cbf" transform="matrix(4.2343801 0 0 -4.2343764 97.676491 522.86238)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.2343801 0 0 -4.2343764 788.7623 819.22103)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.2343801 0 0 -4.2343764 387.09785 624.34645)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.2343801 0 0 -4.2343764 364.87318 629.82505)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.2343801 0 0 -4.2343764 511.99324 725.12292)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.2343801 0 0 -4.2343764 636.90407 624.34645)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.2343801 0 0 -4.2343764 659.13434 629.82505)"/></g></svg> +<svg height="1024" width="1024" xmlns="http://www.w3.org/2000/svg"><rect fill="#1e1a21" height="1008" rx="176.28572" stroke="#2e2832" stroke-width="16" width="1008" x="8" y="8.000001"/><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 926.261959 674.345124)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(4.23438024 0 0 -4.23438024 97.676501 424.342903)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.23438024 0 0 -4.23438024 788.762303 720.701811)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 387.097823 525.827045)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.23438024 0 0 -4.23438024 364.873153 531.305653)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 511.993216 626.603625)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 636.904052 525.827045)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.23438024 0 0 -4.23438024 659.134337 531.305653)"/></svg> diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index 4e1fbdeb20..1cbc576565 100755 --- a/misc/hooks/pre-commit-clang-format +++ b/misc/hooks/pre-commit-clang-format @@ -74,25 +74,39 @@ else against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi +# To get consistent formatting, we recommend contributors to use the same +# clang-format version as CI. +RECOMMENDED_CLANG_FORMAT_MAJOR="11" + if [ ! -x "$CLANG_FORMAT" ] ; then + message="Error: clang-format executable not found. Please install clang-format $RECOMMENDED_CLANG_FORMAT_MAJOR.x.x." + if [ ! -t 1 ] ; then if [ -x "$ZENITY" ] ; then - $ZENITY --error --title="Error" --text="Error: clang-format executable not found." + $ZENITY --error --title="Error" --text="$message" exit 1 elif [ -x "$XMSG" ] ; then - $XMSG -center -title "Error" "Error: clang-format executable not found." + $XMSG -center -title "Error" "$message" exit 1 elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")" - $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: clang-format executable not found." + $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "$message" exit 1 fi fi - printf "Error: clang-format executable not found.\n" + printf "$message\n" printf "Set the correct path in $(canonicalize_filename "$0").\n" exit 1 fi +CLANG_FORMAT_VERSION="$(clang-format --version | cut -d' ' -f3)" +CLANG_FORMAT_MAJOR="$(echo "$CLANG_FORMAT_VERSION" | cut -d'.' -f1)" + +if [ "$CLANG_FORMAT_MAJOR" != "$RECOMMENDED_CLANG_FORMAT_MAJOR" ]; then + echo "Warning: Your clang-format binary is the wrong version ($CLANG_FORMAT_VERSION, expected $CLANG_FORMAT_MAJOR.x.x)." + echo " Consider upgrading or downgrading clang-format as formatting may not be applied correctly." +fi + # create a random filename to store our generated patch prefix="pre-commit-clang-format" suffix="$(date +%s)" @@ -111,6 +125,9 @@ do if grep -q "platform/android/java/lib/src/com" <<< $file; then continue; fi + if grep -q "\-so_wrap." <<< $file; then + continue; + fi # ignore file if we do check for file extensions and the file # does not match any of the extensions specified in $FILE_EXTS diff --git a/misc/hooks/winmessage.ps1 b/misc/hooks/winmessage.ps1 index 3672579544..3672579544 100755..100644 --- a/misc/hooks/winmessage.ps1 +++ b/misc/hooks/winmessage.ps1 diff --git a/misc/scripts/clang_format.sh b/misc/scripts/clang_format.sh index e686305dea..63c66d41c3 100755 --- a/misc/scripts/clang_format.sh +++ b/misc/scripts/clang_format.sh @@ -16,6 +16,8 @@ while IFS= read -rd '' f; do continue elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then continue + elif [[ "$f" == *"-so_wrap."* ]]; then + continue fi for extension in ${CLANG_FORMAT_FILE_EXTS[@]}; do diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh index 0e9db68a90..795431cd28 100755 --- a/misc/scripts/file_format.sh +++ b/misc/scripts/file_format.sh @@ -30,6 +30,8 @@ while IFS= read -rd '' f; do continue elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then continue + elif [[ "$f" == *"-so_wrap."* ]]; then + continue fi # Ensure that files are UTF-8 formatted. recode UTF-8 "$f" 2> /dev/null @@ -38,15 +40,6 @@ while IFS= read -rd '' f; do # Remove trailing space characters and ensures that files end # with newline characters. -l option handles newlines conveniently. perl -i -ple 's/\s*$//g' "$f" - # Remove the character sequence "== true" if it has a leading space. - perl -i -pe 's/\x20== true//g' "$f" - - if [[ $(uname) == "Linux" ]] && [[ "$f" != *"xml" ]]; then - # Remove empty lines after the opening brace of indented blocks. - sed -z -i 's/\x7B\x0A\x0A\x09/\x7B\x0A\x09/g' "$f" - # Remove empty lines before the closing brace (in some cases). - sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f" - fi done git diff > patch.patch diff --git a/modules/SCsub b/modules/SCsub index 24598f4b28..64da3bd0be 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -45,18 +45,6 @@ for name, path in env.module_list.items(): else: SConscript(path + "/SCsub") # Custom. - # Some modules are not linked automatically but can be enabled optionally - # on iOS, so we handle those specially. - if env["platform"] == "iphone" and name in [ - "arkit", - "camera", - "camera_iphone", - "gamecenter", - "inappstore", - "icloud", - ]: - continue - lib = env_modules.add_library("module_%s" % name, env.modules_sources) env.Prepend(LIBS=[lib]) if env["vsproj"]: diff --git a/modules/arkit/SCsub b/modules/arkit/SCsub deleted file mode 100644 index 7e103d6565..0000000000 --- a/modules/arkit/SCsub +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_arkit = env_modules.Clone() - -# (iOS) Enable module support -env_arkit.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - -# (iOS) Build as separate static library -modules_sources = [] -env_arkit.add_source_files(modules_sources, "*.cpp") -env_arkit.add_source_files(modules_sources, "*.mm") -mod_lib = env_modules.add_library("#bin/libgodot_arkit_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/arkit/arkit.gdip b/modules/arkit/arkit.gdip deleted file mode 100644 index 22c0a07e26..0000000000 --- a/modules/arkit/arkit.gdip +++ /dev/null @@ -1,18 +0,0 @@ -[config] -name="ARKit" -binary="arkit_lib.a" - -initialization="register_arkit_types" -deinitialization="unregister_arkit_types" - -[dependencies] -linked=[] -embedded=[] -system=["AVFoundation.framework", "ARKit.framework"] - -capabilities=["arkit"] - -files=[] - -[plist] -NSCameraUsageDescription="Device camera is used for some functionality" diff --git a/modules/arkit/arkit_interface.h b/modules/arkit/arkit_interface.h deleted file mode 100644 index f9b7709aba..0000000000 --- a/modules/arkit/arkit_interface.h +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************/ -/* arkit_interface.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ARKIT_INTERFACE_H -#define ARKIT_INTERFACE_H - -#include "servers/camera/camera_feed.h" -#include "servers/xr/xr_interface.h" -#include "servers/xr/xr_positional_tracker.h" - -/** - @author Bastiaan Olij <mux213@gmail.com> - - ARKit interface between iPhone and Godot -*/ - -// forward declaration for some needed objects -class ARKitShader; - -#ifdef __OBJC__ - -typedef ARAnchor GodotARAnchor; - -#else - -typedef void GodotARAnchor; -#endif - -class ARKitInterface : public XRInterface { - GDCLASS(ARKitInterface, XRInterface); - -private: - bool initialized; - bool session_was_started; - bool plane_detection_is_enabled; - bool light_estimation_is_enabled; - real_t ambient_intensity; - real_t ambient_color_temperature; - - Transform transform; - CameraMatrix projection; - float eye_height, z_near, z_far; - - Ref<CameraFeed> feed; - size_t image_width[2]; - size_t image_height[2]; - Vector<uint8_t> img_data[2]; - - struct anchor_map { - XRPositionalTracker *tracker; - unsigned char uuid[16]; - }; - - ///@TODO should use memory map object from Godot? - unsigned int num_anchors; - unsigned int max_anchors; - anchor_map *anchors; - XRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid); - void remove_anchor_for_uuid(const unsigned char *p_uuid); - void remove_all_anchors(); - -protected: - static void _bind_methods(); - -public: - void start_session(); - void stop_session(); - - bool get_anchor_detection_is_enabled() const override; - void set_anchor_detection_is_enabled(bool p_enable) override; - virtual int get_camera_feed_id() override; - - bool get_light_estimation_is_enabled() const; - void set_light_estimation_is_enabled(bool p_enable); - - real_t get_ambient_intensity() const; - real_t get_ambient_color_temperature() const; - - /* while Godot has its own raycast logic this takes ARKits camera into account and hits on any ARAnchor */ - Array raycast(Vector2 p_screen_coord); - - virtual void notification(int p_what) override; - - virtual StringName get_name() const override; - virtual int get_capabilities() const override; - - virtual bool is_initialized() const override; - virtual bool initialize() override; - virtual void uninitialize() override; - - virtual Size2 get_render_targetsize() override; - virtual bool is_stereo() override; - virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) override; - virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) override; - virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) override; - - virtual void process() override; - - // called by delegate (void * because C++ and Obj-C don't always mix, should really change all platform/iphone/*.cpp files to .mm) - void _add_or_update_anchor(GodotARAnchor *p_anchor); - void _remove_anchor(GodotARAnchor *p_anchor); - - ARKitInterface(); - ~ARKitInterface(); -}; - -#endif /* !ARKIT_INTERFACE_H */ diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm deleted file mode 100644 index 608afd4ff3..0000000000 --- a/modules/arkit/arkit_interface.mm +++ /dev/null @@ -1,791 +0,0 @@ -/*************************************************************************/ -/* arkit_interface.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "core/input/input.h" -#include "core/os/os.h" -#include "scene/resources/surface_tool.h" -#include "servers/rendering/rendering_server_globals.h" - -#import <ARKit/ARKit.h> -#import <UIKit/UIKit.h> - -#include <dlfcn.h> - -#include "arkit_interface.h" -#include "arkit_session_delegate.h" - -// just a dirty workaround for now, declare these as globals. I'll probably encapsulate ARSession and associated logic into an mm object and change ARKitInterface to a normal cpp object that consumes it. -API_AVAILABLE(ios(11.0)) -ARSession *ar_session; - -ARKitSessionDelegate *ar_delegate; -NSTimeInterval last_timestamp; - -/* this is called when we initialize or when we come back from having our app pushed to the background, just (re)start our session */ -void ARKitInterface::start_session() { - // We're active... - session_was_started = true; - - // Ignore this if we're not initialized... - if (initialized) { - print_line("Starting ARKit session"); - - if (@available(iOS 11, *)) { - Class ARWorldTrackingConfigurationClass = NSClassFromString(@"ARWorldTrackingConfiguration"); - ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfigurationClass new]; - - configuration.lightEstimationEnabled = light_estimation_is_enabled; - if (plane_detection_is_enabled) { - if (@available(iOS 11.3, *)) { - configuration.planeDetection = ARPlaneDetectionVertical | ARPlaneDetectionHorizontal; - } else { - configuration.planeDetection = ARPlaneDetectionHorizontal; - } - } else { - configuration.planeDetection = 0; - } - - // make sure our camera is on - if (feed.is_valid()) { - feed->set_active(true); - } - - [ar_session runWithConfiguration:configuration]; - } - } -} - -void ARKitInterface::stop_session() { - session_was_started = false; - - // Ignore this if we're not initialized... - if (initialized) { - // make sure our camera is off - if (feed.is_valid()) { - feed->set_active(false); - } - - if (@available(iOS 11.0, *)) { - [ar_session pause]; - } - } -} - -void ARKitInterface::notification(int p_what) { - // TODO, this is not being called, need to find out why, possibly because this is not a node. - // in that case we need to find a way to get these notifications! - switch (p_what) { - case DisplayServer::WINDOW_EVENT_FOCUS_IN: { - print_line("Focus in"); - - start_session(); - }; break; - case DisplayServer::WINDOW_EVENT_FOCUS_OUT: { - print_line("Focus out"); - - stop_session(); - }; break; - default: - break; - } -} - -bool ARKitInterface::get_anchor_detection_is_enabled() const { - return plane_detection_is_enabled; -} - -void ARKitInterface::set_anchor_detection_is_enabled(bool p_enable) { - if (plane_detection_is_enabled != p_enable) { - plane_detection_is_enabled = p_enable; - - // Restart our session (this will be ignore if we're not initialised) - if (session_was_started) { - start_session(); - } - } -} - -int ARKitInterface::get_camera_feed_id() { - if (feed.is_null()) { - return 0; - } else { - return feed->get_id(); - } -} - -bool ARKitInterface::get_light_estimation_is_enabled() const { - return light_estimation_is_enabled; -} - -void ARKitInterface::set_light_estimation_is_enabled(bool p_enable) { - if (light_estimation_is_enabled != p_enable) { - light_estimation_is_enabled = p_enable; - - // Restart our session (this will be ignore if we're not initialised) - if (session_was_started) { - start_session(); - } - } -} - -real_t ARKitInterface::get_ambient_intensity() const { - return ambient_intensity; -} - -real_t ARKitInterface::get_ambient_color_temperature() const { - return ambient_color_temperature; -} - -StringName ARKitInterface::get_name() const { - return "ARKit"; -} - -int ARKitInterface::get_capabilities() const { - return ARKitInterface::XR_MONO + ARKitInterface::XR_AR; -} - -Array ARKitInterface::raycast(Vector2 p_screen_coord) { - if (@available(iOS 11, *)) { - Array arr; - Size2 screen_size = DisplayServer::get_singleton()->screen_get_size(); - CGPoint point; - point.x = p_screen_coord.x / screen_size.x; - point.y = p_screen_coord.y / screen_size.y; - - ///@TODO maybe give more options here, for now we're taking just ARAchors into account that were found during plane detection keeping their size into account - - NSArray<ARHitTestResult *> *results = [ar_session.currentFrame hitTest:point types:ARHitTestResultTypeExistingPlaneUsingExtent]; - - for (ARHitTestResult *result in results) { - Transform transform; - - matrix_float4x4 m44 = result.worldTransform; - transform.basis.elements[0].x = m44.columns[0][0]; - transform.basis.elements[1].x = m44.columns[0][1]; - transform.basis.elements[2].x = m44.columns[0][2]; - transform.basis.elements[0].y = m44.columns[1][0]; - transform.basis.elements[1].y = m44.columns[1][1]; - transform.basis.elements[2].y = m44.columns[1][2]; - transform.basis.elements[0].z = m44.columns[2][0]; - transform.basis.elements[1].z = m44.columns[2][1]; - transform.basis.elements[2].z = m44.columns[2][2]; - transform.origin.x = m44.columns[3][0]; - transform.origin.y = m44.columns[3][1]; - transform.origin.z = m44.columns[3][2]; - - /* important, NOT scaled to world_scale !! */ - arr.push_back(transform); - } - - return arr; - } else { - return Array(); - } -} - -void ARKitInterface::_bind_methods() { - ClassDB::bind_method(D_METHOD("_notification", "what"), &ARKitInterface::_notification); - - ClassDB::bind_method(D_METHOD("set_light_estimation_is_enabled", "enable"), &ARKitInterface::set_light_estimation_is_enabled); - ClassDB::bind_method(D_METHOD("get_light_estimation_is_enabled"), &ARKitInterface::get_light_estimation_is_enabled); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_estimation"), "set_light_estimation_is_enabled", "get_light_estimation_is_enabled"); - - ClassDB::bind_method(D_METHOD("get_ambient_intensity"), &ARKitInterface::get_ambient_intensity); - ClassDB::bind_method(D_METHOD("get_ambient_color_temperature"), &ARKitInterface::get_ambient_color_temperature); - - ClassDB::bind_method(D_METHOD("raycast", "screen_coord"), &ARKitInterface::raycast); -} - -bool ARKitInterface::is_stereo() { - // this is a mono device... - return false; -} - -bool ARKitInterface::is_initialized() const { - return initialized; -} - -bool ARKitInterface::initialize() { - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, false); - - if (@available(iOS 11, *)) { - if (!initialized) { - print_line("initializing ARKit"); - - // create our ar session and delegate - Class ARSessionClass = NSClassFromString(@"ARSession"); - if (ARSessionClass == Nil) { - void *arkit_handle = dlopen("/System/Library/Frameworks/ARKit.framework/ARKit", RTLD_NOW); - if (arkit_handle) { - ARSessionClass = NSClassFromString(@"ARSession"); - } else { - print_line("ARKit init failed"); - return false; - } - } - ar_session = [ARSessionClass new]; - ar_delegate = [ARKitSessionDelegate new]; - ar_delegate.arkit_interface = this; - ar_session.delegate = ar_delegate; - - // reset our transform - transform = Transform(); - - // make this our primary interface - xr_server->set_primary_interface(this); - - // make sure we have our feed setup - if (feed.is_null()) { - feed.instance(); - feed->set_name("ARKit"); - - CameraServer *cs = CameraServer::get_singleton(); - if (cs != NULL) { - cs->add_feed(feed); - } - } - feed->set_active(true); - - // yeah! - initialized = true; - - // Start our session... - start_session(); - } - - return true; - } else { - return false; - } -} - -void ARKitInterface::uninitialize() { - if (initialized) { - XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != NULL) { - // no longer our primary interface - xr_server->clear_primary_interface_if(this); - } - - if (feed.is_valid()) { - CameraServer *cs = CameraServer::get_singleton(); - if ((cs != NULL)) { - cs->remove_feed(feed); - } - feed.unref(); - } - - remove_all_anchors(); - - if (@available(iOS 11.0, *)) { - ar_session = nil; - } - - ar_delegate = nil; - initialized = false; - session_was_started = false; - } -} - -Size2 ARKitInterface::get_render_targetsize() { - // _THREAD_SAFE_METHOD_ - - Size2 target_size = DisplayServer::get_singleton()->screen_get_size(); - - return target_size; -} - -Transform ARKitInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { - // _THREAD_SAFE_METHOD_ - - Transform transform_for_eye; - - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL_V(xr_server, transform_for_eye); - - if (initialized) { - float world_scale = xr_server->get_world_scale(); - - // just scale our origin point of our transform, note that we really shouldn't be using world_scale in ARKit but.... - transform_for_eye = transform; - transform_for_eye.origin *= world_scale; - - transform_for_eye = p_cam_transform * xr_server->get_reference_frame() * transform_for_eye; - } else { - // huh? well just return what we got.... - transform_for_eye = p_cam_transform; - } - - return transform_for_eye; -} - -CameraMatrix ARKitInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { - // Remember our near and far, it will be used in process when we obtain our projection from our ARKit session. - z_near = p_z_near; - z_far = p_z_far; - - return projection; -} - -void ARKitInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { - // _THREAD_SAFE_METHOD_ - - // We must have a valid render target - ERR_FAIL_COND(!p_render_target.is_valid()); - - // Because we are rendering to our device we must use our main viewport! - ERR_FAIL_COND(p_screen_rect == Rect2()); - - // get the size of our screen - // Rect2 screen_rect = p_screen_rect; - - // screen_rect.position.x += screen_rect.size.x; - // screen_rect.size.x = -screen_rect.size.x; - // screen_rect.position.y += screen_rect.size.y; - // screen_rect.size.y = -screen_rect.size.y; - - // VSG::rasterizer->set_current_render_target(RID()); - // VSG::rasterizer->blit_render_target_to_screen(p_render_target, screen_rect, 0); -} - -XRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) { - if (anchors == NULL) { - num_anchors = 0; - max_anchors = 10; - anchors = (anchor_map *)malloc(sizeof(anchor_map) * max_anchors); - } - - ERR_FAIL_NULL_V(anchors, NULL); - - for (unsigned int i = 0; i < num_anchors; i++) { - if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) { - return anchors[i].tracker; - } - } - - if (num_anchors + 1 == max_anchors) { - max_anchors += 10; - anchors = (anchor_map *)realloc(anchors, sizeof(anchor_map) * max_anchors); - ERR_FAIL_NULL_V(anchors, NULL); - } - - XRPositionalTracker *new_tracker = memnew(XRPositionalTracker); - new_tracker->set_tracker_type(XRServer::TRACKER_ANCHOR); - - char tracker_name[256]; - sprintf(tracker_name, "Anchor %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p_uuid[0], p_uuid[1], p_uuid[2], p_uuid[3], p_uuid[4], p_uuid[5], p_uuid[6], p_uuid[7], p_uuid[8], p_uuid[9], p_uuid[10], p_uuid[11], p_uuid[12], p_uuid[13], p_uuid[14], p_uuid[15]); - - String name = tracker_name; - print_line("Adding tracker " + name); - new_tracker->set_tracker_name(name); - - // add our tracker - XRServer::get_singleton()->add_tracker(new_tracker); - anchors[num_anchors].tracker = new_tracker; - memcpy(anchors[num_anchors].uuid, p_uuid, 16); - num_anchors++; - - return new_tracker; -} - -void ARKitInterface::remove_anchor_for_uuid(const unsigned char *p_uuid) { - if (anchors != NULL) { - for (unsigned int i = 0; i < num_anchors; i++) { - if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) { - // remove our tracker - XRServer::get_singleton()->remove_tracker(anchors[i].tracker); - memdelete(anchors[i].tracker); - - // bring remaining forward - for (unsigned int j = i + 1; j < num_anchors; j++) { - anchors[j - 1] = anchors[j]; - }; - - // decrease count - num_anchors--; - return; - } - } - } -} - -void ARKitInterface::remove_all_anchors() { - if (anchors != NULL) { - for (unsigned int i = 0; i < num_anchors; i++) { - // remove our tracker - XRServer::get_singleton()->remove_tracker(anchors[i].tracker); - memdelete(anchors[i].tracker); - }; - - free(anchors); - anchors = NULL; - num_anchors = 0; - } -} - -void ARKitInterface::process() { - // _THREAD_SAFE_METHOD_ - - if (@available(iOS 11.0, *)) { - if (initialized) { - // get our next ARFrame - ARFrame *current_frame = ar_session.currentFrame; - if (last_timestamp != current_frame.timestamp) { - // only process if we have a new frame - last_timestamp = current_frame.timestamp; - - // get some info about our screen and orientation - Size2 screen_size = DisplayServer::get_singleton()->screen_get_size(); - UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown; - - if (@available(iOS 13, *)) { - orientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation; -#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR - } else { - orientation = [[UIApplication sharedApplication] statusBarOrientation]; -#endif - } - - // Grab our camera image for our backbuffer - CVPixelBufferRef pixelBuffer = current_frame.capturedImage; - if ((CVPixelBufferGetPlaneCount(pixelBuffer) == 2) && (feed != NULL)) { - // Plane 0 is our Y and Plane 1 is our CbCr buffer - - // ignored, we check each plane separately - // image_width = CVPixelBufferGetWidth(pixelBuffer); - // image_height = CVPixelBufferGetHeight(pixelBuffer); - - // printf("Pixel buffer %i - %i\n", image_width, image_height); - - CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); - - // get our buffers - unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - - if (dataY == NULL) { - print_line("Couldn't access Y pixel buffer data"); - } else if (dataCbCr == NULL) { - print_line("Couldn't access CbCr pixel buffer data"); - } else { - Ref<Image> img[2]; - size_t extraLeft, extraRight, extraTop, extraBottom; - - CVPixelBufferGetExtendedPixels(pixelBuffer, &extraLeft, &extraRight, &extraTop, &extraBottom); - - { - // do Y - size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0); - size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); - size_t bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); - - if ((image_width[0] != new_width) || (image_height[0] != new_height)) { - printf("- Camera padding l:%lu r:%lu t:%lu b:%lu\n", extraLeft, extraRight, extraTop, extraBottom); - printf("- Camera Y plane size: %lu, %lu - %lu\n", new_width, new_height, bytes_per_row); - - image_width[0] = new_width; - image_height[0] = new_height; - img_data[0].resize(new_width * new_height); - } - - uint8_t *w = img_data[0].ptrw(); - if (new_width == bytes_per_row) { - memcpy(w, dataY, new_width * new_height); - } else { - size_t offset_a = 0; - size_t offset_b = extraLeft + (extraTop * bytes_per_row); - for (size_t r = 0; r < new_height; r++) { - memcpy(w + offset_a, dataY + offset_b, new_width); - offset_a += new_width; - offset_b += bytes_per_row; - } - } - - img[0].instance(); - img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]); - } - - { - // do CbCr - size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1); - size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1); - size_t bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); - - if ((image_width[1] != new_width) || (image_height[1] != new_height)) { - printf("- Camera CbCr plane size: %lu, %lu - %lu\n", new_width, new_height, bytes_per_row); - - image_width[1] = new_width; - image_height[1] = new_height; - img_data[1].resize(2 * new_width * new_height); - } - - uint8_t *w = img_data[1].ptrw(); - if ((2 * new_width) == bytes_per_row) { - memcpy(w, dataCbCr, 2 * new_width * new_height); - } else { - size_t offset_a = 0; - size_t offset_b = extraLeft + (extraTop * bytes_per_row); - for (size_t r = 0; r < new_height; r++) { - memcpy(w + offset_a, dataCbCr + offset_b, 2 * new_width); - offset_a += 2 * new_width; - offset_b += bytes_per_row; - } - } - - img[1].instance(); - img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]); - } - - // set our texture... - feed->set_YCbCr_imgs(img[0], img[1]); - - // now build our transform to display this as a background image that matches our camera - CGAffineTransform affine_transform = [current_frame displayTransformForOrientation:orientation viewportSize:CGSizeMake(screen_size.width, screen_size.height)]; - - // we need to invert this, probably row v.s. column notation - affine_transform = CGAffineTransformInvert(affine_transform); - - if (orientation != UIInterfaceOrientationPortrait) { - affine_transform.b = -affine_transform.b; - affine_transform.d = -affine_transform.d; - affine_transform.ty = 1.0 - affine_transform.ty; - } else { - affine_transform.c = -affine_transform.c; - affine_transform.a = -affine_transform.a; - affine_transform.tx = 1.0 - affine_transform.tx; - } - - Transform2D display_transform = Transform2D( - affine_transform.a, affine_transform.b, - affine_transform.c, affine_transform.d, - affine_transform.tx, affine_transform.ty); - - feed->set_transform(display_transform); - } - - // and unlock - CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); - } - - // Record light estimation to apply to our scene - if (light_estimation_is_enabled) { - ambient_intensity = current_frame.lightEstimate.ambientIntensity; - - ///@TODO it's there, but not there.. what to do with this... - // https://developer.apple.com/documentation/arkit/arlightestimate?language=objc - // ambient_color_temperature = current_frame.lightEstimate.ambientColorTemperature; - } - - // Process our camera - ARCamera *camera = current_frame.camera; - - // strangely enough we have to states, rolling them up into one - if (camera.trackingState == ARTrackingStateNotAvailable) { - // no tracking, would be good if we black out the screen or something... - tracking_state = XRInterface::XR_NOT_TRACKING; - } else { - if (camera.trackingState == ARTrackingStateNormal) { - tracking_state = XRInterface::XR_NORMAL_TRACKING; - } else if (camera.trackingStateReason == ARTrackingStateReasonExcessiveMotion) { - tracking_state = XRInterface::XR_EXCESSIVE_MOTION; - } else if (camera.trackingStateReason == ARTrackingStateReasonInsufficientFeatures) { - tracking_state = XRInterface::XR_INSUFFICIENT_FEATURES; - } else { - tracking_state = XRInterface::XR_UNKNOWN_TRACKING; - } - - // copy our current frame transform - matrix_float4x4 m44 = camera.transform; - if (orientation == UIInterfaceOrientationLandscapeLeft) { - transform.basis.elements[0].x = m44.columns[0][0]; - transform.basis.elements[1].x = m44.columns[0][1]; - transform.basis.elements[2].x = m44.columns[0][2]; - transform.basis.elements[0].y = m44.columns[1][0]; - transform.basis.elements[1].y = m44.columns[1][1]; - transform.basis.elements[2].y = m44.columns[1][2]; - } else if (orientation == UIInterfaceOrientationPortrait) { - transform.basis.elements[0].x = m44.columns[1][0]; - transform.basis.elements[1].x = m44.columns[1][1]; - transform.basis.elements[2].x = m44.columns[1][2]; - transform.basis.elements[0].y = -m44.columns[0][0]; - transform.basis.elements[1].y = -m44.columns[0][1]; - transform.basis.elements[2].y = -m44.columns[0][2]; - } else if (orientation == UIInterfaceOrientationLandscapeRight) { - transform.basis.elements[0].x = -m44.columns[0][0]; - transform.basis.elements[1].x = -m44.columns[0][1]; - transform.basis.elements[2].x = -m44.columns[0][2]; - transform.basis.elements[0].y = -m44.columns[1][0]; - transform.basis.elements[1].y = -m44.columns[1][1]; - transform.basis.elements[2].y = -m44.columns[1][2]; - } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { - // this may not be correct - transform.basis.elements[0].x = m44.columns[1][0]; - transform.basis.elements[1].x = m44.columns[1][1]; - transform.basis.elements[2].x = m44.columns[1][2]; - transform.basis.elements[0].y = m44.columns[0][0]; - transform.basis.elements[1].y = m44.columns[0][1]; - transform.basis.elements[2].y = m44.columns[0][2]; - } - transform.basis.elements[0].z = m44.columns[2][0]; - transform.basis.elements[1].z = m44.columns[2][1]; - transform.basis.elements[2].z = m44.columns[2][2]; - transform.origin.x = m44.columns[3][0]; - transform.origin.y = m44.columns[3][1]; - transform.origin.z = m44.columns[3][2]; - - // copy our current frame projection, investigate using projectionMatrixWithViewportSize:orientation:zNear:zFar: so we can set our own near and far - m44 = [camera projectionMatrixForOrientation:orientation viewportSize:CGSizeMake(screen_size.width, screen_size.height) zNear:z_near zFar:z_far]; - projection.matrix[0][0] = m44.columns[0][0]; - projection.matrix[1][0] = m44.columns[1][0]; - projection.matrix[2][0] = m44.columns[2][0]; - projection.matrix[3][0] = m44.columns[3][0]; - projection.matrix[0][1] = m44.columns[0][1]; - projection.matrix[1][1] = m44.columns[1][1]; - projection.matrix[2][1] = m44.columns[2][1]; - projection.matrix[3][1] = m44.columns[3][1]; - projection.matrix[0][2] = m44.columns[0][2]; - projection.matrix[1][2] = m44.columns[1][2]; - projection.matrix[2][2] = m44.columns[2][2]; - projection.matrix[3][2] = m44.columns[3][2]; - projection.matrix[0][3] = m44.columns[0][3]; - projection.matrix[1][3] = m44.columns[1][3]; - projection.matrix[2][3] = m44.columns[2][3]; - projection.matrix[3][3] = m44.columns[3][3]; - } - } - } - } -} - -void ARKitInterface::_add_or_update_anchor(GodotARAnchor *p_anchor) { - // _THREAD_SAFE_METHOD_ - - if (@available(iOS 11.0, *)) { - ARAnchor *anchor = (ARAnchor *)p_anchor; - - unsigned char uuid[16]; - [anchor.identifier getUUIDBytes:uuid]; - - XRPositionalTracker *tracker = get_anchor_for_uuid(uuid); - if (tracker != NULL) { - // lets update our mesh! (using Arjens code as is for now) - // we should also probably limit how often we do this... - - // can we safely cast this? - ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor; - - if (@available(iOS 11.3, *)) { - if (planeAnchor.geometry.triangleCount > 0) { - Ref<SurfaceTool> surftool; - surftool.instance(); - surftool->begin(Mesh::PRIMITIVE_TRIANGLES); - - for (int j = planeAnchor.geometry.triangleCount * 3 - 1; j >= 0; j--) { - int16_t index = planeAnchor.geometry.triangleIndices[j]; - simd_float3 vrtx = planeAnchor.geometry.vertices[index]; - simd_float2 textcoord = planeAnchor.geometry.textureCoordinates[index]; - surftool->set_uv(Vector2(textcoord[0], textcoord[1])); - surftool->set_color(Color(0.8, 0.8, 0.8)); - surftool->add_vertex(Vector3(vrtx[0], vrtx[1], vrtx[2])); - } - - surftool->generate_normals(); - tracker->set_mesh(surftool->commit()); - } else { - Ref<Mesh> nomesh; - tracker->set_mesh(nomesh); - } - } else { - Ref<Mesh> nomesh; - tracker->set_mesh(nomesh); - } - - // Note, this also contains a scale factor which gives us an idea of the size of the anchor - // We may extract that in our XRAnchor class - Basis b; - matrix_float4x4 m44 = anchor.transform; - b.elements[0].x = m44.columns[0][0]; - b.elements[1].x = m44.columns[0][1]; - b.elements[2].x = m44.columns[0][2]; - b.elements[0].y = m44.columns[1][0]; - b.elements[1].y = m44.columns[1][1]; - b.elements[2].y = m44.columns[1][2]; - b.elements[0].z = m44.columns[2][0]; - b.elements[1].z = m44.columns[2][1]; - b.elements[2].z = m44.columns[2][2]; - tracker->set_orientation(b); - tracker->set_rw_position(Vector3(m44.columns[3][0], m44.columns[3][1], m44.columns[3][2])); - } - } -} - -void ARKitInterface::_remove_anchor(GodotARAnchor *p_anchor) { - // _THREAD_SAFE_METHOD_ - - if (@available(iOS 11.0, *)) { - ARAnchor *anchor = (ARAnchor *)p_anchor; - - unsigned char uuid[16]; - [anchor.identifier getUUIDBytes:uuid]; - - remove_anchor_for_uuid(uuid); - } -} - -ARKitInterface::ARKitInterface() { - initialized = false; - session_was_started = false; - plane_detection_is_enabled = false; - light_estimation_is_enabled = false; - if (@available(iOS 11.0, *)) { - ar_session = nil; - } - z_near = 0.01; - z_far = 1000.0; - projection.set_perspective(60.0, 1.0, z_near, z_far, false); - anchors = NULL; - num_anchors = 0; - ambient_intensity = 1.0; - ambient_color_temperature = 1.0; - image_width[0] = 0; - image_width[1] = 0; - image_height[0] = 0; - image_height[1] = 0; -} - -ARKitInterface::~ARKitInterface() { - remove_all_anchors(); - - // and make sure we cleanup if we haven't already - if (is_initialized()) { - uninitialize(); - } -} diff --git a/modules/arkit/arkit_module.cpp b/modules/arkit/arkit_module.cpp deleted file mode 100644 index be3c5e29ca..0000000000 --- a/modules/arkit/arkit_module.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************/ -/* arkit_module.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "arkit_module.h" - -#include "arkit_interface.h" - -void register_arkit_types() { - // does it make sense to register the class? - - Ref<ARKitInterface> arkit_interface; - arkit_interface.instance(); - XRServer::get_singleton()->add_interface(arkit_interface); -} - -void unregister_arkit_types() { - // should clean itself up nicely :) -} diff --git a/modules/arkit/arkit_module.h b/modules/arkit/arkit_module.h deleted file mode 100644 index ca48371152..0000000000 --- a/modules/arkit/arkit_module.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* arkit_module.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ARKIT_REGISTER_TYPES_H -#define ARKIT_REGISTER_TYPES_H - -void register_arkit_types(); -void unregister_arkit_types(); - -#endif // ARKIT_REGISTER_TYPES_H diff --git a/modules/arkit/arkit_session_delegate.mm b/modules/arkit/arkit_session_delegate.mm deleted file mode 100644 index 97af5bf42c..0000000000 --- a/modules/arkit/arkit_session_delegate.mm +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ -/* arkit_session_delegate.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "arkit_session_delegate.h" -#include "arkit_interface.h" - -@implementation ARKitSessionDelegate - -@synthesize arkit_interface; - -- (void)session:(ARSession *)session didAddAnchors:(NSArray<ARAnchor *> *)anchors { - for (ARAnchor *anchor in anchors) { - arkit_interface->_add_or_update_anchor(anchor); - } -} - -- (void)session:(ARSession *)session didRemoveAnchors:(NSArray<ARAnchor *> *)anchors { - for (ARAnchor *anchor in anchors) { - arkit_interface->_remove_anchor(anchor); - } -} - -- (void)session:(ARSession *)session didUpdateAnchors:(NSArray<ARAnchor *> *)anchors { - for (ARAnchor *anchor in anchors) { - arkit_interface->_add_or_update_anchor(anchor); - } -} - -@end diff --git a/modules/arkit/config.py b/modules/arkit/config.py deleted file mode 100644 index e68603fc93..0000000000 --- a/modules/arkit/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return platform == "iphone" - - -def configure(env): - pass diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp index 66eb81d7f2..92882a1cc8 100644 --- a/modules/basis_universal/texture_basisu.cpp +++ b/modules/basis_universal/texture_basisu.cpp @@ -207,7 +207,6 @@ Vector<uint8_t> TextureBasisU::get_basisu_data() const { }; TextureBasisU::TextureBasisU() { - flags = FLAGS_DEFAULT; texture = RenderingServer::get_singleton()->texture_create(); }; diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h index 0a4783eaff..282a0dfc8a 100644 --- a/modules/basis_universal/texture_basisu.h +++ b/modules/basis_universal/texture_basisu.h @@ -47,7 +47,7 @@ class TextureBasisU : public Texture { RID texture; Size2 tex_size; - uint32_t flags; + uint32_t flags = FLAGS_DEFAULT; Vector<uint8_t> data; diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index d3f12f0115..379e971458 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -55,24 +55,24 @@ protected: struct bmp_header_s { struct bmp_file_header_s { - uint16_t bmp_signature; - uint32_t bmp_file_size; - uint32_t bmp_file_padding; - uint32_t bmp_file_offset; + uint16_t bmp_signature = 0; + uint32_t bmp_file_size = 0; + uint32_t bmp_file_padding = 0; + uint32_t bmp_file_offset = 0; } bmp_file_header; struct bmp_info_header_s { - uint32_t bmp_header_size; - uint32_t bmp_width; - uint32_t bmp_height; - uint16_t bmp_planes; - uint16_t bmp_bit_count; - uint32_t bmp_compression; - uint32_t bmp_size_image; - uint32_t bmp_pixels_per_meter_x; - uint32_t bmp_pixels_per_meter_y; - uint32_t bmp_colors_used; - uint32_t bmp_important_colors; + uint32_t bmp_header_size = 0; + uint32_t bmp_width = 0; + uint32_t bmp_height = 0; + uint16_t bmp_planes = 0; + uint16_t bmp_bit_count = 0; + uint32_t bmp_compression = 0; + uint32_t bmp_size_image = 0; + uint32_t bmp_pixels_per_meter_x = 0; + uint32_t bmp_pixels_per_meter_y = 0; + uint32_t bmp_colors_used = 0; + uint32_t bmp_important_colors = 0; } bmp_info_header; }; diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index a5fa678fec..7cf666c119 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -80,18 +80,18 @@ public: private: // These are used by function callEvent. Instead to create this each call I create if one time. Variant call_event_res[5]; - Variant *call_event_res_ptr[5]; + Variant *call_event_res_ptr[5] = {}; - btGhostObject *btGhost; + btGhostObject *btGhost = nullptr; Vector<OverlappingObjectData> overlappingObjects; bool monitorable = true; PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; bool spOv_gravityPoint = false; - real_t spOv_gravityPointDistanceScale = 0; - real_t spOv_gravityPointAttenuation = 1; + real_t spOv_gravityPointDistanceScale = 0.0; + real_t spOv_gravityPointAttenuation = 1.0; Vector3 spOv_gravityVec = Vector3(0, -1, 0); - real_t spOv_gravityMag = 10; + real_t spOv_gravityMag = 10.0; real_t spOv_linearDump = 0.1; real_t spOv_angularDump = 0.1; int spOv_priority = 0; diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp index 1568cca63d..109854c9dd 100644 --- a/modules/bullet/btRayShape.cpp +++ b/modules/bullet/btRayShape.cpp @@ -39,11 +39,9 @@ */ btRayShape::btRayShape(btScalar length) : - btConvexInternalShape(), - m_shapeAxis(0, 0, 1) { + btConvexInternalShape() { m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE; setLength(length); - slipsOnSlope = false; } btRayShape::~btRayShape() { diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h index dcc4cc79c7..330755aa31 100644 --- a/modules/bullet/btRayShape.h +++ b/modules/bullet/btRayShape.h @@ -42,10 +42,10 @@ /// Ray shape around z axis ATTRIBUTE_ALIGNED16(class) btRayShape : public btConvexInternalShape { - btScalar m_length; - bool slipsOnSlope; + btScalar m_length = 0; + bool slipsOnSlope = false; /// The default axis is the z - btVector3 m_shapeAxis; + btVector3 m_shapeAxis = btVector3(0, 0, 1); btTransform m_cacheSupportPoint; btScalar m_cacheScaledLength; diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 632682a15d..26e9f5a044 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -625,14 +625,14 @@ uint32_t BulletPhysicsServer3D::body_get_user_flags(RID p_body) const { return 0; } -void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, float p_value) { +void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_param(p_param, p_value); } -float BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const { +real_t BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -807,11 +807,11 @@ int BulletPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const { return body->get_max_collisions_detection(); } -void BulletPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) { +void BulletPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { // Not supported by bullet and even Godot } -float BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const { +real_t BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const { // Not supported by bullet and even Godot return 0.; } @@ -862,7 +862,7 @@ bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform &p_from return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes); } -int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) { +int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); ERR_FAIL_COND_V(!body->get_space(), 0); @@ -1059,16 +1059,16 @@ real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) { return body->get_linear_stiffness(); } -void BulletPhysicsServer3D::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) { +void BulletPhysicsServer3D::soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - body->set_areaAngular_stiffness(p_stiffness); + body->set_angular_stiffness(p_stiffness); } -real_t BulletPhysicsServer3D::soft_body_get_areaAngular_stiffness(RID p_body) { +real_t BulletPhysicsServer3D::soft_body_get_angular_stiffness(RID p_body) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); - return body->get_areaAngular_stiffness(); + return body->get_angular_stiffness(); } void BulletPhysicsServer3D::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) { @@ -1221,7 +1221,7 @@ RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local CreateThenReturnRID(joint_owner, joint); } -void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) { +void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); @@ -1229,7 +1229,7 @@ void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_par pin_joint->set_param(p_param, p_value); } -float BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { +real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); @@ -1309,7 +1309,7 @@ RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3 CreateThenReturnRID(joint_owner, joint); } -void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) { +void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); @@ -1317,7 +1317,7 @@ void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p hinge_joint->set_param(p_param, p_value); } -float BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { +real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); @@ -1361,7 +1361,7 @@ RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform &p_ CreateThenReturnRID(joint_owner, joint); } -void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) { +void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); @@ -1369,7 +1369,7 @@ void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam slider_joint->set_param(p_param, p_value); } -float BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { +real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0); @@ -1395,7 +1395,7 @@ RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform CreateThenReturnRID(joint_owner, joint); } -void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) { +void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); @@ -1403,7 +1403,7 @@ void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJoi coneTwist_joint->set_param(p_param, p_value); } -float BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { +real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0.); ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.); @@ -1431,7 +1431,7 @@ RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transfo CreateThenReturnRID(joint_owner, joint); } -void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) { +void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); @@ -1439,7 +1439,7 @@ void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::A generic_6dof_joint->set_param(p_axis, p_param, p_value); } -float BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { +real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); @@ -1525,7 +1525,7 @@ void BulletPhysicsServer3D::init() { BulletPhysicsDirectBodyState3D::initSingleton(); } -void BulletPhysicsServer3D::step(float p_deltaTime) { +void BulletPhysicsServer3D::step(real_t p_deltaTime) { if (!active) { return; } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index b5dc84c8f5..97b719ae8e 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -207,8 +207,8 @@ public: /// This is not supported by physics server virtual uint32_t body_get_user_flags(RID p_body) const override; - virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) override; - virtual float body_get_param(RID p_body, BodyParameter p_param) const override; + virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) override; + virtual real_t body_get_param(RID p_body, BodyParameter p_param) const override; virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) override; virtual real_t body_get_kinematic_safe_margin(RID p_body) const override; @@ -241,8 +241,8 @@ public: virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override; virtual int body_get_max_contacts_reported(RID p_body) const override; - virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) override; - virtual float body_get_contacts_reported_depth_threshold(RID p_body) const override; + virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) override; + virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const override; virtual void body_set_omit_force_integration(RID p_body, bool p_omit) override; virtual bool body_is_omitting_force_integration(RID p_body) const override; @@ -256,7 +256,7 @@ public: virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override; virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; - virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) override; + virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; /* SOFT BODY API */ @@ -298,8 +298,8 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override; virtual real_t soft_body_get_linear_stiffness(RID p_body) override; - virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override; - virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override; + virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override; + virtual real_t soft_body_get_angular_stiffness(RID p_body) override; virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override; virtual real_t soft_body_get_volume_stiffness(RID p_body) override; @@ -337,8 +337,8 @@ public: virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; - virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) override; - virtual float pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; + virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) override; virtual Vector3 pin_joint_get_local_a(RID p_joint) const override; @@ -349,8 +349,8 @@ public: virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) override; virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; - virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) override; - virtual float hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override; + virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; + virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override; virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override; virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; @@ -358,20 +358,20 @@ public: /// Reference frame is A virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; - virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) override; - virtual float slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; + virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; + virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; /// Reference frame is A virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; - virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) override; - virtual float cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; + virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; + virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; /// Reference frame is A virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; - virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) override; - virtual float generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override; + virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) override; + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override; virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) override; virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) override; @@ -393,7 +393,7 @@ public: } virtual void init() override; - virtual void step(float p_deltaTime) override; + virtual void step(real_t p_deltaTime) override; virtual void flush_queries() override; virtual void finish() override; diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index bea28f2183..c8081a53f1 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -110,7 +110,7 @@ public: }; protected: - Type type; + Type type = TYPE_AREA; ObjectID instance_id; uint32_t collisionLayer = 0; uint32_t collisionMask = 0; diff --git a/modules/bullet/config.py b/modules/bullet/config.py index d22f9454ed..be7cf74f6f 100644 --- a/modules/bullet/config.py +++ b/modules/bullet/config.py @@ -1,5 +1,6 @@ def can_build(env, platform): - return True + # API Changed and bullet is disabled at the moment + return False def configure(env): diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h index 0669d2739a..ca17349130 100644 --- a/modules/bullet/godot_motion_state.h +++ b/modules/bullet/godot_motion_state.h @@ -51,7 +51,7 @@ class GodotMotionState : public btMotionState { /// This data is used to store last world position btTransform bodyCurrentWorldTransform; - RigidBodyBullet *owner; + RigidBodyBullet *owner = nullptr; public: GodotMotionState(RigidBodyBullet *p_owner) : diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h index f705edef81..25798aecb4 100644 --- a/modules/bullet/godot_ray_world_algorithm.h +++ b/modules/bullet/godot_ray_world_algorithm.h @@ -45,7 +45,7 @@ class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm { const btDiscreteDynamicsWorld *m_world; btPersistentManifold *m_manifoldPtr; bool m_ownManifold = false; - bool m_isSwapped; + bool m_isSwapped = false; public: GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *world, btPersistentManifold *mf, const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped); diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index 4f40f7ecfd..f92665f3e4 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -59,8 +59,8 @@ struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResult bool m_pickRay = false; int m_shapeId = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; public: GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : @@ -84,8 +84,8 @@ public: // store all colliding object struct GodotAllConvexResultCallback : public btCollisionWorld::ConvexResultCallback { public: - PhysicsDirectSpaceState3D::ShapeResult *m_results; - int m_resultMax; + PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr; + int m_resultMax = 0; const Set<RID> *m_exclude; int count = 0; @@ -117,8 +117,8 @@ public: const Set<RID> *m_exclude; int m_shapeId = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), @@ -134,13 +134,13 @@ public: struct GodotAllContactResultCallback : public btCollisionWorld::ContactResultCallback { public: const btCollisionObject *m_self_object; - PhysicsDirectSpaceState3D::ShapeResult *m_results; - int m_resultMax; + PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr; + int m_resultMax = 0; const Set<RID> *m_exclude; int m_count = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), @@ -159,13 +159,13 @@ public: struct GodotContactPairContactResultCallback : public btCollisionWorld::ContactResultCallback { public: const btCollisionObject *m_self_object; - Vector3 *m_results; - int m_resultMax; + Vector3 *m_results = nullptr; + int m_resultMax = 0; const Set<RID> *m_exclude; int m_count = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), @@ -183,14 +183,14 @@ public: struct GodotRestInfoContactResultCallback : public btCollisionWorld::ContactResultCallback { public: const btCollisionObject *m_self_object; - PhysicsDirectSpaceState3D::ShapeRestInfo *m_result; + PhysicsDirectSpaceState3D::ShapeRestInfo *m_result = nullptr; const Set<RID> *m_exclude; bool m_collided = false; - real_t m_min_distance = 0; - const btCollisionObject *m_rest_info_collision_object; + real_t m_min_distance = 0.0; + const btCollisionObject *m_rest_info_collision_object = nullptr; btVector3 m_rest_info_bt_point; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeRestInfo *p_result, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h index 0b74a0cc4d..face6b4861 100644 --- a/modules/bullet/rid_bullet.h +++ b/modules/bullet/rid_bullet.h @@ -41,7 +41,7 @@ class BulletPhysicsServer3D; class RIDBullet { RID self; - BulletPhysicsServer3D *physicsServer; + BulletPhysicsServer3D *physicsServer = nullptr; public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 7a53f91b33..a5093afe9d 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -56,11 +56,11 @@ Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const { return gVec; } -float BulletPhysicsDirectBodyState3D::get_total_angular_damp() const { +real_t BulletPhysicsDirectBodyState3D::get_total_angular_damp() const { return body->btBody->getAngularDamping(); } -float BulletPhysicsDirectBodyState3D::get_total_linear_damp() const { +real_t BulletPhysicsDirectBodyState3D::get_total_linear_damp() const { return body->btBody->getLinearDamping(); } @@ -74,7 +74,7 @@ Basis BulletPhysicsDirectBodyState3D::get_principal_inertia_axes() const { return Basis(); } -float BulletPhysicsDirectBodyState3D::get_inverse_mass() const { +real_t BulletPhysicsDirectBodyState3D::get_inverse_mass() const { return body->btBody->getInvMass(); } @@ -158,7 +158,7 @@ Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_normal(int p_contact_i return body->collisions[p_contact_idx].hitNormal; } -float BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const { +real_t BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const { return body->collisions[p_contact_idx].appliedImpulse; } @@ -322,7 +322,8 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) { if (space) { can_integrate_forces = false; isScratchedSpaceOverrideModificator = false; - + // Remove any constraints + space->remove_rigid_body_constraints(this); // Remove this object form the physics world space->remove_rigid_body(this); } @@ -411,7 +412,7 @@ void RigidBodyBullet::on_collision_checker_end() { isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject(); } -bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) { +bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) { if (collisionsCount >= maxCollisionsDetection) { return false; } @@ -709,12 +710,12 @@ bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { } void RigidBodyBullet::reload_axis_lock() { - btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z)))); + btBody->setLinearFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z)))); if (PhysicsServer3D::BODY_MODE_CHARACTER == mode) { /// When character angular is always locked btBody->setAngularFactor(btVector3(0., 0., 0.)); } else { - btBody->setAngularFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z)))); + btBody->setAngularFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z)))); } } diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index fc3f2db796..a4be7f9e07 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -81,21 +81,21 @@ public: } public: - RigidBodyBullet *body; - real_t deltaTime; + RigidBodyBullet *body = nullptr; + real_t deltaTime = 0.0; private: BulletPhysicsDirectBodyState3D() {} public: virtual Vector3 get_total_gravity() const override; - virtual float get_total_angular_damp() const override; - virtual float get_total_linear_damp() const override; + virtual real_t get_total_angular_damp() const override; + virtual real_t get_total_linear_damp() const override; virtual Vector3 get_center_of_mass() const override; virtual Basis get_principal_inertia_axes() const override; // get the mass - virtual float get_inverse_mass() const override; + virtual real_t get_inverse_mass() const override; // get density of this body space virtual Vector3 get_inverse_inertia() const override; // get density of this body space @@ -124,7 +124,7 @@ public: virtual Vector3 get_contact_local_position(int p_contact_idx) const override; virtual Vector3 get_contact_local_normal(int p_contact_idx) const override; - virtual float get_contact_impulse(int p_contact_idx) const override; + virtual real_t get_contact_impulse(int p_contact_idx) const override; virtual int get_contact_local_shape(int p_contact_idx) const override; virtual RID get_contact_collider(int p_contact_idx) const override; @@ -144,13 +144,13 @@ public: class RigidBodyBullet : public RigidCollisionObjectBullet { public: struct CollisionData { - RigidBodyBullet *otherObject; - int other_object_shape; - int local_shape; + RigidBodyBullet *otherObject = nullptr; + int other_object_shape = 0; + int local_shape = 0; Vector3 hitLocalLocation; Vector3 hitWorldLocation; Vector3 hitNormal; - float appliedImpulse; + real_t appliedImpulse = 0.0; }; struct ForceIntegrationCallback { @@ -169,7 +169,7 @@ public: }; struct KinematicUtilities { - RigidBodyBullet *owner; + RigidBodyBullet *owner = nullptr; btScalar safe_margin; Vector<KinematicShape> shapes; @@ -194,10 +194,10 @@ private: GodotMotionState *godotMotionState; btRigidBody *btBody; uint16_t locked_axis = 0; - real_t mass = 1; - real_t gravity_scale = 1; - real_t linearDamp = 0; - real_t angularDamp = 0; + real_t mass = 1.0; + real_t gravity_scale = 1.0; + real_t linearDamp = 0.0; + real_t angularDamp = 0.0; bool can_sleep = true; bool omit_forces_integration = false; bool can_integrate_forces = false; @@ -264,7 +264,7 @@ public: } bool can_add_collision() { return collisionsCount < maxCollisionsDetection; } - bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index); + bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index); bool was_colliding(RigidBodyBullet *p_other_object); void set_activation_state(bool p_active); diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index cc2ec28a9e..82876ab77c 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -480,7 +480,11 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) { Vector<real_t> l_heights; Variant l_heights_v = d["heights"]; +#ifdef REAL_T_IS_DOUBLE + if (l_heights_v.get_type() == Variant::PACKED_FLOAT64_ARRAY) { +#else if (l_heights_v.get_type() == Variant::PACKED_FLOAT32_ARRAY) { +#endif // Ready-to-use heights can be passed l_heights = l_heights_v; @@ -503,7 +507,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) { real_t *w = l_heights.ptrw(); const uint8_t *r = im_data.ptr(); - float *rp = (float *)r; + real_t *rp = (real_t *)r; // At this point, `rp` could be used directly for Bullet, but I don't know how safe it would be. for (int i = 0; i < l_heights.size(); ++i) { @@ -511,7 +515,11 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) { } } else { +#ifdef REAL_T_IS_DOUBLE + ERR_FAIL_MSG("Expected PackedFloat64Array or float Image."); +#else ERR_FAIL_MSG("Expected PackedFloat32Array or float Image."); +#endif } ERR_FAIL_COND(l_width <= 0); diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 63475822de..bfd95747eb 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -213,10 +213,10 @@ private: class HeightMapShapeBullet : public ShapeBullet { public: Vector<real_t> heights; - int width; - int depth; - real_t min_height; - real_t max_height; + int width = 0; + int depth = 0; + real_t min_height = 0.0; + real_t max_height = 0.0; HeightMapShapeBullet(); @@ -231,7 +231,7 @@ private: class RayShapeBullet : public ShapeBullet { public: - real_t length = 1; + real_t length = 1.0; bool slips_on_slope = false; RayShapeBullet(); diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index a490179964..91a1934e07 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -259,10 +259,10 @@ void SoftBodyBullet::set_linear_stiffness(real_t p_val) { } } -void SoftBodyBullet::set_areaAngular_stiffness(real_t p_val) { - areaAngular_stiffness = p_val; +void SoftBodyBullet::set_angular_stiffness(real_t p_val) { + angular_stiffness = p_val; if (bt_soft_body) { - mat0->m_kAST = areaAngular_stiffness; + mat0->m_kAST = angular_stiffness; } } @@ -409,7 +409,7 @@ void SoftBodyBullet::setup_soft_body() { bt_soft_body->generateBendingConstraints(2, mat0); mat0->m_kLST = linear_stiffness; - mat0->m_kAST = areaAngular_stiffness; + mat0->m_kAST = angular_stiffness; mat0->m_kVST = volume_stiffness; // Clusters allow to have Soft vs Soft collision but doesn't work well right now diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index b15b72daf9..23f6fba9a6 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -59,7 +59,7 @@ class SoftBodyBullet : public CollisionObjectBullet { private: btSoftBody *bt_soft_body = nullptr; Vector<Vector<int>> indices_table; - btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody + btSoftBody::Material *mat0 = nullptr; // This is just a copy of pointer managed by btSoftBody bool isScratched = false; Ref<Mesh> soft_mesh; @@ -67,7 +67,7 @@ private: int simulation_precision = 5; real_t total_mass = 1.; real_t linear_stiffness = 0.5; // [0,1] - real_t areaAngular_stiffness = 0.5; // [0,1] + real_t angular_stiffness = 0.5; // [0,1] real_t volume_stiffness = 0.5; // [0,1] real_t pressure_coefficient = 0.; // [-inf,+inf] real_t pose_matching_coefficient = 0.; // [0,1] @@ -129,8 +129,8 @@ public: void set_linear_stiffness(real_t p_val); _FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; } - void set_areaAngular_stiffness(real_t p_val); - _FORCE_INLINE_ real_t get_areaAngular_stiffness() const { return areaAngular_stiffness; } + void set_angular_stiffness(real_t p_val); + _FORCE_INLINE_ real_t get_angular_stiffness() const { return angular_stiffness; } void set_volume_stiffness(real_t p_val); _FORCE_INLINE_ real_t get_volume_stiffness() const { return volume_stiffness; } diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index a8d55b59b3..7d337bc4d0 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -117,7 +117,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V } } -int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return 0; } @@ -152,7 +152,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra return btQuery.m_count; } -bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { +bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { r_closest_safe = 0.0f; r_closest_unsafe = 0.0f; btVector3 bt_motion; @@ -177,8 +177,10 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf bt_xform_to.getOrigin() += bt_motion; if ((bt_xform_to.getOrigin() - bt_xform_from.getOrigin()).fuzzyZero()) { + r_closest_safe = 1.0f; + r_closest_unsafe = 1.0f; bulletdelete(btShape); - return false; + return true; } GodotClosestConvexResultCallback btResult(bt_xform_from.getOrigin(), bt_xform_to.getOrigin(), &p_exclude, p_collide_with_bodies, p_collide_with_areas); @@ -212,7 +214,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf } /// Returns the list of contacts pairs in this order: Local contact, other body contact -bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return false; } @@ -248,7 +250,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & return btQuery.m_count; } -bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -477,7 +479,7 @@ void SpaceBullet::add_rigid_body(RigidBodyBullet *p_body) { } } -void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) { +void SpaceBullet::remove_rigid_body_constraints(RigidBodyBullet *p_body) { btRigidBody *btBody = p_body->get_bt_rigid_body(); int constraints = btBody->getNumConstraintRefs(); @@ -487,6 +489,10 @@ void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) { dynamicsWorld->removeConstraint(btBody->getConstraintRef(i)); } } +} + +void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) { + btRigidBody *btBody = p_body->get_bt_rigid_body(); if (p_body->is_static()) { dynamicsWorld->removeCollisionObject(btBody); @@ -835,7 +841,7 @@ void SpaceBullet::check_body_collision() { Vector3 collisionWorldPosition; Vector3 collisionLocalPosition; Vector3 normalOnB; - float appliedImpulse = pt.m_appliedImpulse; + real_t appliedImpulse = pt.m_appliedImpulse; B_TO_G(pt.m_normalWorldOnB, normalOnB); // The pt.m_index only contains the shape index when more than one collision shape is used @@ -1056,7 +1062,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f return has_penetration; } -int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin) { +int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) { btTransform body_transform; G_TO_B(p_transform, body_transform); UNSCALE_BT_BASIS(body_transform); @@ -1086,13 +1092,13 @@ private: btDbvtVolume bounds; const btCollisionObject *self_collision_object; - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 0; + uint32_t collision_mask = 0; struct CompoundLeafCallback : btDbvt::ICollide { private: - RecoverPenetrationBroadPhaseCallback *parent_callback; - btCollisionObject *collision_object; + RecoverPenetrationBroadPhaseCallback *parent_callback = nullptr; + btCollisionObject *collision_object = nullptr; public: CompoundLeafCallback(RecoverPenetrationBroadPhaseCallback *p_parent_callback, btCollisionObject *p_collision_object) : @@ -1110,8 +1116,8 @@ private: public: struct BroadphaseResult { - btCollisionObject *collision_object; - int compound_child_index; + btCollisionObject *collision_object = nullptr; + int compound_child_index = 0; }; Vector<BroadphaseResult> results; diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 42f982d5f0..87aa2b9e93 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -78,11 +78,11 @@ public: virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override; - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; + virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; /// Returns the list of contacts pairs in this order: Local contact, other body contact - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override; }; @@ -100,12 +100,12 @@ class SpaceBullet : public RIDBullet { btGhostPairCallback *ghostPairCallback = nullptr; GodotFilterCallback *godotFilterCallback = nullptr; - btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver; - btVoronoiSimplexSolver *gjk_simplex_solver; + btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver = nullptr; + btVoronoiSimplexSolver *gjk_simplex_solver = nullptr; BulletPhysicsDirectSpaceState *direct_access; Vector3 gravityDirection = Vector3(0, -1, 0); - real_t gravityMagnitude = 10; + real_t gravityMagnitude = 10.0; real_t linear_damp = 0.0; real_t angular_damp = 0.0; @@ -151,6 +151,7 @@ public: void reload_collision_filters(AreaBullet *p_area); void add_rigid_body(RigidBodyBullet *p_body); + void remove_rigid_body_constraints(RigidBodyBullet *p_body); void remove_rigid_body(RigidBodyBullet *p_body); void reload_collision_filters(RigidBodyBullet *p_body); @@ -188,7 +189,7 @@ public: real_t get_angular_damp() const { return angular_damp; } bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes); - int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin); + int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin); private: void create_empty_world(bool p_create_soft_world); diff --git a/modules/camera_iphone/SCsub b/modules/camera_iphone/SCsub deleted file mode 100644 index 0a37d9a6f5..0000000000 --- a/modules/camera_iphone/SCsub +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_camera = env_modules.Clone() - -# (iOS) Enable module support -env_camera.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - -# (iOS) Build as separate static library -modules_sources = [] -env_camera.add_source_files(modules_sources, "*.cpp") -env_camera.add_source_files(modules_sources, "*.mm") -mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/camera_iphone/camera.gdip b/modules/camera_iphone/camera.gdip deleted file mode 100644 index 09017b8d27..0000000000 --- a/modules/camera_iphone/camera.gdip +++ /dev/null @@ -1,18 +0,0 @@ -[config] -name="Camera" -binary="camera_lib.a" - -initialization="register_camera_types" -deinitialization="unregister_camera_types" - -[dependencies] -linked=[] -embedded=[] -system=["AVFoundation.framework"] - -capabilities=[] - -files=[] - -[plist] -NSCameraUsageDescription="Device camera is used for some functionality" diff --git a/modules/camera_iphone/camera_ios.h b/modules/camera_iphone/camera_ios.h deleted file mode 100644 index 0566457a0f..0000000000 --- a/modules/camera_iphone/camera_ios.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************/ -/* camera_ios.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef CAMERAIOS_H -#define CAMERAIOS_H - -#include "servers/camera_server.h" - -class CameraIOS : public CameraServer { -private: -public: - CameraIOS(); - ~CameraIOS(); - - void update_feeds(); -}; - -#endif /* CAMERAIOS_H */ diff --git a/modules/camera_iphone/camera_ios.mm b/modules/camera_iphone/camera_ios.mm deleted file mode 100644 index 39568fbd6c..0000000000 --- a/modules/camera_iphone/camera_ios.mm +++ /dev/null @@ -1,445 +0,0 @@ -/*************************************************************************/ -/* camera_ios.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -///@TODO this is a near duplicate of CameraOSX, we should find a way to combine those to minimize code duplication!!!! -// If you fix something here, make sure you fix it there as wel! - -#include "camera_ios.h" -#include "servers/camera/camera_feed.h" - -#import <AVFoundation/AVFoundation.h> -#import <UIKit/UIKit.h> - -////////////////////////////////////////////////////////////////////////// -// MyCaptureSession - This is a little helper class so we can capture our frames - -@interface MyCaptureSession : AVCaptureSession <AVCaptureVideoDataOutputSampleBufferDelegate> { - Ref<CameraFeed> feed; - size_t width[2]; - size_t height[2]; - Vector<uint8_t> img_data[2]; - - AVCaptureDeviceInput *input; - AVCaptureVideoDataOutput *output; -} - -@end - -@implementation MyCaptureSession - -- (id)initForFeed:(Ref<CameraFeed>)p_feed andDevice:(AVCaptureDevice *)p_device { - if (self = [super init]) { - NSError *error; - feed = p_feed; - width[0] = 0; - height[0] = 0; - width[1] = 0; - height[1] = 0; - - // prepare our device - [p_device lockForConfiguration:&error]; - - [p_device setFocusMode:AVCaptureFocusModeLocked]; - [p_device setExposureMode:AVCaptureExposureModeLocked]; - [p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked]; - - [p_device unlockForConfiguration]; - - [self beginConfiguration]; - - // setup our capture - self.sessionPreset = AVCaptureSessionPreset1280x720; - - input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error]; - if (!input) { - print_line("Couldn't get input device for camera"); - } else { - [self addInput:input]; - } - - output = [AVCaptureVideoDataOutput new]; - if (!output) { - print_line("Couldn't get output device for camera"); - } else { - NSDictionary *settings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) }; - output.videoSettings = settings; - - // discard if the data output queue is blocked (as we process the still image) - [output setAlwaysDiscardsLateVideoFrames:YES]; - - // now set ourselves as the delegate to receive new frames. Note that we're doing this on the main thread at the moment, we may need to change this.. - [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; - - [self addOutput:output]; - } - - [self commitConfiguration]; - - // kick off our session.. - [self startRunning]; - }; - return self; -} - -- (void)cleanup { - // stop running - [self stopRunning]; - - // cleanup - [self beginConfiguration]; - - if (input) { - [self removeInput:input]; - // don't release this - input = nil; - } - - if (output) { - [self removeOutput:output]; - [output setSampleBufferDelegate:nil queue:NULL]; - output = nil; - } - - [self commitConfiguration]; -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { - // This gets called every time our camera has a new image for us to process. - // May need to investigate in a way to throttle this if we get more images then we're rendering frames.. - - // For now, version 1, we're just doing the bare minimum to make this work... - - CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - // int width = CVPixelBufferGetWidth(pixelBuffer); - // int height = CVPixelBufferGetHeight(pixelBuffer); - - // It says that we need to lock this on the documentation pages but it's not in the samples - // need to lock our base address so we can access our pixel buffers, better safe then sorry? - CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); - - // get our buffers - unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - if (dataY == NULL) { - print_line("Couldn't access Y pixel buffer data"); - } else if (dataCbCr == NULL) { - print_line("Couldn't access CbCr pixel buffer data"); - } else { - UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown; - - if (@available(iOS 13, *)) { - orientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation; -#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR - } else { - orientation = [[UIApplication sharedApplication] statusBarOrientation]; -#endif - } - - Ref<Image> img[2]; - - { - // do Y - size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0); - size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); - - if ((width[0] != new_width) || (height[0] != new_height)) { - width[0] = new_width; - height[0] = new_height; - img_data[0].resize(new_width * new_height); - } - - uint8_t *w = img_data[0].ptrw(); - memcpy(w, dataY, new_width * new_height); - - img[0].instance(); - img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]); - } - - { - // do CbCr - size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1); - size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1); - - if ((width[1] != new_width) || (height[1] != new_height)) { - width[1] = new_width; - height[1] = new_height; - img_data[1].resize(2 * new_width * new_height); - } - - uint8_t *w = img_data[1].ptrw(); - memcpy(w, dataCbCr, 2 * new_width * new_height); - - ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion - img[1].instance(); - img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]); - } - - // set our texture... - feed->set_YCbCr_imgs(img[0], img[1]); - - // update our matrix to match the orientation, note, before changing anything - // here, be aware that the project orientation settings must match your xcode - // settings or this will go wrong! - Transform2D display_transform; - switch (orientation) { - case UIInterfaceOrientationPortrait: { - display_transform = Transform2D(0.0, -1.0, -1.0, 0.0, 1.0, 1.0); - } break; - case UIInterfaceOrientationLandscapeRight: { - display_transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); - } break; - case UIInterfaceOrientationLandscapeLeft: { - display_transform = Transform2D(-1.0, 0.0, 0.0, 1.0, 1.0, 0.0); - } break; - default: { - display_transform = Transform2D(0.0, 1.0, 1.0, 0.0, 0.0, 0.0); - } break; - } - - //TODO: this is correct for the camera on the back, I have a feeling this needs to be inversed for the camera on the front! - feed->set_transform(display_transform); - } - - // and unlock - CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); -} - -@end - -////////////////////////////////////////////////////////////////////////// -// CameraFeedIOS - Subclass for camera feeds in iOS - -class CameraFeedIOS : public CameraFeed { -private: - AVCaptureDevice *device; - MyCaptureSession *capture_session; - -public: - bool get_is_arkit() const; - AVCaptureDevice *get_device() const; - - CameraFeedIOS(); - ~CameraFeedIOS(); - - void set_device(AVCaptureDevice *p_device); - - bool activate_feed(); - void deactivate_feed(); -}; - -AVCaptureDevice *CameraFeedIOS::get_device() const { - return device; -}; - -CameraFeedIOS::CameraFeedIOS() { - capture_session = NULL; - device = NULL; - transform = Transform2D(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); /* should re-orientate this based on device orientation */ -}; - -void CameraFeedIOS::set_device(AVCaptureDevice *p_device) { - device = p_device; - - // get some info - NSString *device_name = p_device.localizedName; - name = device_name.UTF8String; - position = CameraFeed::FEED_UNSPECIFIED; - if ([p_device position] == AVCaptureDevicePositionBack) { - position = CameraFeed::FEED_BACK; - } else if ([p_device position] == AVCaptureDevicePositionFront) { - position = CameraFeed::FEED_FRONT; - }; -}; - -CameraFeedIOS::~CameraFeedIOS() { - if (capture_session) { - capture_session = nil; - }; - - if (device) { - device = nil; - }; -}; - -bool CameraFeedIOS::activate_feed() { - if (capture_session) { - // already recording! - } else { - // start camera capture - capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device]; - }; - - return true; -}; - -void CameraFeedIOS::deactivate_feed() { - // end camera capture if we have one - if (capture_session) { - [capture_session cleanup]; - capture_session = nil; - }; -}; - -////////////////////////////////////////////////////////////////////////// -// MyDeviceNotifications - This is a little helper class gets notifications -// when devices are connected/disconnected - -@interface MyDeviceNotifications : NSObject { - CameraIOS *camera_server; -} - -@end - -@implementation MyDeviceNotifications - -- (void)devices_changed:(NSNotification *)notification { - camera_server->update_feeds(); -} - -- (id)initForServer:(CameraIOS *)p_server { - if (self = [super init]) { - camera_server = p_server; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasConnectedNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - }; - return self; -} - -- (void)dealloc { - // remove notifications - [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil]; -} - -@end - -MyDeviceNotifications *device_notifications = nil; - -////////////////////////////////////////////////////////////////////////// -// CameraIOS - Subclass for our camera server on iPhone - -void CameraIOS::update_feeds() { - // this way of doing things is deprecated but still works, - // rewrite to using AVCaptureDeviceDiscoverySession - - NSMutableArray *deviceTypes = [NSMutableArray array]; - - if (@available(iOS 10, *)) { - [deviceTypes addObject:AVCaptureDeviceTypeBuiltInWideAngleCamera]; - [deviceTypes addObject:AVCaptureDeviceTypeBuiltInTelephotoCamera]; - - if (@available(iOS 10.2, *)) { - [deviceTypes addObject:AVCaptureDeviceTypeBuiltInDualCamera]; - } - - if (@available(iOS 11.1, *)) { - [deviceTypes addObject:AVCaptureDeviceTypeBuiltInTrueDepthCamera]; - } - - AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession - discoverySessionWithDeviceTypes:deviceTypes - mediaType:AVMediaTypeVideo - position:AVCaptureDevicePositionUnspecified]; - - // remove devices that are gone.. - for (int i = feeds.size() - 1; i >= 0; i--) { - Ref<CameraFeedIOS> feed(feeds[i]); - - if (feed.is_null()) { - // feed not managed by us - } else if (![session.devices containsObject:feed->get_device()]) { - // remove it from our array, this will also destroy it ;) - remove_feed(feed); - }; - }; - - // add new devices.. - for (AVCaptureDevice *device in session.devices) { - bool found = false; - - for (int i = 0; i < feeds.size() && !found; i++) { - Ref<CameraFeedIOS> feed(feeds[i]); - - if (feed.is_null()) { - // feed not managed by us - } else if (feed->get_device() == device) { - found = true; - }; - }; - - if (!found) { - Ref<CameraFeedIOS> newfeed; - newfeed.instance(); - newfeed->set_device(device); - add_feed(newfeed); - }; - }; - } -}; - -CameraIOS::CameraIOS() { - // check if we have our usage description - NSString *usage_desc = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSCameraUsageDescription"]; - if (usage_desc == NULL) { - // don't initialise if we don't get anything - print_line("No NSCameraUsageDescription key in pList, no access to cameras."); - return; - } else if (usage_desc.length == 0) { - // don't initialise if we don't get anything - print_line("Empty NSCameraUsageDescription key in pList, no access to cameras."); - return; - } - - // now we'll request access. - // If this is the first time the user will be prompted with the string (iOS will read it). - // Once a decision is made it is returned. If the user wants to change it later on they - // need to go into setting. - print_line("Requesting Camera permissions"); - - [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo - completionHandler:^(BOOL granted) { - if (granted) { - print_line("Access to cameras granted!"); - - // Find available cameras we have at this time - update_feeds(); - - // should only have one of these.... - device_notifications = [[MyDeviceNotifications alloc] initForServer:this]; - } else { - print_line("No access to cameras!"); - } - }]; -}; - -CameraIOS::~CameraIOS() { - device_notifications = nil; -}; diff --git a/modules/camera_iphone/camera_module.cpp b/modules/camera_iphone/camera_module.cpp deleted file mode 100644 index 7ea035892e..0000000000 --- a/modules/camera_iphone/camera_module.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************/ -/* camera_module.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "camera_module.h" - -#include "camera_ios.h" - -void register_camera_types() { - CameraServer::make_default<CameraIOS>(); -} - -void unregister_camera_types() { -} diff --git a/modules/camera_iphone/camera_module.h b/modules/camera_iphone/camera_module.h deleted file mode 100644 index 5a94d8b529..0000000000 --- a/modules/camera_iphone/camera_module.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************/ -/* camera_module.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -void register_camera_types(); -void unregister_camera_types(); diff --git a/modules/camera_iphone/config.py b/modules/camera_iphone/config.py deleted file mode 100644 index e68603fc93..0000000000 --- a/modules/camera_iphone/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return platform == "iphone" - - -def configure(env): - pass diff --git a/modules/csg/csg.h b/modules/csg/csg.h index 1612c16a32..3fbed66e5c 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -48,9 +48,9 @@ struct CSGBrush { Vector3 vertices[3]; Vector2 uvs[3]; AABB aabb; - bool smooth; - bool invert; - int material; + bool smooth = false; + bool invert = false; + int material = 0; }; Vector<Face> faces; @@ -74,20 +74,20 @@ struct CSGBrushOperation { struct MeshMerge { struct Face { - bool from_b; - bool inside; - int points[3]; + bool from_b = false; + bool inside = false; + int points[3] = {}; Vector2 uvs[3]; - bool smooth; - bool invert; - int material_idx; + bool smooth = false; + bool invert = false; + int material_idx = 0; }; struct FaceBVH { - int face; - int left; - int right; - int next; + int face = 0; + int left = 0; + int right = 0; + int next = 0; Vector3 center; AABB aabb; }; @@ -142,7 +142,7 @@ struct CSGBrushOperation { Map<Ref<Material>, int> materials; Map<Vector3, int> vertex_map; OAHashMap<VertexKey, int, VertexKeyHash> snap_cache; - float vertex_snap; + float vertex_snap = 0.0; inline void _add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const; inline bool _bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const; @@ -159,7 +159,7 @@ struct CSGBrushOperation { }; struct Face2D { - int vertex_idx[3]; + int vertex_idx[3] = {}; }; Vector<Vertex2D> vertices; @@ -167,7 +167,7 @@ struct CSGBrushOperation { Plane plane; Transform to_2D; Transform to_3D; - float vertex_snap2; + float vertex_snap2 = 0.0; inline int _get_point_idx(const Vector2 &p_point); inline int _add_vertex(const Vertex2D &p_vertex); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 042c3aaca7..40ba457e43 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -45,7 +45,8 @@ void CSGShape3D::set_use_collision(bool p_enable) { if (use_collision) { root_collision_shape.instance(); - root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + root_collision_instance = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid()); PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space()); @@ -58,7 +59,7 @@ void CSGShape3D::set_use_collision(bool p_enable) { root_collision_instance = RID(); root_collision_shape.unref(); } - _change_notify(); + notify_property_list_changed(); } bool CSGShape3D::is_using_collision() const { @@ -494,7 +495,8 @@ void CSGShape3D::_notification(int p_what) { if (use_collision && is_root_shape()) { root_collision_shape.instance(); - root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + root_collision_instance = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid()); PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space()); @@ -625,15 +627,6 @@ void CSGShape3D::_bind_methods() { } CSGShape3D::CSGShape3D() { - operation = OPERATION_UNION; - parent = nullptr; - brush = nullptr; - dirty = false; - snap = 0.001; - use_collision = false; - collision_layer = 1; - collision_mask = 1; - calculate_tangents = true; set_notify_local_transform(true); } @@ -927,25 +920,27 @@ CSGBrush *CSGSphere3D::_build_brush() { bool *invertw = invert.ptrw(); int face = 0; + const double lat_step = Math_TAU / rings; + const double lon_step = Math_TAU / radial_segments; for (int i = 1; i <= rings; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / rings); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double u0 = double(i - 1) / rings; - double lat1 = Math_PI * (-0.5 + (double)i / rings); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); double u1 = double(i) / rings; for (int j = radial_segments; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / radial_segments; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double v0 = double(i - 1) / radial_segments; - double lng1 = 2 * Math_PI * (double)(j) / radial_segments; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); double v1 = double(i) / radial_segments; @@ -1038,7 +1033,6 @@ void CSGSphere3D::set_radius(const float p_radius) { radius = p_radius; _make_dirty(); update_gizmo(); - _change_notify("radius"); } float CSGSphere3D::get_radius() const { @@ -1208,7 +1202,6 @@ void CSGBox3D::set_size(const Vector3 &p_size) { size = p_size; _make_dirty(); update_gizmo(); - _change_notify("size"); } Vector3 CSGBox3D::get_size() const { @@ -1266,8 +1259,8 @@ CSGBrush *CSGCylinder3D::_build_brush() { float inc = float(i) / sides; float inc_n = float((i + 1)) / sides; - float ang = inc * Math_PI * 2.0; - float ang_n = inc_n * Math_PI * 2.0; + float ang = inc * Math_TAU; + float ang_n = inc_n * Math_TAU; Vector3 base(Math::cos(ang), 0, Math::sin(ang)); Vector3 base_n(Math::cos(ang_n), 0, Math::sin(ang_n)); @@ -1390,7 +1383,6 @@ void CSGCylinder3D::set_radius(const float p_radius) { radius = p_radius; _make_dirty(); update_gizmo(); - _change_notify("radius"); } float CSGCylinder3D::get_radius() const { @@ -1401,7 +1393,6 @@ void CSGCylinder3D::set_height(const float p_height) { height = p_height; _make_dirty(); update_gizmo(); - _change_notify("height"); } float CSGCylinder3D::get_height() const { @@ -1508,8 +1499,8 @@ CSGBrush *CSGTorus3D::_build_brush() { float inci = float(i) / sides; float inci_n = float((i + 1)) / sides; - float angi = inci * Math_PI * 2.0; - float angi_n = inci_n * Math_PI * 2.0; + float angi = inci * Math_TAU; + float angi_n = inci_n * Math_TAU; Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi)); Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n)); @@ -1518,8 +1509,8 @@ CSGBrush *CSGTorus3D::_build_brush() { float incj = float(j) / ring_sides; float incj_n = float((j + 1)) / ring_sides; - float angj = incj * Math_PI * 2.0; - float angj_n = incj_n * Math_PI * 2.0; + float angj = incj * Math_TAU; + float angj_n = incj_n * Math_TAU; Vector2 normalj = Vector2(Math::cos(angj), Math::sin(angj)) * radius + Vector2(min_radius + radius, 0); Vector2 normalj_n = Vector2(Math::cos(angj_n), Math::sin(angj_n)) * radius + Vector2(min_radius + radius, 0); @@ -1611,7 +1602,6 @@ void CSGTorus3D::set_inner_radius(const float p_inner_radius) { inner_radius = p_inner_radius; _make_dirty(); update_gizmo(); - _change_notify("inner_radius"); } float CSGTorus3D::get_inner_radius() const { @@ -1622,7 +1612,6 @@ void CSGTorus3D::set_outer_radius(const float p_outer_radius) { outer_radius = p_outer_radius; _make_dirty(); update_gizmo(); - _change_notify("outer_radius"); } float CSGTorus3D::get_outer_radius() const { @@ -1891,8 +1880,8 @@ CSGBrush *CSGPolygon3D::_build_brush() { float inci = float(i) / spin_sides; float inci_n = float((i + 1)) / spin_sides; - float angi = -(inci * spin_degrees / 360.0) * Math_PI * 2.0; - float angi_n = -(inci_n * spin_degrees / 360.0) * Math_PI * 2.0; + float angi = -Math::deg2rad(inci * spin_degrees); + float angi_n = -Math::deg2rad(inci_n * spin_degrees); Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi)); Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n)); @@ -2269,7 +2258,7 @@ void CSGPolygon3D::set_mode(Mode p_mode) { mode = p_mode; _make_dirty(); update_gizmo(); - _change_notify(); + notify_property_list_changed(); } CSGPolygon3D::Mode CSGPolygon3D::get_mode() const { diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index 7dff8b6d3b..de7de09f00 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -50,23 +50,23 @@ public: }; private: - Operation operation; - CSGShape3D *parent; + Operation operation = OPERATION_UNION; + CSGShape3D *parent = nullptr; - CSGBrush *brush; + CSGBrush *brush = nullptr; AABB node_aabb; - bool dirty; - float snap; + bool dirty = false; + float snap = 0.001; - bool use_collision; - uint32_t collision_layer; - uint32_t collision_mask; + bool use_collision = false; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; Ref<ConcavePolygonShape3D> root_collision_shape; RID root_collision_instance; - bool calculate_tangents; + bool calculate_tangents = true; Ref<ArrayMesh> root_mesh; @@ -85,12 +85,12 @@ private: Vector<Vector2> uvs; Vector<float> tans; Ref<Material> material; - int last_added; + int last_added = 0; - Vector3 *verticesw; - Vector3 *normalsw; - Vector2 *uvsw; - float *tansw; + Vector3 *verticesw = nullptr; + Vector3 *normalsw = nullptr; + Vector2 *uvsw = nullptr; + float *tansw = nullptr; }; //mikktspace callbacks diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index 6661dbbb0b..3beca3d12a 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -33,30 +33,31 @@ #include "core/os/os.h" #include "core/os/thread.h" #include "core/string/print_string.h" +#include "core/templates/safe_refcount.h" #include <ConvectionKernels.h> struct CVTTCompressionJobParams { - bool is_hdr; - bool is_signed; - int bytes_per_pixel; + bool is_hdr = false; + bool is_signed = false; + int bytes_per_pixel = 0; cvtt::Options options; }; struct CVTTCompressionRowTask { const uint8_t *in_mm_bytes; - uint8_t *out_mm_bytes; - int y_start; - int width; - int height; + uint8_t *out_mm_bytes = nullptr; + int y_start = 0; + int width = 0; + int height = 0; }; struct CVTTCompressionJobQueue { CVTTCompressionJobParams job_params; const CVTTCompressionRowTask *job_tasks; - uint32_t num_tasks; - uint32_t current_task; + uint32_t num_tasks = 0; + SafeNumeric<uint32_t> current_task; }; static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const CVTTCompressionRowTask &p_row_task) { @@ -131,7 +132,7 @@ static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const static void _digest_job_queue(void *p_job_queue) { CVTTCompressionJobQueue *job_queue = static_cast<CVTTCompressionJobQueue *>(p_job_queue); - for (uint32_t next_task = atomic_increment(&job_queue->current_task); next_task <= job_queue->num_tasks; next_task = atomic_increment(&job_queue->current_task)) { + for (uint32_t next_task = job_queue->current_task.increment(); next_task <= job_queue->num_tasks; next_task = job_queue->current_task.increment()) { _digest_row_task(job_queue->job_params, job_queue->job_tasks[next_task - 1]); } } @@ -263,16 +264,17 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann const CVTTCompressionRowTask *tasks_rb = tasks.ptr(); job_queue.job_tasks = &tasks_rb[0]; - job_queue.current_task = 0; + job_queue.current_task.set(0); job_queue.num_tasks = static_cast<uint32_t>(tasks.size()); for (int i = 0; i < num_job_threads; i++) { - threads_wb[i] = Thread::create(_digest_job_queue, &job_queue); + threads_wb[i] = memnew(Thread); + threads_wb[i]->start(_digest_job_queue, &job_queue); } _digest_job_queue(&job_queue); for (int i = 0; i < num_job_threads; i++) { - Thread::wait_to_finish(threads_wb[i]); + threads_wb[i]->wait_to_finish(); memdelete(threads_wb[i]); } } diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index 2865b3c9ae..2fef576b77 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -69,11 +69,11 @@ enum DDSFormat { struct DDSFormatInfo { const char *name; - bool compressed; - bool palette; - uint32_t divisor; - uint32_t block_size; - Image::Format format; + bool compressed = false; + bool palette = false; + uint32_t divisor = 0; + uint32_t block_size = 0; + Image::Format format = Image::Format::FORMAT_BPTC_RGBA; }; static const DDSFormatInfo dds_format_info[DDS_MAX] = { @@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 } }; -RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index 605e791969..cf93156423 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -36,7 +36,7 @@ class ResourceFormatDDS : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index f46ef2d812..c8f32ffde6 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -5,6 +5,8 @@ </brief_description> <description> A PacketPeer implementation that should be passed to [member SceneTree.network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals. + ENet's purpose is to provide a relatively thin, simple and robust network communication layer on top of UDP (User Datagram Protocol). + [b]Note:[/b] ENet only uses UDP, not TCP. When forwarding the server port to make your server accessible on the public Internet, you only need to forward the server port in UDP. You can use the [UPNP] class to try to forward the server port automatically when starting the server. </description> <tutorials> <link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link> @@ -122,6 +124,22 @@ Configure the [CryptoKey] to use when [member use_dtls] is [code]true[/code]. Remember to also call [method set_dtls_certificate] to setup your [X509Certificate]. </description> </method> + <method name="set_peer_timeout"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="timeout_limit" type="int"> + </argument> + <argument index="2" name="timeout_min" type="int"> + </argument> + <argument index="3" name="timeout_max" type="int"> + </argument> + <description> + Sets the timeout parameters for a peer. The timeout parameters control how and when a peer will timeout from a failure to acknowledge reliable traffic. Timeout values are expressed in milliseconds. + The [code]timeout_limit[/code] is a factor that, multiplied by a value based on the avarage round trip time, will determine the timeout limit for a reliable packet. When that limit is reached, the timeout will be doubled, and the peer will be disconnected if that limit has reached [code]timeout_min[/code]. The [code]timeout_max[/code] parameter, on the other hand, defines a fixed timeout for which any packet must be acknowledged or the peer will be dropped. + </description> + </method> </methods> <members> <member name="always_ordered" type="bool" setter="set_always_ordered" getter="is_always_ordered" default="false"> diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 66db9ab84e..276f13e553 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -784,6 +784,14 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const { #endif } +void NetworkedMultiplayerENet::set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max) { + ERR_FAIL_COND_MSG(!peer_map.has(p_peer_id), vformat("Peer ID %d not found in the list of peers.", p_peer_id)); + ERR_FAIL_COND_MSG(!is_server() && p_peer_id != 1, "Can't change the timeout of peers other then the server when acting as a client."); + ERR_FAIL_COND_MSG(peer_map[p_peer_id] == nullptr, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id)); + ERR_FAIL_COND_MSG(p_timeout_limit > p_timeout_min || p_timeout_min > p_timeout_max, "Timeout limit must be less than minimum timeout, which itself must be less then maximum timeout"); + enet_peer_timeout(peer_map[p_peer_id], p_timeout_limit, p_timeout_min, p_timeout_max); +} + void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) { ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel)); ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG)); @@ -838,6 +846,7 @@ void NetworkedMultiplayerENet::_bind_methods() { ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &NetworkedMultiplayerENet::is_dtls_verify_enabled); ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address); ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port); + ClassDB::bind_method(D_METHOD("set_peer_timeout", "id", "timeout_limit", "timeout_min", "timeout_max"), &NetworkedMultiplayerENet::set_peer_timeout); ClassDB::bind_method(D_METHOD("get_packet_channel"), &NetworkedMultiplayerENet::get_packet_channel); ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &NetworkedMultiplayerENet::get_last_packet_channel); @@ -866,28 +875,12 @@ void NetworkedMultiplayerENet::_bind_methods() { } NetworkedMultiplayerENet::NetworkedMultiplayerENet() { - active = false; - server = false; - refuse_connections = false; - server_relay = true; - unique_id = 0; - target_peer = 0; - current_packet.packet = nullptr; - transfer_mode = TRANSFER_MODE_RELIABLE; - channel_count = SYSCH_MAX; - transfer_channel = -1; - always_ordered = false; - connection_status = CONNECTION_DISCONNECTED; - compression_mode = COMPRESS_NONE; enet_compressor.context = this; enet_compressor.compress = enet_compress; enet_compressor.decompress = enet_decompress; enet_compressor.destroy = enet_compressor_destroy; bind_ip = IP_Address("*"); - - dtls_enabled = false; - dtls_verify = true; } NetworkedMultiplayerENet::~NetworkedMultiplayerENet() { diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 4baa48be5e..b99b14d218 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -62,35 +62,35 @@ private: SYSCH_MAX }; - bool active; - bool server; + bool active = false; + bool server = false; - uint32_t unique_id; + uint32_t unique_id = 0; - int target_peer; - TransferMode transfer_mode; - int transfer_channel; - int channel_count; - bool always_ordered; + int target_peer = 0; + TransferMode transfer_mode = TRANSFER_MODE_RELIABLE; + int transfer_channel = -1; + int channel_count = SYSCH_MAX; + bool always_ordered = false; ENetEvent event; - ENetPeer *peer; - ENetHost *host; + ENetPeer *peer = nullptr; + ENetHost *host = nullptr; - bool refuse_connections; - bool server_relay; + bool refuse_connections = false; + bool server_relay = true; - ConnectionStatus connection_status; + ConnectionStatus connection_status = CONNECTION_DISCONNECTED; Map<int, ENetPeer *> peer_map; struct Packet { - ENetPacket *packet; - int from; - int channel; + ENetPacket *packet = nullptr; + int from = 0; + int channel = 0; }; - CompressionMode compression_mode; + CompressionMode compression_mode = COMPRESS_NONE; List<Packet> incoming_packets; @@ -110,10 +110,10 @@ private: IP_Address bind_ip; - bool dtls_enabled; + bool dtls_enabled = false; Ref<CryptoKey> dtls_key; Ref<X509Certificate> dtls_cert; - bool dtls_verify; + bool dtls_verify = true; protected: static void _bind_methods(); @@ -127,6 +127,7 @@ public: virtual IP_Address get_peer_address(int p_peer_id) const; virtual int get_peer_port(int p_peer_id) const; + void set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max); Error create_server(int p_port, int p_max_clients = 32, int p_in_bandwidth = 0, int p_out_bandwidth = 0); Error create_client(const String &p_address, int p_port, int p_in_bandwidth = 0, int p_out_bandwidth = 0, int p_client_port = 0); diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index b0ea109f76..95db9315d5 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -35,14 +35,14 @@ struct ETC1Header { char tag[6]; // "PKM 10" - uint16_t format; // Format == number of mips (== zero) - uint16_t texWidth; // Texture dimensions, multiple of 4 (big-endian) - uint16_t texHeight; - uint16_t origWidth; // Original dimensions (big-endian) - uint16_t origHeight; + uint16_t format = 0; // Format == number of mips (== zero) + uint16_t texWidth = 0; // Texture dimensions, multiple of 4 (big-endian) + uint16_t texHeight = 0; + uint16_t origWidth = 0; // Original dimensions (big-endian) + uint16_t origHeight = 0; }; -RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h index 67fbee3a7e..2ed5e75807 100644 --- a/modules/etc/texture_loader_pkm.h +++ b/modules/etc/texture_loader_pkm.h @@ -36,7 +36,7 @@ class ResourceFormatPKM : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/fbx/data/fbx_material.h b/modules/fbx/data/fbx_material.h index e974a256f6..23310b8e1d 100644 --- a/modules/fbx/data/fbx_material.h +++ b/modules/fbx/data/fbx_material.h @@ -217,9 +217,6 @@ struct FBXMaterial : public Reference { { "TransparencyFactor", PROPERTY_DESC_TRANSPARENT }, { "Maya|opacity", PROPERTY_DESC_TRANSPARENT }, - /* Metallic */ - { "Shininess", PROPERTY_DESC_METALLIC }, - { "Reflectivity", PROPERTY_DESC_METALLIC }, { "Maya|metalness", PROPERTY_DESC_METALLIC }, { "Maya|metallic", PROPERTY_DESC_METALLIC }, @@ -241,6 +238,8 @@ struct FBXMaterial : public Reference { { "Maya|emissionColor", PROPERTY_DESC_EMISSIVE_COLOR }, /* Ignore */ + { "Shininess", PROPERTY_DESC_IGNORE }, + { "Reflectivity", PROPERTY_DESC_IGNORE }, { "Maya|diffuseRoughness", PROPERTY_DESC_IGNORE }, { "Maya", PROPERTY_DESC_IGNORE }, { "Diffuse", PROPERTY_DESC_ALBEDO_COLOR }, diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp index 963a815896..883651943e 100644 --- a/modules/fbx/data/fbx_mesh_data.cpp +++ b/modules/fbx/data/fbx_mesh_data.cpp @@ -34,7 +34,7 @@ #include "scene/resources/mesh.h" #include "scene/resources/surface_tool.h" -#include "thirdparty/misc/triangulator.h" +#include "thirdparty/misc/polypartition.h" template <class T> T collect_first(const Vector<VertexData<T>> *p_data, T p_fall_back) { @@ -930,30 +930,30 @@ void FBXMeshData::triangulate_polygon(Ref<SurfaceTool> st, Vector<int> p_polygon } } - TriangulatorPoly triangulator_poly; - triangulator_poly.Init(polygon_vertex_count); + TPPLPoly tppl_poly; + tppl_poly.Init(polygon_vertex_count); std::vector<Vector2> projected_vertices(polygon_vertex_count); for (int i = 0; i < polygon_vertex_count; i += 1) { const Vector2 pv(poly_vertices[i][axis_1_coord], poly_vertices[i][axis_2_coord]); projected_vertices[i] = pv; - triangulator_poly.GetPoint(i) = pv; + tppl_poly.GetPoint(i) = pv; } - triangulator_poly.SetOrientation(TRIANGULATOR_CCW); + tppl_poly.SetOrientation(TPPL_ORIENTATION_CCW); - List<TriangulatorPoly> out_poly; + List<TPPLPoly> out_poly; - TriangulatorPartition triangulator_partition; - if (triangulator_partition.Triangulate_OPT(&triangulator_poly, &out_poly) == 0) { // Good result. - if (triangulator_partition.Triangulate_EC(&triangulator_poly, &out_poly) == 0) { // Medium result. - if (triangulator_partition.Triangulate_MONO(&triangulator_poly, &out_poly) == 0) { // Really poor result. + TPPLPartition tppl_partition; + if (tppl_partition.Triangulate_OPT(&tppl_poly, &out_poly) == 0) { // Good result. + if (tppl_partition.Triangulate_EC(&tppl_poly, &out_poly) == 0) { // Medium result. + if (tppl_partition.Triangulate_MONO(&tppl_poly, &out_poly) == 0) { // Really poor result. ERR_FAIL_MSG("The triangulation of this polygon failed, please try to triangulate your mesh or check if it has broken polygons."); } } } std::vector<Vector2> tris(out_poly.size()); - for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { - TriangulatorPoly &tp = I->get(); + for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) { + TPPLPoly &tp = I->get(); ERR_FAIL_COND_MSG(tp.GetNumPoints() != 3, "The triangulator retuned more points, how this is possible?"); // Find Index diff --git a/modules/fbx/data/pivot_transform.cpp b/modules/fbx/data/pivot_transform.cpp index 7a56074bc5..1895af6f9f 100644 --- a/modules/fbx/data/pivot_transform.cpp +++ b/modules/fbx/data/pivot_transform.cpp @@ -76,12 +76,14 @@ void PivotTransform::ReadTransformChain() { const Vector3 &Scaling = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "Lcl Scaling", ok)); if (ok) { scaling = Scaling; + } else { + scaling = Vector3(1, 1, 1); } const Vector3 &GeometricScaling = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "GeometricScaling", ok)); if (ok) { geometric_scaling = GeometricScaling; } else { - geometric_scaling = Vector3(0, 0, 0); + geometric_scaling = Vector3(1, 1, 1); } const Vector3 &GeometricRotation = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "GeometricRotation", ok)); @@ -207,6 +209,8 @@ Transform PivotTransform::ComputeGlobalTransform(Vector3 p_translation, Quat p_r Transform local_transform = T * Roff * Rp * Rpre * R * Rpost.affine_inverse() * Rp.affine_inverse() * Soff * Sp * S * Sp.affine_inverse(); //Transform local_translation_pivoted = Transform(Basis(), LocalTransform.origin); + ERR_FAIL_COND_V_MSG(local_transform.basis.determinant() == 0, Transform(), "Det == 0 prevented in scene file"); + // manual hack to force SSC not to be compensated for - until we can handle it properly with tests return parent_global_xform * local_transform; } @@ -290,5 +294,14 @@ void PivotTransform::Execute() { ComputePivotTransform(); ImportUtils::debug_xform("global xform: ", GlobalTransform); + + if (LocalTransform.basis.determinant() == 0) { + print_error("Serious det == 0!"); + } + + if (GlobalTransform.basis.determinant() == 0) { + print_error("Serious! node has det == 0!"); + } + computed_global_xform = true; } diff --git a/modules/gamecenter/SCsub b/modules/gamecenter/SCsub deleted file mode 100644 index 72fbf7ab0e..0000000000 --- a/modules/gamecenter/SCsub +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_gamecenter = env_modules.Clone() - -# (iOS) Enable module support -env_gamecenter.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - -# (iOS) Build as separate static library -modules_sources = [] -env_gamecenter.add_source_files(modules_sources, "*.cpp") -env_gamecenter.add_source_files(modules_sources, "*.mm") -mod_lib = env_modules.add_library("#bin/libgodot_gamecenter_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/gamecenter/config.py b/modules/gamecenter/config.py deleted file mode 100644 index e68603fc93..0000000000 --- a/modules/gamecenter/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return platform == "iphone" - - -def configure(env): - pass diff --git a/modules/gamecenter/game_center.mm b/modules/gamecenter/game_center.mm deleted file mode 100644 index b971bc1da3..0000000000 --- a/modules/gamecenter/game_center.mm +++ /dev/null @@ -1,380 +0,0 @@ -/*************************************************************************/ -/* game_center.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "game_center.h" -#import "platform/iphone/app_delegate.h" - -#import "game_center_delegate.h" -#import "platform/iphone/view_controller.h" -#import <GameKit/GameKit.h> - -GameCenter *GameCenter::instance = NULL; -GodotGameCenterDelegate *gameCenterDelegate = nil; - -void GameCenter::_bind_methods() { - ClassDB::bind_method(D_METHOD("authenticate"), &GameCenter::authenticate); - ClassDB::bind_method(D_METHOD("is_authenticated"), &GameCenter::is_authenticated); - - ClassDB::bind_method(D_METHOD("post_score"), &GameCenter::post_score); - ClassDB::bind_method(D_METHOD("award_achievement", "achievement"), &GameCenter::award_achievement); - ClassDB::bind_method(D_METHOD("reset_achievements"), &GameCenter::reset_achievements); - ClassDB::bind_method(D_METHOD("request_achievements"), &GameCenter::request_achievements); - ClassDB::bind_method(D_METHOD("request_achievement_descriptions"), &GameCenter::request_achievement_descriptions); - ClassDB::bind_method(D_METHOD("show_game_center"), &GameCenter::show_game_center); - ClassDB::bind_method(D_METHOD("request_identity_verification_signature"), &GameCenter::request_identity_verification_signature); - - ClassDB::bind_method(D_METHOD("get_pending_event_count"), &GameCenter::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"), &GameCenter::pop_pending_event); -}; - -Error GameCenter::authenticate() { - //if this class isn't available, game center isn't implemented - if ((NSClassFromString(@"GKLocalPlayer")) == nil) { - return ERR_UNAVAILABLE; - } - - GKLocalPlayer *player = [GKLocalPlayer localPlayer]; - ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE); - - UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController; - ERR_FAIL_COND_V(!root_controller, FAILED); - - // This handler is called several times. First when the view needs to be shown, then again - // after the view is cancelled or the user logs in. Or if the user's already logged in, it's - // called just once to confirm they're authenticated. This is why no result needs to be specified - // in the presentViewController phase. In this case, more calls to this function will follow. - _weakify(root_controller); - _weakify(player); - player.authenticateHandler = (^(UIViewController *controller, NSError *error) { - _strongify(root_controller); - _strongify(player); - - if (controller) { - [root_controller presentViewController:controller animated:YES completion:nil]; - } else { - Dictionary ret; - ret["type"] = "authentication"; - if (player.isAuthenticated) { - ret["result"] = "ok"; - if (@available(iOS 13, *)) { - ret["player_id"] = [player.teamPlayerID UTF8String]; -#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR - } else { - ret["player_id"] = [player.playerID UTF8String]; -#endif - } - - GameCenter::get_singleton()->authenticated = true; - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - ret["error_description"] = [error.localizedDescription UTF8String]; - GameCenter::get_singleton()->authenticated = false; - }; - - pending_events.push_back(ret); - }; - }); - - return OK; -}; - -bool GameCenter::is_authenticated() { - return authenticated; -}; - -Error GameCenter::post_score(Dictionary p_score) { - ERR_FAIL_COND_V(!p_score.has("score") || !p_score.has("category"), ERR_INVALID_PARAMETER); - float score = p_score["score"]; - String category = p_score["category"]; - - NSString *cat_str = [[NSString alloc] initWithUTF8String:category.utf8().get_data()]; - GKScore *reporter = [[GKScore alloc] initWithLeaderboardIdentifier:cat_str]; - reporter.value = score; - - ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE); - - [GKScore reportScores:@[ reporter ] - withCompletionHandler:^(NSError *error) { - Dictionary ret; - ret["type"] = "post_score"; - if (error == nil) { - ret["result"] = "ok"; - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - ret["error_description"] = [error.localizedDescription UTF8String]; - }; - - pending_events.push_back(ret); - }]; - - return OK; -}; - -Error GameCenter::award_achievement(Dictionary p_params) { - ERR_FAIL_COND_V(!p_params.has("name") || !p_params.has("progress"), ERR_INVALID_PARAMETER); - String name = p_params["name"]; - float progress = p_params["progress"]; - - NSString *name_str = [[NSString alloc] initWithUTF8String:name.utf8().get_data()]; - GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:name_str]; - ERR_FAIL_COND_V(!achievement, FAILED); - - ERR_FAIL_COND_V([GKAchievement respondsToSelector:@selector(reportAchievements)], ERR_UNAVAILABLE); - - achievement.percentComplete = progress; - achievement.showsCompletionBanner = NO; - if (p_params.has("show_completion_banner")) { - achievement.showsCompletionBanner = p_params["show_completion_banner"] ? YES : NO; - } - - [GKAchievement reportAchievements:@[ achievement ] - withCompletionHandler:^(NSError *error) { - Dictionary ret; - ret["type"] = "award_achievement"; - if (error == nil) { - ret["result"] = "ok"; - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - }; - - pending_events.push_back(ret); - }]; - - return OK; -}; - -void GameCenter::request_achievement_descriptions() { - [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) { - Dictionary ret; - ret["type"] = "achievement_descriptions"; - if (error == nil) { - ret["result"] = "ok"; - PackedStringArray names; - PackedStringArray titles; - PackedStringArray unachieved_descriptions; - PackedStringArray achieved_descriptions; - PackedInt32Array maximum_points; - Array hidden; - Array replayable; - - for (NSUInteger i = 0; i < [descriptions count]; i++) { - GKAchievementDescription *description = [descriptions objectAtIndex:i]; - - const char *str = [description.identifier UTF8String]; - names.push_back(String::utf8(str != NULL ? str : "")); - - str = [description.title UTF8String]; - titles.push_back(String::utf8(str != NULL ? str : "")); - - str = [description.unachievedDescription UTF8String]; - unachieved_descriptions.push_back(String::utf8(str != NULL ? str : "")); - - str = [description.achievedDescription UTF8String]; - achieved_descriptions.push_back(String::utf8(str != NULL ? str : "")); - - maximum_points.push_back(description.maximumPoints); - - hidden.push_back(description.hidden == YES); - - replayable.push_back(description.replayable == YES); - } - - ret["names"] = names; - ret["titles"] = titles; - ret["unachieved_descriptions"] = unachieved_descriptions; - ret["achieved_descriptions"] = achieved_descriptions; - ret["maximum_points"] = maximum_points; - ret["hidden"] = hidden; - ret["replayable"] = replayable; - - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - }; - - pending_events.push_back(ret); - }]; -}; - -void GameCenter::request_achievements() { - [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) { - Dictionary ret; - ret["type"] = "achievements"; - if (error == nil) { - ret["result"] = "ok"; - PackedStringArray names; - PackedFloat32Array percentages; - - for (NSUInteger i = 0; i < [achievements count]; i++) { - GKAchievement *achievement = [achievements objectAtIndex:i]; - const char *str = [achievement.identifier UTF8String]; - names.push_back(String::utf8(str != NULL ? str : "")); - - percentages.push_back(achievement.percentComplete); - } - - ret["names"] = names; - ret["progress"] = percentages; - - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - }; - - pending_events.push_back(ret); - }]; -}; - -void GameCenter::reset_achievements() { - [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) { - Dictionary ret; - ret["type"] = "reset_achievements"; - if (error == nil) { - ret["result"] = "ok"; - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - }; - - pending_events.push_back(ret); - }]; -}; - -Error GameCenter::show_game_center(Dictionary p_params) { - ERR_FAIL_COND_V(!NSProtocolFromString(@"GKGameCenterControllerDelegate"), FAILED); - - GKGameCenterViewControllerState view_state = GKGameCenterViewControllerStateDefault; - if (p_params.has("view")) { - String view_name = p_params["view"]; - if (view_name == "default") { - view_state = GKGameCenterViewControllerStateDefault; - } else if (view_name == "leaderboards") { - view_state = GKGameCenterViewControllerStateLeaderboards; - } else if (view_name == "achievements") { - view_state = GKGameCenterViewControllerStateAchievements; - } else if (view_name == "challenges") { - view_state = GKGameCenterViewControllerStateChallenges; - } else { - return ERR_INVALID_PARAMETER; - } - } - - GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init]; - ERR_FAIL_COND_V(!controller, FAILED); - - UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController; - ERR_FAIL_COND_V(!root_controller, FAILED); - - controller.gameCenterDelegate = gameCenterDelegate; - controller.viewState = view_state; - if (view_state == GKGameCenterViewControllerStateLeaderboards) { - controller.leaderboardIdentifier = nil; - if (p_params.has("leaderboard_name")) { - String name = p_params["leaderboard_name"]; - NSString *name_str = [[NSString alloc] initWithUTF8String:name.utf8().get_data()]; - controller.leaderboardIdentifier = name_str; - } - } - - [root_controller presentViewController:controller animated:YES completion:nil]; - - return OK; -}; - -Error GameCenter::request_identity_verification_signature() { - ERR_FAIL_COND_V(!is_authenticated(), ERR_UNAUTHORIZED); - - GKLocalPlayer *player = [GKLocalPlayer localPlayer]; - [player generateIdentityVerificationSignatureWithCompletionHandler:^(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error) { - Dictionary ret; - ret["type"] = "identity_verification_signature"; - if (error == nil) { - ret["result"] = "ok"; - ret["public_key_url"] = [publicKeyUrl.absoluteString UTF8String]; - ret["signature"] = [[signature base64EncodedStringWithOptions:0] UTF8String]; - ret["salt"] = [[salt base64EncodedStringWithOptions:0] UTF8String]; - ret["timestamp"] = timestamp; - if (@available(iOS 13, *)) { - ret["player_id"] = [player.teamPlayerID UTF8String]; -#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR - } else { - ret["player_id"] = [player.playerID UTF8String]; -#endif - } - } else { - ret["result"] = "error"; - ret["error_code"] = (int64_t)error.code; - ret["error_description"] = [error.localizedDescription UTF8String]; - }; - - pending_events.push_back(ret); - }]; - - return OK; -}; - -void GameCenter::game_center_closed() { - Dictionary ret; - ret["type"] = "show_game_center"; - ret["result"] = "ok"; - pending_events.push_back(ret); -} - -int GameCenter::get_pending_event_count() { - return pending_events.size(); -}; - -Variant GameCenter::pop_pending_event() { - Variant front = pending_events.front()->get(); - pending_events.pop_front(); - - return front; -}; - -GameCenter *GameCenter::get_singleton() { - return instance; -}; - -GameCenter::GameCenter() { - ERR_FAIL_COND(instance != NULL); - instance = this; - authenticated = false; - - gameCenterDelegate = [[GodotGameCenterDelegate alloc] init]; -}; - -GameCenter::~GameCenter() { - if (gameCenterDelegate) { - gameCenterDelegate = nil; - } -} diff --git a/modules/gamecenter/game_center_delegate.h b/modules/gamecenter/game_center_delegate.h deleted file mode 100644 index ef1d2ae93d..0000000000 --- a/modules/gamecenter/game_center_delegate.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************/ -/* game_center_delegate.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#import <GameKit/GameKit.h> - -@interface GodotGameCenterDelegate : NSObject <GKGameCenterControllerDelegate> - -@end diff --git a/modules/gamecenter/game_center_delegate.mm b/modules/gamecenter/game_center_delegate.mm deleted file mode 100644 index 6e20db572b..0000000000 --- a/modules/gamecenter/game_center_delegate.mm +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************/ -/* game_center_delegate.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#import "game_center_delegate.h" - -#include "game_center.h" - -@implementation GodotGameCenterDelegate - -- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { - //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone - if (GameCenter::get_singleton()) { - GameCenter::get_singleton()->game_center_closed(); - } - [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; -} - -@end diff --git a/modules/gamecenter/game_center_module.h b/modules/gamecenter/game_center_module.h deleted file mode 100644 index 5df3645b1c..0000000000 --- a/modules/gamecenter/game_center_module.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************/ -/* game_center_module.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -void register_gamecenter_types(); -void unregister_gamecenter_types(); diff --git a/modules/gamecenter/gamecenter.gdip b/modules/gamecenter/gamecenter.gdip deleted file mode 100644 index eb44effbdd..0000000000 --- a/modules/gamecenter/gamecenter.gdip +++ /dev/null @@ -1,17 +0,0 @@ -[config] -name="GameCenter" -binary="gamecenter_lib.a" - -initialization="register_gamecenter_types" -deinitialization="unregister_gamecenter_types" - -[dependencies] -linked=[] -embedded=[] -system=["GameKit.framework"] - -capabilities=["gamekit"] - -files=[] - -[plist] diff --git a/modules/gdnative/android/android_gdn.cpp b/modules/gdnative/android/android_gdn.cpp index a48e51a390..fe3b3e7e12 100644 --- a/modules/gdnative/android/android_gdn.cpp +++ b/modules/gdnative/android/android_gdn.cpp @@ -48,7 +48,7 @@ extern "C" { JNIEnv *GDAPI godot_android_get_env() { #ifdef __ANDROID__ - return ThreadAndroid::get_env(); + return get_jni_env(); #else return nullptr; #endif diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index e3a359e09a..86bd8b820d 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -110,6 +110,16 @@ bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const return false; } +void GDNativeLibrary::reset_state() { + config_file.instance(); + current_library_path = ""; + current_dependencies.clear(); + symbol_prefix = default_symbol_prefix; + load_once = default_load_once; + singleton = default_singleton; + reloadable = default_reloadable; +} + void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { // set entries List<String> entry_key_list; @@ -508,7 +518,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_ return result; } -RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<GDNativeLibrary> lib; lib.instance(); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 765087d176..a28c58ec0d 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -63,6 +63,8 @@ class GDNativeLibrary : public Resource { bool reloadable; public: + virtual void reset_state() override; + GDNativeLibrary(); ~GDNativeLibrary(); @@ -166,7 +168,7 @@ public: class GDNativeLibraryResourceLoader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/gdnative/aabb.cpp b/modules/gdnative/gdnative/aabb.cpp index 41b5029ef4..5d3f224adc 100644 --- a/modules/gdnative/gdnative/aabb.cpp +++ b/modules/gdnative/gdnative/aabb.cpp @@ -31,195 +31,15 @@ #include "gdnative/aabb.h" #include "core/math/aabb.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_aabb) == sizeof(AABB), "AABB size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_aabb) == sizeof(AABB), "AABB size mismatch"); - -void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) { - const Vector3 *pos = (const Vector3 *)p_pos; - const Vector3 *size = (const Vector3 *)p_size; - AABB *dest = (AABB *)r_dest; - *dest = AABB(*pos, *size); -} - -godot_vector3 GDAPI godot_aabb_get_position(const godot_aabb *p_self) { - godot_vector3 raw_ret; - const AABB *self = (const AABB *)p_self; - Vector3 *ret = (Vector3 *)&raw_ret; - *ret = self->position; - return raw_ret; -} - -void GDAPI godot_aabb_set_position(const godot_aabb *p_self, const godot_vector3 *p_v) { - AABB *self = (AABB *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - self->position = *v; -} - -godot_vector3 GDAPI godot_aabb_get_size(const godot_aabb *p_self) { - godot_vector3 raw_ret; - const AABB *self = (const AABB *)p_self; - Vector3 *ret = (Vector3 *)&raw_ret; - *ret = self->size; - return raw_ret; -} - -void GDAPI godot_aabb_set_size(const godot_aabb *p_self, const godot_vector3 *p_v) { - AABB *self = (AABB *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - self->size = *v; -} - -godot_string GDAPI godot_aabb_as_string(const godot_aabb *p_self) { - godot_string ret; - const AABB *self = (const AABB *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_aabb GDAPI godot_aabb_abs(const godot_aabb *p_self) { - godot_aabb dest; - const AABB *self = (const AABB *)p_self; - *((AABB *)&dest) = self->abs(); - return dest; -} - -godot_real GDAPI godot_aabb_get_area(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->get_area(); -} - -godot_bool GDAPI godot_aabb_has_no_area(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->has_no_area(); -} - -godot_bool GDAPI godot_aabb_has_no_surface(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->has_no_surface(); -} - -godot_bool GDAPI godot_aabb_intersects(const godot_aabb *p_self, const godot_aabb *p_with) { - const AABB *self = (const AABB *)p_self; - const AABB *with = (const AABB *)p_with; - return self->intersects(*with); -} - -godot_bool GDAPI godot_aabb_encloses(const godot_aabb *p_self, const godot_aabb *p_with) { - const AABB *self = (const AABB *)p_self; - const AABB *with = (const AABB *)p_with; - return self->encloses(*with); -} - -godot_aabb GDAPI godot_aabb_merge(const godot_aabb *p_self, const godot_aabb *p_with) { - godot_aabb dest; - const AABB *self = (const AABB *)p_self; - const AABB *with = (const AABB *)p_with; - *((AABB *)&dest) = self->merge(*with); - return dest; -} - -godot_aabb GDAPI godot_aabb_intersection(const godot_aabb *p_self, const godot_aabb *p_with) { - godot_aabb dest; - const AABB *self = (const AABB *)p_self; - const AABB *with = (const AABB *)p_with; - *((AABB *)&dest) = self->intersection(*with); - return dest; -} - -godot_bool GDAPI godot_aabb_intersects_plane(const godot_aabb *p_self, const godot_plane *p_plane) { - const AABB *self = (const AABB *)p_self; - const Plane *plane = (const Plane *)p_plane; - return self->intersects_plane(*plane); -} - -godot_bool GDAPI godot_aabb_intersects_segment(const godot_aabb *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to) { - const AABB *self = (const AABB *)p_self; - const Vector3 *from = (const Vector3 *)p_from; - const Vector3 *to = (const Vector3 *)p_to; - return self->intersects_segment(*from, *to); -} - -godot_bool GDAPI godot_aabb_has_point(const godot_aabb *p_self, const godot_vector3 *p_point) { - const AABB *self = (const AABB *)p_self; - const Vector3 *point = (const Vector3 *)p_point; - return self->has_point(*point); -} - -godot_vector3 GDAPI godot_aabb_get_support(const godot_aabb *p_self, const godot_vector3 *p_dir) { - godot_vector3 dest; - const AABB *self = (const AABB *)p_self; - const Vector3 *dir = (const Vector3 *)p_dir; - *((Vector3 *)&dest) = self->get_support(*dir); - return dest; -} - -godot_vector3 GDAPI godot_aabb_get_longest_axis(const godot_aabb *p_self) { - godot_vector3 dest; - const AABB *self = (const AABB *)p_self; - *((Vector3 *)&dest) = self->get_longest_axis(); - return dest; -} - -godot_int GDAPI godot_aabb_get_longest_axis_index(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->get_longest_axis_index(); -} - -godot_real GDAPI godot_aabb_get_longest_axis_size(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->get_longest_axis_size(); -} - -godot_vector3 GDAPI godot_aabb_get_shortest_axis(const godot_aabb *p_self) { - godot_vector3 dest; - const AABB *self = (const AABB *)p_self; - *((Vector3 *)&dest) = self->get_shortest_axis(); - return dest; -} - -godot_int GDAPI godot_aabb_get_shortest_axis_index(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->get_shortest_axis_index(); -} - -godot_real GDAPI godot_aabb_get_shortest_axis_size(const godot_aabb *p_self) { - const AABB *self = (const AABB *)p_self; - return self->get_shortest_axis_size(); -} - -godot_aabb GDAPI godot_aabb_expand(const godot_aabb *p_self, const godot_vector3 *p_to_point) { - godot_aabb dest; - const AABB *self = (const AABB *)p_self; - const Vector3 *to_point = (const Vector3 *)p_to_point; - *((AABB *)&dest) = self->expand(*to_point); - return dest; -} - -godot_aabb GDAPI godot_aabb_grow(const godot_aabb *p_self, const godot_real p_by) { - godot_aabb dest; - const AABB *self = (const AABB *)p_self; - - *((AABB *)&dest) = self->grow(p_by); - return dest; -} - -godot_vector3 GDAPI godot_aabb_get_endpoint(const godot_aabb *p_self, const godot_int p_idx) { - godot_vector3 dest; - const AABB *self = (const AABB *)p_self; - - *((Vector3 *)&dest) = self->get_endpoint(p_idx); - return dest; -} - -godot_bool GDAPI godot_aabb_operator_equal(const godot_aabb *p_self, const godot_aabb *p_b) { - const AABB *self = (const AABB *)p_self; - const AABB *b = (const AABB *)p_b; - return *self == *b; +void GDAPI godot_aabb_new(godot_aabb *p_self) { + memnew_placement(p_self, AABB); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 7099b9d459..e68b60c5e6 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -33,367 +33,28 @@ #include "core/os/memory.h" #include "core/variant/array.h" -#include "core/math/color.h" - -#include "core/variant/variant.h" +static_assert(sizeof(godot_array) == sizeof(Array), "Array size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_array) == sizeof(Array), "Array size mismatch"); - -void GDAPI godot_array_new(godot_array *r_dest) { - Array *dest = (Array *)r_dest; - memnew_placement(dest, Array); -} - -void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src) { - Array *dest = (Array *)r_dest; - const Array *src = (const Array *)p_src; - memnew_placement(dest, Array(*src)); -} - -void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_packed_color_array *p_pca) { - Array *dest = (Array *)r_dest; - Vector<Color> *pca = (Vector<Color> *)p_pca; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a) { - Array *dest = (Array *)r_dest; - Vector<Vector3> *pca = (Vector<Vector3> *)p_pv3a; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a) { - Array *dest = (Array *)r_dest; - Vector<Vector2> *pca = (Vector<Vector2> *)p_pv2a; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_vector2i_array(godot_array *r_dest, const godot_packed_vector2i_array *p_pv2a) { - Array *dest = (Array *)r_dest; - Vector<Vector2i> *pca = (Vector<Vector2i> *)p_pv2a; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa) { - Array *dest = (Array *)r_dest; - Vector<String> *pca = (Vector<String> *)p_psa; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_float32_array(godot_array *r_dest, const godot_packed_float32_array *p_pra) { - Array *dest = (Array *)r_dest; - Vector<float> *pca = (Vector<float> *)p_pra; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_float64_array(godot_array *r_dest, const godot_packed_float64_array *p_pra) { - Array *dest = (Array *)r_dest; - Vector<double> *pca = (Vector<double> *)p_pra; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_int32_array(godot_array *r_dest, const godot_packed_int32_array *p_pia) { - Array *dest = (Array *)r_dest; - Vector<int32_t> *pca = (Vector<int32_t> *)p_pia; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_int64_array(godot_array *r_dest, const godot_packed_int64_array *p_pia) { - Array *dest = (Array *)r_dest; - Vector<int64_t> *pca = (Vector<int64_t> *)p_pia; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba) { - Array *dest = (Array *)r_dest; - Vector<uint8_t> *pca = (Vector<uint8_t> *)p_pba; - memnew_placement(dest, Array); - dest->resize(pca->size()); - - for (int i = 0; i < dest->size(); i++) { - Variant v = pca->operator[](i); - dest->operator[](i) = v; - } -} - -void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value) { - Array *self = (Array *)p_self; - Variant *val = (Variant *)p_value; - self->operator[](p_idx) = *val; -} - -godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx) { - godot_variant raw_dest; - Variant *dest = (Variant *)&raw_dest; - const Array *self = (const Array *)p_self; - memnew_placement(dest, Variant(self->operator[](p_idx))); - return raw_dest; -} - -godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx) { - Array *self = (Array *)p_self; - return (godot_variant *)&self->operator[](p_idx); -} - -const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx) { - const Array *self = (const Array *)p_self; - return (const godot_variant *)&self->operator[](p_idx); -} - -void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value) { - Array *self = (Array *)p_self; - Variant *val = (Variant *)p_value; - self->append(*val); -} - -void GDAPI godot_array_clear(godot_array *p_self) { - Array *self = (Array *)p_self; - self->clear(); -} - -godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value) { - const Array *self = (const Array *)p_self; - const Variant *val = (const Variant *)p_value; - return self->count(*val); -} - -godot_bool GDAPI godot_array_is_empty(const godot_array *p_self) { - const Array *self = (const Array *)p_self; - return self->is_empty(); -} - -void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value) { - Array *self = (Array *)p_self; - const Variant *val = (const Variant *)p_value; - self->erase(*val); -} - -godot_variant GDAPI godot_array_front(const godot_array *p_self) { - const Array *self = (const Array *)p_self; - godot_variant v; - Variant *val = (Variant *)&v; - memnew_placement(val, Variant); - *val = self->front(); - return v; -} - -godot_variant GDAPI godot_array_back(const godot_array *p_self) { - const Array *self = (const Array *)p_self; - godot_variant v; - Variant *val = (Variant *)&v; - memnew_placement(val, Variant); - *val = self->back(); - return v; -} - -godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) { - const Array *self = (const Array *)p_self; - const Variant *val = (const Variant *)p_what; - return self->find(*val, p_from); -} - -godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what) { - const Array *self = (const Array *)p_self; - const Variant *val = (const Variant *)p_what; - return self->find_last(*val); -} - -godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value) { - const Array *self = (const Array *)p_self; - const Variant *val = (const Variant *)p_value; - return self->has(*val); -} - -godot_int GDAPI godot_array_hash(const godot_array *p_self) { - const Array *self = (const Array *)p_self; - return self->hash(); -} - -void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value) { - Array *self = (Array *)p_self; - const Variant *val = (const Variant *)p_value; - self->insert(p_pos, *val); -} - -void GDAPI godot_array_invert(godot_array *p_self) { - Array *self = (Array *)p_self; - self->invert(); -} - -godot_variant GDAPI godot_array_pop_back(godot_array *p_self) { - Array *self = (Array *)p_self; - godot_variant v; - Variant *val = (Variant *)&v; - memnew_placement(val, Variant); - *val = self->pop_back(); - return v; -} - -godot_variant GDAPI godot_array_pop_front(godot_array *p_self) { - Array *self = (Array *)p_self; - godot_variant v; - Variant *val = (Variant *)&v; - memnew_placement(val, Variant); - *val = self->pop_front(); - return v; -} - -void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value) { - Array *self = (Array *)p_self; - const Variant *val = (const Variant *)p_value; - self->push_back(*val); -} - -void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value) { - Array *self = (Array *)p_self; - const Variant *val = (const Variant *)p_value; - self->push_front(*val); -} - -void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx) { - Array *self = (Array *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size) { - Array *self = (Array *)p_self; - self->resize(p_size); -} - -godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) { - const Array *self = (const Array *)p_self; - const Variant *val = (const Variant *)p_what; - return self->rfind(*val, p_from); -} - -godot_int GDAPI godot_array_size(const godot_array *p_self) { - const Array *self = (const Array *)p_self; - return self->size(); -} - -void GDAPI godot_array_sort(godot_array *p_self) { - Array *self = (Array *)p_self; - self->sort(); -} - -void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func) { - Array *self = (Array *)p_self; - const String *func = (const String *)p_func; - self->sort_custom((Object *)p_obj, *func); -} - -godot_int GDAPI godot_array_bsearch(godot_array *p_self, const godot_variant *p_value, const godot_bool p_before) { - Array *self = (Array *)p_self; - return self->bsearch(*(const Variant *)p_value, p_before); -} - -godot_int GDAPI godot_array_bsearch_custom(godot_array *p_self, const godot_variant *p_value, godot_object *p_obj, const godot_string *p_func, const godot_bool p_before) { - Array *self = (Array *)p_self; - const String *func = (const String *)p_func; - return self->bsearch_custom(*(const Variant *)p_value, (Object *)p_obj, *func, p_before); +void GDAPI godot_array_new(godot_array *p_self) { + memnew_placement(p_self, Array); } void GDAPI godot_array_destroy(godot_array *p_self) { ((Array *)p_self)->~Array(); } -godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep) { - const Array *self = (const Array *)p_self; - godot_array res; - Array *val = (Array *)&res; - memnew_placement(val, Array); - *val = self->duplicate(p_deep); - return res; -} - -godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep) { - const Array *self = (const Array *)p_self; - godot_array res; - Array *val = (Array *)&res; - memnew_placement(val, Array); - *val = self->slice(p_begin, p_end, p_step, p_deep); - return res; -} - -godot_variant GDAPI godot_array_max(const godot_array *p_self) { - const Array *self = (const Array *)p_self; - godot_variant v; - Variant *val = (Variant *)&v; - memnew_placement(val, Variant); - *val = self->max(); - return v; +godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, godot_int p_index) { + Array *self = (Array *)p_self; + return (godot_variant *)&self->operator[](p_index); } -godot_variant GDAPI godot_array_min(const godot_array *p_self) { +const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, godot_int p_index) { const Array *self = (const Array *)p_self; - godot_variant v; - Variant *val = (Variant *)&v; - memnew_placement(val, Variant); - *val = self->min(); - return v; -} - -void GDAPI godot_array_shuffle(godot_array *p_self) { - Array *self = (Array *)p_self; - self->shuffle(); + return (const godot_variant *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index bfcd9bbf2c..df3e1255ac 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -31,266 +31,25 @@ #include "gdnative/basis.h" #include "core/math/basis.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_basis) == sizeof(Basis), "Basis size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_basis) == sizeof(Basis), "Basis size mismatch"); - -void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis) { - const Vector3 *x_axis = (const Vector3 *)p_x_axis; - const Vector3 *y_axis = (const Vector3 *)p_y_axis; - const Vector3 *z_axis = (const Vector3 *)p_z_axis; - Basis *dest = (Basis *)r_dest; - *dest = Basis(*x_axis, *y_axis, *z_axis); -} - -void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi) { - const Vector3 *axis = (const Vector3 *)p_axis; - Basis *dest = (Basis *)r_dest; - *dest = Basis(*axis, p_phi); -} - -void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler) { - const Vector3 *euler = (const Vector3 *)p_euler; - Basis *dest = (Basis *)r_dest; - *dest = Basis(*euler); -} - -godot_string GDAPI godot_basis_as_string(const godot_basis *p_self) { - godot_string ret; - const Basis *self = (const Basis *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_basis GDAPI godot_basis_inverse(const godot_basis *p_self) { - godot_basis dest; - const Basis *self = (const Basis *)p_self; - *((Basis *)&dest) = self->inverse(); - return dest; -} - -godot_basis GDAPI godot_basis_transposed(const godot_basis *p_self) { - godot_basis dest; - const Basis *self = (const Basis *)p_self; - *((Basis *)&dest) = self->transposed(); - return dest; -} - -godot_basis GDAPI godot_basis_orthonormalized(const godot_basis *p_self) { - godot_basis dest; - const Basis *self = (const Basis *)p_self; - *((Basis *)&dest) = self->orthonormalized(); - return dest; -} - -godot_real GDAPI godot_basis_determinant(const godot_basis *p_self) { - const Basis *self = (const Basis *)p_self; - return self->determinant(); -} - -godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_phi) { - godot_basis dest; - const Basis *self = (const Basis *)p_self; - const Vector3 *axis = (const Vector3 *)p_axis; - *((Basis *)&dest) = self->rotated(*axis, p_phi); - return dest; -} - -godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale) { - godot_basis dest; - const Basis *self = (const Basis *)p_self; - const Vector3 *scale = (const Vector3 *)p_scale; - *((Basis *)&dest) = self->scaled(*scale); - return dest; -} - -godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self) { - godot_vector3 dest; - const Basis *self = (const Basis *)p_self; - *((Vector3 *)&dest) = self->get_scale(); - return dest; -} - -godot_quat GDAPI godot_basis_get_quat(const godot_basis *p_self) { - godot_quat dest; - const Basis *self = (const Basis *)p_self; - *((Quat *)&dest) = self->get_quat(); - return dest; -} - -void GDAPI godot_basis_set_quat(godot_basis *p_self, const godot_quat *p_quat) { - Basis *self = (Basis *)p_self; - const Quat *quat = (const Quat *)p_quat; - self->set_quat(*quat); +void GDAPI godot_basis_new(godot_basis *p_self) { + memnew_placement(p_self, Basis); } -void GDAPI godot_basis_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale) { +godot_vector3 GDAPI *godot_basis_operator_index(godot_basis *p_self, godot_int p_index) { Basis *self = (Basis *)p_self; - const Vector3 *axis = (const Vector3 *)p_axis; - const Vector3 *scale = (const Vector3 *)p_scale; - self->set_axis_angle_scale(*axis, p_phi, *scale); -} - -void GDAPI godot_basis_set_euler_scale(godot_basis *p_self, const godot_vector3 *p_euler, const godot_vector3 *p_scale) { - Basis *self = (Basis *)p_self; - const Vector3 *euler = (const Vector3 *)p_euler; - const Vector3 *scale = (const Vector3 *)p_scale; - self->set_euler_scale(*euler, *scale); -} - -void GDAPI godot_basis_set_quat_scale(godot_basis *p_self, const godot_quat *p_quat, const godot_vector3 *p_scale) { - Basis *self = (Basis *)p_self; - const Quat *quat = (const Quat *)p_quat; - const Vector3 *scale = (const Vector3 *)p_scale; - self->set_quat_scale(*quat, *scale); -} - -godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self) { - godot_vector3 dest; - const Basis *self = (const Basis *)p_self; - *((Vector3 *)&dest) = self->get_euler(); - return dest; -} - -godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with) { - const Basis *self = (const Basis *)p_self; - const Vector3 *with = (const Vector3 *)p_with; - return self->tdotx(*with); -} - -godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with) { - const Basis *self = (const Basis *)p_self; - const Vector3 *with = (const Vector3 *)p_with; - return self->tdoty(*with); -} - -godot_real GDAPI godot_basis_tdotz(const godot_basis *p_self, const godot_vector3 *p_with) { - const Basis *self = (const Basis *)p_self; - const Vector3 *with = (const Vector3 *)p_with; - return self->tdotz(*with); -} - -godot_vector3 GDAPI godot_basis_xform(const godot_basis *p_self, const godot_vector3 *p_v) { - godot_vector3 dest; - const Basis *self = (const Basis *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - *((Vector3 *)&dest) = self->xform(*v); - return dest; -} - -godot_vector3 GDAPI godot_basis_xform_inv(const godot_basis *p_self, const godot_vector3 *p_v) { - godot_vector3 dest; - const Basis *self = (const Basis *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - *((Vector3 *)&dest) = self->xform_inv(*v); - return dest; -} - -godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self) { - const Basis *self = (const Basis *)p_self; - return self->get_orthogonal_index(); -} - -void GDAPI godot_basis_new(godot_basis *r_dest) { - Basis *dest = (Basis *)r_dest; - *dest = Basis(); -} - -void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler) { - Basis *dest = (Basis *)r_dest; - const Quat *euler = (const Quat *)p_euler; - *dest = Basis(*euler); -} - -// p_elements is a pointer to an array of 3 (!!) vector3 -void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements) { - const Basis *self = (const Basis *)p_self; - Vector3 *elements = (Vector3 *)p_elements; - elements[0] = self->elements[0]; - elements[1] = self->elements[1]; - elements[2] = self->elements[2]; -} - -godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis) { - godot_vector3 dest; - Vector3 *d = (Vector3 *)&dest; - const Basis *self = (const Basis *)p_self; - *d = self->get_axis(p_axis); - return dest; -} - -void GDAPI godot_basis_set_axis(godot_basis *p_self, const godot_int p_axis, const godot_vector3 *p_value) { - Basis *self = (Basis *)p_self; - const Vector3 *value = (const Vector3 *)p_value; - self->set_axis(p_axis, *value); -} - -godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_self, const godot_int p_row) { - godot_vector3 dest; - Vector3 *d = (Vector3 *)&dest; - const Basis *self = (const Basis *)p_self; - *d = self->get_row(p_row); - return dest; -} - -void GDAPI godot_basis_set_row(godot_basis *p_self, const godot_int p_row, const godot_vector3 *p_value) { - Basis *self = (Basis *)p_self; - const Vector3 *value = (const Vector3 *)p_value; - self->set_row(p_row, *value); -} - -godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const godot_basis *p_b) { - const Basis *self = (const Basis *)p_self; - const Basis *b = (const Basis *)p_b; - return *self == *b; -} - -godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b) { - godot_basis raw_dest; - Basis *dest = (Basis *)&raw_dest; - const Basis *self = (const Basis *)p_self; - const Basis *b = (const Basis *)p_b; - *dest = *self + *b; - return raw_dest; -} - -godot_basis GDAPI godot_basis_operator_subtract(const godot_basis *p_self, const godot_basis *p_b) { - godot_basis raw_dest; - Basis *dest = (Basis *)&raw_dest; - const Basis *self = (const Basis *)p_self; - const Basis *b = (const Basis *)p_b; - *dest = *self - *b; - return raw_dest; -} - -godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b) { - godot_basis raw_dest; - Basis *dest = (Basis *)&raw_dest; - const Basis *self = (const Basis *)p_self; - const Basis *b = (const Basis *)p_b; - *dest = *self * *b; - return raw_dest; -} - -godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b) { - godot_basis raw_dest; - Basis *dest = (Basis *)&raw_dest; - const Basis *self = (const Basis *)p_self; - *dest = *self * p_b; - return raw_dest; + return (godot_vector3 *)&self->operator[](p_index); } -godot_basis GDAPI godot_basis_slerp(const godot_basis *p_self, const godot_basis *p_b, const godot_real p_t) { - godot_basis raw_dest; - Basis *dest = (Basis *)&raw_dest; +const godot_vector3 GDAPI *godot_basis_operator_index_const(const godot_basis *p_self, godot_int p_index) { const Basis *self = (const Basis *)p_self; - const Basis *b = (const Basis *)p_b; - *dest = self->slerp(*b, p_t); - return raw_dest; + return (const godot_vector3 *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/callable.cpp b/modules/gdnative/gdnative/callable.cpp index d4730a14b3..7c62b5928f 100644 --- a/modules/gdnative/gdnative/callable.cpp +++ b/modules/gdnative/gdnative/callable.cpp @@ -30,36 +30,17 @@ #include "gdnative/callable.h" -#include "core/io/resource.h" #include "core/variant/callable.h" #include "core/variant/variant.h" +static_assert(sizeof(godot_callable) == sizeof(Callable), "Callable size mismatch"); + #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_callable) == sizeof(Callable), "Callable size mismatch"); -static_assert(sizeof(godot_signal) == sizeof(Signal), "Signal size mismatch"); - -// Callable - -void GDAPI godot_callable_new_with_object(godot_callable *r_dest, const godot_object *p_object, const godot_string_name *p_method) { - Callable *dest = (Callable *)r_dest; - const Object *object = (const Object *)p_object; - const StringName *method = (const StringName *)p_method; - memnew_placement(dest, Callable(object, *method)); -} - -void GDAPI godot_callable_new_with_object_id(godot_callable *r_dest, uint64_t p_objectid, const godot_string_name *p_method) { - Callable *dest = (Callable *)r_dest; - const StringName *method = (const StringName *)p_method; - memnew_placement(dest, Callable(ObjectID(p_objectid), *method)); -} - -void GDAPI godot_callable_new_copy(godot_callable *r_dest, const godot_callable *p_src) { - Callable *dest = (Callable *)r_dest; - const Callable *src = (const Callable *)p_src; - memnew_placement(dest, Callable(*src)); +void GDAPI godot_callable_new(godot_callable *p_self) { + memnew_placement(p_self, Callable); } void GDAPI godot_callable_destroy(godot_callable *p_self) { @@ -67,186 +48,6 @@ void GDAPI godot_callable_destroy(godot_callable *p_self) { self->~Callable(); } -godot_int GDAPI godot_callable_call(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount, godot_variant *r_return_value) { - const Callable *self = (const Callable *)p_self; - const Variant **arguments = (const Variant **)p_arguments; - Variant *return_value = (Variant *)r_return_value; - Variant ret; - Callable::CallError err; - self->call(arguments, p_argcount, ret, err); - if (return_value) - (*return_value) = ret; - return (godot_int)err.error; -} - -void GDAPI godot_callable_call_deferred(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount) { - const Callable *self = (const Callable *)p_self; - const Variant **arguments = (const Variant **)p_arguments; - self->call_deferred(arguments, p_argcount); -} - -godot_bool GDAPI godot_callable_is_null(const godot_callable *p_self) { - const Callable *self = (const Callable *)p_self; - return self->is_null(); -} - -godot_bool GDAPI godot_callable_is_custom(const godot_callable *p_self) { - const Callable *self = (const Callable *)p_self; - return self->is_custom(); -} - -godot_bool GDAPI godot_callable_is_standard(const godot_callable *p_self) { - const Callable *self = (const Callable *)p_self; - return self->is_standard(); -} - -godot_object GDAPI *godot_callable_get_object(const godot_callable *p_self) { - const Callable *self = (const Callable *)p_self; - return (godot_object *)self->get_object(); -} - -uint64_t GDAPI godot_callable_get_object_id(const godot_callable *p_self) { - const Callable *self = (const Callable *)p_self; - return (uint64_t)self->get_object_id(); -} - -godot_string_name GDAPI godot_callable_get_method(const godot_callable *p_self) { - godot_string_name raw_dest; - const Callable *self = (const Callable *)p_self; - StringName *dest = (StringName *)&raw_dest; - memnew_placement(dest, StringName(self->get_method())); - return raw_dest; -} - -uint32_t GDAPI godot_callable_hash(const godot_callable *p_self) { - const Callable *self = (const Callable *)p_self; - return self->hash(); -} - -godot_string GDAPI godot_callable_as_string(const godot_callable *p_self) { - godot_string ret; - const Callable *self = (const Callable *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_bool GDAPI godot_callable_operator_equal(const godot_callable *p_self, const godot_callable *p_other) { - const Callable *self = (const Callable *)p_self; - const Callable *other = (const Callable *)p_other; - return *self == *other; -} - -godot_bool GDAPI godot_callable_operator_less(const godot_callable *p_self, const godot_callable *p_other) { - const Callable *self = (const Callable *)p_self; - const Callable *other = (const Callable *)p_other; - return *self < *other; -} - -// Signal - -void GDAPI godot_signal_new_with_object(godot_signal *r_dest, const godot_object *p_object, const godot_string_name *p_name) { - Signal *dest = (Signal *)r_dest; - const Object *object = (const Object *)p_object; - const StringName *name = (const StringName *)p_name; - memnew_placement(dest, Signal(object, *name)); -} - -void GDAPI godot_signal_new_with_object_id(godot_signal *r_dest, uint64_t p_objectid, const godot_string_name *p_name) { - Signal *dest = (Signal *)r_dest; - const StringName *name = (const StringName *)p_name; - memnew_placement(dest, Signal(ObjectID(p_objectid), *name)); -} - -void GDAPI godot_signal_new_copy(godot_signal *r_dest, const godot_signal *p_src) { - Signal *dest = (Signal *)r_dest; - const Signal *src = (const Signal *)p_src; - memnew_placement(dest, Signal(*src)); -} - -void GDAPI godot_signal_destroy(godot_signal *p_self) { - Signal *self = (Signal *)p_self; - self->~Signal(); -} - -godot_int GDAPI godot_signal_emit(const godot_signal *p_self, const godot_variant **p_arguments, godot_int p_argcount) { - const Signal *self = (const Signal *)p_self; - const Variant **arguments = (const Variant **)p_arguments; - return (godot_int)self->emit(arguments, p_argcount); -} - -godot_int GDAPI godot_signal_connect(godot_signal *p_self, const godot_callable *p_callable, const godot_array *p_binds, uint32_t p_flags) { - Signal *self = (Signal *)p_self; - const Callable *callable = (const Callable *)p_callable; - const Array *binds_ar = (const Array *)p_binds; - Vector<Variant> binds; - for (int i = 0; i < binds_ar->size(); i++) { - binds.push_back(binds_ar->get(i)); - } - return (godot_int)self->connect(*callable, binds, p_flags); -} - -void GDAPI godot_signal_disconnect(godot_signal *p_self, const godot_callable *p_callable) { - Signal *self = (Signal *)p_self; - const Callable *callable = (const Callable *)p_callable; - self->disconnect(*callable); -} - -godot_bool GDAPI godot_signal_is_null(const godot_signal *p_self) { - const Signal *self = (const Signal *)p_self; - return self->is_null(); -} - -godot_bool GDAPI godot_signal_is_connected(const godot_signal *p_self, const godot_callable *p_callable) { - const Signal *self = (const Signal *)p_self; - const Callable *callable = (const Callable *)p_callable; - return self->is_connected(*callable); -} - -godot_array GDAPI godot_signal_get_connections(const godot_signal *p_self) { - godot_array raw_dest; - const Signal *self = (const Signal *)p_self; - Array *dest = (Array *)&raw_dest; - memnew_placement(dest, Array(self->get_connections())); - return raw_dest; -} - -godot_object GDAPI *godot_signal_get_object(const godot_signal *p_self) { - const Signal *self = (const Signal *)p_self; - return (godot_object *)self->get_object(); -} - -uint64_t GDAPI godot_signal_get_object_id(const godot_signal *p_self) { - const Signal *self = (const Signal *)p_self; - return (uint64_t)self->get_object_id(); -} - -godot_string_name GDAPI godot_signal_get_name(const godot_signal *p_self) { - godot_string_name raw_dest; - const Signal *self = (const Signal *)p_self; - StringName *dest = (StringName *)&raw_dest; - memnew_placement(dest, StringName(self->get_name())); - return raw_dest; -} - -godot_string GDAPI godot_signal_as_string(const godot_signal *p_self) { - godot_string ret; - const Signal *self = (const Signal *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_bool GDAPI godot_signal_operator_equal(const godot_signal *p_self, const godot_signal *p_other) { - const Signal *self = (const Signal *)p_self; - const Signal *other = (const Signal *)p_other; - return *self == *other; -} - -godot_bool GDAPI godot_signal_operator_less(const godot_signal *p_self, const godot_signal *p_other) { - const Signal *self = (const Signal *)p_self; - const Signal *other = (const Signal *)p_other; - return *self < *other; -} - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp index 939dec3a47..12a800d333 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -31,178 +31,25 @@ #include "gdnative/color.h" #include "core/math/color.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_color) == sizeof(Color), "Color size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_color) == sizeof(Color), "Color size mismatch"); - -void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a) { - Color *dest = (Color *)r_dest; - *dest = Color(p_r, p_g, p_b, p_a); -} - -void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b) { - Color *dest = (Color *)r_dest; - *dest = Color(p_r, p_g, p_b); -} - -godot_real godot_color_get_r(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->r; -} - -void godot_color_set_r(godot_color *p_self, const godot_real val) { - Color *self = (Color *)p_self; - self->r = val; -} - -godot_real godot_color_get_g(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->g; -} - -void godot_color_set_g(godot_color *p_self, const godot_real val) { - Color *self = (Color *)p_self; - self->g = val; -} - -godot_real godot_color_get_b(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->b; +void GDAPI godot_color_new(godot_color *p_self) { + memnew_placement(p_self, Color); } -void godot_color_set_b(godot_color *p_self, const godot_real val) { +float GDAPI *godot_color_operator_index(godot_color *p_self, godot_int p_index) { Color *self = (Color *)p_self; - self->b = val; -} - -godot_real godot_color_get_a(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->a; -} - -void godot_color_set_a(godot_color *p_self, const godot_real val) { - Color *self = (Color *)p_self; - self->a = val; -} - -godot_real godot_color_get_h(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->get_h(); -} - -godot_real godot_color_get_s(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->get_s(); -} - -godot_real godot_color_get_v(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->get_v(); -} - -godot_string GDAPI godot_color_as_string(const godot_color *p_self) { - godot_string ret; - const Color *self = (const Color *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->to_rgba32(); -} - -godot_int GDAPI godot_color_to_abgr32(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->to_abgr32(); -} - -godot_int GDAPI godot_color_to_abgr64(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->to_abgr64(); -} - -godot_int GDAPI godot_color_to_argb64(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->to_argb64(); -} - -godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->to_rgba64(); -} - -godot_int GDAPI godot_color_to_argb32(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->to_argb32(); -} - -godot_color GDAPI godot_color_inverted(const godot_color *p_self) { - godot_color dest; - const Color *self = (const Color *)p_self; - *((Color *)&dest) = self->inverted(); - return dest; -} - -godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t) { - godot_color dest; - const Color *self = (const Color *)p_self; - const Color *b = (const Color *)p_b; - *((Color *)&dest) = self->lerp(*b, p_t); - return dest; -} - -godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over) { - godot_color dest; - const Color *self = (const Color *)p_self; - const Color *over = (const Color *)p_over; - *((Color *)&dest) = self->blend(*over); - return dest; -} - -godot_color GDAPI godot_color_darkened(const godot_color *p_self, const godot_real p_amount) { - godot_color dest; - const Color *self = (const Color *)p_self; - *((Color *)&dest) = self->darkened(p_amount); - return dest; -} - -godot_color GDAPI godot_color_from_hsv(const godot_color *p_self, const godot_real p_h, const godot_real p_s, const godot_real p_v, const godot_real p_a) { - godot_color dest; - const Color *self = (const Color *)p_self; - *((Color *)&dest) = self->from_hsv(p_h, p_s, p_v, p_a); - return dest; -} - -godot_color GDAPI godot_color_lightened(const godot_color *p_self, const godot_real p_amount) { - godot_color dest; - const Color *self = (const Color *)p_self; - *((Color *)&dest) = self->lightened(p_amount); - return dest; -} - -godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha) { - godot_string dest; - const Color *self = (const Color *)p_self; - - memnew_placement(&dest, String(self->to_html(p_with_alpha))); - return dest; -} - -godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b) { - const Color *self = (const Color *)p_self; - const Color *b = (const Color *)p_b; - return *self == *b; + return (float *)&self->operator[](p_index); } -godot_bool GDAPI godot_color_operator_less(const godot_color *p_self, const godot_color *p_b) { +const float GDAPI *godot_color_operator_index_const(const godot_color *p_self, godot_int p_index) { const Color *self = (const Color *)p_self; - const Color *b = (const Color *)p_b; - return *self < *b; + return (const float *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index f3c040428a..9fa4a27a83 100644 --- a/modules/gdnative/gdnative/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -30,26 +30,17 @@ #include "gdnative/dictionary.h" -#include "core/variant/variant.h" -// core/variant/variant.h before to avoid compile errors with MSVC -#include "core/io/json.h" #include "core/variant/dictionary.h" +#include "core/variant/variant.h" + +static_assert(sizeof(godot_dictionary) == sizeof(Dictionary), "Dictionary size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_dictionary) == sizeof(Dictionary), "Dictionary size mismatch"); - -void GDAPI godot_dictionary_new(godot_dictionary *r_dest) { - Dictionary *dest = (Dictionary *)r_dest; - memnew_placement(dest, Dictionary); -} - -void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src) { - Dictionary *dest = (Dictionary *)r_dest; - const Dictionary *src = (const Dictionary *)p_src; - memnew_placement(dest, Dictionary(*src)); +void GDAPI godot_dictionary_new(godot_dictionary *p_self) { + memnew_placement(p_self, Dictionary); } void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) { @@ -57,133 +48,14 @@ void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) { self->~Dictionary(); } -godot_dictionary GDAPI godot_dictionary_duplicate(const godot_dictionary *p_self, const godot_bool p_deep) { - const Dictionary *self = (const Dictionary *)p_self; - godot_dictionary res; - Dictionary *val = (Dictionary *)&res; - memnew_placement(val, Dictionary); - *val = self->duplicate(p_deep); - return res; -} - -godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self) { - const Dictionary *self = (const Dictionary *)p_self; - return self->size(); -} - -godot_bool GDAPI godot_dictionary_is_empty(const godot_dictionary *p_self) { - const Dictionary *self = (const Dictionary *)p_self; - return self->is_empty(); -} - -void GDAPI godot_dictionary_clear(godot_dictionary *p_self) { - Dictionary *self = (Dictionary *)p_self; - self->clear(); -} - -godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_self, const godot_variant *p_key) { - const Dictionary *self = (const Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - return self->has(*key); -} - -godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_self, const godot_array *p_keys) { - const Dictionary *self = (const Dictionary *)p_self; - const Array *keys = (const Array *)p_keys; - return self->has_all(*keys); -} - -void GDAPI godot_dictionary_erase(godot_dictionary *p_self, const godot_variant *p_key) { - Dictionary *self = (Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - self->erase(*key); -} - -godot_int GDAPI godot_dictionary_hash(const godot_dictionary *p_self) { - const Dictionary *self = (const Dictionary *)p_self; - return self->hash(); -} - -godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_self) { - godot_array dest; - const Dictionary *self = (const Dictionary *)p_self; - memnew_placement(&dest, Array(self->keys())); - return dest; -} - -godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_self) { - godot_array dest; - const Dictionary *self = (const Dictionary *)p_self; - memnew_placement(&dest, Array(self->values())); - return dest; -} - -godot_variant GDAPI godot_dictionary_get(const godot_dictionary *p_self, const godot_variant *p_key) { - godot_variant raw_dest; - Variant *dest = (Variant *)&raw_dest; - const Dictionary *self = (const Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - memnew_placement(dest, Variant(self->operator[](*key))); - return raw_dest; -} - -void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_value) { - Dictionary *self = (Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - const Variant *value = (const Variant *)p_value; - self->operator[](*key) = *value; -} - godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key) { Dictionary *self = (Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - return (godot_variant *)&self->operator[](*key); + return (godot_variant *)&self->operator[](*((const Variant *)p_key)); } const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key) { const Dictionary *self = (const Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - return (const godot_variant *)&self->operator[](*key); -} - -godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key) { - Dictionary *self = (Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - return (godot_variant *)self->next(key); -} - -godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b) { - const Dictionary *self = (const Dictionary *)p_self; - const Dictionary *b = (const Dictionary *)p_b; - return *self == *b; -} - -godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self) { - godot_string raw_dest; - String *dest = (String *)&raw_dest; - const Dictionary *self = (const Dictionary *)p_self; - memnew_placement(dest, String(JSON::print(Variant(*self)))); - return raw_dest; -} - -// GDNative core 1.1 - -godot_bool GDAPI godot_dictionary_erase_with_return(godot_dictionary *p_self, const godot_variant *p_key) { - Dictionary *self = (Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - return self->erase(*key); -} - -godot_variant GDAPI godot_dictionary_get_with_default(const godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_default) { - const Dictionary *self = (const Dictionary *)p_self; - const Variant *key = (const Variant *)p_key; - const Variant *def = (const Variant *)p_default; - - godot_variant raw_dest; - Variant *dest = (Variant *)&raw_dest; - memnew_placement(dest, Variant(self->get(*key, *def))); - - return raw_dest; + return (const godot_variant *)&self->operator[](*((const Variant *)p_key)); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 1c11130d89..b84ce2d192 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -99,7 +99,7 @@ godot_class_constructor GDAPI godot_get_class_constructor(const char *p_classnam godot_dictionary GDAPI godot_get_global_constants() { godot_dictionary constants; - godot_dictionary_new(&constants); + memnew_placement(&constants, Dictionary); Dictionary *p_constants = (Dictionary *)&constants; const int constants_count = CoreConstants::get_global_constant_count(); for (int i = 0; i < constants_count; ++i) { @@ -127,16 +127,15 @@ void GDAPI godot_free(void *p_ptr) { memfree(p_ptr); } +// Helper print functions. void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR); } - void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line) { _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING); } - -void GDAPI godot_print(const godot_string *p_message) { - print_line(*(String *)p_message); +void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { + _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT); } void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have) { diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp index 7b215c0d0b..02c2f9b22b 100644 --- a/modules/gdnative/gdnative/node_path.cpp +++ b/modules/gdnative/gdnative/node_path.cpp @@ -31,24 +31,15 @@ #include "gdnative/node_path.h" #include "core/string/node_path.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_node_path) == sizeof(NodePath), "NodePath size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_node_path) == sizeof(NodePath), "NodePath size mismatch"); - -void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from) { - NodePath *dest = (NodePath *)r_dest; - const String *from = (const String *)p_from; - memnew_placement(dest, NodePath(*from)); -} - -void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src) { - NodePath *dest = (NodePath *)r_dest; - const NodePath *src = (const NodePath *)p_src; - memnew_placement(dest, NodePath(*src)); +void GDAPI godot_node_path_new(godot_node_path *p_self) { + memnew_placement(p_self, NodePath); } void GDAPI godot_node_path_destroy(godot_node_path *p_self) { @@ -56,71 +47,6 @@ void GDAPI godot_node_path_destroy(godot_node_path *p_self) { self->~NodePath(); } -godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_self) { - godot_string ret; - const NodePath *self = (const NodePath *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_self) { - const NodePath *self = (const NodePath *)p_self; - return self->is_absolute(); -} - -godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_self) { - const NodePath *self = (const NodePath *)p_self; - return self->get_name_count(); -} - -godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_self, const godot_int p_idx) { - godot_string dest; - const NodePath *self = (const NodePath *)p_self; - - memnew_placement(&dest, String(self->get_name(p_idx))); - return dest; -} - -godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_self) { - const NodePath *self = (const NodePath *)p_self; - return self->get_subname_count(); -} - -godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_self, const godot_int p_idx) { - godot_string dest; - const NodePath *self = (const NodePath *)p_self; - - memnew_placement(&dest, String(self->get_subname(p_idx))); - return dest; -} - -godot_string GDAPI godot_node_path_get_concatenated_subnames(const godot_node_path *p_self) { - godot_string dest; - const NodePath *self = (const NodePath *)p_self; - memnew_placement(&dest, String(self->get_concatenated_subnames())); - return dest; -} - -godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self) { - const NodePath *self = (const NodePath *)p_self; - return self->is_empty(); -} - -godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b) { - const NodePath *self = (const NodePath *)p_self; - const NodePath *b = (const NodePath *)p_b; - return *self == *b; -} - -godot_node_path godot_node_path_get_as_property_path(const godot_node_path *p_self) { - const NodePath *self = (const NodePath *)p_self; - godot_node_path res; - NodePath *val = (NodePath *)&res; - memnew_placement(val, NodePath); - *val = self->get_as_property_path(); - return res; -} - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp index e714999234..63a2425b87 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -30,1110 +30,247 @@ #include "gdnative/packed_arrays.h" -#include "core/variant/array.h" - #include "core/variant/variant.h" -#include "core/math/color.h" #include "core/math/vector2.h" -#include "core/math/vector3.h" +#include "core/math/vector3i.h" + +static_assert(sizeof(godot_packed_byte_array) == sizeof(PackedByteArray), "PackedByteArray size mismatch"); +static_assert(sizeof(godot_packed_int32_array) == sizeof(PackedInt32Array), "PackedInt32Array size mismatch"); +static_assert(sizeof(godot_packed_int64_array) == sizeof(PackedInt64Array), "PackedInt64Array size mismatch"); +static_assert(sizeof(godot_packed_float32_array) == sizeof(PackedFloat32Array), "PackedFloat32Array size mismatch"); +static_assert(sizeof(godot_packed_float64_array) == sizeof(PackedFloat64Array), "PackedFloat64Array size mismatch"); +static_assert(sizeof(godot_packed_string_array) == sizeof(PackedStringArray), "PackedStringArray size mismatch"); +static_assert(sizeof(godot_packed_vector2_array) == sizeof(PackedVector2Array), "PackedVector2Array size mismatch"); +static_assert(sizeof(godot_packed_vector2i_array) == sizeof(Vector<Vector2i>), "Vector<Vector2i> size mismatch"); +static_assert(sizeof(godot_packed_vector3_array) == sizeof(PackedVector3Array), "PackedVector3Array size mismatch"); +static_assert(sizeof(godot_packed_vector3i_array) == sizeof(Vector<Vector3i>), "Vector<Vector3i> size mismatch"); +static_assert(sizeof(godot_packed_color_array) == sizeof(PackedColorArray), "PackedColorArray size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_packed_byte_array) == sizeof(Vector<uint8_t>), "Vector<uint8_t> size mismatch"); -static_assert(sizeof(godot_packed_int32_array) == sizeof(Vector<int32_t>), "Vector<int32_t> size mismatch"); -static_assert(sizeof(godot_packed_int64_array) == sizeof(Vector<int64_t>), "Vector<int64_t> size mismatch"); -static_assert(sizeof(godot_packed_float32_array) == sizeof(Vector<float>), "Vector<float> size mismatch"); -static_assert(sizeof(godot_packed_float64_array) == sizeof(Vector<double>), "Vector<double> size mismatch"); -static_assert(sizeof(godot_packed_string_array) == sizeof(Vector<String>), "Vector<String> size mismatch"); -static_assert(sizeof(godot_packed_vector2_array) == sizeof(Vector<Vector2>), "Vector<Vector2> size mismatch"); -static_assert(sizeof(godot_packed_vector2i_array) == sizeof(Vector<Vector2i>), "Vector<Vector2i> size mismatch"); -static_assert(sizeof(godot_packed_vector3_array) == sizeof(Vector<Vector3>), "Vector<Vector3> size mismatch"); -static_assert(sizeof(godot_packed_color_array) == sizeof(Vector<Color>), "Vector<Color> size mismatch"); - #define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr) // byte -void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *r_dest) { - Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest; - memnew_placement(dest, Vector<uint8_t>); -} - -void GDAPI godot_packed_byte_array_new_copy(godot_packed_byte_array *r_dest, const godot_packed_byte_array *p_src) { - Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest; - const Vector<uint8_t> *src = (const Vector<uint8_t> *)p_src; - memnew_placement(dest, Vector<uint8_t>(*src)); -} - -void GDAPI godot_packed_byte_array_new_with_array(godot_packed_byte_array *r_dest, const godot_array *p_a) { - Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<uint8_t>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const uint8_t GDAPI *godot_packed_byte_array_ptr(const godot_packed_byte_array *p_self) { - const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self; - return self->ptr(); -} - -uint8_t GDAPI *godot_packed_byte_array_ptrw(godot_packed_byte_array *p_self) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - return self->ptrw(); -} - -void GDAPI godot_packed_byte_array_append(godot_packed_byte_array *p_self, const uint8_t p_data) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, const godot_packed_byte_array *p_array) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - Vector<uint8_t> *array = (Vector<uint8_t> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - return (godot_error)self->insert(p_idx, p_data); -} - -godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - return (godot_bool)self->has(p_value); -} - -void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->invert(); -} - -void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_byte_array_remove(godot_packed_byte_array *p_self, const godot_int p_idx) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_byte_array_resize(godot_packed_byte_array *p_self, const godot_int p_size) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_byte_array_set(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) { - Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; - self->set(p_idx, p_data); -} - -uint8_t GDAPI godot_packed_byte_array_get(const godot_packed_byte_array *p_self, const godot_int p_idx) { - const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self; - return self->get(p_idx); -} - -godot_int GDAPI godot_packed_byte_array_size(const godot_packed_byte_array *p_self) { - const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self; - return self->size(); -} - -godot_bool GDAPI godot_packed_byte_array_is_empty(const godot_packed_byte_array *p_self) { - const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *p_self) { + memnew_placement(p_self, PackedByteArray); } void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self) { - ((Vector<uint8_t> *)p_self)->~Vector(); + ((PackedByteArray *)p_self)->~PackedByteArray(); } -// int32 - -void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *r_dest) { - Vector<int32_t> *dest = (Vector<int32_t> *)r_dest; - memnew_placement(dest, Vector<int32_t>); +uint8_t GDAPI *godot_packed_byte_array_operator_index(godot_packed_byte_array *p_self, godot_int p_index) { + PackedByteArray *self = (PackedByteArray *)p_self; + return (uint8_t *)&self->operator[](p_index); } -void GDAPI godot_packed_int32_array_new_copy(godot_packed_int32_array *r_dest, const godot_packed_int32_array *p_src) { - Vector<int32_t> *dest = (Vector<int32_t> *)r_dest; - const Vector<int32_t> *src = (const Vector<int32_t> *)p_src; - memnew_placement(dest, Vector<int32_t>(*src)); +const uint8_t GDAPI *godot_packed_byte_array_operator_index_const(const godot_packed_byte_array *p_self, godot_int p_index) { + const PackedByteArray *self = (const PackedByteArray *)p_self; + return (const uint8_t *)&self->operator[](p_index); } -void GDAPI godot_packed_int32_array_new_with_array(godot_packed_int32_array *r_dest, const godot_array *p_a) { - Vector<int32_t> *dest = (Vector<int32_t> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<int32_t>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const int32_t GDAPI *godot_packed_int32_array_ptr(const godot_packed_int32_array *p_self) { - const Vector<int32_t> *self = (const Vector<int32_t> *)p_self; - return self->ptr(); -} - -int32_t GDAPI *godot_packed_int32_array_ptrw(godot_packed_int32_array *p_self) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - return self->ptrw(); -} - -void GDAPI godot_packed_int32_array_append(godot_packed_int32_array *p_self, const int32_t p_data) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_self, const godot_packed_int32_array *p_array) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - Vector<int32_t> *array = (Vector<int32_t> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - return (godot_error)self->insert(p_idx, p_data); -} - -godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - return (godot_bool)self->has(p_value); -} - -void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->invert(); -} - -void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_int32_array_remove(godot_packed_int32_array *p_self, const godot_int p_idx) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_int32_array_resize(godot_packed_int32_array *p_self, const godot_int p_size) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_int32_array_set(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data) { - Vector<int32_t> *self = (Vector<int32_t> *)p_self; - self->set(p_idx, p_data); -} - -int32_t GDAPI godot_packed_int32_array_get(const godot_packed_int32_array *p_self, const godot_int p_idx) { - const Vector<int32_t> *self = (const Vector<int32_t> *)p_self; - return self->get(p_idx); -} - -godot_int GDAPI godot_packed_int32_array_size(const godot_packed_int32_array *p_self) { - const Vector<int32_t> *self = (const Vector<int32_t> *)p_self; - return self->size(); -} +// int32 -godot_bool GDAPI godot_packed_int32_array_is_empty(const godot_packed_int32_array *p_self) { - const Vector<int32_t> *self = (const Vector<int32_t> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *p_self) { + memnew_placement(p_self, PackedInt32Array); } void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self) { - ((Vector<int32_t> *)p_self)->~Vector(); -} - -// int64 - -void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *r_dest) { - Vector<int64_t> *dest = (Vector<int64_t> *)r_dest; - memnew_placement(dest, Vector<int64_t>); -} - -void GDAPI godot_packed_int64_array_new_copy(godot_packed_int64_array *r_dest, const godot_packed_int64_array *p_src) { - Vector<int64_t> *dest = (Vector<int64_t> *)r_dest; - const Vector<int64_t> *src = (const Vector<int64_t> *)p_src; - memnew_placement(dest, Vector<int64_t>(*src)); -} - -void GDAPI godot_packed_int64_array_new_with_array(godot_packed_int64_array *r_dest, const godot_array *p_a) { - Vector<int64_t> *dest = (Vector<int64_t> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<int64_t>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const int64_t GDAPI *godot_packed_int64_array_ptr(const godot_packed_int64_array *p_self) { - const Vector<int64_t> *self = (const Vector<int64_t> *)p_self; - return self->ptr(); -} - -int64_t GDAPI *godot_packed_int64_array_ptrw(godot_packed_int64_array *p_self) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - return self->ptrw(); + ((PackedInt32Array *)p_self)->~PackedInt32Array(); } -void GDAPI godot_packed_int64_array_append(godot_packed_int64_array *p_self, const int64_t p_data) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->push_back(p_data); +int32_t GDAPI *godot_packed_int32_array_operator_index(godot_packed_int32_array *p_self, godot_int p_index) { + PackedInt32Array *self = (PackedInt32Array *)p_self; + return (int32_t *)&self->operator[](p_index); } -void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_self, const godot_packed_int64_array *p_array) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - Vector<int64_t> *array = (Vector<int64_t> *)p_array; - self->append_array(*array); +const int32_t GDAPI *godot_packed_int32_array_operator_index_const(const godot_packed_int32_array *p_self, godot_int p_index) { + const PackedInt32Array *self = (const PackedInt32Array *)p_self; + return (const int32_t *)&self->operator[](p_index); } -godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - return (godot_error)self->insert(p_idx, p_data); -} - -godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - return (godot_bool)self->has(p_value); -} - -void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->invert(); -} - -void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_int64_array_remove(godot_packed_int64_array *p_self, const godot_int p_idx) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_int64_array_resize(godot_packed_int64_array *p_self, const godot_int p_size) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_int64_array_set(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data) { - Vector<int64_t> *self = (Vector<int64_t> *)p_self; - self->set(p_idx, p_data); -} - -int64_t GDAPI godot_packed_int64_array_get(const godot_packed_int64_array *p_self, const godot_int p_idx) { - const Vector<int64_t> *self = (const Vector<int64_t> *)p_self; - return self->get(p_idx); -} - -godot_int GDAPI godot_packed_int64_array_size(const godot_packed_int64_array *p_self) { - const Vector<int64_t> *self = (const Vector<int64_t> *)p_self; - return self->size(); -} +// int64 -godot_bool GDAPI godot_packed_int64_array_is_empty(const godot_packed_int64_array *p_self) { - const Vector<int64_t> *self = (const Vector<int64_t> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *p_self) { + memnew_placement(p_self, PackedInt64Array); } void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self) { - ((Vector<int64_t> *)p_self)->~Vector(); -} - -// float32 - -void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *r_dest) { - Vector<float> *dest = (Vector<float> *)r_dest; - memnew_placement(dest, Vector<float>); -} - -void GDAPI godot_packed_float32_array_new_copy(godot_packed_float32_array *r_dest, const godot_packed_float32_array *p_src) { - Vector<float> *dest = (Vector<float> *)r_dest; - const Vector<float> *src = (const Vector<float> *)p_src; - memnew_placement(dest, Vector<float>(*src)); -} - -void GDAPI godot_packed_float32_array_new_with_array(godot_packed_float32_array *r_dest, const godot_array *p_a) { - Vector<float> *dest = (Vector<float> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<float>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const float GDAPI *godot_packed_float32_array_ptr(const godot_packed_float32_array *p_self) { - const Vector<float> *self = (const Vector<float> *)p_self; - return self->ptr(); -} - -float GDAPI *godot_packed_float32_array_ptrw(godot_packed_float32_array *p_self) { - Vector<float> *self = (Vector<float> *)p_self; - return self->ptrw(); -} - -void GDAPI godot_packed_float32_array_append(godot_packed_float32_array *p_self, const float p_data) { - Vector<float> *self = (Vector<float> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p_self, const godot_packed_float32_array *p_array) { - Vector<float> *self = (Vector<float> *)p_self; - Vector<float> *array = (Vector<float> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data) { - Vector<float> *self = (Vector<float> *)p_self; - return (godot_error)self->insert(p_idx, p_data); -} - -godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value) { - Vector<float> *self = (Vector<float> *)p_self; - return (godot_bool)self->has(p_value); -} - -void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self) { - Vector<float> *self = (Vector<float> *)p_self; - self->sort(); + ((PackedInt64Array *)p_self)->~PackedInt64Array(); } -void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self) { - Vector<float> *self = (Vector<float> *)p_self; - self->invert(); +int64_t GDAPI *godot_packed_int64_array_operator_index(godot_packed_int64_array *p_self, godot_int p_index) { + PackedInt64Array *self = (PackedInt64Array *)p_self; + return (int64_t *)&self->operator[](p_index); } -void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data) { - Vector<float> *self = (Vector<float> *)p_self; - self->push_back(p_data); +const int64_t GDAPI *godot_packed_int64_array_operator_index_const(const godot_packed_int64_array *p_self, godot_int p_index) { + const PackedInt64Array *self = (const PackedInt64Array *)p_self; + return (const int64_t *)&self->operator[](p_index); } -void GDAPI godot_packed_float32_array_remove(godot_packed_float32_array *p_self, const godot_int p_idx) { - Vector<float> *self = (Vector<float> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_float32_array_resize(godot_packed_float32_array *p_self, const godot_int p_size) { - Vector<float> *self = (Vector<float> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_float32_array_set(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data) { - Vector<float> *self = (Vector<float> *)p_self; - self->set(p_idx, p_data); -} - -float GDAPI godot_packed_float32_array_get(const godot_packed_float32_array *p_self, const godot_int p_idx) { - const Vector<float> *self = (const Vector<float> *)p_self; - return self->get(p_idx); -} - -godot_int GDAPI godot_packed_float32_array_size(const godot_packed_float32_array *p_self) { - const Vector<float> *self = (const Vector<float> *)p_self; - return self->size(); -} +// float32 -godot_bool GDAPI godot_packed_float32_array_is_empty(const godot_packed_float32_array *p_self) { - const Vector<float> *self = (const Vector<float> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *p_self) { + memnew_placement(p_self, PackedFloat32Array); } void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self) { - ((Vector<float> *)p_self)->~Vector(); -} - -// float64 - -void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *r_dest) { - Vector<double> *dest = (Vector<double> *)r_dest; - memnew_placement(dest, Vector<double>); -} - -void GDAPI godot_packed_float64_array_new_copy(godot_packed_float64_array *r_dest, const godot_packed_float64_array *p_src) { - Vector<double> *dest = (Vector<double> *)r_dest; - const Vector<double> *src = (const Vector<double> *)p_src; - memnew_placement(dest, Vector<double>(*src)); -} - -void GDAPI godot_packed_float64_array_new_with_array(godot_packed_float64_array *r_dest, const godot_array *p_a) { - Vector<double> *dest = (Vector<double> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<double>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const double GDAPI *godot_packed_float64_array_ptr(const godot_packed_float64_array *p_self) { - const Vector<double> *self = (const Vector<double> *)p_self; - return self->ptr(); + ((PackedFloat32Array *)p_self)->~PackedFloat32Array(); } -double GDAPI *godot_packed_float64_array_ptrw(godot_packed_float64_array *p_self) { - Vector<double> *self = (Vector<double> *)p_self; - return self->ptrw(); +float GDAPI *godot_packed_float32_array_operator_index(godot_packed_float32_array *p_self, godot_int p_index) { + PackedFloat32Array *self = (PackedFloat32Array *)p_self; + return (float *)&self->operator[](p_index); } -void GDAPI godot_packed_float64_array_append(godot_packed_float64_array *p_self, const double p_data) { - Vector<double> *self = (Vector<double> *)p_self; - self->push_back(p_data); +const float GDAPI *godot_packed_float32_array_operator_index_const(const godot_packed_float32_array *p_self, godot_int p_index) { + const PackedFloat32Array *self = (const PackedFloat32Array *)p_self; + return (const float *)&self->operator[](p_index); } -void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p_self, const godot_packed_float64_array *p_array) { - Vector<double> *self = (Vector<double> *)p_self; - Vector<double> *array = (Vector<double> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data) { - Vector<double> *self = (Vector<double> *)p_self; - return (godot_error)self->insert(p_idx, p_data); -} - -godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value) { - Vector<double> *self = (Vector<double> *)p_self; - return (godot_bool)self->has(p_value); -} - -void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self) { - Vector<double> *self = (Vector<double> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self) { - Vector<double> *self = (Vector<double> *)p_self; - self->invert(); -} - -void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data) { - Vector<double> *self = (Vector<double> *)p_self; - self->push_back(p_data); -} - -void GDAPI godot_packed_float64_array_remove(godot_packed_float64_array *p_self, const godot_int p_idx) { - Vector<double> *self = (Vector<double> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_float64_array_resize(godot_packed_float64_array *p_self, const godot_int p_size) { - Vector<double> *self = (Vector<double> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_float64_array_set(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data) { - Vector<double> *self = (Vector<double> *)p_self; - self->set(p_idx, p_data); -} - -double GDAPI godot_packed_float64_array_get(const godot_packed_float64_array *p_self, const godot_int p_idx) { - const Vector<double> *self = (const Vector<double> *)p_self; - return self->get(p_idx); -} - -godot_int GDAPI godot_packed_float64_array_size(const godot_packed_float64_array *p_self) { - const Vector<double> *self = (const Vector<double> *)p_self; - return self->size(); -} +// float64 -godot_bool GDAPI godot_packed_float64_array_is_empty(const godot_packed_float64_array *p_self) { - const Vector<double> *self = (const Vector<double> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *p_self) { + memnew_placement(p_self, PackedFloat64Array); } void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self) { - ((Vector<double> *)p_self)->~Vector(); -} - -// string - -void GDAPI godot_packed_string_array_new(godot_packed_string_array *r_dest) { - Vector<String> *dest = (Vector<String> *)r_dest; - memnew_placement(dest, Vector<String>); -} - -void GDAPI godot_packed_string_array_new_copy(godot_packed_string_array *r_dest, const godot_packed_string_array *p_src) { - Vector<String> *dest = (Vector<String> *)r_dest; - const Vector<String> *src = (const Vector<String> *)p_src; - memnew_placement(dest, Vector<String>(*src)); -} - -void GDAPI godot_packed_string_array_new_with_array(godot_packed_string_array *r_dest, const godot_array *p_a) { - Vector<String> *dest = (Vector<String> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<String>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const godot_string GDAPI *godot_packed_string_array_ptr(const godot_packed_string_array *p_self) { - const Vector<String> *self = (const Vector<String> *)p_self; - return (const godot_string *)self->ptr(); -} - -godot_string GDAPI *godot_packed_string_array_ptrw(godot_packed_string_array *p_self) { - Vector<String> *self = (Vector<String> *)p_self; - return (godot_string *)self->ptrw(); -} - -void GDAPI godot_packed_string_array_append(godot_packed_string_array *p_self, const godot_string *p_data) { - Vector<String> *self = (Vector<String> *)p_self; - String &s = *(String *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_self, const godot_packed_string_array *p_array) { - Vector<String> *self = (Vector<String> *)p_self; - Vector<String> *array = (Vector<String> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data) { - Vector<String> *self = (Vector<String> *)p_self; - String &s = *(String *)p_data; - return (godot_error)self->insert(p_idx, s); -} - -godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value) { - Vector<String> *self = (Vector<String> *)p_self; - String &s = *(String *)p_value; - return (godot_bool)self->has(s); + ((PackedFloat64Array *)p_self)->~PackedFloat64Array(); } -void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self) { - Vector<String> *self = (Vector<String> *)p_self; - self->sort(); +double GDAPI *godot_packed_float64_array_operator_index(godot_packed_float64_array *p_self, godot_int p_index) { + PackedFloat64Array *self = (PackedFloat64Array *)p_self; + return (double *)&self->operator[](p_index); } -void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self) { - Vector<String> *self = (Vector<String> *)p_self; - self->invert(); +const double GDAPI *godot_packed_float64_array_operator_index_const(const godot_packed_float64_array *p_self, godot_int p_index) { + const PackedFloat64Array *self = (const PackedFloat64Array *)p_self; + return (const double *)&self->operator[](p_index); } -void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data) { - Vector<String> *self = (Vector<String> *)p_self; - String &s = *(String *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_string_array_remove(godot_packed_string_array *p_self, const godot_int p_idx) { - Vector<String> *self = (Vector<String> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_string_array_resize(godot_packed_string_array *p_self, const godot_int p_size) { - Vector<String> *self = (Vector<String> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_string_array_set(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data) { - Vector<String> *self = (Vector<String> *)p_self; - String &s = *(String *)p_data; - self->set(p_idx, s); -} - -godot_string GDAPI godot_packed_string_array_get(const godot_packed_string_array *p_self, const godot_int p_idx) { - const Vector<String> *self = (const Vector<String> *)p_self; - godot_string str; - String *s = (String *)&str; - memnew_placement(s, String); - *s = self->get(p_idx); - return str; -} - -godot_int GDAPI godot_packed_string_array_size(const godot_packed_string_array *p_self) { - const Vector<String> *self = (const Vector<String> *)p_self; - return self->size(); -} +// string -godot_bool GDAPI godot_packed_string_array_is_empty(const godot_packed_string_array *p_self) { - const Vector<String> *self = (const Vector<String> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_string_array_new(godot_packed_string_array *p_self) { + memnew_placement(p_self, PackedStringArray); } void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self) { - ((Vector<String> *)p_self)->~Vector(); -} - -// vector2 - -void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *r_dest) { - Vector<Vector2> *dest = (Vector<Vector2> *)r_dest; - memnew_placement(dest, Vector<Vector2>); -} - -void GDAPI godot_packed_vector2_array_new_copy(godot_packed_vector2_array *r_dest, const godot_packed_vector2_array *p_src) { - Vector<Vector2> *dest = (Vector<Vector2> *)r_dest; - const Vector<Vector2> *src = (const Vector<Vector2> *)p_src; - memnew_placement(dest, Vector<Vector2>(*src)); -} - -void GDAPI godot_packed_vector2_array_new_with_array(godot_packed_vector2_array *r_dest, const godot_array *p_a) { - Vector<Vector2> *dest = (Vector<Vector2> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<Vector2>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } + ((PackedStringArray *)p_self)->~PackedStringArray(); } -const godot_vector2 GDAPI *godot_packed_vector2_array_ptr(const godot_packed_vector2_array *p_self) { - const Vector<Vector2> *self = (const Vector<Vector2> *)p_self; - return (const godot_vector2 *)self->ptr(); +godot_string GDAPI *godot_packed_string_array_operator_index(godot_packed_string_array *p_self, godot_int p_index) { + PackedStringArray *self = (PackedStringArray *)p_self; + return (godot_string *)&self->operator[](p_index); } -godot_vector2 GDAPI *godot_packed_vector2_array_ptrw(godot_packed_vector2_array *p_self) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - return (godot_vector2 *)self->ptrw(); +const godot_string GDAPI *godot_packed_string_array_operator_index_const(const godot_packed_string_array *p_self, godot_int p_index) { + const PackedStringArray *self = (const PackedStringArray *)p_self; + return (const godot_string *)&self->operator[](p_index); } -void GDAPI godot_packed_vector2_array_append(godot_packed_vector2_array *p_self, const godot_vector2 *p_data) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - Vector2 &s = *(Vector2 *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p_self, const godot_packed_vector2_array *p_array) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - Vector<Vector2> *array = (Vector<Vector2> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - Vector2 &s = *(Vector2 *)p_data; - return (godot_error)self->insert(p_idx, s); -} - -godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - Vector2 &v = *(Vector2 *)p_value; - return (godot_bool)self->has(v); -} - -void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - self->invert(); -} - -void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - Vector2 &s = *(Vector2 *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_vector2_array_remove(godot_packed_vector2_array *p_self, const godot_int p_idx) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_vector2_array_resize(godot_packed_vector2_array *p_self, const godot_int p_size) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_vector2_array_set(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) { - Vector<Vector2> *self = (Vector<Vector2> *)p_self; - Vector2 &s = *(Vector2 *)p_data; - self->set(p_idx, s); -} - -godot_vector2 GDAPI godot_packed_vector2_array_get(const godot_packed_vector2_array *p_self, const godot_int p_idx) { - const Vector<Vector2> *self = (const Vector<Vector2> *)p_self; - godot_vector2 v; - Vector2 *s = (Vector2 *)&v; - *s = self->get(p_idx); - return v; -} - -godot_int GDAPI godot_packed_vector2_array_size(const godot_packed_vector2_array *p_self) { - const Vector<Vector2> *self = (const Vector<Vector2> *)p_self; - return self->size(); -} +// vector2 -godot_bool GDAPI godot_packed_vector2_array_is_empty(const godot_packed_vector2_array *p_self) { - const Vector<Vector2> *self = (const Vector<Vector2> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *p_self) { + memnew_placement(p_self, PackedVector2Array); } void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self) { - ((Vector<Vector2> *)p_self)->~Vector(); -} - -// vector2i - -void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *r_dest) { - Vector<Vector2i> *dest = (Vector<Vector2i> *)r_dest; - memnew_placement(dest, Vector<Vector2i>); -} - -void GDAPI godot_packed_vector2i_array_new_copy(godot_packed_vector2i_array *r_dest, const godot_packed_vector2i_array *p_src) { - Vector<Vector2i> *dest = (Vector<Vector2i> *)r_dest; - const Vector<Vector2i> *src = (const Vector<Vector2i> *)p_src; - memnew_placement(dest, Vector<Vector2i>(*src)); -} - -void GDAPI godot_packed_vector2i_array_new_with_array(godot_packed_vector2i_array *r_dest, const godot_array *p_a) { - Vector<Vector2i> *dest = (Vector<Vector2i> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<Vector2i>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const godot_vector2i GDAPI *godot_packed_vector2i_array_ptr(const godot_packed_vector2i_array *p_self) { - const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self; - return (const godot_vector2i *)self->ptr(); -} - -godot_vector2i GDAPI *godot_packed_vector2i_array_ptrw(godot_packed_vector2i_array *p_self) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - return (godot_vector2i *)self->ptrw(); -} - -void GDAPI godot_packed_vector2i_array_append(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - Vector2i &s = *(Vector2i *)p_data; - self->push_back(s); + ((PackedVector2Array *)p_self)->~PackedVector2Array(); } -void GDAPI godot_packed_vector2i_array_append_array(godot_packed_vector2i_array *p_self, const godot_packed_vector2i_array *p_array) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - Vector<Vector2i> *array = (Vector<Vector2i> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_vector2i_array_insert(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - Vector2i &s = *(Vector2i *)p_data; - return (godot_error)self->insert(p_idx, s); +godot_vector2 GDAPI *godot_packed_vector2_array_operator_index(godot_packed_vector2_array *p_self, godot_int p_index) { + PackedVector2Array *self = (PackedVector2Array *)p_self; + return (godot_vector2 *)&self->operator[](p_index); } -godot_bool GDAPI godot_packed_vector2i_array_has(godot_packed_vector2i_array *p_self, const godot_vector2i *p_value) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - Vector2i &v = *(Vector2i *)p_value; - return (godot_bool)self->has(v); -} - -void GDAPI godot_packed_vector2i_array_sort(godot_packed_vector2i_array *p_self) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_vector2i_array_invert(godot_packed_vector2i_array *p_self) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - self->invert(); +const godot_vector2 GDAPI *godot_packed_vector2_array_operator_index_const(const godot_packed_vector2_array *p_self, godot_int p_index) { + const PackedVector2Array *self = (const PackedVector2Array *)p_self; + return (const godot_vector2 *)&self->operator[](p_index); } -void GDAPI godot_packed_vector2i_array_push_back(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - Vector2i &s = *(Vector2i *)p_data; - self->push_back(s); -} +// vector2i -void GDAPI godot_packed_vector2i_array_remove(godot_packed_vector2i_array *p_self, const godot_int p_idx) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - self->remove(p_idx); +void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *p_self) { + memnew_placement(p_self, Vector<Vector2i>); } -void GDAPI godot_packed_vector2i_array_resize(godot_packed_vector2i_array *p_self, const godot_int p_size) { - Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - self->resize(p_size); +void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self) { + ((Vector<Vector2i> *)p_self)->~Vector(); } -void GDAPI godot_packed_vector2i_array_set(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data) { +godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index(godot_packed_vector2i_array *p_self, godot_int p_index) { Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; - Vector2i &s = *(Vector2i *)p_data; - self->set(p_idx, s); + return (godot_vector2i *)&self->operator[](p_index); } -godot_vector2i GDAPI godot_packed_vector2i_array_get(const godot_packed_vector2i_array *p_self, const godot_int p_idx) { +const godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index_const(const godot_packed_vector2i_array *p_self, godot_int p_index) { const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self; - godot_vector2i v; - Vector2i *s = (Vector2i *)&v; - *s = self->get(p_idx); - return v; -} - -godot_int GDAPI godot_packed_vector2i_array_size(const godot_packed_vector2i_array *p_self) { - const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self; - return self->size(); -} - -godot_bool GDAPI godot_packed_vector2i_array_is_empty(const godot_packed_vector2i_array *p_self) { - const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self; - return self->is_empty(); -} - -void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self) { - ((Vector<Vector2i> *)p_self)->~Vector(); + return (const godot_vector2i *)&self->operator[](p_index); } // vector3 -void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *r_dest) { - Vector<Vector3> *dest = (Vector<Vector3> *)r_dest; - memnew_placement(dest, Vector<Vector3>); -} - -void GDAPI godot_packed_vector3_array_new_copy(godot_packed_vector3_array *r_dest, const godot_packed_vector3_array *p_src) { - Vector<Vector3> *dest = (Vector<Vector3> *)r_dest; - const Vector<Vector3> *src = (const Vector<Vector3> *)p_src; - memnew_placement(dest, Vector<Vector3>(*src)); -} - -void GDAPI godot_packed_vector3_array_new_with_array(godot_packed_vector3_array *r_dest, const godot_array *p_a) { - Vector<Vector3> *dest = (Vector<Vector3> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<Vector3>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } -} - -const godot_vector3 GDAPI *godot_packed_vector3_array_ptr(const godot_packed_vector3_array *p_self) { - const Vector<Vector3> *self = (const Vector<Vector3> *)p_self; - return (const godot_vector3 *)self->ptr(); -} - -godot_vector3 GDAPI *godot_packed_vector3_array_ptrw(godot_packed_vector3_array *p_self) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - return (godot_vector3 *)self->ptrw(); -} - -void GDAPI godot_packed_vector3_array_append(godot_packed_vector3_array *p_self, const godot_vector3 *p_data) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - Vector3 &s = *(Vector3 *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p_self, const godot_packed_vector3_array *p_array) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - Vector<Vector3> *array = (Vector<Vector3> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - Vector3 &s = *(Vector3 *)p_data; - return (godot_error)self->insert(p_idx, s); -} - -godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - Vector3 &v = *(Vector3 *)p_value; - return (godot_bool)self->has(v); -} - -void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - self->invert(); -} - -void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - Vector3 &s = *(Vector3 *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_vector3_array_remove(godot_packed_vector3_array *p_self, const godot_int p_idx) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_vector3_array_resize(godot_packed_vector3_array *p_self, const godot_int p_size) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_vector3_array_set(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) { - Vector<Vector3> *self = (Vector<Vector3> *)p_self; - Vector3 &s = *(Vector3 *)p_data; - self->set(p_idx, s); -} - -godot_vector3 GDAPI godot_packed_vector3_array_get(const godot_packed_vector3_array *p_self, const godot_int p_idx) { - const Vector<Vector3> *self = (const Vector<Vector3> *)p_self; - godot_vector3 v; - Vector3 *s = (Vector3 *)&v; - *s = self->get(p_idx); - return v; -} - -godot_int GDAPI godot_packed_vector3_array_size(const godot_packed_vector3_array *p_self) { - const Vector<Vector3> *self = (const Vector<Vector3> *)p_self; - return self->size(); -} - -godot_bool GDAPI godot_packed_vector3_array_is_empty(const godot_packed_vector3_array *p_self) { - const Vector<Vector3> *self = (const Vector<Vector3> *)p_self; - return self->is_empty(); +void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *p_self) { + memnew_placement(p_self, PackedVector3Array); } void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self) { - ((Vector<Vector3> *)p_self)->~Vector(); -} - -// color - -void GDAPI godot_packed_color_array_new(godot_packed_color_array *r_dest) { - Vector<Color> *dest = (Vector<Color> *)r_dest; - memnew_placement(dest, Vector<Color>); + ((PackedVector3Array *)p_self)->~PackedVector3Array(); } -void GDAPI godot_packed_color_array_new_copy(godot_packed_color_array *r_dest, const godot_packed_color_array *p_src) { - Vector<Color> *dest = (Vector<Color> *)r_dest; - const Vector<Color> *src = (const Vector<Color> *)p_src; - memnew_placement(dest, Vector<Color>(*src)); -} - -void GDAPI godot_packed_color_array_new_with_array(godot_packed_color_array *r_dest, const godot_array *p_a) { - Vector<Color> *dest = (Vector<Color> *)r_dest; - Array *a = (Array *)p_a; - memnew_placement(dest, Vector<Color>); - - dest->resize(a->size()); - for (int i = 0; i < a->size(); i++) { - dest->set(i, (*a)[i]); - } +godot_vector3 GDAPI *godot_packed_vector3_array_operator_index(godot_packed_vector3_array *p_self, godot_int p_index) { + PackedVector3Array *self = (PackedVector3Array *)p_self; + return (godot_vector3 *)&self->operator[](p_index); } -const godot_color GDAPI *godot_packed_color_array_ptr(const godot_packed_color_array *p_self) { - const Vector<Color> *self = (const Vector<Color> *)p_self; - return (const godot_color *)self->ptr(); +const godot_vector3 GDAPI *godot_packed_vector3_array_operator_index_const(const godot_packed_vector3_array *p_self, godot_int p_index) { + const PackedVector3Array *self = (const PackedVector3Array *)p_self; + return (const godot_vector3 *)&self->operator[](p_index); } -godot_color GDAPI *godot_packed_color_array_ptrw(godot_packed_color_array *p_self) { - Vector<Color> *self = (Vector<Color> *)p_self; - return (godot_color *)self->ptrw(); -} - -void GDAPI godot_packed_color_array_append(godot_packed_color_array *p_self, const godot_color *p_data) { - Vector<Color> *self = (Vector<Color> *)p_self; - Color &s = *(Color *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_self, const godot_packed_color_array *p_array) { - Vector<Color> *self = (Vector<Color> *)p_self; - Vector<Color> *array = (Vector<Color> *)p_array; - self->append_array(*array); -} +// vector3i -godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data) { - Vector<Color> *self = (Vector<Color> *)p_self; - Color &s = *(Color *)p_data; - return (godot_error)self->insert(p_idx, s); +void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self) { + memnew_placement(p_self, Vector<Vector3i>); } -godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value) { - Vector<Color> *self = (Vector<Color> *)p_self; - Color &c = *(Color *)p_value; - return (godot_bool)self->has(c); +void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_self) { + ((Vector<Vector3i> *)p_self)->~Vector(); } -void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self) { - Vector<Color> *self = (Vector<Color> *)p_self; - self->sort(); +godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index(godot_packed_vector3i_array *p_self, godot_int p_index) { + Vector<Vector3i> *self = (Vector<Vector3i> *)p_self; + return (godot_vector3i *)&self->operator[](p_index); } -void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self) { - Vector<Color> *self = (Vector<Color> *)p_self; - self->invert(); +const godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index_const(const godot_packed_vector3i_array *p_self, godot_int p_index) { + const Vector<Vector3i> *self = (const Vector<Vector3i> *)p_self; + return (const godot_vector3i *)&self->operator[](p_index); } -void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data) { - Vector<Color> *self = (Vector<Color> *)p_self; - Color &s = *(Color *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_color_array_remove(godot_packed_color_array *p_self, const godot_int p_idx) { - Vector<Color> *self = (Vector<Color> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_color_array_resize(godot_packed_color_array *p_self, const godot_int p_size) { - Vector<Color> *self = (Vector<Color> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_color_array_set(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data) { - Vector<Color> *self = (Vector<Color> *)p_self; - Color &s = *(Color *)p_data; - self->set(p_idx, s); -} +// color -godot_color GDAPI godot_packed_color_array_get(const godot_packed_color_array *p_self, const godot_int p_idx) { - const Vector<Color> *self = (const Vector<Color> *)p_self; - godot_color v; - Color *s = (Color *)&v; - *s = self->get(p_idx); - return v; +void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self) { + memnew_placement(p_self, PackedColorArray); } -godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self) { - const Vector<Color> *self = (const Vector<Color> *)p_self; - return self->size(); +void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) { + ((PackedColorArray *)p_self)->~PackedColorArray(); } -godot_bool GDAPI godot_packed_color_array_is_empty(const godot_packed_color_array *p_self) { - const Vector<Color> *self = (const Vector<Color> *)p_self; - return self->is_empty(); +godot_color GDAPI *godot_packed_color_array_operator_index(godot_packed_color_array *p_self, godot_int p_index) { + PackedColorArray *self = (PackedColorArray *)p_self; + return (godot_color *)&self->operator[](p_index); } -void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) { - ((Vector<Color> *)p_self)->~Vector(); +const godot_color GDAPI *godot_packed_color_array_operator_index_const(const godot_packed_color_array *p_self, godot_int p_index) { + const PackedColorArray *self = (const PackedColorArray *)p_self; + return (const godot_color *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp index 32a90d08fa..61d5e09fad 100644 --- a/modules/gdnative/gdnative/plane.cpp +++ b/modules/gdnative/gdnative/plane.cpp @@ -31,139 +31,15 @@ #include "gdnative/plane.h" #include "core/math/plane.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_plane) == sizeof(Plane), "Plane size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_plane) == sizeof(Plane), "Plane size mismatch"); - -void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d) { - Plane *dest = (Plane *)r_dest; - *dest = Plane(p_a, p_b, p_c, p_d); -} - -void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3) { - const Vector3 *v1 = (const Vector3 *)p_v1; - const Vector3 *v2 = (const Vector3 *)p_v2; - const Vector3 *v3 = (const Vector3 *)p_v3; - Plane *dest = (Plane *)r_dest; - *dest = Plane(*v1, *v2, *v3); -} - -void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d) { - const Vector3 *normal = (const Vector3 *)p_normal; - Plane *dest = (Plane *)r_dest; - *dest = Plane(*normal, p_d); -} - -godot_string GDAPI godot_plane_as_string(const godot_plane *p_self) { - godot_string ret; - const Plane *self = (const Plane *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_plane GDAPI godot_plane_normalized(const godot_plane *p_self) { - godot_plane dest; - const Plane *self = (const Plane *)p_self; - *((Plane *)&dest) = self->normalized(); - return dest; -} - -godot_vector3 GDAPI godot_plane_center(const godot_plane *p_self) { - godot_vector3 dest; - const Plane *self = (const Plane *)p_self; - *((Vector3 *)&dest) = self->center(); - return dest; -} - -godot_bool GDAPI godot_plane_is_point_over(const godot_plane *p_self, const godot_vector3 *p_point) { - const Plane *self = (const Plane *)p_self; - const Vector3 *point = (const Vector3 *)p_point; - return self->is_point_over(*point); -} - -godot_real GDAPI godot_plane_distance_to(const godot_plane *p_self, const godot_vector3 *p_point) { - const Plane *self = (const Plane *)p_self; - const Vector3 *point = (const Vector3 *)p_point; - return self->distance_to(*point); -} - -godot_bool GDAPI godot_plane_has_point(const godot_plane *p_self, const godot_vector3 *p_point, const godot_real p_epsilon) { - const Plane *self = (const Plane *)p_self; - const Vector3 *point = (const Vector3 *)p_point; - return self->has_point(*point, p_epsilon); -} - -godot_vector3 GDAPI godot_plane_project(const godot_plane *p_self, const godot_vector3 *p_point) { - godot_vector3 dest; - const Plane *self = (const Plane *)p_self; - const Vector3 *point = (const Vector3 *)p_point; - *((Vector3 *)&dest) = self->project(*point); - return dest; -} - -godot_bool GDAPI godot_plane_intersect_3(const godot_plane *p_self, godot_vector3 *r_dest, const godot_plane *p_b, const godot_plane *p_c) { - const Plane *self = (const Plane *)p_self; - const Plane *b = (const Plane *)p_b; - const Plane *c = (const Plane *)p_c; - Vector3 *dest = (Vector3 *)r_dest; - return self->intersect_3(*b, *c, dest); -} - -godot_bool GDAPI godot_plane_intersects_ray(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_from, const godot_vector3 *p_dir) { - const Plane *self = (const Plane *)p_self; - const Vector3 *from = (const Vector3 *)p_from; - const Vector3 *dir = (const Vector3 *)p_dir; - Vector3 *dest = (Vector3 *)r_dest; - return self->intersects_ray(*from, *dir, dest); -} - -godot_bool GDAPI godot_plane_intersects_segment(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_begin, const godot_vector3 *p_end) { - const Plane *self = (const Plane *)p_self; - const Vector3 *begin = (const Vector3 *)p_begin; - const Vector3 *end = (const Vector3 *)p_end; - Vector3 *dest = (Vector3 *)r_dest; - return self->intersects_segment(*begin, *end, dest); -} - -godot_plane GDAPI godot_plane_operator_neg(const godot_plane *p_self) { - godot_plane raw_dest; - Plane *dest = (Plane *)&raw_dest; - const Plane *self = (const Plane *)p_self; - *dest = -(*self); - return raw_dest; -} - -godot_bool GDAPI godot_plane_operator_equal(const godot_plane *p_self, const godot_plane *p_b) { - const Plane *self = (const Plane *)p_self; - const Plane *b = (const Plane *)p_b; - return *self == *b; -} - -void GDAPI godot_plane_set_normal(godot_plane *p_self, const godot_vector3 *p_normal) { - Plane *self = (Plane *)p_self; - const Vector3 *normal = (const Vector3 *)p_normal; - self->set_normal(*normal); -} - -godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_self) { - const Plane *self = (const Plane *)p_self; - const Vector3 normal = self->get_normal(); - godot_vector3 *v3 = (godot_vector3 *)&normal; - return *v3; -} - -godot_real GDAPI godot_plane_get_d(const godot_plane *p_self) { - const Plane *self = (const Plane *)p_self; - return self->d; -} - -void GDAPI godot_plane_set_d(godot_plane *p_self, const godot_real p_d) { - Plane *self = (Plane *)p_self; - self->d = p_d; +void GDAPI godot_plane_new(godot_plane *p_self) { + memnew_placement(p_self, Plane); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp index 29edad6636..836d6390d6 100644 --- a/modules/gdnative/gdnative/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -31,205 +31,25 @@ #include "gdnative/quat.h" #include "core/math/quat.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_quat) == sizeof(Quat), "Quat size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_quat) == sizeof(Quat), "Quat size mismatch"); - -void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w) { - Quat *dest = (Quat *)r_dest; - *dest = Quat(p_x, p_y, p_z, p_w); -} - -void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle) { - const Vector3 *axis = (const Vector3 *)p_axis; - Quat *dest = (Quat *)r_dest; - *dest = Quat(*axis, p_angle); +void GDAPI godot_quat_new(godot_quat *p_self) { + memnew_placement(p_self, Quat); } -void GDAPI godot_quat_new_with_basis(godot_quat *r_dest, const godot_basis *p_basis) { - const Basis *basis = (const Basis *)p_basis; - Quat *dest = (Quat *)r_dest; - *dest = Quat(*basis); -} - -void GDAPI godot_quat_new_with_euler(godot_quat *r_dest, const godot_vector3 *p_euler) { - const Vector3 *euler = (const Vector3 *)p_euler; - Quat *dest = (Quat *)r_dest; - *dest = Quat(*euler); -} - -godot_real GDAPI godot_quat_get_x(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->x; -} - -void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val) { - Quat *self = (Quat *)p_self; - self->x = val; -} - -godot_real GDAPI godot_quat_get_y(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->y; -} - -void GDAPI godot_quat_set_y(godot_quat *p_self, const godot_real val) { +godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index) { Quat *self = (Quat *)p_self; - self->y = val; -} - -godot_real GDAPI godot_quat_get_z(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->z; -} - -void GDAPI godot_quat_set_z(godot_quat *p_self, const godot_real val) { - Quat *self = (Quat *)p_self; - self->z = val; -} - -godot_real GDAPI godot_quat_get_w(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->w; -} - -void GDAPI godot_quat_set_w(godot_quat *p_self, const godot_real val) { - Quat *self = (Quat *)p_self; - self->w = val; -} - -godot_string GDAPI godot_quat_as_string(const godot_quat *p_self) { - godot_string ret; - const Quat *self = (const Quat *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_real GDAPI godot_quat_length(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->length(); -} - -godot_real GDAPI godot_quat_length_squared(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->length_squared(); -} - -godot_quat GDAPI godot_quat_normalized(const godot_quat *p_self) { - godot_quat dest; - const Quat *self = (const Quat *)p_self; - *((Quat *)&dest) = self->normalized(); - return dest; -} - -godot_bool GDAPI godot_quat_is_normalized(const godot_quat *p_self) { - const Quat *self = (const Quat *)p_self; - return self->is_normalized(); -} - -godot_quat GDAPI godot_quat_inverse(const godot_quat *p_self) { - godot_quat dest; - const Quat *self = (const Quat *)p_self; - *((Quat *)&dest) = self->inverse(); - return dest; -} - -godot_real GDAPI godot_quat_dot(const godot_quat *p_self, const godot_quat *p_b) { - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - return self->dot(*b); + return (godot_real_t *)&self->operator[](p_index); } -godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v) { - godot_vector3 dest; +const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index) { const Quat *self = (const Quat *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - *((Vector3 *)&dest) = self->xform(*v); - return dest; -} - -godot_quat GDAPI godot_quat_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t) { - godot_quat dest; - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - *((Quat *)&dest) = self->slerp(*b, p_t); - return dest; -} - -godot_quat GDAPI godot_quat_slerpni(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t) { - godot_quat dest; - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - *((Quat *)&dest) = self->slerpni(*b, p_t); - return dest; -} - -godot_quat GDAPI godot_quat_cubic_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_quat *p_pre_a, const godot_quat *p_post_b, const godot_real p_t) { - godot_quat dest; - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - const Quat *pre_a = (const Quat *)p_pre_a; - const Quat *post_b = (const Quat *)p_post_b; - *((Quat *)&dest) = self->cubic_slerp(*b, *pre_a, *post_b, p_t); - return dest; -} - -godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const godot_real p_b) { - godot_quat raw_dest; - Quat *dest = (Quat *)&raw_dest; - const Quat *self = (const Quat *)p_self; - *dest = *self * p_b; - return raw_dest; -} - -godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b) { - godot_quat raw_dest; - Quat *dest = (Quat *)&raw_dest; - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - *dest = *self + *b; - return raw_dest; -} - -godot_quat GDAPI godot_quat_operator_subtract(const godot_quat *p_self, const godot_quat *p_b) { - godot_quat raw_dest; - Quat *dest = (Quat *)&raw_dest; - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - *dest = *self - *b; - return raw_dest; -} - -godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b) { - godot_quat raw_dest; - Quat *dest = (Quat *)&raw_dest; - const Quat *self = (const Quat *)p_self; - *dest = *self / p_b; - return raw_dest; -} - -godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot_quat *p_b) { - const Quat *self = (const Quat *)p_self; - const Quat *b = (const Quat *)p_b; - return *self == *b; -} - -godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self) { - godot_quat raw_dest; - Quat *dest = (Quat *)&raw_dest; - const Quat *self = (const Quat *)p_self; - *dest = -(*self); - return raw_dest; -} - -void GDAPI godot_quat_set_axis_angle(godot_quat *p_self, const godot_vector3 *p_axis, const godot_real p_angle) { - Quat *self = (Quat *)p_self; - const Vector3 *axis = (const Vector3 *)p_axis; - self->set_axis_angle(*axis, p_angle); + return (const godot_real_t *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index 40e8e64ca1..086592ec22 100644 --- a/modules/gdnative/gdnative/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -30,300 +30,21 @@ #include "gdnative/rect2.h" -#include "core/math/transform_2d.h" -#include "core/variant/variant.h" - -#ifdef __cplusplus -extern "C" { -#endif +#include "core/math/rect2.h" static_assert(sizeof(godot_rect2) == sizeof(Rect2), "Rect2 size mismatch"); static_assert(sizeof(godot_rect2i) == sizeof(Rect2i), "Rect2i size mismatch"); -// Rect2 - -void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size) { - const Vector2 *position = (const Vector2 *)p_pos; - const Vector2 *size = (const Vector2 *)p_size; - Rect2 *dest = (Rect2 *)r_dest; - *dest = Rect2(*position, *size); -} - -void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height) { - Rect2 *dest = (Rect2 *)r_dest; - *dest = Rect2(p_x, p_y, p_width, p_height); -} - -godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self) { - godot_string ret; - const Rect2 *self = (const Rect2 *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_rect2i GDAPI godot_rect2_as_rect2i(const godot_rect2 *p_self) { - godot_rect2i dest; - const Rect2 *self = (const Rect2 *)p_self; - *((Rect2i *)&dest) = Rect2i(*self); - return dest; -} - -godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self) { - const Rect2 *self = (const Rect2 *)p_self; - return self->get_area(); -} - -godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b) { - const Rect2 *self = (const Rect2 *)p_self; - const Rect2 *b = (const Rect2 *)p_b; - return self->intersects(*b); -} - -godot_bool GDAPI godot_rect2_encloses(const godot_rect2 *p_self, const godot_rect2 *p_b) { - const Rect2 *self = (const Rect2 *)p_self; - const Rect2 *b = (const Rect2 *)p_b; - return self->encloses(*b); -} - -godot_bool GDAPI godot_rect2_has_no_area(const godot_rect2 *p_self) { - const Rect2 *self = (const Rect2 *)p_self; - return self->has_no_area(); -} - -godot_rect2 GDAPI godot_rect2_intersection(const godot_rect2 *p_self, const godot_rect2 *p_b) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - const Rect2 *b = (const Rect2 *)p_b; - *((Rect2 *)&dest) = self->intersection(*b); - return dest; -} - -godot_rect2 GDAPI godot_rect2_merge(const godot_rect2 *p_self, const godot_rect2 *p_b) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - const Rect2 *b = (const Rect2 *)p_b; - *((Rect2 *)&dest) = self->merge(*b); - return dest; -} - -godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_vector2 *p_point) { - const Rect2 *self = (const Rect2 *)p_self; - const Vector2 *point = (const Vector2 *)p_point; - return self->has_point(*point); -} - -godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - - *((Rect2 *)&dest) = self->grow(p_by); - return dest; -} - -godot_rect2 GDAPI godot_rect2_grow_individual(const godot_rect2 *p_self, const godot_real p_left, const godot_real p_top, const godot_real p_right, const godot_real p_bottom) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - *((Rect2 *)&dest) = self->grow_individual(p_left, p_top, p_right, p_bottom); - return dest; -} - -godot_rect2 GDAPI godot_rect2_grow_side(const godot_rect2 *p_self, const godot_int p_side, const godot_real p_by) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - *((Rect2 *)&dest) = self->grow_side((Side)p_side, p_by); - return dest; -} - -godot_rect2 GDAPI godot_rect2_abs(const godot_rect2 *p_self) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - *((Rect2 *)&dest) = self->abs(); - return dest; -} - -godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to) { - godot_rect2 dest; - const Rect2 *self = (const Rect2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - *((Rect2 *)&dest) = self->expand(*to); - return dest; -} - -godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b) { - const Rect2 *self = (const Rect2 *)p_self; - const Rect2 *b = (const Rect2 *)p_b; - return *self == *b; -} - -godot_vector2 GDAPI godot_rect2_get_position(const godot_rect2 *p_self) { - godot_vector2 dest; - Vector2 *d = (Vector2 *)&dest; - const Rect2 *self = (const Rect2 *)p_self; - *d = self->get_position(); - return dest; -} - -godot_vector2 GDAPI godot_rect2_get_size(const godot_rect2 *p_self) { - godot_vector2 dest; - Vector2 *d = (Vector2 *)&dest; - const Rect2 *self = (const Rect2 *)p_self; - *d = self->get_size(); - return dest; -} - -void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_pos) { - Rect2 *self = (Rect2 *)p_self; - const Vector2 *position = (const Vector2 *)p_pos; - self->set_position(*position); -} - -void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size) { - Rect2 *self = (Rect2 *)p_self; - const Vector2 *size = (const Vector2 *)p_size; - self->set_size(*size); -} - -// Rect2i - -void GDAPI godot_rect2i_new_with_position_and_size(godot_rect2i *r_dest, const godot_vector2i *p_pos, const godot_vector2i *p_size) { - const Vector2i *position = (const Vector2i *)p_pos; - const Vector2i *size = (const Vector2i *)p_size; - Rect2i *dest = (Rect2i *)r_dest; - *dest = Rect2i(*position, *size); -} - -void GDAPI godot_rect2i_new(godot_rect2i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_width, const godot_int p_height) { - Rect2i *dest = (Rect2i *)r_dest; - *dest = Rect2i(p_x, p_y, p_width, p_height); -} - -godot_string GDAPI godot_rect2i_as_string(const godot_rect2i *p_self) { - godot_string ret; - const Rect2i *self = (const Rect2i *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_rect2 GDAPI godot_rect2i_as_rect2(const godot_rect2i *p_self) { - godot_rect2 dest; - const Rect2i *self = (const Rect2i *)p_self; - *((Rect2 *)&dest) = Rect2(*self); - return dest; -} - -godot_int GDAPI godot_rect2i_get_area(const godot_rect2i *p_self) { - const Rect2i *self = (const Rect2i *)p_self; - return self->get_area(); -} - -godot_bool GDAPI godot_rect2i_intersects(const godot_rect2i *p_self, const godot_rect2i *p_b) { - const Rect2i *self = (const Rect2i *)p_self; - const Rect2i *b = (const Rect2i *)p_b; - return self->intersects(*b); -} - -godot_bool GDAPI godot_rect2i_encloses(const godot_rect2i *p_self, const godot_rect2i *p_b) { - const Rect2i *self = (const Rect2i *)p_self; - const Rect2i *b = (const Rect2i *)p_b; - return self->encloses(*b); -} - -godot_bool GDAPI godot_rect2i_has_no_area(const godot_rect2i *p_self) { - const Rect2i *self = (const Rect2i *)p_self; - return self->has_no_area(); -} - -godot_rect2i GDAPI godot_rect2i_intersection(const godot_rect2i *p_self, const godot_rect2i *p_b) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - const Rect2i *b = (const Rect2i *)p_b; - *((Rect2i *)&dest) = self->intersection(*b); - return dest; -} - -godot_rect2i GDAPI godot_rect2i_merge(const godot_rect2i *p_self, const godot_rect2i *p_b) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - const Rect2i *b = (const Rect2i *)p_b; - *((Rect2i *)&dest) = self->merge(*b); - return dest; -} - -godot_bool GDAPI godot_rect2i_has_point(const godot_rect2i *p_self, const godot_vector2i *p_point) { - const Rect2i *self = (const Rect2i *)p_self; - const Vector2i *point = (const Vector2i *)p_point; - return self->has_point(*point); -} - -godot_rect2i GDAPI godot_rect2i_grow(const godot_rect2i *p_self, const godot_int p_by) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - - *((Rect2i *)&dest) = self->grow(p_by); - return dest; -} - -godot_rect2i GDAPI godot_rect2i_grow_individual(const godot_rect2i *p_self, const godot_int p_left, const godot_int p_top, const godot_int p_right, const godot_int p_bottom) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - *((Rect2i *)&dest) = self->grow_individual(p_left, p_top, p_right, p_bottom); - return dest; -} - -godot_rect2i GDAPI godot_rect2i_grow_side(const godot_rect2i *p_self, const godot_int p_side, const godot_int p_by) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - *((Rect2i *)&dest) = self->grow_side((Side)p_side, p_by); - return dest; -} - -godot_rect2i GDAPI godot_rect2i_abs(const godot_rect2i *p_self) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - *((Rect2i *)&dest) = self->abs(); - return dest; -} - -godot_rect2i GDAPI godot_rect2i_expand(const godot_rect2i *p_self, const godot_vector2i *p_to) { - godot_rect2i dest; - const Rect2i *self = (const Rect2i *)p_self; - const Vector2i *to = (const Vector2i *)p_to; - *((Rect2i *)&dest) = self->expand(*to); - return dest; -} - -godot_bool GDAPI godot_rect2i_operator_equal(const godot_rect2i *p_self, const godot_rect2i *p_b) { - const Rect2i *self = (const Rect2i *)p_self; - const Rect2i *b = (const Rect2i *)p_b; - return *self == *b; -} - -godot_vector2i GDAPI godot_rect2i_get_position(const godot_rect2i *p_self) { - godot_vector2i dest; - Vector2i *d = (Vector2i *)&dest; - const Rect2i *self = (const Rect2i *)p_self; - *d = self->get_position(); - return dest; -} - -godot_vector2i GDAPI godot_rect2i_get_size(const godot_rect2i *p_self) { - godot_vector2i dest; - Vector2i *d = (Vector2i *)&dest; - const Rect2i *self = (const Rect2i *)p_self; - *d = self->get_size(); - return dest; -} +#ifdef __cplusplus +extern "C" { +#endif -void GDAPI godot_rect2i_set_position(godot_rect2i *p_self, const godot_vector2i *p_pos) { - Rect2i *self = (Rect2i *)p_self; - const Vector2i *position = (const Vector2i *)p_pos; - self->set_position(*position); +void GDAPI godot_rect2_new(godot_rect2 *p_self) { + memnew_placement(p_self, Rect2); } -void GDAPI godot_rect2i_set_size(godot_rect2i *p_self, const godot_vector2i *p_size) { - Rect2i *self = (Rect2i *)p_self; - const Vector2i *size = (const Vector2i *)p_size; - self->set_size(*size); +void GDAPI godot_rect2i_new(godot_rect2i *p_self) { + memnew_placement(p_self, Rect2i); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp index 33685ef51f..5cab9a21ed 100644 --- a/modules/gdnative/gdnative/rid.cpp +++ b/modules/gdnative/gdnative/rid.cpp @@ -30,45 +30,17 @@ #include "gdnative/rid.h" -#include "core/io/resource.h" +#include "core/os/memory.h" #include "core/templates/rid.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_rid) == sizeof(RID), "RID size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_rid) == sizeof(RID), "RID size mismatch"); - -void GDAPI godot_rid_new(godot_rid *r_dest) { - RID *dest = (RID *)r_dest; - memnew_placement(dest, RID); -} - -godot_int GDAPI godot_rid_get_id(const godot_rid *p_self) { - const RID *self = (const RID *)p_self; - return self->get_id(); -} - -void GDAPI godot_rid_new_with_resource(godot_rid *r_dest, const godot_object *p_from) { - const Resource *res_from = Object::cast_to<Resource>((Object *)p_from); - godot_rid_new(r_dest); - if (res_from) { - RID *dest = (RID *)r_dest; - *dest = RID(res_from->get_rid()); - } -} - -godot_bool GDAPI godot_rid_operator_equal(const godot_rid *p_self, const godot_rid *p_b) { - const RID *self = (const RID *)p_self; - const RID *b = (const RID *)p_b; - return *self == *b; -} - -godot_bool GDAPI godot_rid_operator_less(const godot_rid *p_self, const godot_rid *p_b) { - const RID *self = (const RID *)p_self; - const RID *b = (const RID *)p_b; - return *self < *b; +void GDAPI godot_rid_new(godot_rid *p_self) { + memnew_placement(p_self, RID); } #ifdef __cplusplus diff --git a/core/os/thread_dummy.cpp b/modules/gdnative/gdnative/signal.cpp index 006757b8e4..bcb4c93b62 100644 --- a/core/os/thread_dummy.cpp +++ b/modules/gdnative/gdnative/signal.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* thread_dummy.cpp */ +/* signal.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,22 +28,26 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "thread_dummy.h" +#include "gdnative/signal.h" -#include "core/os/memory.h" +#include "core/variant/callable.h" +#include "core/variant/variant.h" -Thread *ThreadDummy::create(ThreadCreateCallback p_callback, void *p_user, const Thread::Settings &p_settings) { - return memnew(ThreadDummy); -} +static_assert(sizeof(godot_signal) == sizeof(Signal), "Signal size mismatch"); + +#ifdef __cplusplus +extern "C" { +#endif -void ThreadDummy::make_default() { - Thread::create_func = &ThreadDummy::create; +void GDAPI godot_signal_new(godot_signal *p_self) { + memnew_placement(p_self, Signal); } -RWLock *RWLockDummy::create() { - return memnew(RWLockDummy); +void GDAPI godot_signal_destroy(godot_signal *p_self) { + Signal *self = (Signal *)p_self; + self->~Signal(); } -void RWLockDummy::make_default() { - RWLock::create_func = &RWLockDummy::create; +#ifdef __cplusplus } +#endif diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 734bbe0d16..19d95f2048 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -30,57 +30,15 @@ #include "gdnative/string.h" -#include "core/string/string_name.h" #include "core/string/ustring.h" -#include "core/variant/variant.h" -#include <string.h> +static_assert(sizeof(godot_string) == sizeof(String), "String size mismatch"); +static_assert(sizeof(godot_char_type) == sizeof(char32_t), "char32_t size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_char16_string) == sizeof(Char16String), "Char16String size mismatch"); -static_assert(sizeof(godot_char_string) == sizeof(CharString), "CharString size mismatch"); -static_assert(sizeof(godot_string) == sizeof(String), "String size mismatch"); -static_assert(sizeof(godot_char_type) == sizeof(char32_t), "char32_t size mismatch"); - -godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs) { - const CharString *cs = (const CharString *)p_cs; - - return cs->length(); -} - -const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs) { - const CharString *cs = (const CharString *)p_cs; - - return cs->get_data(); -} - -void GDAPI godot_char_string_destroy(godot_char_string *p_cs) { - CharString *cs = (CharString *)p_cs; - - cs->~CharString(); -} - -godot_int GDAPI godot_char16_string_length(const godot_char16_string *p_cs) { - const Char16String *cs = (const Char16String *)p_cs; - - return cs->length(); -} - -const char16_t GDAPI *godot_char16_string_get_data(const godot_char16_string *p_cs) { - const Char16String *cs = (const Char16String *)p_cs; - - return cs->get_data(); -} - -void GDAPI godot_char16_string_destroy(godot_char16_string *p_cs) { - Char16String *cs = (Char16String *)p_cs; - - cs->~Char16String(); -} - void GDAPI godot_string_new(godot_string *r_dest) { String *dest = (String *)r_dest; memnew_placement(dest, String); @@ -167,1206 +125,11 @@ void GDAPI godot_string_new_with_wide_chars_and_len(godot_string *r_dest, const } } -const godot_char_type GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx) { - String *self = (String *)p_self; - return &(self->operator[](p_idx)); -} - -godot_char_type GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx) { - const String *self = (const String *)p_self; - return self->operator[](p_idx); -} - -const godot_char_type GDAPI *godot_string_get_data(const godot_string *p_self) { - const String *self = (const String *)p_self; - return self->get_data(); -} - -godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b) { - const String *self = (const String *)p_self; - const String *b = (const String *)p_b; - return *self == *b; -} - -godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b) { - const String *self = (const String *)p_self; - const String *b = (const String *)p_b; - return *self < *b; -} - -godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b) { - godot_string ret; - const String *self = (const String *)p_self; - const String *b = (const String *)p_b; - memnew_placement(&ret, String(*self + *b)); - return ret; -} - void GDAPI godot_string_destroy(godot_string *p_self) { String *self = (String *)p_self; self->~String(); } -/* Standard size stuff */ - -godot_int GDAPI godot_string_length(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->length(); -} - -/* Helpers */ - -signed char GDAPI godot_string_casecmp_to(const godot_string *p_self, const godot_string *p_str) { - const String *self = (const String *)p_self; - const String *str = (const String *)p_str; - - return self->casecmp_to(*str); -} - -signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const godot_string *p_str) { - const String *self = (const String *)p_self; - const String *str = (const String *)p_str; - - return self->nocasecmp_to(*str); -} - -signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str) { - const String *self = (const String *)p_self; - const String *str = (const String *)p_str; - - return self->naturalnocasecmp_to(*str); -} - -godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string) { - const String *self = (const String *)p_self; - const String *string = (const String *)p_string; - - return self->begins_with(*string); -} - -godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array) { - const String *self = (const String *)p_self; - - return self->begins_with(p_char_array); -} - -godot_packed_string_array GDAPI godot_string_bigrams(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->bigrams())); - return ret; -}; - -godot_string GDAPI godot_string_chr(godot_char_type p_character) { - godot_string result; - memnew_placement(&result, String(String::chr(p_character))); - - return result; -} - -godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string) { - const String *self = (const String *)p_self; - const String *string = (const String *)p_string; - - return self->ends_with(*string); -} - -godot_bool GDAPI godot_string_ends_with_char_array(const godot_string *p_self, const char *p_char_array) { - const String *self = (const String *)p_self; - - return self->ends_with(p_char_array); -} - -godot_int GDAPI godot_string_count(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->count(*what, p_from, p_to); -} - -godot_int GDAPI godot_string_countn(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->countn(*what, p_from, p_to); -} - -godot_int GDAPI godot_string_find(const godot_string *p_self, const godot_string *p_what) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->find(*what); -} - -godot_int GDAPI godot_string_find_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->find(*what, p_from); -} - -godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_packed_string_array *p_keys) { - const String *self = (const String *)p_self; - const Vector<String> *keys = (const Vector<String> *)p_keys; - return self->findmk(*keys); -} - -godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from) { - const String *self = (const String *)p_self; - const Vector<String> *keys = (const Vector<String> *)p_keys; - return self->findmk(*keys, p_from); -} - -godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from, godot_int *r_key) { - const String *self = (const String *)p_self; - const Vector<String> *keys = (const Vector<String> *)p_keys; - int key; - int ret = self->findmk(*keys, p_from, &key); - if (r_key) { - *r_key = key; - } - return ret; -} - -godot_int GDAPI godot_string_findn(const godot_string *p_self, const godot_string *p_what) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->findn(*what); -} - -godot_int GDAPI godot_string_findn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->findn(*what, p_from); -} - -godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values) { - const String *self = (const String *)p_self; - const Variant *values = (const Variant *)p_values; - godot_string result; - memnew_placement(&result, String(self->format(*values))); - - return result; -} - -godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder) { - const String *self = (const String *)p_self; - const Variant *values = (const Variant *)p_values; - String placeholder = String(p_placeholder); - godot_string result; - memnew_placement(&result, String(self->format(*values, placeholder))); - - return result; -} - -godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len) { - godot_string result; - memnew_placement(&result, String(String::hex_encode_buffer(p_buffer, p_len))); - - return result; -} - -godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, const godot_string *p_string) { - const String *self = (const String *)p_self; - const String *content = (const String *)p_string; - godot_string result; - memnew_placement(&result, String(self->insert(p_at_pos, *content))); - - return result; -} - -godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_numeric(); -} - -godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string) { - const String *self = (const String *)p_self; - const String *string = (const String *)p_string; - - return self->is_subsequence_of(*string); -} - -godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string) { - const String *self = (const String *)p_self; - const String *string = (const String *)p_string; - - return self->is_subsequence_ofi(*string); -} - -godot_string GDAPI godot_string_lpad(const godot_string *p_self, godot_int p_min_length) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->lpad(p_min_length))); - - return result; -} - -godot_string GDAPI godot_string_lpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character) { - const String *self = (const String *)p_self; - const String *character = (const String *)p_character; - godot_string result; - memnew_placement(&result, String(self->lpad(p_min_length, *character))); - - return result; -} - -godot_bool GDAPI godot_string_match(const godot_string *p_self, const godot_string *p_wildcard) { - const String *self = (const String *)p_self; - const String *wildcard = (const String *)p_wildcard; - - return self->match(*wildcard); -} - -godot_bool GDAPI godot_string_matchn(const godot_string *p_self, const godot_string *p_wildcard) { - const String *self = (const String *)p_self; - const String *wildcard = (const String *)p_wildcard; - - return self->matchn(*wildcard); -} - -godot_string GDAPI godot_string_md5(const uint8_t *p_md5) { - godot_string result; - memnew_placement(&result, String(String::md5(p_md5))); - - return result; -} - -godot_string GDAPI godot_string_num(double p_num) { - godot_string result; - memnew_placement(&result, String(String::num(p_num))); - - return result; -} - -godot_string GDAPI godot_string_num_int64(int64_t p_num, godot_int p_base) { - godot_string result; - memnew_placement(&result, String(String::num_int64(p_num, p_base))); - - return result; -} - -godot_string GDAPI godot_string_num_int64_capitalized(int64_t p_num, godot_int p_base, godot_bool p_capitalize_hex) { - godot_string result; - memnew_placement(&result, String(String::num_int64(p_num, p_base, true))); - - return result; -} - -godot_string GDAPI godot_string_num_real(double p_num) { - godot_string result; - memnew_placement(&result, String(String::num_real(p_num))); - - return result; -} - -godot_string GDAPI godot_string_num_scientific(double p_num) { - godot_string result; - memnew_placement(&result, String(String::num_scientific(p_num))); - - return result; -} - -godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals) { - godot_string result; - memnew_placement(&result, String(String::num(p_num, p_decimals))); - - return result; -} - -godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->pad_decimals(p_digits))); - - return result; -} - -godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->pad_zeros(p_digits))); - - return result; -} - -godot_string GDAPI godot_string_replace(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) { - const String *self = (const String *)p_self; - const String *key = (const String *)p_key; - const String *with = (const String *)p_with; - godot_string result; - memnew_placement(&result, String(self->replace(*key, *with))); - - return result; -} - -godot_string GDAPI godot_string_replacen(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) { - const String *self = (const String *)p_self; - const String *key = (const String *)p_key; - const String *with = (const String *)p_with; - godot_string result; - memnew_placement(&result, String(self->replacen(*key, *with))); - - return result; -} - -godot_int GDAPI godot_string_rfind(const godot_string *p_self, const godot_string *p_what) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->rfind(*what); -} - -godot_int GDAPI godot_string_rfindn(const godot_string *p_self, const godot_string *p_what) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->rfindn(*what); -} - -godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->rfind(*what, p_from); -} - -godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) { - const String *self = (const String *)p_self; - const String *what = (const String *)p_what; - - return self->rfindn(*what, p_from); -} - -godot_string GDAPI godot_string_replace_first(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) { - const String *self = (const String *)p_self; - const String *key = (const String *)p_key; - const String *with = (const String *)p_with; - godot_string result; - memnew_placement(&result, String(self->replace_first(*key, *with))); - - return result; -} - -godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->rpad(p_min_length))); - - return result; -} - -godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character) { - const String *self = (const String *)p_self; - const String *character = (const String *)p_character; - godot_string result; - memnew_placement(&result, String(self->rpad(p_min_length, *character))); - - return result; -} - -godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string) { - const String *self = (const String *)p_self; - const String *string = (const String *)p_string; - - return self->similarity(*string); -} - -godot_string GDAPI godot_string_sprintf(const godot_string *p_self, const godot_array *p_values, godot_bool *p_error) { - const String *self = (const String *)p_self; - const Array *values = (const Array *)p_values; - - godot_string result; - String return_value = self->sprintf(*values, p_error); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_from, godot_int p_chars) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->substr(p_from, p_chars))); - - return result; -} - -godot_int GDAPI godot_string_to_int(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->to_int(); -} - -double GDAPI godot_string_to_float(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->to_float(); -} - -godot_string GDAPI godot_string_capitalize(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->capitalize())); - - return result; -} - -godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->camelcase_to_underscore(false))); - - return result; -} - -godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->camelcase_to_underscore())); - - return result; -} - -double GDAPI godot_string_char_to_float(const char *p_what) { - return String::to_float(p_what); -} - -double GDAPI godot_string_wchar_to_float(const wchar_t *p_str, const wchar_t **r_end) { - return String::to_float(p_str, r_end); -} - -godot_int GDAPI godot_string_char_to_int(const char *p_what) { - return String::to_int(p_what); -} - -godot_int GDAPI godot_string_wchar_to_int(const wchar_t *p_str) { - return String::to_int(p_str); -} - -godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len) { - return String::to_int(p_what, p_len); -} - -godot_int GDAPI godot_string_wchar_to_int_with_len(const wchar_t *p_str, int p_len) { - return String::to_int(p_str, p_len); -} - -godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->hex_to_int(false); -} - -godot_int GDAPI godot_string_hex_to_int_with_prefix(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->hex_to_int(); -} - -godot_string GDAPI godot_string_get_slice(const godot_string *p_self, const godot_string *p_splitter, godot_int p_slice) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - godot_string result; - memnew_placement(&result, String(self->get_slice(*splitter, p_slice))); - - return result; -} - -godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, godot_char_type p_splitter, godot_int p_slice) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->get_slicec(p_splitter, p_slice))); - - return result; -} - -godot_packed_string_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->split(*splitter, false))); - return ret; -} - -godot_packed_string_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->split(*splitter, true))); - return ret; -} - -godot_packed_string_array GDAPI godot_string_split_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->split(*splitter, p_allow_empty, p_maxsplit))); - return ret; -} - -godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, false))); - return ret; -} - -godot_packed_string_array GDAPI godot_string_rsplit_allow_empty(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, true))); - return ret; -} - -godot_packed_string_array GDAPI godot_string_rsplit_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, p_allow_empty, p_maxsplit))); - return ret; -} - -godot_packed_float32_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_float32_array ret; - memnew_placement(&ret, Vector<float>(self->split_floats(*splitter, false))); - return ret; -} - -godot_packed_float32_array GDAPI godot_string_split_floats_allow_empty(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_float32_array ret; - memnew_placement(&ret, Vector<float>(self->split_floats(*splitter, true))); - return ret; -} - -godot_packed_float32_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters) { - const String *self = (const String *)p_self; - const Vector<String> *splitters = (const Vector<String> *)p_splitters; - - godot_packed_float32_array ret; - memnew_placement(&ret, Vector<float>(self->split_floats_mk(*splitters, false))); - return ret; -} - -godot_packed_float32_array GDAPI godot_string_split_floats_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters) { - const String *self = (const String *)p_self; - const Vector<String> *splitters = (const Vector<String> *)p_splitters; - - godot_packed_float32_array ret; - memnew_placement(&ret, Vector<float>(self->split_floats_mk(*splitters, true))); - return ret; -} - -godot_packed_int32_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_int32_array ret; - memnew_placement(&ret, Vector<int>(self->split_ints(*splitter, false))); - return ret; -} - -godot_packed_int32_array GDAPI godot_string_split_ints_allow_empty(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - godot_packed_int32_array ret; - memnew_placement(&ret, Vector<int>(self->split_ints(*splitter, true))); - return ret; -} - -godot_packed_int32_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters) { - const String *self = (const String *)p_self; - const Vector<String> *splitters = (const Vector<String> *)p_splitters; - - godot_packed_int32_array ret; - memnew_placement(&ret, Vector<int>(self->split_ints_mk(*splitters, false))); - return ret; -} - -godot_packed_int32_array GDAPI godot_string_split_ints_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters) { - const String *self = (const String *)p_self; - const Vector<String> *splitters = (const Vector<String> *)p_splitters; - - godot_packed_int32_array ret; - memnew_placement(&ret, Vector<int>(self->split_ints_mk(*splitters, true))); - return ret; -} - -godot_packed_string_array GDAPI godot_string_split_spaces(const godot_string *p_self) { - const String *self = (const String *)p_self; - - godot_packed_string_array ret; - memnew_placement(&ret, Vector<String>(self->split_spaces())); - return ret; -} - -godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, const godot_string *p_splitter) { - const String *self = (const String *)p_self; - const String *splitter = (const String *)p_splitter; - - return self->get_slice_count(*splitter); -} - -godot_char_type GDAPI godot_string_char_lowercase(godot_char_type p_char) { - return String::char_lowercase(p_char); -} - -godot_char_type GDAPI godot_string_char_uppercase(godot_char_type p_char) { - return String::char_uppercase(p_char); -} - -godot_string GDAPI godot_string_to_lower(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->to_lower())); - - return result; -} - -godot_string GDAPI godot_string_to_upper(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->to_upper())); - - return result; -} - -godot_string GDAPI godot_string_get_basename(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->get_basename())); - - return result; -} - -godot_string GDAPI godot_string_get_extension(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->get_extension())); - - return result; -} - -godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->left(p_pos))); - - return result; -} - -godot_char_type GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx) { - const String *self = (const String *)p_self; - - return self->ord_at(p_idx); -} - -godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file) { - const String *self = (const String *)p_self; - const String *file = (const String *)p_file; - godot_string result; - memnew_placement(&result, String(self->plus_file(*file))); - - return result; -} - -godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->right(p_pos))); - - return result; -} - -godot_string GDAPI godot_string_repeat(const godot_string *p_self, godot_int p_count) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->repeat(p_count))); - - return result; -} - -godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->strip_edges(p_left, p_right))); - - return result; -} - -godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->strip_escapes())); - - return result; -} - -void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars) { - String *self = (String *)p_self; - - return self->erase(p_pos, p_chars); -} - -godot_char_string GDAPI godot_string_ascii(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_char_string result; - - memnew_placement(&result, CharString(self->ascii())); - - return result; -} - -godot_char_string GDAPI godot_string_latin1(const godot_string *p_self) { - const String *self = (const String *)p_self; - - godot_char_string result; - - memnew_placement(&result, CharString(self->ascii(true))); - - return result; -} - -godot_char_string GDAPI godot_string_utf8(const godot_string *p_self) { - const String *self = (const String *)p_self; - - godot_char_string result; - - memnew_placement(&result, CharString(self->utf8())); - - return result; -} - -godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8) { - String *self = (String *)p_self; - - return self->parse_utf8(p_utf8); -} - -godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len) { - String *self = (String *)p_self; - - return self->parse_utf8(p_utf8, p_len); -} - -godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8) { - godot_string result; - memnew_placement(&result, String(String::utf8(p_utf8))); - - return result; -} - -godot_string GDAPI godot_string_chars_to_utf8_with_len(const char *p_utf8, godot_int p_len) { - godot_string result; - memnew_placement(&result, String(String::utf8(p_utf8, p_len))); - - return result; -} - -godot_char16_string GDAPI godot_string_utf16(const godot_string *p_self) { - const String *self = (const String *)p_self; - - godot_char16_string result; - - memnew_placement(&result, Char16String(self->utf16())); - - return result; -} - -godot_bool GDAPI godot_string_parse_utf16(godot_string *p_self, const char16_t *p_utf16) { - String *self = (String *)p_self; - - return self->parse_utf16(p_utf16); -} - -godot_bool GDAPI godot_string_parse_utf16_with_len(godot_string *p_self, const char16_t *p_utf16, godot_int p_len) { - String *self = (String *)p_self; - - return self->parse_utf16(p_utf16, p_len); -} - -godot_string GDAPI godot_string_chars_to_utf16(const char16_t *p_utf16) { - godot_string result; - memnew_placement(&result, String(String::utf16(p_utf16))); - - return result; -} - -godot_string GDAPI godot_string_chars_to_utf16_with_len(const char16_t *p_utf16, godot_int p_len) { - godot_string result; - memnew_placement(&result, String(String::utf16(p_utf16, p_len))); - - return result; -} - -uint32_t GDAPI godot_string_hash(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->hash(); -} - -uint64_t GDAPI godot_string_hash64(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->hash64(); -} - -uint32_t GDAPI godot_string_hash_chars(const char *p_cstr) { - return String::hash(p_cstr); -} - -uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len) { - return String::hash(p_cstr, p_len); -} - -uint32_t GDAPI godot_string_hash_wide_chars(const wchar_t *p_str) { - return String::hash(p_str); -} - -uint32_t GDAPI godot_string_hash_wide_chars_with_len(const wchar_t *p_str, godot_int p_len) { - return String::hash(p_str, p_len); -} - -godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_packed_byte_array result; - memnew_placement(&result, PackedByteArray(self->md5_buffer())); - return result; -} - -godot_string GDAPI godot_string_md5_text(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->md5_text())); - - return result; -} - -godot_packed_byte_array GDAPI godot_string_sha1_buffer(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_packed_byte_array result; - memnew_placement(&result, PackedByteArray(self->sha1_buffer())); - return result; -} - -godot_string GDAPI godot_string_sha1_text(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->sha1_text())); - - return result; -} - -godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_packed_byte_array result; - memnew_placement(&result, PackedByteArray(self->sha256_buffer())); - return result; -} - -godot_string GDAPI godot_string_sha256_text(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - memnew_placement(&result, String(self->sha256_text())); - - return result; -} - -godot_bool godot_string_is_empty(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_empty(); -} - -// path functions -godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->get_base_dir(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_get_file(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->get_file(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_humanize_size(uint64_t p_size) { - godot_string result; - String return_value = String::humanize_size(p_size); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_abs_path(); -} - -godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_rel_path(); -} - -godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_resource_file(); -} - -godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path) { - const String *self = (const String *)p_self; - String *path = (String *)p_path; - godot_string result; - String return_value = self->path_to(*path); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path) { - const String *self = (const String *)p_self; - String *path = (String *)p_path; - godot_string result; - String return_value = self->path_to_file(*path); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_simplify_path(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->simplify_path(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_c_escape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->c_escape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->c_escape_multiline(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_c_unescape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->c_unescape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_http_escape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->http_escape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_http_unescape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->http_unescape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_json_escape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->json_escape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_xml_escape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->xml_escape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->xml_escape(true); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->xml_unescape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_percent_decode(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->percent_decode(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_percent_encode(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->percent_encode(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_join(const godot_string *p_self, const godot_packed_string_array *p_parts) { - const String *self = (const String *)p_self; - const Vector<String> *parts = (const Vector<String> *)p_parts; - godot_string result; - String return_value = self->join(*parts); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_bool GDAPI godot_string_is_valid_filename(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_valid_filename(); -} - -godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_valid_float(); -} - -godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix) { - const String *self = (const String *)p_self; - - return self->is_valid_hex_number(p_with_prefix); -} - -godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_valid_html_color(); -} - -godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_valid_identifier(); -} - -godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_valid_integer(); -} - -godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self) { - const String *self = (const String *)p_self; - - return self->is_valid_ip_address(); -} - -godot_string GDAPI godot_string_dedent(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->dedent(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix) { - const String *self = (const String *)p_self; - String *prefix = (String *)p_prefix; - godot_string result; - String return_value = self->trim_prefix(*prefix); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix) { - const String *self = (const String *)p_self; - String *suffix = (String *)p_suffix; - godot_string result; - String return_value = self->trim_suffix(*suffix); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_lstrip(const godot_string *p_self, const godot_string *p_chars) { - const String *self = (const String *)p_self; - String *chars = (String *)p_chars; - godot_string result; - String return_value = self->lstrip(*chars); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars) { - const String *self = (const String *)p_self; - String *chars = (String *)p_chars; - godot_string result; - String return_value = self->rstrip(*chars); - memnew_placement(&result, String(return_value)); - - return result; -} - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp index 3d83f744d6..c9d2dd5bc3 100644 --- a/modules/gdnative/gdnative/string_name.cpp +++ b/modules/gdnative/gdnative/string_name.cpp @@ -31,54 +31,27 @@ #include "gdnative/string_name.h" #include "core/string/string_name.h" -#include "core/string/ustring.h" -#include <string.h> +static_assert(sizeof(godot_string_name) == sizeof(StringName), "StringName size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_string_name) == sizeof(StringName), "StringName size mismatch"); - -void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name) { +void GDAPI godot_string_name_new(godot_string_name *r_dest) { StringName *dest = (StringName *)r_dest; - const String *name = (const String *)p_name; - memnew_placement(dest, StringName(*name)); + memnew_placement(dest, StringName); } -void GDAPI godot_string_name_new_data(godot_string_name *r_dest, const char *p_name) { +void GDAPI godot_string_name_new_copy(godot_string_name *r_dest, const godot_string_name *p_src) { StringName *dest = (StringName *)r_dest; - memnew_placement(dest, StringName(p_name)); -} - -godot_string GDAPI godot_string_name_get_name(const godot_string_name *p_self) { - godot_string ret; - const StringName *self = (const StringName *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -uint32_t GDAPI godot_string_name_get_hash(const godot_string_name *p_self) { - const StringName *self = (const StringName *)p_self; - return self->hash(); -} - -const void GDAPI *godot_string_name_get_data_unique_pointer(const godot_string_name *p_self) { - const StringName *self = (const StringName *)p_self; - return self->data_unique_pointer(); + const StringName *src = (const StringName *)p_src; + memnew_placement(dest, StringName(*src)); } -godot_bool GDAPI godot_string_name_operator_equal(const godot_string_name *p_self, const godot_string_name *p_other) { - const StringName *self = (const StringName *)p_self; - const StringName *other = (const StringName *)p_other; - return self == other; -} - -godot_bool GDAPI godot_string_name_operator_less(const godot_string_name *p_self, const godot_string_name *p_other) { - const StringName *self = (const StringName *)p_self; - const StringName *other = (const StringName *)p_other; - return self < other; +void GDAPI godot_string_name_new_with_latin1_chars(godot_string_name *r_dest, const char *p_contents) { + StringName *dest = (StringName *)r_dest; + memnew_placement(dest, StringName(p_contents)); } void GDAPI godot_string_name_destroy(godot_string_name *p_self) { diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp index 059e12b401..eae981bd07 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -31,198 +31,15 @@ #include "gdnative/transform.h" #include "core/math/transform.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_transform) == sizeof(Transform), "Transform size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_transform) == sizeof(Transform), "Transform size mismatch"); - -void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin) { - const Vector3 *x_axis = (const Vector3 *)p_x_axis; - const Vector3 *y_axis = (const Vector3 *)p_y_axis; - const Vector3 *z_axis = (const Vector3 *)p_z_axis; - const Vector3 *origin = (const Vector3 *)p_origin; - Transform *dest = (Transform *)r_dest; - dest->basis.set_axis(0, *x_axis); - dest->basis.set_axis(1, *y_axis); - dest->basis.set_axis(2, *z_axis); - dest->origin = *origin; -} - -void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin) { - const Basis *basis = (const Basis *)p_basis; - const Vector3 *origin = (const Vector3 *)p_origin; - Transform *dest = (Transform *)r_dest; - *dest = Transform(*basis, *origin); -} - -void GDAPI godot_transform_new_with_quat(godot_transform *r_dest, const godot_quat *p_quat) { - const Quat *quat = (const Quat *)p_quat; - Transform *dest = (Transform *)r_dest; - *dest = Transform(*quat); -} - -godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self) { - godot_basis dest; - const Transform *self = (const Transform *)p_self; - *((Basis *)&dest) = self->basis; - return dest; -} - -void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v) { - Transform *self = (Transform *)p_self; - const Basis *v = (const Basis *)p_v; - self->basis = *v; -} - -godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self) { - godot_vector3 dest; - const Transform *self = (const Transform *)p_self; - *((Vector3 *)&dest) = self->origin; - return dest; -} - -void GDAPI godot_transform_set_origin(godot_transform *p_self, const godot_vector3 *p_v) { - Transform *self = (Transform *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - self->origin = *v; -} - -godot_string GDAPI godot_transform_as_string(const godot_transform *p_self) { - godot_string ret; - const Transform *self = (const Transform *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_transform GDAPI godot_transform_inverse(const godot_transform *p_self) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - *((Transform *)&dest) = self->inverse(); - return dest; -} - -godot_transform GDAPI godot_transform_affine_inverse(const godot_transform *p_self) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - *((Transform *)&dest) = self->affine_inverse(); - return dest; -} - -godot_transform GDAPI godot_transform_orthonormalized(const godot_transform *p_self) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - *((Transform *)&dest) = self->orthonormalized(); - return dest; -} - -godot_transform GDAPI godot_transform_rotated(const godot_transform *p_self, const godot_vector3 *p_axis, const godot_real p_phi) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - const Vector3 *axis = (const Vector3 *)p_axis; - *((Transform *)&dest) = self->rotated(*axis, p_phi); - return dest; -} - -godot_transform GDAPI godot_transform_scaled(const godot_transform *p_self, const godot_vector3 *p_scale) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - const Vector3 *scale = (const Vector3 *)p_scale; - *((Transform *)&dest) = self->scaled(*scale); - return dest; -} - -godot_transform GDAPI godot_transform_translated(const godot_transform *p_self, const godot_vector3 *p_ofs) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - const Vector3 *ofs = (const Vector3 *)p_ofs; - *((Transform *)&dest) = self->translated(*ofs); - return dest; -} - -godot_transform GDAPI godot_transform_looking_at(const godot_transform *p_self, const godot_vector3 *p_target, const godot_vector3 *p_up) { - godot_transform dest; - const Transform *self = (const Transform *)p_self; - const Vector3 *target = (const Vector3 *)p_target; - const Vector3 *up = (const Vector3 *)p_up; - *((Transform *)&dest) = self->looking_at(*target, *up); - return dest; -} - -godot_plane GDAPI godot_transform_xform_plane(const godot_transform *p_self, const godot_plane *p_v) { - godot_plane raw_dest; - Plane *dest = (Plane *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const Plane *v = (const Plane *)p_v; - *dest = self->xform(*v); - return raw_dest; -} - -godot_plane GDAPI godot_transform_xform_inv_plane(const godot_transform *p_self, const godot_plane *p_v) { - godot_plane raw_dest; - Plane *dest = (Plane *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const Plane *v = (const Plane *)p_v; - *dest = self->xform_inv(*v); - return raw_dest; -} - -void GDAPI godot_transform_new_identity(godot_transform *r_dest) { - Transform *dest = (Transform *)r_dest; - *dest = Transform(); -} - -godot_bool GDAPI godot_transform_operator_equal(const godot_transform *p_self, const godot_transform *p_b) { - const Transform *self = (const Transform *)p_self; - const Transform *b = (const Transform *)p_b; - return *self == *b; -} - -godot_transform GDAPI godot_transform_operator_multiply(const godot_transform *p_self, const godot_transform *p_b) { - godot_transform raw_dest; - Transform *dest = (Transform *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const Transform *b = (const Transform *)p_b; - *dest = *self * *b; - return raw_dest; -} - -godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, const godot_vector3 *p_v) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - *dest = self->xform(*v); - return raw_dest; -} - -godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - *dest = self->xform_inv(*v); - return raw_dest; -} - -godot_aabb GDAPI godot_transform_xform_aabb(const godot_transform *p_self, const godot_aabb *p_v) { - godot_aabb raw_dest; - AABB *dest = (AABB *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const AABB *v = (const AABB *)p_v; - *dest = self->xform(*v); - return raw_dest; -} - -godot_aabb GDAPI godot_transform_xform_inv_aabb(const godot_transform *p_self, const godot_aabb *p_v) { - godot_aabb raw_dest; - AABB *dest = (AABB *)&raw_dest; - const Transform *self = (const Transform *)p_self; - const AABB *v = (const AABB *)p_v; - *dest = self->xform_inv(*v); - return raw_dest; +void GDAPI godot_transform_new(godot_transform *p_self) { + memnew_placement(p_self, Transform); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index 878599514d..679174d5a5 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -31,179 +31,25 @@ #include "gdnative/transform2d.h" #include "core/math/transform_2d.h" -#include "core/variant/variant.h" + +static_assert(sizeof(godot_transform2d) == sizeof(Transform2D), "Transform2D size mismatch"); #ifdef __cplusplus extern "C" { #endif -static_assert(sizeof(godot_transform2d) == sizeof(Transform2D), "Transform2D size mismatch"); - -void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos) { - const Vector2 *pos = (const Vector2 *)p_pos; - Transform2D *dest = (Transform2D *)r_dest; - *dest = Transform2D(p_rot, *pos); -} - -void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin) { - const Vector2 *x_axis = (const Vector2 *)p_x_axis; - const Vector2 *y_axis = (const Vector2 *)p_y_axis; - const Vector2 *origin = (const Vector2 *)p_origin; - Transform2D *dest = (Transform2D *)r_dest; - *dest = Transform2D(x_axis->x, x_axis->y, y_axis->x, y_axis->y, origin->x, origin->y); -} - -godot_string GDAPI godot_transform2d_as_string(const godot_transform2d *p_self) { - godot_string ret; - const Transform2D *self = (const Transform2D *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_self) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - *((Transform2D *)&dest) = self->inverse(); - return dest; -} - -godot_transform2d GDAPI godot_transform2d_affine_inverse(const godot_transform2d *p_self) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - *((Transform2D *)&dest) = self->affine_inverse(); - return dest; -} - -godot_real GDAPI godot_transform2d_get_rotation(const godot_transform2d *p_self) { - const Transform2D *self = (const Transform2D *)p_self; - return self->get_rotation(); -} - -godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self) { - godot_vector2 dest; - const Transform2D *self = (const Transform2D *)p_self; - *((Vector2 *)&dest) = self->get_origin(); - return dest; -} - -godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self) { - godot_vector2 dest; - const Transform2D *self = (const Transform2D *)p_self; - *((Vector2 *)&dest) = self->get_scale(); - return dest; -} - -godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - *((Transform2D *)&dest) = self->orthonormalized(); - return dest; -} - -godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - - *((Transform2D *)&dest) = self->rotated(p_phi); - return dest; +void GDAPI godot_transform2d_new(godot_transform2d *p_self) { + memnew_placement(p_self, Transform2D); } -godot_transform2d GDAPI godot_transform2d_scaled(const godot_transform2d *p_self, const godot_vector2 *p_scale) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - const Vector2 *scale = (const Vector2 *)p_scale; - *((Transform2D *)&dest) = self->scaled(*scale); - return dest; -} - -godot_transform2d GDAPI godot_transform2d_translated(const godot_transform2d *p_self, const godot_vector2 *p_offset) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - const Vector2 *offset = (const Vector2 *)p_offset; - *((Transform2D *)&dest) = self->translated(*offset); - return dest; -} - -godot_vector2 GDAPI godot_transform2d_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Transform2D *self = (const Transform2D *)p_self; - const Vector2 *v = (const Vector2 *)p_v; - *dest = self->xform(*v); - return raw_dest; -} - -godot_vector2 GDAPI godot_transform2d_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Transform2D *self = (const Transform2D *)p_self; - const Vector2 *v = (const Vector2 *)p_v; - *dest = self->xform_inv(*v); - return raw_dest; -} - -godot_vector2 GDAPI godot_transform2d_basis_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Transform2D *self = (const Transform2D *)p_self; - const Vector2 *v = (const Vector2 *)p_v; - *dest = self->basis_xform(*v); - return raw_dest; -} - -godot_vector2 GDAPI godot_transform2d_basis_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Transform2D *self = (const Transform2D *)p_self; - const Vector2 *v = (const Vector2 *)p_v; - *dest = self->basis_xform_inv(*v); - return raw_dest; -} - -godot_transform2d GDAPI godot_transform2d_interpolate_with(const godot_transform2d *p_self, const godot_transform2d *p_m, const godot_real p_c) { - godot_transform2d dest; - const Transform2D *self = (const Transform2D *)p_self; - const Transform2D *m = (const Transform2D *)p_m; - *((Transform2D *)&dest) = self->interpolate_with(*m, p_c); - return dest; -} - -godot_bool GDAPI godot_transform2d_operator_equal(const godot_transform2d *p_self, const godot_transform2d *p_b) { - const Transform2D *self = (const Transform2D *)p_self; - const Transform2D *b = (const Transform2D *)p_b; - return *self == *b; -} - -godot_transform2d GDAPI godot_transform2d_operator_multiply(const godot_transform2d *p_self, const godot_transform2d *p_b) { - godot_transform2d raw_dest; - Transform2D *dest = (Transform2D *)&raw_dest; - const Transform2D *self = (const Transform2D *)p_self; - const Transform2D *b = (const Transform2D *)p_b; - *dest = *self * *b; - return raw_dest; -} - -void GDAPI godot_transform2d_new_identity(godot_transform2d *r_dest) { - Transform2D *dest = (Transform2D *)r_dest; - *dest = Transform2D(); -} - -godot_rect2 GDAPI godot_transform2d_xform_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v) { - godot_rect2 raw_dest; - Rect2 *dest = (Rect2 *)&raw_dest; - const Transform2D *self = (const Transform2D *)p_self; - const Rect2 *v = (const Rect2 *)p_v; - *dest = self->xform(*v); - return raw_dest; +godot_vector2 GDAPI *godot_transform2d_operator_index(godot_transform2d *p_self, godot_int p_index) { + Transform2D *self = (Transform2D *)p_self; + return (godot_vector2 *)&self->operator[](p_index); } -godot_rect2 GDAPI godot_transform2d_xform_inv_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v) { - godot_rect2 raw_dest; - Rect2 *dest = (Rect2 *)&raw_dest; +const godot_vector2 GDAPI *godot_transform2d_operator_index_const(const godot_transform2d *p_self, godot_int p_index) { const Transform2D *self = (const Transform2D *)p_self; - const Rect2 *v = (const Rect2 *)p_v; - *dest = self->xform_inv(*v); - return raw_dest; + return (const godot_vector2 *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 7ee5fe59e2..ee4353bb48 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -55,16 +55,11 @@ static_assert(sizeof(godot_variant) == sizeof(Variant), "Variant size mismatch") #pragma GCC pop_options #endif -// Constructors - -godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self) { - const Variant *self = (const Variant *)p_self; - return (godot_variant_type)self->get_type(); -} +// Memory void GDAPI godot_variant_new_copy(godot_variant *p_dest, const godot_variant *p_src) { Variant *dest = (Variant *)p_dest; - Variant *src = (Variant *)p_src; + const Variant *src = (const Variant *)p_src; memnew_placement(dest, Variant(*src)); } @@ -78,139 +73,134 @@ void GDAPI godot_variant_new_bool(godot_variant *r_dest, const godot_bool p_b) { memnew_placement_custom(dest, Variant, Variant(p_b)); } -void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i) { +void GDAPI godot_variant_new_int(godot_variant *r_dest, const godot_int p_i) { Variant *dest = (Variant *)r_dest; memnew_placement_custom(dest, Variant, Variant(p_i)); } -void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i) { - Variant *dest = (Variant *)r_dest; - memnew_placement_custom(dest, Variant, Variant(p_i)); -} - -void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r) { +void GDAPI godot_variant_new_float(godot_variant *r_dest, const godot_float p_r) { Variant *dest = (Variant *)r_dest; memnew_placement_custom(dest, Variant, Variant(p_r)); } void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s) { Variant *dest = (Variant *)r_dest; - String *s = (String *)p_s; + const String *s = (const String *)p_s; memnew_placement_custom(dest, Variant, Variant(*s)); } void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s) { Variant *dest = (Variant *)r_dest; - StringName *s = (StringName *)p_s; + const StringName *s = (const StringName *)p_s; memnew_placement_custom(dest, Variant, Variant(*s)); } void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2) { Variant *dest = (Variant *)r_dest; - Vector2 *v2 = (Vector2 *)p_v2; + const Vector2 *v2 = (const Vector2 *)p_v2; memnew_placement_custom(dest, Variant, Variant(*v2)); } void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2) { Variant *dest = (Variant *)r_dest; - Vector2i *v2 = (Vector2i *)p_v2; + const Vector2i *v2 = (const Vector2i *)p_v2; memnew_placement_custom(dest, Variant, Variant(*v2)); } void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2) { Variant *dest = (Variant *)r_dest; - Rect2 *rect2 = (Rect2 *)p_rect2; + const Rect2 *rect2 = (const Rect2 *)p_rect2; memnew_placement_custom(dest, Variant, Variant(*rect2)); } void GDAPI godot_variant_new_rect2i(godot_variant *r_dest, const godot_rect2i *p_rect2) { Variant *dest = (Variant *)r_dest; - Rect2i *rect2 = (Rect2i *)p_rect2; + const Rect2i *rect2 = (const Rect2i *)p_rect2; memnew_placement_custom(dest, Variant, Variant(*rect2)); } void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3) { Variant *dest = (Variant *)r_dest; - Vector3 *v3 = (Vector3 *)p_v3; + const Vector3 *v3 = (const Vector3 *)p_v3; memnew_placement_custom(dest, Variant, Variant(*v3)); } void GDAPI godot_variant_new_vector3i(godot_variant *r_dest, const godot_vector3i *p_v3) { Variant *dest = (Variant *)r_dest; - Vector3i *v3 = (Vector3i *)p_v3; + const Vector3i *v3 = (const Vector3i *)p_v3; memnew_placement_custom(dest, Variant, Variant(*v3)); } void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d) { Variant *dest = (Variant *)r_dest; - Transform2D *t2d = (Transform2D *)p_t2d; + const Transform2D *t2d = (const Transform2D *)p_t2d; memnew_placement_custom(dest, Variant, Variant(*t2d)); } void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane) { Variant *dest = (Variant *)r_dest; - Plane *plane = (Plane *)p_plane; + const Plane *plane = (const Plane *)p_plane; memnew_placement_custom(dest, Variant, Variant(*plane)); } void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat) { Variant *dest = (Variant *)r_dest; - Quat *quat = (Quat *)p_quat; + const Quat *quat = (const Quat *)p_quat; memnew_placement_custom(dest, Variant, Variant(*quat)); } void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb) { Variant *dest = (Variant *)r_dest; - AABB *aabb = (AABB *)p_aabb; + const AABB *aabb = (const AABB *)p_aabb; memnew_placement_custom(dest, Variant, Variant(*aabb)); } void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis) { Variant *dest = (Variant *)r_dest; - Basis *basis = (Basis *)p_basis; + const Basis *basis = (const Basis *)p_basis; memnew_placement_custom(dest, Variant, Variant(*basis)); } void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans) { Variant *dest = (Variant *)r_dest; - Transform *trans = (Transform *)p_trans; + const Transform *trans = (const Transform *)p_trans; memnew_placement_custom(dest, Variant, Variant(*trans)); } void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color) { Variant *dest = (Variant *)r_dest; - Color *color = (Color *)p_color; + const Color *color = (const Color *)p_color; memnew_placement_custom(dest, Variant, Variant(*color)); } void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np) { Variant *dest = (Variant *)r_dest; - NodePath *np = (NodePath *)p_np; + const NodePath *np = (const NodePath *)p_np; memnew_placement_custom(dest, Variant, Variant(*np)); } void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid) { Variant *dest = (Variant *)r_dest; - RID *rid = (RID *)p_rid; + const RID *rid = (const RID *)p_rid; memnew_placement_custom(dest, Variant, Variant(*rid)); } void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_cb) { Variant *dest = (Variant *)r_dest; - Callable *cb = (Callable *)p_cb; + const Callable *cb = (const Callable *)p_cb; memnew_placement_custom(dest, Variant, Variant(*cb)); } void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal) { Variant *dest = (Variant *)r_dest; - Signal *signal = (Signal *)p_signal; + const Signal *signal = (const Signal *)p_signal; memnew_placement_custom(dest, Variant, Variant(*signal)); } void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj) { Variant *dest = (Variant *)r_dest; - Object *obj = (Object *)p_obj; - Reference *reference = Object::cast_to<Reference>(obj); + const Object *obj = (const Object *)p_obj; + const Reference *reference = Object::cast_to<Reference>(obj); REF ref; if (reference) { ref = REF(reference); @@ -229,67 +219,67 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict) { Variant *dest = (Variant *)r_dest; - Dictionary *dict = (Dictionary *)p_dict; + const Dictionary *dict = (const Dictionary *)p_dict; memnew_placement_custom(dest, Variant, Variant(*dict)); } void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr) { Variant *dest = (Variant *)r_dest; - Array *arr = (Array *)p_arr; + const Array *arr = (const Array *)p_arr; memnew_placement_custom(dest, Variant, Variant(*arr)); } void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba) { Variant *dest = (Variant *)r_dest; - PackedByteArray *pba = (PackedByteArray *)p_pba; + const PackedByteArray *pba = (const PackedByteArray *)p_pba; memnew_placement_custom(dest, Variant, Variant(*pba)); } void GDAPI godot_variant_new_packed_int32_array(godot_variant *r_dest, const godot_packed_int32_array *p_pia) { Variant *dest = (Variant *)r_dest; - PackedInt32Array *pia = (PackedInt32Array *)p_pia; + const PackedInt32Array *pia = (const PackedInt32Array *)p_pia; memnew_placement_custom(dest, Variant, Variant(*pia)); } void GDAPI godot_variant_new_packed_int64_array(godot_variant *r_dest, const godot_packed_int64_array *p_pia) { Variant *dest = (Variant *)r_dest; - PackedInt64Array *pia = (PackedInt64Array *)p_pia; + const PackedInt64Array *pia = (const PackedInt64Array *)p_pia; memnew_placement_custom(dest, Variant, Variant(*pia)); } void GDAPI godot_variant_new_packed_float32_array(godot_variant *r_dest, const godot_packed_float32_array *p_pra) { Variant *dest = (Variant *)r_dest; - PackedFloat32Array *pra = (PackedFloat32Array *)p_pra; + const PackedFloat32Array *pra = (const PackedFloat32Array *)p_pra; memnew_placement_custom(dest, Variant, Variant(*pra)); } void GDAPI godot_variant_new_packed_float64_array(godot_variant *r_dest, const godot_packed_float64_array *p_pra) { Variant *dest = (Variant *)r_dest; - PackedFloat64Array *pra = (PackedFloat64Array *)p_pra; + const PackedFloat64Array *pra = (const PackedFloat64Array *)p_pra; memnew_placement_custom(dest, Variant, Variant(*pra)); } void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa) { Variant *dest = (Variant *)r_dest; - PackedStringArray *psa = (PackedStringArray *)p_psa; + const PackedStringArray *psa = (const PackedStringArray *)p_psa; memnew_placement_custom(dest, Variant, Variant(*psa)); } void GDAPI godot_variant_new_packed_vector2_array(godot_variant *r_dest, const godot_packed_vector2_array *p_pv2a) { Variant *dest = (Variant *)r_dest; - PackedVector2Array *pv2a = (PackedVector2Array *)p_pv2a; + const PackedVector2Array *pv2a = (const PackedVector2Array *)p_pv2a; memnew_placement_custom(dest, Variant, Variant(*pv2a)); } void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const godot_packed_vector3_array *p_pv3a) { Variant *dest = (Variant *)r_dest; - PackedVector3Array *pv3a = (PackedVector3Array *)p_pv3a; + const PackedVector3Array *pv3a = (const PackedVector3Array *)p_pv3a; memnew_placement_custom(dest, Variant, Variant(*pv3a)); } void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca) { Variant *dest = (Variant *)r_dest; - PackedColorArray *pca = (PackedColorArray *)p_pca; + const PackedColorArray *pca = (const PackedColorArray *)p_pca; memnew_placement_custom(dest, Variant, Variant(*pca)); } @@ -298,17 +288,12 @@ godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self) { return self->operator bool(); } -uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self) { - const Variant *self = (const Variant *)p_self; - return self->operator uint64_t(); -} - -int64_t GDAPI godot_variant_as_int(const godot_variant *p_self) { +godot_int GDAPI godot_variant_as_int(const godot_variant *p_self) { const Variant *self = (const Variant *)p_self; return self->operator int64_t(); } -double GDAPI godot_variant_as_real(const godot_variant *p_self) { +godot_float GDAPI godot_variant_as_float(const godot_variant *p_self) { const Variant *self = (const Variant *)p_self; return self->operator double(); } @@ -569,47 +554,137 @@ godot_packed_color_array GDAPI godot_variant_as_packed_color_array(const godot_v return raw_dest; } -godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error) { +void GDAPI godot_variant_destroy(godot_variant *p_self) { + Variant *self = (Variant *)p_self; + self->~Variant(); +} + +// Dynamic interaction. + +void GDAPI godot_variant_call(godot_variant *p_self, const godot_string_name *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant *r_return, godot_variant_call_error *r_error) { Variant *self = (Variant *)p_self; - String *method = (String *)p_method; + const StringName *method = (const StringName *)p_method; const Variant **args = (const Variant **)p_args; - godot_variant raw_dest; - Variant *dest = (Variant *)&raw_dest; - Callable::CallError error; Variant ret; + Callable::CallError error; self->call(*method, args, p_argcount, ret, error); - memnew_placement_custom(dest, Variant, Variant(ret)); + memnew_placement_custom(r_return, Variant, Variant(ret)); + if (r_error) { r_error->error = (godot_variant_call_error_error)error.error; r_error->argument = error.argument; r_error->expected = (godot_variant_type)error.expected; } - return raw_dest; } -godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string *p_method) { +void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_return, bool *r_valid) { + Variant::Operator op = (Variant::Operator)p_op; + const Variant *a = (const Variant *)p_a; + const Variant *b = (const Variant *)p_b; + Variant *ret = (Variant *)r_return; + Variant::evaluate(op, *a, *b, *ret, *r_valid); +} + +void GDAPI godot_variant_set(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid) { + Variant *self = (Variant *)p_self; + const Variant *key = (const Variant *)p_key; + const Variant *value = (const Variant *)p_value; + + self->set(*key, *value, r_valid); +} + +void GDAPI godot_variant_set_named(godot_variant *p_self, const godot_string_name *p_name, const godot_variant *p_value, bool *r_valid) { + Variant *self = (Variant *)p_self; + const StringName *name = (const StringName *)p_name; + const Variant *value = (const Variant *)p_value; + + self->set_named(*name, *value, *r_valid); +} + +void GDAPI godot_variant_set_keyed(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid) { + Variant *self = (Variant *)p_self; + const Variant *key = (const Variant *)p_key; + const Variant *value = (const Variant *)p_value; + + self->set_keyed(*key, *value, *r_valid); +} + +void GDAPI godot_variant_set_indexed(godot_variant *p_self, godot_int p_index, const godot_variant *p_value, bool *r_valid, bool *r_oob) { + Variant *self = (Variant *)p_self; + const Variant *value = (const Variant *)p_value; + + self->set_indexed(p_index, value, *r_valid, *r_oob); +} + +godot_variant GDAPI godot_variant_get(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid) { const Variant *self = (const Variant *)p_self; - const String *method = (const String *)p_method; - return self->has_method(*method); + const Variant *key = (const Variant *)p_key; + Variant ret; + + ret = self->get(*key, r_valid); + godot_variant result; + memnew_placement_custom(&result, Variant, Variant(ret)); + return result; } -godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other) { +godot_variant GDAPI godot_variant_get_named(const godot_variant *p_self, const godot_string_name *p_key, bool *r_valid) { const Variant *self = (const Variant *)p_self; - const Variant *other = (const Variant *)p_other; - return self->operator==(*other); + const StringName *key = (const StringName *)p_key; + Variant ret; + + ret = self->get_named(*key, *r_valid); + godot_variant result; + memnew_placement_custom(&result, Variant, Variant(ret)); + return result; } -godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other) { +godot_variant GDAPI godot_variant_get_keyed(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid) { const Variant *self = (const Variant *)p_self; - const Variant *other = (const Variant *)p_other; - return self->operator<(*other); + const Variant *key = (const Variant *)p_key; + Variant ret; + + ret = self->get_keyed(*key, *r_valid); + godot_variant result; + memnew_placement_custom(&result, Variant, Variant(ret)); + return result; +} + +godot_variant GDAPI godot_variant_get_indexed(const godot_variant *p_self, godot_int p_index, bool *r_valid, bool *r_oob) { + const Variant *self = (const Variant *)p_self; + Variant ret; + + ret = self->get_indexed(p_index, *r_valid, *r_oob); + godot_variant result; + memnew_placement_custom(&result, Variant, Variant(ret)); + return result; } -uint32_t GDAPI godot_variant_hash(const godot_variant *p_self) { +/// Iteration. +bool GDAPI godot_variant_iter_init(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid) { const Variant *self = (const Variant *)p_self; - return self->hash(); + Variant *iter = (Variant *)r_iter; + + return self->iter_init(*iter, *r_valid); } +bool GDAPI godot_variant_iter_next(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid) { + const Variant *self = (const Variant *)p_self; + Variant *iter = (Variant *)r_iter; + + return self->iter_next(*iter, *r_valid); +} + +godot_variant GDAPI godot_variant_iter_get(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid) { + const Variant *self = (const Variant *)p_self; + Variant *iter = (Variant *)r_iter; + + Variant result = self->iter_next(*iter, *r_valid); + godot_variant ret; + memnew_placement_custom(&ret, Variant, Variant(result)); + return ret; +} + +/// Variant functions. godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other) { const Variant *self = (const Variant *)p_self; const Variant *other = (const Variant *)p_other; @@ -621,27 +696,503 @@ godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self) { return self->booleanize(); } -void GDAPI godot_variant_destroy(godot_variant *p_self) { - Variant *self = (Variant *)p_self; - self->~Variant(); +void GDAPI godot_variant_blend(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst) { + const Variant *a = (const Variant *)p_a; + const Variant *b = (const Variant *)p_b; + Variant *dst = (Variant *)r_dst; + Variant::blend(*a, *b, p_c, *dst); } -// GDNative core 1.1 +void GDAPI godot_variant_interpolate(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst) { + const Variant *a = (const Variant *)p_a; + const Variant *b = (const Variant *)p_b; + Variant *dst = (Variant *)r_dst; + Variant::interpolate(*a, *b, p_c, *dst); +} -godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_op) { - Variant::Operator op = (Variant::Operator)p_op; - godot_string raw_dest; - String *dest = (String *)&raw_dest; - memnew_placement(dest, String(Variant::get_operator_name(op))); // operator = is overloaded by String - return raw_dest; +godot_variant GDAPI godot_variant_duplicate(const godot_variant *p_self, godot_bool p_deep) { + const Variant *self = (const Variant *)p_self; + Variant result = self->duplicate(p_deep); + godot_variant ret; + memnew_placement_custom(&ret, Variant, Variant(result)); + return ret; } -void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_ret, godot_bool *r_valid) { - Variant::Operator op = (Variant::Operator)p_op; - const Variant *a = (const Variant *)p_a; - const Variant *b = (const Variant *)p_b; +godot_string GDAPI godot_variant_stringify(const godot_variant *p_self) { + const Variant *self = (const Variant *)p_self; + String result = *self; + godot_string ret; + memnew_placement_custom(&ret, String, String(result)); + return ret; +} + +// Discovery API + +/// Operators +godot_validated_operator_evaluator GDAPI godot_variant_get_validated_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b) { + return (godot_validated_operator_evaluator)Variant::get_validated_operator_evaluator((Variant::Operator)p_operator, (Variant::Type)p_type_a, (Variant::Type)p_type_b); +} + +godot_ptr_operator_evaluator GDAPI godot_variant_get_ptr_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b) { + return (godot_ptr_operator_evaluator)Variant::get_ptr_operator_evaluator((Variant::Operator)p_operator, (Variant::Type)p_type_a, (Variant::Type)p_type_b); +} + +godot_variant_type GDAPI godot_variant_get_operator_return_type(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b) { + return (godot_variant_type)Variant::get_operator_return_type((Variant::Operator)p_operator, (Variant::Type)p_type_a, (Variant::Type)p_type_b); +} + +godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_operator) { + String op_name = Variant::get_operator_name((Variant::Operator)p_operator); + godot_string ret; + memnew_placement_custom(&ret, String, String(op_name)); + return ret; +} + +/// Built-in Methods + +bool GDAPI godot_variant_has_builtin_method(godot_variant_type p_type, const godot_string_name *p_method) { + return Variant::has_builtin_method((Variant::Type)p_type, *((const StringName *)p_method)); +} + +bool GDAPI godot_variant_has_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method) { + return Variant::has_builtin_method((Variant::Type)p_type, StringName(p_method)); +} + +godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method(godot_variant_type p_type, const godot_string_name *p_method) { + return (godot_validated_builtin_method)Variant::get_validated_builtin_method((Variant::Type)p_type, *((const StringName *)p_method)); +} + +godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method) { + return (godot_validated_builtin_method)Variant::get_validated_builtin_method((Variant::Type)p_type, StringName(p_method)); +} + +godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method(godot_variant_type p_type, const godot_string_name *p_method) { + return (godot_ptr_builtin_method)Variant::get_ptr_builtin_method((Variant::Type)p_type, *((const StringName *)p_method)); +} + +godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method) { + return (godot_ptr_builtin_method)Variant::get_ptr_builtin_method((Variant::Type)p_type, StringName(p_method)); +} + +int GDAPI godot_variant_get_builtin_method_argument_count(godot_variant_type p_type, const godot_string_name *p_method) { + return Variant::get_builtin_method_argument_count((Variant::Type)p_type, *((const StringName *)p_method)); +} + +int GDAPI godot_variant_get_builtin_method_argument_count_with_cstring(godot_variant_type p_type, const char *p_method) { + return Variant::get_builtin_method_argument_count((Variant::Type)p_type, StringName(p_method)); +} + +godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type(godot_variant_type p_type, const godot_string_name *p_method, int p_argument) { + return (godot_variant_type)Variant::get_builtin_method_argument_type((Variant::Type)p_type, *((const StringName *)p_method), p_argument); +} + +godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument) { + return (godot_variant_type)Variant::get_builtin_method_argument_type((Variant::Type)p_type, StringName(p_method), p_argument); +} + +godot_string GDAPI godot_variant_get_builtin_method_argument_name(godot_variant_type p_type, const godot_string_name *p_method, int p_argument) { + String name = Variant::get_builtin_method_argument_name((Variant::Type)p_type, *((const StringName *)p_method), p_argument); + return *(godot_string *)&name; +} + +godot_string GDAPI godot_variant_get_builtin_method_argument_name_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument) { + String name = Variant::get_builtin_method_argument_name((Variant::Type)p_type, StringName(p_method), p_argument); + return *(godot_string *)&name; +} + +bool GDAPI godot_variant_has_builtin_method_return_value(godot_variant_type p_type, const godot_string_name *p_method) { + return Variant::has_builtin_method_return_value((Variant::Type)p_type, *((const StringName *)p_method)); +} + +bool GDAPI godot_variant_has_builtin_method_return_value_with_cstring(godot_variant_type p_type, const char *p_method) { + return Variant::has_builtin_method_return_value((Variant::Type)p_type, StringName(p_method)); +} + +godot_variant_type GDAPI godot_variant_get_builtin_method_return_type(godot_variant_type p_type, const godot_string_name *p_method) { + return (godot_variant_type)Variant::get_builtin_method_return_type((Variant::Type)p_type, *((const StringName *)p_method)); +} + +godot_variant_type GDAPI godot_variant_get_builtin_method_return_type_with_cstring(godot_variant_type p_type, const char *p_method) { + return (godot_variant_type)Variant::get_builtin_method_return_type((Variant::Type)p_type, StringName(p_method)); +} + +bool GDAPI godot_variant_is_builtin_method_const(godot_variant_type p_type, const godot_string_name *p_method) { + return Variant::is_builtin_method_const((Variant::Type)p_type, *((const StringName *)p_method)); +} + +bool GDAPI godot_variant_is_builtin_method_const_with_cstring(godot_variant_type p_type, const char *p_method) { + return Variant::is_builtin_method_const((Variant::Type)p_type, StringName(p_method)); +} + +bool GDAPI godot_variant_is_builtin_method_vararg(godot_variant_type p_type, const godot_string_name *p_method) { + return Variant::is_builtin_method_vararg((Variant::Type)p_type, *((const StringName *)p_method)); +} + +bool GDAPI godot_variant_is_builtin_method_vararg_with_cstring(godot_variant_type p_type, const char *p_method) { + return Variant::is_builtin_method_vararg((Variant::Type)p_type, StringName(p_method)); +} + +int GDAPI godot_variant_get_builtin_method_count(godot_variant_type p_type) { + return Variant::get_builtin_method_count((Variant::Type)p_type); +} + +void GDAPI godot_variant_get_builtin_method_list(godot_variant_type p_type, godot_string_name *r_list) { + List<StringName> list; + Variant::get_builtin_method_list((Variant::Type)p_type, &list); + int i = 0; + for (const List<StringName>::Element *E = list.front(); E; E = E->next()) { + memnew_placement_custom(&r_list[i], StringName, StringName(E->get())); + } +} + +/// Constructors + +int GDAPI godot_variant_get_constructor_count(godot_variant_type p_type) { + return Variant::get_constructor_count((Variant::Type)p_type); +} + +godot_validated_constructor GDAPI godot_variant_get_validated_constructor(godot_variant_type p_type, int p_constructor) { + return (godot_validated_constructor)Variant::get_validated_constructor((Variant::Type)p_type, p_constructor); +} + +godot_ptr_constructor GDAPI godot_variant_get_ptr_constructor(godot_variant_type p_type, int p_constructor) { + return (godot_ptr_constructor)Variant::get_ptr_constructor((Variant::Type)p_type, p_constructor); +} + +int GDAPI godot_variant_get_constructor_argument_count(godot_variant_type p_type, int p_constructor) { + return Variant::get_constructor_argument_count((Variant::Type)p_type, p_constructor); +} + +godot_variant_type GDAPI godot_variant_get_constructor_argument_type(godot_variant_type p_type, int p_constructor, int p_argument) { + return (godot_variant_type)Variant::get_constructor_argument_type((Variant::Type)p_type, p_constructor, p_argument); +} + +godot_string GDAPI godot_variant_get_constructor_argument_name(godot_variant_type p_type, int p_constructor, int p_argument) { + String name = Variant::get_constructor_argument_name((Variant::Type)p_type, p_constructor, p_argument); + godot_string ret; + memnew_placement(&ret, String(name)); + return ret; +} + +void GDAPI godot_variant_construct(godot_variant_type p_type, godot_variant *p_base, const godot_variant **p_args, int p_argcount, godot_variant_call_error *r_error) { + Variant::construct((Variant::Type)p_type, *((Variant *)p_base), (const Variant **)p_args, p_argcount, *((Callable::CallError *)r_error)); +} + +/// Properties. +godot_variant_type GDAPI godot_variant_get_member_type(godot_variant_type p_type, const godot_string_name *p_member) { + return (godot_variant_type)Variant::get_member_type((Variant::Type)p_type, *((const StringName *)p_member)); +} + +godot_variant_type GDAPI godot_variant_get_member_type_with_cstring(godot_variant_type p_type, const char *p_member) { + return (godot_variant_type)Variant::get_member_type((Variant::Type)p_type, StringName(p_member)); +} + +int GDAPI godot_variant_get_member_count(godot_variant_type p_type) { + return Variant::get_member_count((Variant::Type)p_type); +} + +void GDAPI godot_variant_get_member_list(godot_variant_type p_type, godot_string_name *r_list) { + List<StringName> members; + Variant::get_member_list((Variant::Type)p_type, &members); + int i = 0; + for (const List<StringName>::Element *E = members.front(); E; E = E->next()) { + memnew_placement_custom(&r_list[i++], StringName, StringName(E->get())); + } +} + +godot_validated_setter GDAPI godot_variant_get_validated_setter(godot_variant_type p_type, const godot_string_name *p_member) { + return (godot_validated_setter)Variant::get_member_validated_setter((Variant::Type)p_type, *((const StringName *)p_member)); +} + +godot_validated_setter GDAPI godot_variant_get_validated_setter_with_cstring(godot_variant_type p_type, const char *p_member) { + return (godot_validated_setter)Variant::get_member_validated_setter((Variant::Type)p_type, StringName(p_member)); +} + +godot_validated_getter GDAPI godot_variant_get_validated_getter(godot_variant_type p_type, const godot_string_name *p_member) { + return (godot_validated_getter)Variant::get_member_validated_getter((Variant::Type)p_type, *((const StringName *)p_member)); +} + +godot_validated_getter GDAPI godot_variant_get_validated_getter_with_cstring(godot_variant_type p_type, const char *p_member) { + return (godot_validated_getter)Variant::get_member_validated_getter((Variant::Type)p_type, StringName(p_member)); +} + +godot_ptr_setter GDAPI godot_variant_get_ptr_setter(godot_variant_type p_type, const godot_string_name *p_member) { + return (godot_ptr_setter)Variant::get_member_ptr_setter((Variant::Type)p_type, *((const StringName *)p_member)); +} + +godot_ptr_setter GDAPI godot_variant_get_ptr_setter_with_cstring(godot_variant_type p_type, const char *p_member) { + return (godot_ptr_setter)Variant::get_member_ptr_setter((Variant::Type)p_type, StringName(p_member)); +} + +godot_ptr_getter GDAPI godot_variant_get_ptr_getter(godot_variant_type p_type, const godot_string_name *p_member) { + return (godot_ptr_getter)Variant::get_member_ptr_getter((Variant::Type)p_type, *((const StringName *)p_member)); +} + +godot_ptr_getter GDAPI godot_variant_get_ptr_getter_with_cstring(godot_variant_type p_type, const char *p_member) { + return (godot_ptr_getter)Variant::get_member_ptr_getter((Variant::Type)p_type, StringName(p_member)); +} + +/// Indexing. +bool GDAPI godot_variant_has_indexing(godot_variant_type p_type) { + return Variant::has_indexing((Variant::Type)p_type); +} + +godot_variant_type GDAPI godot_variant_get_indexed_element_type(godot_variant_type p_type) { + return (godot_variant_type)Variant::get_indexed_element_type((Variant::Type)p_type); +} + +godot_validated_indexed_setter GDAPI godot_variant_get_validated_indexed_setter(godot_variant_type p_type) { + return (godot_validated_indexed_setter)Variant::get_member_validated_indexed_setter((Variant::Type)p_type); +} + +godot_validated_indexed_getter GDAPI godot_variant_get_validated_indexed_getter(godot_variant_type p_type) { + return (godot_validated_indexed_getter)Variant::get_member_validated_indexed_getter((Variant::Type)p_type); +} + +godot_ptr_indexed_setter GDAPI godot_variant_get_ptr_indexed_setter(godot_variant_type p_type) { + return (godot_ptr_indexed_setter)Variant::get_member_ptr_indexed_setter((Variant::Type)p_type); +} + +godot_ptr_indexed_getter GDAPI godot_variant_get_ptr_indexed_getter(godot_variant_type p_type) { + return (godot_ptr_indexed_getter)Variant::get_member_ptr_indexed_getter((Variant::Type)p_type); +} + +uint64_t GDAPI godot_variant_get_indexed_size(const godot_variant *p_self) { + const Variant *self = (const Variant *)p_self; + return self->get_indexed_size(); +} + +/// Keying. +bool GDAPI godot_variant_is_keyed(godot_variant_type p_type) { + return Variant::is_keyed((Variant::Type)p_type); +} + +godot_validated_keyed_setter GDAPI godot_variant_get_validated_keyed_setter(godot_variant_type p_type) { + return (godot_validated_keyed_setter)Variant::get_member_validated_keyed_setter((Variant::Type)p_type); +} + +godot_validated_keyed_getter GDAPI godot_variant_get_validated_keyed_getter(godot_variant_type p_type) { + return (godot_validated_keyed_getter)Variant::get_member_validated_keyed_getter((Variant::Type)p_type); +} + +godot_validated_keyed_checker GDAPI godot_variant_get_validated_keyed_checker(godot_variant_type p_type) { + return (godot_validated_keyed_checker)Variant::get_member_validated_keyed_checker((Variant::Type)p_type); +} + +godot_ptr_keyed_setter GDAPI godot_variant_get_ptr_keyed_setter(godot_variant_type p_type) { + return (godot_ptr_keyed_setter)Variant::get_member_ptr_keyed_setter((Variant::Type)p_type); +} + +godot_ptr_keyed_getter GDAPI godot_variant_get_ptr_keyed_getter(godot_variant_type p_type) { + return (godot_ptr_keyed_getter)Variant::get_member_ptr_keyed_getter((Variant::Type)p_type); +} + +godot_ptr_keyed_checker GDAPI godot_variant_get_ptr_keyed_checker(godot_variant_type p_type) { + return (godot_ptr_keyed_checker)Variant::get_member_ptr_keyed_checker((Variant::Type)p_type); +} + +/// Constants. +int GDAPI godot_variant_get_constants_count(godot_variant_type p_type) { + return Variant::get_constants_count_for_type((Variant::Type)p_type); +} + +void GDAPI godot_variant_get_constants_list(godot_variant_type p_type, godot_string_name *r_list) { + List<StringName> constants; + int i = 0; + Variant::get_constants_for_type((Variant::Type)p_type, &constants); + for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) { + memnew_placement_custom(&r_list[i++], StringName, StringName(E->get())); + } +} + +bool GDAPI godot_variant_has_constant(godot_variant_type p_type, const godot_string_name *p_constant) { + return Variant::has_constant((Variant::Type)p_type, *((const StringName *)p_constant)); +} + +bool GDAPI godot_variant_has_constant_with_cstring(godot_variant_type p_type, const char *p_constant) { + return Variant::has_constant((Variant::Type)p_type, StringName(p_constant)); +} + +godot_variant GDAPI godot_variant_get_constant_value(godot_variant_type p_type, const godot_string_name *p_constant) { + Variant constant = Variant::get_constant_value((Variant::Type)p_type, *((const StringName *)p_constant)); + godot_variant ret; + memnew_placement_custom(&ret, Variant, Variant(constant)); + return ret; +} + +godot_variant GDAPI godot_variant_get_constant_value_with_cstring(godot_variant_type p_type, const char *p_constant) { + Variant constant = Variant::get_constant_value((Variant::Type)p_type, StringName(p_constant)); + godot_variant ret; + memnew_placement_custom(&ret, Variant, Variant(constant)); + return ret; +} + +/// Utilities. +bool GDAPI godot_variant_has_utility_function(const godot_string_name *p_function) { + return Variant::has_utility_function(*((const StringName *)p_function)); +} + +bool GDAPI godot_variant_has_utility_function_with_cstring(const char *p_function) { + return Variant::has_utility_function(StringName(p_function)); +} + +void GDAPI godot_variant_call_utility_function(const godot_string_name *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error) { + const StringName *function = (const StringName *)p_function; Variant *ret = (Variant *)r_ret; - Variant::evaluate(op, *a, *b, *ret, *r_valid); + const Variant **args = (const Variant **)p_args; + Callable::CallError error; + + Variant::call_utility_function(*function, ret, args, p_argument_count, error); + + if (r_error) { + r_error->error = (godot_variant_call_error_error)error.error; + r_error->argument = error.argument; + r_error->expected = (godot_variant_type)error.expected; + } +} + +void GDAPI godot_variant_call_utility_function_with_cstring(const char *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error) { + Variant *ret = (Variant *)r_ret; + const Variant **args = (const Variant **)p_args; + Callable::CallError error; + + Variant::call_utility_function(StringName(p_function), ret, args, p_argument_count, error); + + if (r_error) { + r_error->error = (godot_variant_call_error_error)error.error; + r_error->argument = error.argument; + r_error->expected = (godot_variant_type)error.expected; + } +} + +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function(const godot_string_name *p_function) { + return (godot_ptr_utility_function)Variant::get_ptr_utility_function(*((const StringName *)p_function)); +} + +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function_with_cstring(const char *p_function) { + return (godot_ptr_utility_function)Variant::get_ptr_utility_function(StringName(p_function)); +} + +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function(const godot_string_name *p_function) { + return (godot_validated_utility_function)Variant::get_validated_utility_function(*((const StringName *)p_function)); +} + +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function_with_cstring(const char *p_function) { + return (godot_validated_utility_function)Variant::get_validated_utility_function(StringName(p_function)); +} + +godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type(const godot_string_name *p_function) { + return (godot_variant_utility_function_type)Variant::get_utility_function_type(*((const StringName *)p_function)); +} + +godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type_with_cstring(const char *p_function) { + return (godot_variant_utility_function_type)Variant::get_utility_function_type(StringName(p_function)); +} + +int GDAPI godot_variant_get_utility_function_argument_count(const godot_string_name *p_function) { + return Variant::get_utility_function_argument_count(*((const StringName *)p_function)); +} + +int GDAPI godot_variant_get_utility_function_argument_count_with_cstring(const char *p_function) { + return Variant::get_utility_function_argument_count(StringName(p_function)); +} + +godot_variant_type GDAPI godot_variant_get_utility_function_argument_type(const godot_string_name *p_function, int p_argument) { + return (godot_variant_type)Variant::get_utility_function_argument_type(*((const StringName *)p_function), p_argument); +} + +godot_variant_type GDAPI godot_variant_get_utility_function_argument_type_with_cstring(const char *p_function, int p_argument) { + return (godot_variant_type)Variant::get_utility_function_argument_type(StringName(p_function), p_argument); +} + +godot_string GDAPI godot_variant_get_utility_function_argument_name(const godot_string_name *p_function, int p_argument) { + String argument_name = Variant::get_utility_function_argument_name(*((const StringName *)p_function), p_argument); + godot_string ret; + memnew_placement_custom(&ret, String, String(argument_name)); + return ret; +} + +godot_string GDAPI godot_variant_get_utility_function_argument_name_with_cstring(const char *p_function, int p_argument) { + String argument_name = Variant::get_utility_function_argument_name(StringName(p_function), p_argument); + godot_string ret; + memnew_placement_custom(&ret, String, String(argument_name)); + return ret; +} + +bool GDAPI godot_variant_has_utility_function_return_value(const godot_string_name *p_function) { + return Variant::has_utility_function_return_value(*((const StringName *)p_function)); +} + +bool GDAPI godot_variant_has_utility_function_return_value_with_cstring(const char *p_function) { + return Variant::has_utility_function_return_value(StringName(p_function)); +} + +godot_variant_type GDAPI godot_variant_get_utility_function_return_type(const godot_string_name *p_function) { + return (godot_variant_type)Variant::get_utility_function_return_type(*((const StringName *)p_function)); +} + +godot_variant_type GDAPI godot_variant_get_utility_function_return_type_with_cstring(const char *p_function) { + return (godot_variant_type)Variant::get_utility_function_return_type(StringName(p_function)); +} + +bool GDAPI godot_variant_is_utility_function_vararg(const godot_string_name *p_function) { + return Variant::is_utility_function_vararg(*((const StringName *)p_function)); +} + +bool GDAPI godot_variant_is_utility_function_vararg_with_cstring(const char *p_function) { + return Variant::is_utility_function_vararg(StringName(p_function)); +} + +int GDAPI godot_variant_get_utility_function_count() { + return Variant::get_utility_function_count(); +} + +void GDAPI godot_variant_get_utility_function_list(godot_string_name *r_functions) { + List<StringName> functions; + godot_string_name *func = r_functions; + Variant::get_utility_function_list(&functions); + + for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) { + memnew_placement_custom(func++, StringName, StringName(E->get())); + } +} + +// Introspection. + +godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self) { + const Variant *self = (const Variant *)p_self; + return (godot_variant_type)self->get_type(); +} + +bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string_name *p_method) { + const Variant *self = (const Variant *)p_self; + const StringName *method = (const StringName *)p_method; + return self->has_method(*method); +} + +bool GDAPI godot_variant_has_member(godot_variant_type p_type, const godot_string_name *p_member) { + return Variant::has_member((Variant::Type)p_type, *((const StringName *)p_member)); +} + +bool GDAPI godot_variant_has_key(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid) { + const Variant *self = (const Variant *)p_self; + const Variant *key = (const Variant *)p_key; + return self->has_key(*key, *r_valid); +} + +godot_string GDAPI godot_variant_get_type_name(godot_variant_type p_type) { + String name = Variant::get_type_name((Variant::Type)p_type); + godot_string ret; + memnew_placement_custom(&ret, String, String(name)); + return ret; +} + +bool GDAPI godot_variant_can_convert(godot_variant_type p_from, godot_variant_type p_to) { + return Variant::can_convert((Variant::Type)p_from, (Variant::Type)p_to); +} + +bool GDAPI godot_variant_can_convert_strict(godot_variant_type p_from, godot_variant_type p_to) { + return Variant::can_convert_strict((Variant::Type)p_from, (Variant::Type)p_to); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 6f42935228..ebb1996649 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -31,430 +31,40 @@ #include "gdnative/vector2.h" #include "core/math/vector2.h" -#include "core/variant/variant.h" - -#ifdef __cplusplus -extern "C" { -#endif static_assert(sizeof(godot_vector2) == sizeof(Vector2), "Vector2 size mismatch"); static_assert(sizeof(godot_vector2i) == sizeof(Vector2i), "Vector2i size mismatch"); -// Vector2 - -void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) { - Vector2 *dest = (Vector2 *)r_dest; - *dest = Vector2(p_x, p_y); -} - -godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self) { - godot_string ret; - const Vector2 *self = (const Vector2 *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_vector2i GDAPI godot_vector2_as_vector2i(const godot_vector2 *p_self) { - godot_vector2i dest; - const Vector2 *self = (const Vector2 *)p_self; - *((Vector2i *)&dest) = Vector2i(*self); - return dest; -} - -godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - *((Vector2 *)&dest) = self->normalized(); - return dest; -} - -godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self) { - const Vector2 *self = (const Vector2 *)p_self; - return self->length(); -} - -godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_self) { - const Vector2 *self = (const Vector2 *)p_self; - return self->angle(); -} - -godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self) { - const Vector2 *self = (const Vector2 *)p_self; - return self->length_squared(); -} - -godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self) { - const Vector2 *self = (const Vector2 *)p_self; - return self->is_normalized(); -} - -godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_to) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - *((Vector2 *)&dest) = self->direction_to(*to); - return dest; -} - -godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - return self->distance_to(*to); -} - -godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - return self->distance_squared_to(*to); -} - -godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot_vector2 *p_to) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - return self->angle_to(*to); -} - -godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - return self->angle_to_point(*to); -} - -godot_vector2 GDAPI godot_vector2_lerp(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - *((Vector2 *)&dest) = self->lerp(*b, p_t); - return dest; -} - -godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - const Vector2 *pre_a = (const Vector2 *)p_pre_a; - const Vector2 *post_b = (const Vector2 *)p_post_b; - *((Vector2 *)&dest) = self->cubic_interpolate(*b, *pre_a, *post_b, p_t); - return dest; -} - -godot_vector2 GDAPI godot_vector2_move_toward(const godot_vector2 *p_self, const godot_vector2 *p_to, const godot_real p_delta) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *to = (const Vector2 *)p_to; - *((Vector2 *)&dest) = self->move_toward(*to, p_delta); - return dest; -} - -godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - - *((Vector2 *)&dest) = self->rotated(p_phi); - return dest; -} - -godot_vector2 GDAPI godot_vector2_orthogonal(const godot_vector2 *p_self) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - *((Vector2 *)&dest) = self->orthogonal(); - return dest; -} - -godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - *((Vector2 *)&dest) = self->floor(); - return dest; -} - -godot_vector2 GDAPI godot_vector2_sign(const godot_vector2 *p_self) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - *((Vector2 *)&dest) = self->sign(); - return dest; -} - -godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *by = (const Vector2 *)p_by; - *((Vector2 *)&dest) = self->snapped(*by); - return dest; -} - -godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self) { - const Vector2 *self = (const Vector2 *)p_self; - return self->aspect(); -} - -godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_self, const godot_vector2 *p_with) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *with = (const Vector2 *)p_with; - return self->dot(*with); -} - -godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_self, const godot_vector2 *p_n) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *n = (const Vector2 *)p_n; - *((Vector2 *)&dest) = self->slide(*n); - return dest; -} - -godot_vector2 GDAPI godot_vector2_bounce(const godot_vector2 *p_self, const godot_vector2 *p_n) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *n = (const Vector2 *)p_n; - *((Vector2 *)&dest) = self->bounce(*n); - return dest; -} - -godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_self, const godot_vector2 *p_n) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *n = (const Vector2 *)p_n; - *((Vector2 *)&dest) = self->reflect(*n); - return dest; -} - -godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_self) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - *((Vector2 *)&dest) = self->abs(); - return dest; -} - -godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const godot_real p_length) { - godot_vector2 dest; - const Vector2 *self = (const Vector2 *)p_self; - - *((Vector2 *)&dest) = self->clamped(p_length); - return dest; -} - -godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - *dest = *self + *b; - return raw_dest; -} - -godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_self, const godot_vector2 *p_b) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - *dest = *self - *b; - return raw_dest; -} - -godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - *dest = *self * *b; - return raw_dest; -} - -godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_self, const godot_real p_b) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - *dest = *self * p_b; - return raw_dest; -} - -godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_self, const godot_vector2 *p_b) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - *dest = *self / *b; - return raw_dest; -} - -godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_self, const godot_real p_b) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - *dest = *self / p_b; - return raw_dest; -} - -godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_self, const godot_vector2 *p_b) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - return *self == *b; -} - -godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_self, const godot_vector2 *p_b) { - const Vector2 *self = (const Vector2 *)p_self; - const Vector2 *b = (const Vector2 *)p_b; - return *self < *b; -} +#ifdef __cplusplus +extern "C" { +#endif -godot_vector2 GDAPI godot_vector2_operator_neg(const godot_vector2 *p_self) { - godot_vector2 raw_dest; - Vector2 *dest = (Vector2 *)&raw_dest; - const Vector2 *self = (const Vector2 *)p_self; - *dest = -(*self); - return raw_dest; +void GDAPI godot_vector2_new(godot_vector2 *p_self) { + memnew_placement(p_self, Vector2); } -void GDAPI godot_vector2_set_x(godot_vector2 *p_self, const godot_real p_x) { - Vector2 *self = (Vector2 *)p_self; - self->x = p_x; +void GDAPI godot_vector2i_new(godot_vector2i *p_self) { + memnew_placement(p_self, Vector2i); } -void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y) { +godot_real_t GDAPI *godot_vector2_operator_index(godot_vector2 *p_self, godot_int p_index) { Vector2 *self = (Vector2 *)p_self; - self->y = p_y; + return (godot_real_t *)&self->operator[](p_index); } -godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self) { +const godot_real_t GDAPI *godot_vector2_operator_index_const(const godot_vector2 *p_self, godot_int p_index) { const Vector2 *self = (const Vector2 *)p_self; - return self->x; -} - -godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self) { - const Vector2 *self = (const Vector2 *)p_self; - return self->y; -} - -// Vector2i - -void GDAPI godot_vector2i_new(godot_vector2i *r_dest, const godot_int p_x, const godot_int p_y) { - Vector2i *dest = (Vector2i *)r_dest; - *dest = Vector2i(p_x, p_y); -} - -godot_string GDAPI godot_vector2i_as_string(const godot_vector2i *p_self) { - godot_string ret; - const Vector2i *self = (const Vector2i *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_vector2 GDAPI godot_vector2i_as_vector2(const godot_vector2i *p_self) { - godot_vector2 dest; - const Vector2i *self = (const Vector2i *)p_self; - *((Vector2 *)&dest) = Vector2(*self); - return dest; -} - -godot_real GDAPI godot_vector2i_aspect(const godot_vector2i *p_self) { - const Vector2i *self = (const Vector2i *)p_self; - return self->aspect(); -} - -godot_vector2i GDAPI godot_vector2i_abs(const godot_vector2i *p_self) { - godot_vector2i dest; - const Vector2i *self = (const Vector2i *)p_self; - *((Vector2i *)&dest) = self->abs(); - return dest; -} - -godot_vector2i GDAPI godot_vector2i_sign(const godot_vector2i *p_self) { - godot_vector2i dest; - const Vector2i *self = (const Vector2i *)p_self; - *((Vector2i *)&dest) = self->sign(); - return dest; -} - -godot_vector2i GDAPI godot_vector2i_operator_add(const godot_vector2i *p_self, const godot_vector2i *p_b) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - const Vector2i *b = (const Vector2i *)p_b; - *dest = *self + *b; - return raw_dest; -} - -godot_vector2i GDAPI godot_vector2i_operator_subtract(const godot_vector2i *p_self, const godot_vector2i *p_b) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - const Vector2i *b = (const Vector2i *)p_b; - *dest = *self - *b; - return raw_dest; -} - -godot_vector2i GDAPI godot_vector2i_operator_multiply_vector(const godot_vector2i *p_self, const godot_vector2i *p_b) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - const Vector2i *b = (const Vector2i *)p_b; - *dest = *self * *b; - return raw_dest; -} - -godot_vector2i GDAPI godot_vector2i_operator_multiply_scalar(const godot_vector2i *p_self, const godot_int p_b) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - *dest = *self * p_b; - return raw_dest; + return (const godot_real_t *)&self->operator[](p_index); } -godot_vector2i GDAPI godot_vector2i_operator_divide_vector(const godot_vector2i *p_self, const godot_vector2i *p_b) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - const Vector2i *b = (const Vector2i *)p_b; - *dest = *self / *b; - return raw_dest; -} - -godot_vector2i GDAPI godot_vector2i_operator_divide_scalar(const godot_vector2i *p_self, const godot_int p_b) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - *dest = *self / p_b; - return raw_dest; -} - -godot_bool GDAPI godot_vector2i_operator_equal(const godot_vector2i *p_self, const godot_vector2i *p_b) { - const Vector2i *self = (const Vector2i *)p_self; - const Vector2i *b = (const Vector2i *)p_b; - return *self == *b; -} - -godot_bool GDAPI godot_vector2i_operator_less(const godot_vector2i *p_self, const godot_vector2i *p_b) { - const Vector2i *self = (const Vector2i *)p_self; - const Vector2i *b = (const Vector2i *)p_b; - return *self < *b; -} - -godot_vector2i GDAPI godot_vector2i_operator_neg(const godot_vector2i *p_self) { - godot_vector2i raw_dest; - Vector2i *dest = (Vector2i *)&raw_dest; - const Vector2i *self = (const Vector2i *)p_self; - *dest = -(*self); - return raw_dest; -} - -void GDAPI godot_vector2i_set_x(godot_vector2i *p_self, const godot_int p_x) { - Vector2i *self = (Vector2i *)p_self; - self->x = p_x; -} - -void GDAPI godot_vector2i_set_y(godot_vector2i *p_self, const godot_int p_y) { +int32_t GDAPI *godot_vector2i_operator_index(godot_vector2i *p_self, godot_int p_index) { Vector2i *self = (Vector2i *)p_self; - self->y = p_y; -} - -godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self) { - const Vector2i *self = (const Vector2i *)p_self; - return self->x; + return (int32_t *)&self->operator[](p_index); } -godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self) { +const int32_t GDAPI *godot_vector2i_operator_index_const(const godot_vector2i *p_self, godot_int p_index) { const Vector2i *self = (const Vector2i *)p_self; - return self->y; + return (const int32_t *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index 75aeb59c87..0fe1b292a7 100644 --- a/modules/gdnative/gdnative/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -30,433 +30,41 @@ #include "gdnative/vector3.h" -#include "core/templates/vector.h" -#include "core/variant/variant.h" - -#ifdef __cplusplus -extern "C" { -#endif +#include "core/math/vector3.h" static_assert(sizeof(godot_vector3) == sizeof(Vector3), "Vector3 size mismatch"); static_assert(sizeof(godot_vector3i) == sizeof(Vector3i), "Vector3i size mismatch"); -// Vector3 - -void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) { - Vector3 *dest = (Vector3 *)r_dest; - *dest = Vector3(p_x, p_y, p_z); -} - -godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self) { - godot_string ret; - const Vector3 *self = (const Vector3 *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_vector3i GDAPI godot_vector3_as_vector3i(const godot_vector3 *p_self) { - godot_vector3i dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3i *)&dest) = Vector3i(*self); - return dest; -} - -godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self) { - const Vector3 *self = (const Vector3 *)p_self; - return self->min_axis(); -} - -godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self) { - const Vector3 *self = (const Vector3 *)p_self; - return self->max_axis(); -} - -godot_real GDAPI godot_vector3_length(const godot_vector3 *p_self) { - const Vector3 *self = (const Vector3 *)p_self; - return self->length(); -} - -godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_self) { - const Vector3 *self = (const Vector3 *)p_self; - return self->length_squared(); -} - -godot_bool GDAPI godot_vector3_is_normalized(const godot_vector3 *p_self) { - const Vector3 *self = (const Vector3 *)p_self; - return self->is_normalized(); -} - -godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_self) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3 *)&dest) = self->normalized(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_self) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3 *)&dest) = self->inverse(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const godot_vector3 *p_by) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *snap_axis = (const Vector3 *)p_by; - - *((Vector3 *)&dest) = self->snapped(*snap_axis); - return dest; -} - -godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *axis = (const Vector3 *)p_axis; - *((Vector3 *)&dest) = self->rotated(*axis, p_phi); - return dest; -} - -godot_vector3 GDAPI godot_vector3_lerp(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *((Vector3 *)&dest) = self->lerp(*b, p_t); - return dest; -} - -godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - const Vector3 *pre_a = (const Vector3 *)p_pre_a; - const Vector3 *post_b = (const Vector3 *)p_post_b; - *((Vector3 *)&dest) = self->cubic_interpolate(*b, *pre_a, *post_b, p_t); - return dest; -} - -godot_vector3 GDAPI godot_vector3_move_toward(const godot_vector3 *p_self, const godot_vector3 *p_to, const godot_real p_delta) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *to = (const Vector3 *)p_to; - *((Vector3 *)&dest) = self->move_toward(*to, p_delta); - return dest; -} - -godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b) { - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - return self->dot(*b); -} - -godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *((Vector3 *)&dest) = self->cross(*b); - return dest; -} - -godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_self, const godot_vector3 *p_b) { - godot_basis dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *((Basis *)&dest) = self->outer(*b); - return dest; -} - -godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self) { - godot_basis dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Basis *)&dest) = self->to_diagonal_matrix(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3 *)&dest) = self->abs(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_sign(const godot_vector3 *p_self) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3 *)&dest) = self->sign(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3 *)&dest) = self->floor(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - *((Vector3 *)&dest) = self->ceil(); - return dest; -} - -godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_to) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *to = (const Vector3 *)p_to; - *((Vector3 *)&dest) = self->direction_to(*to); - return dest; -} - -godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b) { - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - return self->distance_to(*b); -} - -godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b) { - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - return self->distance_squared_to(*b); -} - -godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_self, const godot_vector3 *p_to) { - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *to = (const Vector3 *)p_to; - return self->angle_to(*to); -} - -godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_self, const godot_vector3 *p_n) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *n = (const Vector3 *)p_n; - *((Vector3 *)&dest) = self->slide(*n); - return dest; -} - -godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_self, const godot_vector3 *p_n) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *n = (const Vector3 *)p_n; - *((Vector3 *)&dest) = self->bounce(*n); - return dest; -} - -godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const godot_vector3 *p_n) { - godot_vector3 dest; - const Vector3 *self = (const Vector3 *)p_self; - const Vector3 *n = (const Vector3 *)p_n; - *((Vector3 *)&dest) = self->reflect(*n); - return dest; -} - -godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - Vector3 *self = (Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *dest = *self + *b; - return raw_dest; -} - -godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_self, const godot_vector3 *p_b) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - Vector3 *self = (Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *dest = *self - *b; - return raw_dest; -} - -godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - Vector3 *self = (Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *dest = *self * *b; - return raw_dest; -} - -godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_self, const godot_real p_b) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - Vector3 *self = (Vector3 *)p_self; - *dest = *self * p_b; - return raw_dest; -} - -godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_self, const godot_vector3 *p_b) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - Vector3 *self = (Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - *dest = *self / *b; - return raw_dest; -} - -godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_self, const godot_real p_b) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - Vector3 *self = (Vector3 *)p_self; - *dest = *self / p_b; - return raw_dest; -} - -godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_self, const godot_vector3 *p_b) { - Vector3 *self = (Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - return *self == *b; -} +#ifdef __cplusplus +extern "C" { +#endif -godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_self, const godot_vector3 *p_b) { - Vector3 *self = (Vector3 *)p_self; - const Vector3 *b = (const Vector3 *)p_b; - return *self < *b; +void GDAPI godot_vector3_new(godot_vector3 *p_self) { + memnew_placement(p_self, Vector3); } -godot_vector3 GDAPI godot_vector3_operator_neg(const godot_vector3 *p_self) { - godot_vector3 raw_dest; - Vector3 *dest = (Vector3 *)&raw_dest; - const Vector3 *self = (const Vector3 *)p_self; - *dest = -(*self); - return raw_dest; +void GDAPI godot_vector3i_new(godot_vector3i *p_self) { + memnew_placement(p_self, Vector3i); } -void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val) { +godot_real_t GDAPI *godot_vector3_operator_index(godot_vector3 *p_self, godot_int p_index) { Vector3 *self = (Vector3 *)p_self; - self->set_axis(p_axis, p_val); + return (godot_real_t *)&self->operator[](p_index); } -godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis) { +const godot_real_t GDAPI *godot_vector3_operator_index_const(const godot_vector3 *p_self, godot_int p_index) { const Vector3 *self = (const Vector3 *)p_self; - return self->get_axis(p_axis); -} - -// Vector3i - -void GDAPI godot_vector3i_new(godot_vector3i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_z) { - Vector3i *dest = (Vector3i *)r_dest; - *dest = Vector3i(p_x, p_y, p_z); -} - -godot_string GDAPI godot_vector3i_as_string(const godot_vector3i *p_self) { - godot_string ret; - const Vector3i *self = (const Vector3i *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_vector3 GDAPI godot_vector3i_as_vector3(const godot_vector3i *p_self) { - godot_vector3 dest; - const Vector3i *self = (const Vector3i *)p_self; - *((Vector3 *)&dest) = Vector3(*self); - return dest; -} - -godot_int GDAPI godot_vector3i_min_axis(const godot_vector3i *p_self) { - const Vector3i *self = (const Vector3i *)p_self; - return self->min_axis(); -} - -godot_int GDAPI godot_vector3i_max_axis(const godot_vector3i *p_self) { - const Vector3i *self = (const Vector3i *)p_self; - return self->max_axis(); -} - -godot_vector3i GDAPI godot_vector3i_abs(const godot_vector3i *p_self) { - godot_vector3i dest; - const Vector3i *self = (const Vector3i *)p_self; - *((Vector3i *)&dest) = self->abs(); - return dest; -} - -godot_vector3i GDAPI godot_vector3i_sign(const godot_vector3i *p_self) { - godot_vector3i dest; - const Vector3i *self = (const Vector3i *)p_self; - *((Vector3i *)&dest) = self->sign(); - return dest; -} - -godot_vector3i GDAPI godot_vector3i_operator_add(const godot_vector3i *p_self, const godot_vector3i *p_b) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - Vector3i *self = (Vector3i *)p_self; - const Vector3i *b = (const Vector3i *)p_b; - *dest = *self + *b; - return raw_dest; -} - -godot_vector3i GDAPI godot_vector3i_operator_subtract(const godot_vector3i *p_self, const godot_vector3i *p_b) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - Vector3i *self = (Vector3i *)p_self; - const Vector3i *b = (const Vector3i *)p_b; - *dest = *self - *b; - return raw_dest; -} - -godot_vector3i GDAPI godot_vector3i_operator_multiply_vector(const godot_vector3i *p_self, const godot_vector3i *p_b) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - Vector3i *self = (Vector3i *)p_self; - const Vector3i *b = (const Vector3i *)p_b; - *dest = *self * *b; - return raw_dest; -} - -godot_vector3i GDAPI godot_vector3i_operator_multiply_scalar(const godot_vector3i *p_self, const godot_int p_b) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - Vector3i *self = (Vector3i *)p_self; - *dest = *self * p_b; - return raw_dest; -} - -godot_vector3i GDAPI godot_vector3i_operator_divide_vector(const godot_vector3i *p_self, const godot_vector3i *p_b) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - Vector3i *self = (Vector3i *)p_self; - const Vector3i *b = (const Vector3i *)p_b; - *dest = *self / *b; - return raw_dest; -} - -godot_vector3i GDAPI godot_vector3i_operator_divide_scalar(const godot_vector3i *p_self, const godot_int p_b) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - Vector3i *self = (Vector3i *)p_self; - *dest = *self / p_b; - return raw_dest; -} - -godot_bool GDAPI godot_vector3i_operator_equal(const godot_vector3i *p_self, const godot_vector3i *p_b) { - Vector3i *self = (Vector3i *)p_self; - const Vector3i *b = (const Vector3i *)p_b; - return *self == *b; -} - -godot_bool GDAPI godot_vector3i_operator_less(const godot_vector3i *p_self, const godot_vector3i *p_b) { - Vector3i *self = (Vector3i *)p_self; - const Vector3i *b = (const Vector3i *)p_b; - return *self < *b; -} - -godot_vector3i GDAPI godot_vector3i_operator_neg(const godot_vector3i *p_self) { - godot_vector3i raw_dest; - Vector3i *dest = (Vector3i *)&raw_dest; - const Vector3i *self = (const Vector3i *)p_self; - *dest = -(*self); - return raw_dest; + return (const godot_real_t *)&self->operator[](p_index); } -void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val) { +int32_t GDAPI *godot_vector3i_operator_index(godot_vector3i *p_self, godot_int p_index) { Vector3i *self = (Vector3i *)p_self; - self->set_axis(p_axis, p_val); + return (int32_t *)&self->operator[](p_index); } -godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis) { +const int32_t GDAPI *godot_vector3i_operator_index_const(const godot_vector3i *p_self, godot_int p_index) { const Vector3i *self = (const Vector3i *)p_self; - return self->get_axis(p_axis); + return (const int32_t *)&self->operator[](p_index); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index a29a0808ca..c163fbbc1b 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -1,8074 +1,5249 @@ { - "core": { - "type": "CORE", - "version": { - "major": 4, - "minor": 0 - }, - "next": null, - "api": [ - { - "name": "godot_aabb_new", - "return_type": "void", - "arguments": [ - ["godot_aabb *", "r_dest"], - ["const godot_vector3 *", "p_pos"], - ["const godot_vector3 *", "p_size"] - ] - }, - { - "name": "godot_aabb_get_position", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_set_position", - "return_type": "void", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_aabb_get_size", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_set_size", - "return_type": "void", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_aabb_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_abs", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_get_area", - "return_type": "godot_real", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_has_no_area", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_has_no_surface", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_intersects", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_aabb *", "p_with"] - ] - }, - { - "name": "godot_aabb_encloses", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_aabb *", "p_with"] - ] - }, - { - "name": "godot_aabb_merge", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_aabb *", "p_with"] - ] - }, - { - "name": "godot_aabb_intersection", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_aabb *", "p_with"] - ] - }, - { - "name": "godot_aabb_intersects_plane", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_plane *", "p_plane"] - ] - }, - { - "name": "godot_aabb_intersects_segment", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_vector3 *", "p_from"], - ["const godot_vector3 *", "p_to"] - ] - }, - { - "name": "godot_aabb_has_point", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_vector3 *", "p_point"] - ] - }, - { - "name": "godot_aabb_get_support", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_vector3 *", "p_dir"] - ] - }, - { - "name": "godot_aabb_get_longest_axis", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_get_longest_axis_index", - "return_type": "godot_int", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_get_longest_axis_size", - "return_type": "godot_real", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_get_shortest_axis", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_get_shortest_axis_index", - "return_type": "godot_int", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_get_shortest_axis_size", - "return_type": "godot_real", - "arguments": [ - ["const godot_aabb *", "p_self"] - ] - }, - { - "name": "godot_aabb_expand", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_vector3 *", "p_to_point"] - ] - }, - { - "name": "godot_aabb_grow", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_real", "p_by"] - ] - }, - { - "name": "godot_aabb_get_endpoint", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_aabb_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_aabb *", "p_self"], - ["const godot_aabb *", "p_b"] - ] - }, - { - "name": "godot_array_new", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"] - ] - }, - { - "name": "godot_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_array *", "p_src"] - ] - }, - { - "name": "godot_array_new_packed_color_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_color_array *", "p_pca"] - ] - }, - { - "name": "godot_array_new_packed_vector3_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_vector3_array *", "p_pv3a"] - ] - }, - { - "name": "godot_array_new_packed_vector2_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_vector2_array *", "p_pv2a"] - ] - }, - { - "name": "godot_array_new_packed_vector2i_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_vector2i_array *", "p_pv2a"] - ] - }, - { - "name": "godot_array_new_packed_string_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_string_array *", "p_psa"] - ] - }, - { - "name": "godot_array_new_packed_float32_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_float32_array *", "p_pra"] - ] - }, - { - "name": "godot_array_new_packed_float64_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_float64_array *", "p_pra"] - ] - }, - { - "name": "godot_array_new_packed_int32_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_int32_array *", "p_pia"] - ] - }, - { - "name": "godot_array_new_packed_int64_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_int64_array *", "p_pia"] - ] - }, - { - "name": "godot_array_new_packed_byte_array", - "return_type": "void", - "arguments": [ - ["godot_array *", "r_dest"], - ["const godot_packed_byte_array *", "p_pba"] - ] - }, - { - "name": "godot_array_set", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_get", - "return_type": "godot_variant", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_array_operator_index", - "return_type": "godot_variant *", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_array_operator_index_const", - "return_type": "const godot_variant *", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_array_append", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_clear", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_count", - "return_type": "godot_int", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_duplicate", - "return_type": "godot_array", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_bool", "p_deep"] - ] - }, - { - "name": "godot_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_erase", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_front", - "return_type": "godot_variant", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_back", - "return_type": "godot_variant", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_find", - "return_type": "godot_int", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_variant *", "p_what"], - ["const godot_int", "p_from"] - ] - }, - { - "name": "godot_array_find_last", - "return_type": "godot_int", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_variant *", "p_what"] - ] - }, - { - "name": "godot_array_has", - "return_type": "godot_bool", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_hash", - "return_type": "godot_int", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_insert", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_int", "p_pos"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_invert", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_max", - "return_type": "godot_variant", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_min", - "return_type": "godot_variant", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_pop_back", - "return_type": "godot_variant", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_pop_front", - "return_type": "godot_variant", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_push_front", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_array_remove", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_array_resize", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_array_rfind", - "return_type": "godot_int", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_variant *", "p_what"], - ["const godot_int", "p_from"] - ] - }, - { - "name": "godot_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_shuffle", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_slice", - "return_type": "godot_array", - "arguments": [ - ["const godot_array *", "p_self"], - ["const godot_int", "p_begin"], - ["const godot_int", "p_end"], - ["const godot_int", "p_step"], - ["const godot_bool", "p_deep"] - ] - }, - { - "name": "godot_array_sort", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_array_sort_custom", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"], - ["godot_object *", "p_obj"], - ["const godot_string *", "p_func"] - ] - }, - { - "name": "godot_array_bsearch", - "return_type": "godot_int", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_variant *", "p_value"], - ["const godot_bool", "p_before"] - ] - }, - { - "name": "godot_array_bsearch_custom", - "return_type": "godot_int", - "arguments": [ - ["godot_array *", "p_self"], - ["const godot_variant *", "p_value"], - ["godot_object *", "p_obj"], - ["const godot_string *", "p_func"], - ["const godot_bool", "p_before"] - ] - }, - { - "name": "godot_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_array *", "p_self"] - ] - }, - { - "name": "godot_basis_new_with_rows", - "return_type": "void", - "arguments": [ - ["godot_basis *", "r_dest"], - ["const godot_vector3 *", "p_x_axis"], - ["const godot_vector3 *", "p_y_axis"], - ["const godot_vector3 *", "p_z_axis"] - ] - }, - { - "name": "godot_basis_new_with_axis_and_angle", - "return_type": "void", - "arguments": [ - ["godot_basis *", "r_dest"], - ["const godot_vector3 *", "p_axis"], - ["const godot_real", "p_phi"] - ] - }, - { - "name": "godot_basis_new_with_euler", - "return_type": "void", - "arguments": [ - ["godot_basis *", "r_dest"], - ["const godot_vector3 *", "p_euler"] - ] - }, - { - "name": "godot_basis_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_inverse", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_transposed", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_orthonormalized", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_determinant", - "return_type": "godot_real", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_rotated", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_axis"], - ["const godot_real", "p_phi"] - ] - }, - { - "name": "godot_basis_scaled", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_scale"] - ] - }, - { - "name": "godot_basis_get_scale", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_get_euler", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_tdotx", - "return_type": "godot_real", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_with"] - ] - }, - { - "name": "godot_basis_tdoty", - "return_type": "godot_real", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_with"] - ] - }, - { - "name": "godot_basis_tdotz", - "return_type": "godot_real", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_with"] - ] - }, - { - "name": "godot_basis_xform", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_basis_xform_inv", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_basis_get_orthogonal_index", - "return_type": "godot_int", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_new", - "return_type": "void", - "arguments": [ - ["godot_basis *", "r_dest"] - ] - }, - { - "name": "godot_basis_new_with_euler_quat", - "return_type": "void", - "arguments": [ - ["godot_basis *", "r_dest"], - ["const godot_quat *", "p_euler"] - ] - }, - { - "name": "godot_basis_get_elements", - "return_type": "void", - "arguments": [ - ["const godot_basis *", "p_self"], - ["godot_vector3 *", "p_elements"] - ] - }, - { - "name": "godot_basis_get_axis", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_int", "p_axis"] - ] - }, - { - "name": "godot_basis_set_axis", - "return_type": "void", - "arguments": [ - ["godot_basis *", "p_self"], - ["const godot_int", "p_axis"], - ["const godot_vector3 *", "p_value"] - ] - }, - { - "name": "godot_basis_get_row", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_int", "p_row"] - ] - }, - { - "name": "godot_basis_set_row", - "return_type": "void", - "arguments": [ - ["godot_basis *", "p_self"], - ["const godot_int", "p_row"], - ["const godot_vector3 *", "p_value"] - ] - }, - { - "name": "godot_basis_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_basis *", "p_b"] - ] - }, - { - "name": "godot_basis_operator_add", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_basis *", "p_b"] - ] - }, - { - "name": "godot_basis_operator_subtract", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_basis *", "p_b"] - ] - }, - { - "name": "godot_basis_operator_multiply_vector", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_basis *", "p_b"] - ] - }, - { - "name": "godot_basis_operator_multiply_scalar", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_basis_slerp", - "return_type": "godot_basis", - "arguments": [ - ["const godot_basis *", "p_self"], - ["const godot_basis *", "p_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_basis_get_quat", - "return_type": "godot_quat", - "arguments": [ - ["const godot_basis *", "p_self"] - ] - }, - { - "name": "godot_basis_set_quat", - "return_type": "void", - "arguments": [ - ["godot_basis *", "p_self"], - ["const godot_quat *", "p_quat"] - ] - }, - { - "name": "godot_basis_set_axis_angle_scale", - "return_type": "void", - "arguments": [ - ["godot_basis *", "p_self"], - ["const godot_vector3 *", "p_axis"], - ["godot_real", "p_phi"], - ["const godot_vector3 *", "p_scale"] - ] - }, - { - "name": "godot_basis_set_euler_scale", - "return_type": "void", - "arguments": [ - ["godot_basis *", "p_self"], - ["const godot_vector3 *", "p_euler"], - ["const godot_vector3 *", "p_scale"] - ] - }, - { - "name": "godot_basis_set_quat_scale", - "return_type": "void", - "arguments": [ - ["godot_basis *", "p_self"], - ["const godot_quat *", "p_quat"], - ["const godot_vector3 *", "p_scale"] - ] - }, - { - "name": "godot_callable_new_with_object", - "return_type": "void", - "arguments": [ - ["godot_callable *", "r_dest"], - ["const godot_object *", "p_object"], - ["const godot_string_name *", "p_method"] - ] - }, - { - "name": "godot_callable_new_with_object_id", - "return_type": "void", - "arguments": [ - ["godot_callable *", "r_dest"], - ["uint64_t", "p_objectid"], - ["const godot_string_name *", "p_method"] - ] - }, - { - "name": "godot_callable_new_copy", - "return_type": "void", - "arguments": [ - ["godot_callable *", "r_dest"], - ["const godot_callable *", "p_src"] - ] - }, - { - "name": "godot_callable_destroy", - "return_type": "void", - "arguments": [ - ["godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_call", - "return_type": "godot_int", - "arguments": [ - ["const godot_callable *", "p_self"], - ["const godot_variant **", "p_arguments"], - ["godot_int", "p_argcount"], - ["godot_variant *", "r_return_value"] - ] - }, - { - "name": "godot_callable_call_deferred", - "return_type": "void", - "arguments": [ - ["const godot_callable *", "p_self"], - ["const godot_variant **", "p_arguments"], - ["godot_int", "p_argcount"] - ] - }, - { - "name": "godot_callable_is_null", - "return_type": "godot_bool", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_is_custom", - "return_type": "godot_bool", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_is_standard", - "return_type": "godot_bool", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_get_object", - "return_type": "godot_object *", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_get_object_id", - "return_type": "uint64_t", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_get_method", - "return_type": "godot_string_name", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_hash", - "return_type": "uint32_t", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_callable *", "p_self"] - ] - }, - { - "name": "godot_callable_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_callable *", "p_self"], - ["const godot_callable *", "p_other"] - ] - }, - { - "name": "godot_callable_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_callable *", "p_self"], - ["const godot_callable *", "p_other"] - ] - }, - { - "name": "godot_signal_new_with_object", - "return_type": "void", - "arguments": [ - ["godot_signal *", "r_dest"], - ["const godot_object *", "p_object"], - ["const godot_string_name *", "p_method"] - ] - }, - { - "name": "godot_signal_new_with_object_id", - "return_type": "void", - "arguments": [ - ["godot_signal *", "r_dest"], - ["uint64_t", "p_objectid"], - ["const godot_string_name *", "p_method"] - ] - }, - { - "name": "godot_signal_new_copy", - "return_type": "void", - "arguments": [ - ["godot_signal *", "r_dest"], - ["const godot_signal *", "p_src"] - ] - }, - { - "name": "godot_signal_destroy", - "return_type": "void", - "arguments": [ - ["godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_emit", - "return_type": "godot_int", - "arguments": [ - ["const godot_signal *", "p_self"], - ["const godot_variant **", "p_arguments"], - ["godot_int", "p_argcount"] - ] - }, - { - "name": "godot_signal_connect", - "return_type": "godot_int", - "arguments": [ - ["godot_signal *", "p_self"], - ["const godot_callable *", "p_callable"], - ["const godot_array *", "p_binds"], - ["uint32_t", "p_flags"] - ] - }, - { - "name": "godot_signal_disconnect", - "return_type": "void", - "arguments": [ - ["godot_signal *", "p_self"], - ["const godot_callable *", "p_callable"] - ] - }, - { - "name": "godot_signal_is_null", - "return_type": "godot_bool", - "arguments": [ - ["const godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_is_connected", - "return_type": "godot_bool", - "arguments": [ - ["const godot_signal *", "p_self"], - ["const godot_callable *", "p_callable"] - ] - }, - { - "name": "godot_signal_get_connections", - "return_type": "godot_array", - "arguments": [ - ["const godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_get_object", - "return_type": "godot_object *", - "arguments": [ - ["const godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_get_object_id", - "return_type": "uint64_t", - "arguments": [ - ["const godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_get_name", - "return_type": "godot_string_name", - "arguments": [ - ["const godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_signal *", "p_self"] - ] - }, - { - "name": "godot_signal_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_signal *", "p_self"], - ["const godot_signal *", "p_other"] - ] - }, - { - "name": "godot_signal_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_signal *", "p_self"], - ["const godot_signal *", "p_other"] - ] - }, - { - "name": "godot_color_new_rgba", - "return_type": "void", - "arguments": [ - ["godot_color *", "r_dest"], - ["const godot_real", "p_r"], - ["const godot_real", "p_g"], - ["const godot_real", "p_b"], - ["const godot_real", "p_a"] - ] - }, - { - "name": "godot_color_new_rgb", - "return_type": "void", - "arguments": [ - ["godot_color *", "r_dest"], - ["const godot_real", "p_r"], - ["const godot_real", "p_g"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_color_get_r", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_set_r", - "return_type": "void", - "arguments": [ - ["godot_color *", "p_self"], - ["const godot_real", "r"] - ] - }, - { - "name": "godot_color_get_g", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_set_g", - "return_type": "void", - "arguments": [ - ["godot_color *", "p_self"], - ["const godot_real", "g"] - ] - }, - { - "name": "godot_color_get_b", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_set_b", - "return_type": "void", - "arguments": [ - ["godot_color *", "p_self"], - ["const godot_real", "b"] - ] - }, - { - "name": "godot_color_get_a", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_set_a", - "return_type": "void", - "arguments": [ - ["godot_color *", "p_self"], - ["const godot_real", "a"] - ] - }, - { - "name": "godot_color_get_h", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_get_s", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_get_v", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_to_rgba32", - "return_type": "godot_int", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_to_argb32", - "return_type": "godot_int", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_inverted", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_lerp", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_color *", "p_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_color_blend", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_color *", "p_over"] - ] - }, - { - "name": "godot_color_to_html", - "return_type": "godot_string", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_bool", "p_with_alpha"] - ] - }, - { - "name": "godot_color_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_color *", "p_b"] - ] - }, - { - "name": "godot_color_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_color *", "p_b"] - ] - }, - { - "name": "godot_color_to_abgr32", - "return_type": "godot_int", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_to_abgr64", - "return_type": "godot_int", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_to_argb64", - "return_type": "godot_int", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_to_rgba64", - "return_type": "godot_int", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { - "name": "godot_color_darkened", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_real", "p_amount"] - ] - }, - { - "name": "godot_color_from_hsv", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_real", "p_h"], - ["const godot_real", "p_s"], - ["const godot_real", "p_v"], - ["const godot_real", "p_a"] - ] - }, - { - "name": "godot_color_lightened", - "return_type": "godot_color", - "arguments": [ - ["const godot_color *", "p_self"], - ["const godot_real", "p_amount"] - ] - }, - { - "name": "godot_dictionary_new", - "return_type": "void", - "arguments": [ - ["godot_dictionary *", "r_dest"] - ] - }, - { - "name": "godot_dictionary_new_copy", - "return_type": "void", - "arguments": [ - ["godot_dictionary *", "r_dest"], - ["const godot_dictionary *", "p_src"] - ] - }, - { - "name": "godot_dictionary_destroy", - "return_type": "void", - "arguments": [ - ["godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_clear", - "return_type": "void", - "arguments": [ - ["godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_has", - "return_type": "godot_bool", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_dictionary_has_all", - "return_type": "godot_bool", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_array *", "p_keys"] - ] - }, - { - "name": "godot_dictionary_erase", - "return_type": "void", - "arguments": [ - ["godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_dictionary_hash", - "return_type": "godot_int", - "arguments": [ - ["const godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_keys", - "return_type": "godot_array", - "arguments": [ - ["const godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_values", - "return_type": "godot_array", - "arguments": [ - ["const godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_get", - "return_type": "godot_variant", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_dictionary_set", - "return_type": "void", - "arguments": [ - ["godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"], - ["const godot_variant *", "p_value"] - ] - }, - { - "name": "godot_dictionary_operator_index", - "return_type": "godot_variant *", - "arguments": [ - ["godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_dictionary_operator_index_const", - "return_type": "const godot_variant *", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_dictionary_next", - "return_type": "godot_variant *", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_dictionary_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_dictionary *", "p_b"] - ] - }, - { - "name": "godot_dictionary_to_json", - "return_type": "godot_string", - "arguments": [ - ["const godot_dictionary *", "p_self"] - ] - }, - { - "name": "godot_dictionary_duplicate", - "return_type": "godot_dictionary", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_bool", "p_deep"] - ] - }, - { - "name": "godot_dictionary_get_with_default", - "return_type": "godot_variant", - "arguments": [ - ["const godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"], - ["const godot_variant *", "p_default"] - ] - }, - { - "name": "godot_dictionary_erase_with_return", - "return_type": "bool", - "arguments": [ - ["godot_dictionary *", "p_self"], - ["const godot_variant *", "p_key"] - ] - }, - { - "name": "godot_node_path_new", - "return_type": "void", - "arguments": [ - ["godot_node_path *", "r_dest"], - ["const godot_string *", "p_from"] - ] - }, - { - "name": "godot_node_path_new_copy", - "return_type": "void", - "arguments": [ - ["godot_node_path *", "r_dest"], - ["const godot_node_path *", "p_src"] - ] - }, - { - "name": "godot_node_path_destroy", - "return_type": "void", - "arguments": [ - ["godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_is_absolute", - "return_type": "godot_bool", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_get_name_count", - "return_type": "godot_int", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_get_name", - "return_type": "godot_string", - "arguments": [ - ["const godot_node_path *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_node_path_get_subname_count", - "return_type": "godot_int", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_get_subname", - "return_type": "godot_string", - "arguments": [ - ["const godot_node_path *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_node_path_get_concatenated_subnames", - "return_type": "godot_string", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_node_path_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_node_path *", "p_self"], - ["const godot_node_path *", "p_b"] - ] - }, - { - "name": "godot_node_path_get_as_property_path", - "return_type": "godot_node_path", - "arguments": [ - ["const godot_node_path *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_byte_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "r_dest"], - ["const godot_packed_byte_array *", "p_src"] - ] - }, - { - "name": "godot_packed_byte_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_byte_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const uint8_t", "p_data"] - ] - }, - { - "name": "godot_packed_byte_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const godot_packed_byte_array *", "p_array"] - ] - }, - { - "name": "godot_packed_byte_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const uint8_t", "p_data"] - ] - }, - { - "name": "godot_packed_byte_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const uint8_t", "p_value"] - ] - }, - { - "name": "godot_packed_byte_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const uint8_t", "p_data"] - ] - }, - { - "name": "godot_packed_byte_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_byte_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_byte_array_ptr", - "return_type": "const uint8_t *", - "arguments": [ - ["const godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_ptrw", - "return_type": "uint8_t *", - "arguments": [ - ["godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const uint8_t", "p_data"] - ] - }, - { - "name": "godot_packed_byte_array_get", - "return_type": "uint8_t", - "arguments": [ - ["const godot_packed_byte_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_byte_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_byte_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_byte_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_int32_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "r_dest"], - ["const godot_packed_int32_array *", "p_src"] - ] - }, - { - "name": "godot_packed_int32_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_int32_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const int32_t", "p_data"] - ] - }, - { - "name": "godot_packed_int32_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const godot_packed_int32_array *", "p_array"] - ] - }, - { - "name": "godot_packed_int32_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const int32_t", "p_data"] - ] - }, - { - "name": "godot_packed_int32_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const int32_t", "p_value"] - ] - }, - { - "name": "godot_packed_int32_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const int32_t", "p_data"] - ] - }, - { - "name": "godot_packed_int32_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_int32_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_int32_array_ptr", - "return_type": "const int32_t *", - "arguments": [ - ["const godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_ptrw", - "return_type": "int32_t *", - "arguments": [ - ["godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const int32_t", "p_data"] - ] - }, - { - "name": "godot_packed_int32_array_get", - "return_type": "int32_t", - "arguments": [ - ["const godot_packed_int32_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_int32_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int32_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_int32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_int64_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "r_dest"], - ["const godot_packed_int64_array *", "p_src"] - ] - }, - { - "name": "godot_packed_int64_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_int64_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const int64_t", "p_data"] - ] - }, - { - "name": "godot_packed_int64_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const godot_packed_int64_array *", "p_array"] - ] - }, - { - "name": "godot_packed_int64_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const int64_t", "p_data"] - ] - }, - { - "name": "godot_packed_int64_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const int64_t", "p_value"] - ] - }, - { - "name": "godot_packed_int64_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const int64_t", "p_data"] - ] - }, - { - "name": "godot_packed_int64_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_int64_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_int64_array_ptr", - "return_type": "const int64_t *", - "arguments": [ - ["const godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_ptrw", - "return_type": "int64_t *", - "arguments": [ - ["godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const int64_t", "p_data"] - ] - }, - { - "name": "godot_packed_int64_array_get", - "return_type": "int64_t", - "arguments": [ - ["const godot_packed_int64_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_int64_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_int64_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_int64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_float32_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "r_dest"], - ["const godot_packed_float32_array *", "p_src"] - ] - }, - { - "name": "godot_packed_float32_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_float32_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const float", "p_data"] - ] - }, - { - "name": "godot_packed_float32_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const godot_packed_float32_array *", "p_array"] - ] - }, - { - "name": "godot_packed_float32_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const float", "p_data"] - ] - }, - { - "name": "godot_packed_float32_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const float", "p_value"] - ] - }, - { - "name": "godot_packed_float32_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const float", "p_data"] - ] - }, - { - "name": "godot_packed_float32_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_float32_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_float32_array_ptr", - "return_type": "const float *", - "arguments": [ - ["const godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_ptrw", - "return_type": "float *", - "arguments": [ - ["godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const float", "p_data"] - ] - }, - { - "name": "godot_packed_float32_array_get", - "return_type": "float", - "arguments": [ - ["const godot_packed_float32_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_float32_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float32_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_float32_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_float64_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "r_dest"], - ["const godot_packed_float64_array *", "p_src"] - ] - }, - { - "name": "godot_packed_float64_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_float64_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const double", "p_data"] - ] - }, - { - "name": "godot_packed_float64_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const godot_packed_float64_array *", "p_array"] - ] - }, - { - "name": "godot_packed_float64_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const double", "p_data"] - ] - }, - { - "name": "godot_packed_float64_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const double", "p_value"] - ] - }, - { - "name": "godot_packed_float64_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const double", "p_data"] - ] - }, - { - "name": "godot_packed_float64_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_float64_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_float64_array_ptr", - "return_type": "const double *", - "arguments": [ - ["const godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_ptrw", - "return_type": "double *", - "arguments": [ - ["godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const double", "p_data"] - ] - }, - { - "name": "godot_packed_float64_array_get", - "return_type": "double", - "arguments": [ - ["const godot_packed_float64_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_float64_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_float64_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_float64_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_string_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "r_dest"], - ["const godot_packed_string_array *", "p_src"] - ] - }, - { - "name": "godot_packed_string_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_string_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_string *", "p_data"] - ] - }, - { - "name": "godot_packed_string_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_packed_string_array *", "p_array"] - ] - }, - { - "name": "godot_packed_string_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_string *", "p_data"] - ] - }, - { - "name": "godot_packed_string_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_string *", "p_value"] - ] - }, - { - "name": "godot_packed_string_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_string *", "p_data"] - ] - }, - { - "name": "godot_packed_string_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_string_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_string_array_ptr", - "return_type": "const godot_string *", - "arguments": [ - ["const godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_ptrw", - "return_type": "godot_string *", - "arguments": [ - ["godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_string *", "p_data"] - ] - }, - { - "name": "godot_packed_string_array_get", - "return_type": "godot_string", - "arguments": [ - ["const godot_packed_string_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_string_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_string_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_string_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_vector2_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "r_dest"], - ["const godot_packed_vector2_array *", "p_src"] - ] - }, - { - "name": "godot_packed_vector2_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_vector2_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_vector2 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_packed_vector2_array *", "p_array"] - ] - }, - { - "name": "godot_packed_vector2_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_vector2 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_vector2 *", "p_value"] - ] - }, - { - "name": "godot_packed_vector2_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_vector2 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_vector2_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_vector2_array_ptr", - "return_type": "const godot_vector2 *", - "arguments": [ - ["const godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_ptrw", - "return_type": "godot_vector2 *", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_vector2 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2_array_get", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_packed_vector2_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_vector2_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_vector2i_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "r_dest"], - ["const godot_packed_vector2i_array *", "p_src"] - ] - }, - { - "name": "godot_packed_vector2i_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_vector2i_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_vector2i *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2i_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_packed_vector2i_array *", "p_array"] - ] - }, - { - "name": "godot_packed_vector2i_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_vector2i *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2i_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_vector2i *", "p_value"] - ] - }, - { - "name": "godot_packed_vector2i_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_vector2i *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2i_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_vector2i_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_vector2i_array_ptr", - "return_type": "const godot_vector2i *", - "arguments": [ - ["const godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_ptrw", - "return_type": "godot_vector2i *", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_vector2i *", "p_data"] - ] - }, - { - "name": "godot_packed_vector2i_array_get", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_packed_vector2i_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_vector2i_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector2i_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_vector2i_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_vector3_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "r_dest"], - ["const godot_packed_vector3_array *", "p_src"] - ] - }, - { - "name": "godot_packed_vector3_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_vector3_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_vector3 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector3_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_packed_vector3_array *", "p_array"] - ] - }, - { - "name": "godot_packed_vector3_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_vector3 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector3_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_vector3 *", "p_value"] - ] - }, - { - "name": "godot_packed_vector3_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_vector3 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector3_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_vector3_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_vector3_array_ptr", - "return_type": "const godot_vector3 *", - "arguments": [ - ["const godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_ptrw", - "return_type": "godot_vector3 *", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_vector3 *", "p_data"] - ] - }, - { - "name": "godot_packed_vector3_array_get", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_packed_vector3_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_vector3_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_vector3_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_vector3_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_color_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "r_dest"], - ["const godot_packed_color_array *", "p_src"] - ] - }, - { - "name": "godot_packed_color_array_new_with_array", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "r_dest"], - ["const godot_array *", "p_a"] - ] - }, - { - "name": "godot_packed_color_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_color *", "p_data"] - ] - }, - { - "name": "godot_packed_color_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_packed_color_array *", "p_array"] - ] - }, - { - "name": "godot_packed_color_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_color *", "p_data"] - ] - }, - { - "name": "godot_packed_color_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_color *", "p_value"] - ] - }, - { - "name": "godot_packed_color_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_color *", "p_data"] - ] - }, - { - "name": "godot_packed_color_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_color_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_color_array_ptr", - "return_type": "const godot_color *", - "arguments": [ - ["const godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_ptrw", - "return_type": "godot_color *", - "arguments": [ - ["godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_color *", "p_data"] - ] - }, - { - "name": "godot_packed_color_array_get", - "return_type": "godot_color", - "arguments": [ - ["const godot_packed_color_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_color_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_packed_color_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_color_array *", "p_self"] - ] - }, - { - "name": "godot_plane_new_with_reals", - "return_type": "void", - "arguments": [ - ["godot_plane *", "r_dest"], - ["const godot_real", "p_a"], - ["const godot_real", "p_b"], - ["const godot_real", "p_c"], - ["const godot_real", "p_d"] - ] - }, - { - "name": "godot_plane_new_with_vectors", - "return_type": "void", - "arguments": [ - ["godot_plane *", "r_dest"], - ["const godot_vector3 *", "p_v1"], - ["const godot_vector3 *", "p_v2"], - ["const godot_vector3 *", "p_v3"] - ] - }, - { - "name": "godot_plane_new_with_normal", - "return_type": "void", - "arguments": [ - ["godot_plane *", "r_dest"], - ["const godot_vector3 *", "p_normal"], - ["const godot_real", "p_d"] - ] - }, - { - "name": "godot_plane_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_plane *", "p_self"] - ] - }, - { - "name": "godot_plane_normalized", - "return_type": "godot_plane", - "arguments": [ - ["const godot_plane *", "p_self"] - ] - }, - { - "name": "godot_plane_center", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_plane *", "p_self"] - ] - }, - { - "name": "godot_plane_is_point_over", - "return_type": "godot_bool", - "arguments": [ - ["const godot_plane *", "p_self"], - ["const godot_vector3 *", "p_point"] - ] - }, - { - "name": "godot_plane_distance_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_plane *", "p_self"], - ["const godot_vector3 *", "p_point"] - ] - }, - { - "name": "godot_plane_has_point", - "return_type": "godot_bool", - "arguments": [ - ["const godot_plane *", "p_self"], - ["const godot_vector3 *", "p_point"], - ["const godot_real", "p_epsilon"] - ] - }, - { - "name": "godot_plane_project", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_plane *", "p_self"], - ["const godot_vector3 *", "p_point"] - ] - }, - { - "name": "godot_plane_intersect_3", - "return_type": "godot_bool", - "arguments": [ - ["const godot_plane *", "p_self"], - ["godot_vector3 *", "r_dest"], - ["const godot_plane *", "p_b"], - ["const godot_plane *", "p_c"] - ] - }, - { - "name": "godot_plane_intersects_ray", - "return_type": "godot_bool", - "arguments": [ - ["const godot_plane *", "p_self"], - ["godot_vector3 *", "r_dest"], - ["const godot_vector3 *", "p_from"], - ["const godot_vector3 *", "p_dir"] - ] - }, - { - "name": "godot_plane_intersects_segment", - "return_type": "godot_bool", - "arguments": [ - ["const godot_plane *", "p_self"], - ["godot_vector3 *", "r_dest"], - ["const godot_vector3 *", "p_begin"], - ["const godot_vector3 *", "p_end"] - ] - }, - { - "name": "godot_plane_operator_neg", - "return_type": "godot_plane", - "arguments": [ - ["const godot_plane *", "p_self"] - ] - }, - { - "name": "godot_plane_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_plane *", "p_self"], - ["const godot_plane *", "p_b"] - ] - }, - { - "name": "godot_plane_set_normal", - "return_type": "void", - "arguments": [ - ["godot_plane *", "p_self"], - ["const godot_vector3 *", "p_normal"] - ] - }, - { - "name": "godot_plane_get_normal", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_plane *", "p_self"] - ] - }, - { - "name": "godot_plane_get_d", - "return_type": "godot_real", - "arguments": [ - ["const godot_plane *", "p_self"] - ] - }, - { - "name": "godot_plane_set_d", - "return_type": "void", - "arguments": [ - ["godot_plane *", "p_self"], - ["const godot_real", "p_d"] - ] - }, - { - "name": "godot_quat_new", - "return_type": "void", - "arguments": [ - ["godot_quat *", "r_dest"], - ["const godot_real", "p_x"], - ["const godot_real", "p_y"], - ["const godot_real", "p_z"], - ["const godot_real", "p_w"] - ] - }, - { - "name": "godot_quat_new_with_axis_angle", - "return_type": "void", - "arguments": [ - ["godot_quat *", "r_dest"], - ["const godot_vector3 *", "p_axis"], - ["const godot_real", "p_angle"] - ] - }, - { - "name": "godot_quat_new_with_basis", - "return_type": "void", - "arguments": [ - ["godot_quat *", "r_dest"], - ["const godot_basis *", "p_basis"] - ] - }, - { - "name": "godot_quat_new_with_euler", - "return_type": "void", - "arguments": [ - ["godot_quat *", "r_dest"], - ["const godot_vector3 *", "p_euler"] - ] - }, - { - "name": "godot_quat_get_x", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_set_x", - "return_type": "void", - "arguments": [ - ["godot_quat *", "p_self"], - ["const godot_real", "val"] - ] - }, - { - "name": "godot_quat_get_y", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_set_y", - "return_type": "void", - "arguments": [ - ["godot_quat *", "p_self"], - ["const godot_real", "val"] - ] - }, - { - "name": "godot_quat_get_z", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_set_z", - "return_type": "void", - "arguments": [ - ["godot_quat *", "p_self"], - ["const godot_real", "val"] - ] - }, - { - "name": "godot_quat_get_w", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_set_w", - "return_type": "void", - "arguments": [ - ["godot_quat *", "p_self"], - ["const godot_real", "val"] - ] - }, - { - "name": "godot_quat_set_axis_angle", - "return_type": "void", - "arguments": [ - ["godot_quat *", "p_self"], - ["const godot_vector3 *", "p_axis"], - ["const godot_real", "p_angle"] - ] - }, - { - "name": "godot_quat_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_length", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_length_squared", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_normalized", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_is_normalized", - "return_type": "godot_bool", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_inverse", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_quat_dot", - "return_type": "godot_real", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"] - ] - }, - { - "name": "godot_quat_xform", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_quat_slerp", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_quat_slerpni", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_quat_cubic_slerp", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"], - ["const godot_quat *", "p_pre_a"], - ["const godot_quat *", "p_post_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_quat_operator_multiply", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_quat_operator_add", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"] - ] - }, - { - "name": "godot_quat_operator_subtract", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"] - ] - }, - { - "name": "godot_quat_operator_divide", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_quat_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_quat *", "p_self"], - ["const godot_quat *", "p_b"] - ] - }, - { - "name": "godot_quat_operator_neg", - "return_type": "godot_quat", - "arguments": [ - ["const godot_quat *", "p_self"] - ] - }, - { - "name": "godot_rect2_new_with_position_and_size", - "return_type": "void", - "arguments": [ - ["godot_rect2 *", "r_dest"], - ["const godot_vector2 *", "p_pos"], - ["const godot_vector2 *", "p_size"] - ] - }, - { - "name": "godot_rect2_new", - "return_type": "void", - "arguments": [ - ["godot_rect2 *", "r_dest"], - ["const godot_real", "p_x"], - ["const godot_real", "p_y"], - ["const godot_real", "p_width"], - ["const godot_real", "p_height"] - ] - }, - { - "name": "godot_rect2_as_rect2i", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_get_area", - "return_type": "godot_real", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_grow_individual", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_real", "p_left"], - ["const godot_real", "p_top"], - ["const godot_real", "p_right"], - ["const godot_real", "p_bottom"] - ] - }, - { - "name": "godot_rect2_grow_side", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_int", "p_side"], - ["const godot_real", "p_by"] - ] - }, - { - "name": "godot_rect2_abs", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_intersects", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_rect2 *", "p_b"] - ] - }, - { - "name": "godot_rect2_encloses", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_rect2 *", "p_b"] - ] - }, - { - "name": "godot_rect2_has_no_area", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_intersection", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_rect2 *", "p_b"] - ] - }, - { - "name": "godot_rect2_merge", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_rect2 *", "p_b"] - ] - }, - { - "name": "godot_rect2_has_point", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_vector2 *", "p_point"] - ] - }, - { - "name": "godot_rect2_grow", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_real", "p_by"] - ] - }, - { - "name": "godot_rect2_expand", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_vector2 *", "p_to"] - ] - }, - { - "name": "godot_rect2_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2 *", "p_self"], - ["const godot_rect2 *", "p_b"] - ] - }, - { - "name": "godot_rect2_get_position", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_get_size", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_rect2 *", "p_self"] - ] - }, - { - "name": "godot_rect2_set_position", - "return_type": "void", - "arguments": [ - ["godot_rect2 *", "p_self"], - ["const godot_vector2 *", "p_pos"] - ] - }, - { - "name": "godot_rect2_set_size", - "return_type": "void", - "arguments": [ - ["godot_rect2 *", "p_self"], - ["const godot_vector2 *", "p_size"] - ] - }, - { - "name": "godot_rect2i_new_with_position_and_size", - "return_type": "void", - "arguments": [ - ["godot_rect2i *", "r_dest"], - ["const godot_vector2i *", "p_pos"], - ["const godot_vector2i *", "p_size"] - ] - }, - { - "name": "godot_rect2i_new", - "return_type": "void", - "arguments": [ - ["godot_rect2i *", "r_dest"], - ["const godot_int", "p_x"], - ["const godot_int", "p_y"], - ["const godot_int", "p_width"], - ["const godot_int", "p_height"] - ] - }, - { - "name": "godot_rect2i_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_as_rect2", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_get_area", - "return_type": "godot_int", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_intersects", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_rect2i *", "p_b"] - ] - }, - { - "name": "godot_rect2i_encloses", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_rect2i *", "p_b"] - ] - }, - { - "name": "godot_rect2i_has_no_area", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_intersection", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_rect2i *", "p_b"] - ] - }, - { - "name": "godot_rect2i_merge", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_rect2i *", "p_b"] - ] - }, - { - "name": "godot_rect2i_has_point", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_vector2i *", "p_point"] - ] - }, - { - "name": "godot_rect2i_grow", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_int", "p_by"] - ] - }, - { - "name": "godot_rect2i_grow_individual", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_int", "p_left"], - ["const godot_int", "p_top"], - ["const godot_int", "p_right"], - ["const godot_int", "p_bottom"] - ] - }, - { - "name": "godot_rect2i_grow_side", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_int", "p_side"], - ["const godot_int", "p_by"] - ] - }, - { - "name": "godot_rect2i_abs", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_expand", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_vector2i *", "p_to"] - ] - }, - { - "name": "godot_rect2i_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rect2i *", "p_self"], - ["const godot_rect2i *", "p_b"] - ] - }, - { - "name": "godot_rect2i_get_position", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_get_size", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_rect2i *", "p_self"] - ] - }, - { - "name": "godot_rect2i_set_position", - "return_type": "void", - "arguments": [ - ["godot_rect2i *", "p_self"], - ["const godot_vector2i *", "p_pos"] - ] - }, - { - "name": "godot_rect2i_set_size", - "return_type": "void", - "arguments": [ - ["godot_rect2i *", "p_self"], - ["const godot_vector2i *", "p_size"] - ] - }, - { - "name": "godot_rid_new", - "return_type": "void", - "arguments": [ - ["godot_rid *", "r_dest"] - ] - }, - { - "name": "godot_rid_get_id", - "return_type": "godot_int", - "arguments": [ - ["const godot_rid *", "p_self"] - ] - }, - { - "name": "godot_rid_new_with_resource", - "return_type": "void", - "arguments": [ - ["godot_rid *", "r_dest"], - ["const godot_object *", "p_from"] - ] - }, - { - "name": "godot_rid_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rid *", "p_self"], - ["const godot_rid *", "p_b"] - ] - }, - { - "name": "godot_rid_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_rid *", "p_self"], - ["const godot_rid *", "p_b"] - ] - }, - { - "name": "godot_char_string_length", - "return_type": "godot_int", - "arguments": [ - ["const godot_char_string *", "p_cs"] - ] - }, - { - "name": "godot_char_string_get_data", - "return_type": "const char *", - "arguments": [ - ["const godot_char_string *", "p_cs"] - ] - }, - { - "name": "godot_char_string_destroy", - "return_type": "void", - "arguments": [ - ["godot_char_string *", "p_cs"] - ] - }, - { - "name": "godot_char16_string_length", - "return_type": "godot_int", - "arguments": [ - ["const godot_char16_string *", "p_cs"] - ] - }, - { - "name": "godot_char16_string_get_data", - "return_type": "const char16_t *", - "arguments": [ - ["const godot_char16_string *", "p_cs"] - ] - }, - { - "name": "godot_char16_string_destroy", - "return_type": "void", - "arguments": [ - ["godot_char16_string *", "p_cs"] - ] - }, - { - "name": "godot_string_new", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"] - ] - }, - { - "name": "godot_string_new_copy", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const godot_string *", "p_src"] - ] - }, - { - "name": "godot_string_new_with_latin1_chars", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char *", "p_contents"] - ] - }, - { - "name": "godot_string_new_with_utf8_chars", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char *", "p_contents"] - ] - }, - { - "name": "godot_string_new_with_utf16_chars", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char16_t *", "p_contents"] - ] - }, - { - "name": "godot_string_new_with_utf32_chars", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char32_t *", "p_contents"] - ] - }, - { - "name": "godot_string_new_with_wide_chars", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const wchar_t *", "p_contents"] - ] - }, - { - "name": "godot_string_new_with_latin1_chars_and_len", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char *", "p_contents"], - ["const int", "p_size"] - ] - }, - { - "name": "godot_string_new_with_utf8_chars_and_len", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char *", "p_contents"], - ["const int", "p_size"] - ] - }, - { - "name": "godot_string_new_with_utf16_chars_and_len", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char16_t *", "p_contents"], - ["const int", "p_size"] - ] - }, - { - "name": "godot_string_new_with_utf32_chars_and_len", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const char32_t *", "p_contents"], - ["const int", "p_size"] - ] - }, - { - "name": "godot_string_new_with_wide_chars_and_len", - "return_type": "void", - "arguments": [ - ["godot_string *", "r_dest"], - ["const wchar_t *", "p_contents"], - ["const int", "p_size"] - ] - }, - { - "name": "godot_string_operator_index", - "return_type": "const godot_char_type *", - "arguments": [ - ["godot_string *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_string_operator_index_const", - "return_type": "godot_char_type", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_string_get_data", - "return_type": "const godot_char_type *", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_b"] - ] - }, - { - "name": "godot_string_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_b"] - ] - }, - { - "name": "godot_string_operator_plus", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_b"] - ] - }, - { - "name": "godot_string_count", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"], - ["godot_int", "p_from"], - ["godot_int", "p_to"] - ] - }, - { - "name": "godot_string_countn", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"], - ["godot_int", "p_from"], - ["godot_int", "p_to"] - ] - }, - { - "name": "godot_string_dedent", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_length", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_casecmp_to", - "return_type": "signed char", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_str"] - ] - }, - { - "name": "godot_string_nocasecmp_to", - "return_type": "signed char", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_str"] - ] - }, - { - "name": "godot_string_naturalnocasecmp_to", - "return_type": "signed char", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_str"] - ] - }, - { - "name": "godot_string_begins_with", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_string"] - ] - }, - { - "name": "godot_string_begins_with_char_array", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const char *", "p_char_array"] - ] - }, - { - "name": "godot_string_bigrams", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_chr", - "return_type": "godot_string", - "arguments": [ - ["godot_char_type", "p_character"] - ] - }, - { - "name": "godot_string_ends_with", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_string"] - ] - }, - { - "name": "godot_string_ends_with_char_array", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const char *", "p_char_array"] - ] - }, - { - "name": "godot_string_find", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"] - ] - }, - { - "name": "godot_string_find_from", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"], - ["godot_int", "p_from"] - ] - }, - { - "name": "godot_string_findmk", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_keys"] - ] - }, - { - "name": "godot_string_findmk_from", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_keys"], - ["godot_int", "p_from"] - ] - }, - { - "name": "godot_string_findmk_from_in_place", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_keys"], - ["godot_int", "p_from"], - ["godot_int *", "r_key"] - ] - }, - { - "name": "godot_string_findn", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"] - ] - }, - { - "name": "godot_string_findn_from", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"], - ["godot_int", "p_from"] - ] - }, - { - "name": "godot_string_format", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_variant *", "p_values"] - ] - }, - { - "name": "godot_string_format_with_custom_placeholder", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_variant *", "p_values"], - ["const char *", "p_placeholder"] - ] - }, - { - "name": "godot_string_hex_encode_buffer", - "return_type": "godot_string", - "arguments": [ - ["const uint8_t *", "p_buffer"], - ["godot_int", "p_len"] - ] - }, - { - "name": "godot_string_insert", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_at_pos"], - ["const godot_string *", "p_string"] - ] - }, - { - "name": "godot_string_is_numeric", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_subsequence_of", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_string"] - ] - }, - { - "name": "godot_string_is_subsequence_ofi", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_string"] - ] - }, - { - "name": "godot_string_lpad", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_min_length"] - ] - }, - { - "name": "godot_string_lpad_with_custom_character", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_min_length"], - ["const godot_string *", "p_character"] - ] - }, - { - "name": "godot_string_match", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_wildcard"] - ] - }, - { - "name": "godot_string_matchn", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_wildcard"] - ] - }, - { - "name": "godot_string_md5", - "return_type": "godot_string", - "arguments": [ - ["const uint8_t *", "p_md5"] - ] - }, - { - "name": "godot_string_num", - "return_type": "godot_string", - "arguments": [ - ["double", "p_num"] - ] - }, - { - "name": "godot_string_num_int64", - "return_type": "godot_string", - "arguments": [ - ["int64_t", "p_num"], - ["godot_int", "p_base"] - ] - }, - { - "name": "godot_string_num_int64_capitalized", - "return_type": "godot_string", - "arguments": [ - ["int64_t", "p_num"], - ["godot_int", "p_base"], - ["godot_bool", "p_capitalize_hex"] - ] - }, - { - "name": "godot_string_num_real", - "return_type": "godot_string", - "arguments": [ - ["double", "p_num"] - ] - }, - { - "name": "godot_string_num_scientific", - "return_type": "godot_string", - "arguments": [ - ["double", "p_num"] - ] - }, - { - "name": "godot_string_num_with_decimals", - "return_type": "godot_string", - "arguments": [ - ["double", "p_num"], - ["godot_int", "p_decimals"] - ] - }, - { - "name": "godot_string_pad_decimals", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_digits"] - ] - }, - { - "name": "godot_string_pad_zeros", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_digits"] - ] - }, - { - "name": "godot_string_replace_first", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_key"], - ["const godot_string *", "p_with"] - ] - }, - { - "name": "godot_string_replace", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_key"], - ["const godot_string *", "p_with"] - ] - }, - { - "name": "godot_string_replacen", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_key"], - ["const godot_string *", "p_with"] - ] - }, - { - "name": "godot_string_rfind", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"] - ] - }, - { - "name": "godot_string_rfindn", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"] - ] - }, - { - "name": "godot_string_rfind_from", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"], - ["godot_int", "p_from"] - ] - }, - { - "name": "godot_string_rfindn_from", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_what"], - ["godot_int", "p_from"] - ] - }, - { - "name": "godot_string_rpad", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_min_length"] - ] - }, - { - "name": "godot_string_rpad_with_custom_character", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_min_length"], - ["const godot_string *", "p_character"] - ] - }, - { - "name": "godot_string_similarity", - "return_type": "godot_real", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_string"] - ] - }, - { - "name": "godot_string_sprintf", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_array *", "p_values"], - ["godot_bool *", "p_error"] - ] - }, - { - "name": "godot_string_substr", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_from"], - ["godot_int", "p_chars"] - ] - }, - { - "name": "godot_string_to_int", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_to_float", - "return_type": "double", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_camelcase_to_underscore", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_camelcase_to_underscore_lowercased", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_capitalize", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_char_to_float", - "return_type": "double", - "arguments": [ - ["const char *", "p_what"] - ] - }, - { - "name": "godot_string_wchar_to_float", - "return_type": "double", - "arguments": [ - ["const wchar_t *", "p_str"], - ["const wchar_t **", "r_end"] - ] - }, - { - "name": "godot_string_char_to_int", - "return_type": "godot_int", - "arguments": [ - ["const char *", "p_what"] - ] - }, - { - "name": "godot_string_wchar_to_int", - "return_type": "godot_int", - "arguments": [ - ["const wchar_t *", "p_str"] - ] - }, - { - "name": "godot_string_char_to_int_with_len", - "return_type": "godot_int", - "arguments": [ - ["const char *", "p_what"], - ["godot_int", "p_len"] - ] - }, - { - "name": "godot_string_wchar_to_int_with_len", - "return_type": "godot_int", - "arguments": [ - ["const wchar_t *", "p_str"], - ["int", "p_len"] - ] - }, - { - "name": "godot_string_hex_to_int", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_hex_to_int_with_prefix", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_get_slice_count", - "return_type": "godot_int", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_get_slice", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"], - ["godot_int", "p_slice"] - ] - }, - { - "name": "godot_string_get_slicec", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_char_type", "p_splitter"], - ["godot_int", "p_slice"] - ] - }, - { - "name": "godot_string_split", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_split_allow_empty", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_split_with_maxsplit", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"], - ["const godot_bool", "p_allow_empty"], - ["const godot_int", "p_maxsplit"] - ] - }, - { - "name": "godot_string_rsplit", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_rsplit_allow_empty", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_rsplit_with_maxsplit", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"], - ["const godot_bool", "p_allow_empty"], - ["const godot_int", "p_maxsplit"] - ] - }, - { - "name": "godot_string_split_floats", - "return_type": "godot_packed_float32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_split_floats_allow_empty", - "return_type": "godot_packed_float32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_split_floats_mk", - "return_type": "godot_packed_float32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_splitters"] - ] - }, - { - "name": "godot_string_split_floats_mk_allow_empty", - "return_type": "godot_packed_float32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_splitters"] - ] - }, - { - "name": "godot_string_split_ints", - "return_type": "godot_packed_int32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_split_ints_allow_empty", - "return_type": "godot_packed_int32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_splitter"] - ] - }, - { - "name": "godot_string_split_ints_mk", - "return_type": "godot_packed_int32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_splitters"] - ] - }, - { - "name": "godot_string_split_ints_mk_allow_empty", - "return_type": "godot_packed_int32_array", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_splitters"] - ] - }, - { - "name": "godot_string_split_spaces", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_lstrip", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_chars"] - ] - }, - { - "name": "godot_string_rstrip", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_chars"] - ] - }, - { - "name": "godot_string_trim_prefix", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_prefix"] - ] - }, - { - "name": "godot_string_trim_suffix", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_suffix"] - ] - }, - { - "name": "godot_string_char_lowercase", - "return_type": "godot_char_type", - "arguments": [ - ["godot_char_type", "p_char"] - ] - }, - { - "name": "godot_string_char_uppercase", - "return_type": "godot_char_type", - "arguments": [ - ["godot_char_type", "p_char"] - ] - }, - { - "name": "godot_string_to_lower", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_to_upper", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_get_basename", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_get_extension", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_left", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_pos"] - ] - }, - { - "name": "godot_string_ord_at", - "return_type": "godot_char_type", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_idx"] - ] - }, - { - "name": "godot_string_plus_file", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_file"] - ] - }, - { - "name": "godot_string_right", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_pos"] - ] - }, - { - "name": "godot_string_repeat", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_int", "p_count"] - ] - }, - { - "name": "godot_string_strip_edges", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_bool", "p_left"], - ["godot_bool", "p_right"] - ] - }, - { - "name": "godot_string_strip_escapes", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_erase", - "return_type": "void", - "arguments": [ - ["godot_string *", "p_self"], - ["godot_int", "p_pos"], - ["godot_int", "p_chars"] - ] - }, - { - "name": "godot_string_ascii", - "return_type": "godot_char_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_latin1", - "return_type": "godot_char_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_utf8", - "return_type": "godot_char_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_parse_utf8", - "return_type": "godot_bool", - "arguments": [ - ["godot_string *", "p_self"], - ["const char *", "p_utf8"] - ] - }, - { - "name": "godot_string_parse_utf8_with_len", - "return_type": "godot_bool", - "arguments": [ - ["godot_string *", "p_self"], - ["const char *", "p_utf8"], - ["godot_int", "p_len"] - ] - }, - { - "name": "godot_string_utf16", - "return_type": "godot_char16_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_parse_utf16", - "return_type": "godot_bool", - "arguments": [ - ["godot_string *", "p_self"], - ["const char16_t *", "p_utf16"] - ] - }, - { - "name": "godot_string_parse_utf16_with_len", - "return_type": "godot_bool", - "arguments": [ - ["godot_string *", "p_self"], - ["const char16_t *", "p_utf16"], - ["godot_int", "p_len"] - ] - }, - { - "name": "godot_string_hash", - "return_type": "uint32_t", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_hash64", - "return_type": "uint64_t", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_hash_chars", - "return_type": "uint32_t", - "arguments": [ - ["const char *", "p_cstr"] - ] - }, - { - "name": "godot_string_hash_chars_with_len", - "return_type": "uint32_t", - "arguments": [ - ["const char *", "p_cstr"], - ["godot_int", "p_len"] - ] - }, - { - "name": "godot_string_hash_wide_chars", - "return_type": "uint32_t", - "arguments": [ - ["const wchar_t *", "p_str"] - ] - }, - { - "name": "godot_string_hash_wide_chars_with_len", - "return_type": "uint32_t", - "arguments": [ - ["const wchar_t *", "p_str"], - ["godot_int", "p_len"] - ] - }, - { - "name": "godot_string_md5_buffer", - "return_type": "godot_packed_byte_array", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_md5_text", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_sha1_buffer", - "return_type": "godot_packed_byte_array", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_sha1_text", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_sha256_buffer", - "return_type": "godot_packed_byte_array", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_sha256_text", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_get_base_dir", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_get_file", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_humanize_size", - "return_type": "godot_string", - "arguments": [ - ["uint64_t", "p_size"] - ] - }, - { - "name": "godot_string_is_abs_path", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_rel_path", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_resource_file", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_path_to", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_path"] - ] - }, - { - "name": "godot_string_path_to_file", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_string *", "p_path"] - ] - }, - { - "name": "godot_string_simplify_path", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_c_escape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_c_escape_multiline", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_c_unescape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_http_escape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_http_unescape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_json_escape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_xml_escape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_xml_escape_with_quotes", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_xml_unescape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_percent_decode", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_percent_encode", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_join", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"], - ["const godot_packed_string_array *", "p_parts"] - ] - }, - { - "name": "godot_string_is_valid_filename", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_valid_float", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_valid_hex_number", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"], - ["godot_bool", "p_with_prefix"] - ] - }, - { - "name": "godot_string_is_valid_html_color", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_valid_identifier", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_valid_integer", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_is_valid_ip_address", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_destroy", - "return_type": "void", - "arguments": [ - ["godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_name_new", - "return_type": "void", - "arguments": [ - ["godot_string_name *", "r_dest"], - ["const godot_string *", "p_name"] - ] - }, - { - "name": "godot_string_name_new_data", - "return_type": "void", - "arguments": [ - ["godot_string_name *", "r_dest"], - ["const char *", "p_name"] - ] - }, - { - "name": "godot_string_name_get_name", - "return_type": "godot_string", - "arguments": [ - ["const godot_string_name *", "p_self"] - ] - }, - { - "name": "godot_string_name_get_hash", - "return_type": "uint32_t", - "arguments": [ - ["const godot_string_name *", "p_self"] - ] - }, - { - "name": "godot_string_name_get_data_unique_pointer", - "return_type": "const void *", - "arguments": [ - ["const godot_string_name *", "p_self"] - ] - }, - { - "name": "godot_string_name_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string_name *", "p_self"], - ["const godot_string_name *", "p_other"] - ] - }, - { - "name": "godot_string_name_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_string_name *", "p_self"], - ["const godot_string_name *", "p_other"] - ] - }, - { - "name": "godot_string_name_destroy", - "return_type": "void", - "arguments": [ - ["godot_string_name *", "p_self"] - ] - }, - { - "name": "godot_transform_new_with_axis_origin", - "return_type": "void", - "arguments": [ - ["godot_transform *", "r_dest"], - ["const godot_vector3 *", "p_x_axis"], - ["const godot_vector3 *", "p_y_axis"], - ["const godot_vector3 *", "p_z_axis"], - ["const godot_vector3 *", "p_origin"] - ] - }, - { - "name": "godot_transform_new_with_quat", - "return_type": "void", - "arguments": [ - ["godot_transform *", "r_dest"], - ["const godot_quat *", "p_quat"] - ] - }, - { - "name": "godot_transform_new", - "return_type": "void", - "arguments": [ - ["godot_transform *", "r_dest"], - ["const godot_basis *", "p_basis"], - ["const godot_vector3 *", "p_origin"] - ] - }, - { - "name": "godot_transform_get_basis", - "return_type": "godot_basis", - "arguments": [ - ["const godot_transform *", "p_self"] - ] - }, - { - "name": "godot_transform_set_basis", - "return_type": "void", - "arguments": [ - ["godot_transform *", "p_self"], - ["const godot_basis *", "p_v"] - ] - }, - { - "name": "godot_transform_get_origin", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_transform *", "p_self"] - ] - }, - { - "name": "godot_transform_set_origin", - "return_type": "void", - "arguments": [ - ["godot_transform *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_transform_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_transform *", "p_self"] - ] - }, - { - "name": "godot_transform_inverse", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"] - ] - }, - { - "name": "godot_transform_affine_inverse", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"] - ] - }, - { - "name": "godot_transform_orthonormalized", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"] - ] - }, - { - "name": "godot_transform_rotated", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_vector3 *", "p_axis"], - ["const godot_real", "p_phi"] - ] - }, - { - "name": "godot_transform_scaled", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_vector3 *", "p_scale"] - ] - }, - { - "name": "godot_transform_translated", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_vector3 *", "p_ofs"] - ] - }, - { - "name": "godot_transform_looking_at", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_vector3 *", "p_target"], - ["const godot_vector3 *", "p_up"] - ] - }, - { - "name": "godot_transform_xform_plane", - "return_type": "godot_plane", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_plane *", "p_v"] - ] - }, - { - "name": "godot_transform_xform_inv_plane", - "return_type": "godot_plane", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_plane *", "p_v"] - ] - }, - { - "name": "godot_transform_new_identity", - "return_type": "void", - "arguments": [ - ["godot_transform *", "r_dest"] - ] - }, - { - "name": "godot_transform_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_transform *", "p_b"] - ] - }, - { - "name": "godot_transform_operator_multiply", - "return_type": "godot_transform", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_transform *", "p_b"] - ] - }, - { - "name": "godot_transform_xform_vector3", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_transform_xform_inv_vector3", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_vector3 *", "p_v"] - ] - }, - { - "name": "godot_transform_xform_aabb", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_aabb *", "p_v"] - ] - }, - { - "name": "godot_transform_xform_inv_aabb", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_transform *", "p_self"], - ["const godot_aabb *", "p_v"] - ] - }, - { - "name": "godot_transform2d_new", - "return_type": "void", - "arguments": [ - ["godot_transform2d *", "r_dest"], - ["const godot_real", "p_rot"], - ["const godot_vector2 *", "p_pos"] - ] - }, - { - "name": "godot_transform2d_new_axis_origin", - "return_type": "void", - "arguments": [ - ["godot_transform2d *", "r_dest"], - ["const godot_vector2 *", "p_x_axis"], - ["const godot_vector2 *", "p_y_axis"], - ["const godot_vector2 *", "p_origin"] - ] - }, - { - "name": "godot_transform2d_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_inverse", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_affine_inverse", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_get_rotation", - "return_type": "godot_real", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_get_origin", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_get_scale", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_orthonormalized", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"] - ] - }, - { - "name": "godot_transform2d_rotated", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_real", "p_phi"] - ] - }, - { - "name": "godot_transform2d_scaled", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_vector2 *", "p_scale"] - ] - }, - { - "name": "godot_transform2d_translated", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_vector2 *", "p_offset"] - ] - }, - { - "name": "godot_transform2d_xform_vector2", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_vector2 *", "p_v"] - ] - }, - { - "name": "godot_transform2d_xform_inv_vector2", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_vector2 *", "p_v"] - ] - }, - { - "name": "godot_transform2d_basis_xform_vector2", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_vector2 *", "p_v"] - ] - }, - { - "name": "godot_transform2d_basis_xform_inv_vector2", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_vector2 *", "p_v"] - ] - }, - { - "name": "godot_transform2d_interpolate_with", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_transform2d *", "p_m"], - ["const godot_real", "p_c"] - ] - }, - { - "name": "godot_transform2d_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_transform2d *", "p_b"] - ] - }, - { - "name": "godot_transform2d_operator_multiply", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_transform2d *", "p_b"] - ] - }, - { - "name": "godot_transform2d_new_identity", - "return_type": "void", - "arguments": [ - ["godot_transform2d *", "r_dest"] - ] - }, - { - "name": "godot_transform2d_xform_rect2", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_rect2 *", "p_v"] - ] - }, - { - "name": "godot_transform2d_xform_inv_rect2", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_transform2d *", "p_self"], - ["const godot_rect2 *", "p_v"] - ] - }, - { - "name": "godot_variant_get_type", - "return_type": "godot_variant_type", - "arguments": [ - ["const godot_variant *", "p_v"] - ] - }, - { - "name": "godot_variant_new_copy", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_variant *", "p_src"] - ] - }, - { - "name": "godot_variant_new_nil", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"] - ] - }, - { - "name": "godot_variant_new_bool", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_bool", "p_b"] - ] - }, - { - "name": "godot_variant_new_uint", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const uint64_t", "p_i"] - ] - }, - { - "name": "godot_variant_new_int", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const int64_t", "p_i"] - ] - }, - { - "name": "godot_variant_new_real", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const double", "p_r"] - ] - }, - { - "name": "godot_variant_new_string", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_string *", "p_s"] - ] - }, - { - "name": "godot_variant_new_string_name", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_string_name *", "p_s"] - ] - }, - { - "name": "godot_variant_new_vector2", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_vector2 *", "p_v2"] - ] - }, - { - "name": "godot_variant_new_vector2i", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_vector2i *", "p_v2"] - ] - }, - { - "name": "godot_variant_new_rect2", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_rect2 *", "p_rect2"] - ] - }, - { - "name": "godot_variant_new_rect2i", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_rect2i *", "p_rect2"] - ] - }, - { - "name": "godot_variant_new_vector3", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_vector3 *", "p_v3"] - ] - }, - { - "name": "godot_variant_new_vector3i", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_vector3i *", "p_v3"] - ] - }, - { - "name": "godot_variant_new_transform2d", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_transform2d *", "p_t2d"] - ] - }, - { - "name": "godot_variant_new_plane", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_plane *", "p_plane"] - ] - }, - { - "name": "godot_variant_new_quat", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_quat *", "p_quat"] - ] - }, - { - "name": "godot_variant_new_aabb", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_aabb *", "p_aabb"] - ] - }, - { - "name": "godot_variant_new_basis", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_basis *", "p_basis"] - ] - }, - { - "name": "godot_variant_new_transform", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_transform *", "p_trans"] - ] - }, - { - "name": "godot_variant_new_color", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_color *", "p_color"] - ] - }, - { - "name": "godot_variant_new_node_path", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_node_path *", "p_np"] - ] - }, - { - "name": "godot_variant_new_rid", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_rid *", "p_rid"] - ] - }, - { - "name": "godot_variant_new_object", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_object *", "p_obj"] - ] - }, - { - "name": "godot_variant_new_callable", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_callable *", "p_cb"] - ] - }, - { - "name": "godot_variant_new_signal", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_signal *", "p_signal"] - ] - }, - { - "name": "godot_variant_new_dictionary", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_dictionary *", "p_dict"] - ] - }, - { - "name": "godot_variant_new_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_array *", "p_arr"] - ] - }, - { - "name": "godot_variant_new_packed_byte_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_byte_array *", "p_pba"] - ] - }, - { - "name": "godot_variant_new_packed_int32_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_int32_array *", "p_pia"] - ] - }, - { - "name": "godot_variant_new_packed_int64_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_int64_array *", "p_pia"] - ] - }, - { - "name": "godot_variant_new_packed_float32_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_float32_array *", "p_pra"] - ] - }, - { - "name": "godot_variant_new_packed_float64_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_float64_array *", "p_pra"] - ] - }, - { - "name": "godot_variant_new_packed_string_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_string_array *", "p_psa"] - ] - }, - { - "name": "godot_variant_new_packed_vector2_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_vector2_array *", "p_pv2a"] - ] - }, - { - "name": "godot_variant_new_packed_vector3_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_vector3_array *", "p_pv3a"] - ] - }, - { - "name": "godot_variant_new_packed_color_array", - "return_type": "void", - "arguments": [ - ["godot_variant *", "r_dest"], - ["const godot_packed_color_array *", "p_pca"] - ] - }, - { - "name": "godot_variant_as_bool", - "return_type": "godot_bool", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_uint", - "return_type": "uint64_t", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_int", - "return_type": "int64_t", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_real", - "return_type": "double", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_string_name", - "return_type": "godot_string_name", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_vector2", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_vector2i", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_rect2", - "return_type": "godot_rect2", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_rect2i", - "return_type": "godot_rect2i", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_vector3", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_vector3i", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_transform2d", - "return_type": "godot_transform2d", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_plane", - "return_type": "godot_plane", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_quat", - "return_type": "godot_quat", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_aabb", - "return_type": "godot_aabb", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_basis", - "return_type": "godot_basis", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_transform", - "return_type": "godot_transform", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_color", - "return_type": "godot_color", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_node_path", - "return_type": "godot_node_path", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_rid", - "return_type": "godot_rid", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_object", - "return_type": "godot_object *", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_callable", - "return_type": "godot_callable", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_signal", - "return_type": "godot_signal", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_dictionary", - "return_type": "godot_dictionary", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_array", - "return_type": "godot_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_byte_array", - "return_type": "godot_packed_byte_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_int32_array", - "return_type": "godot_packed_int32_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_int64_array", - "return_type": "godot_packed_int64_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_float32_array", - "return_type": "godot_packed_float32_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_float64_array", - "return_type": "godot_packed_float64_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_string_array", - "return_type": "godot_packed_string_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_vector2_array", - "return_type": "godot_packed_vector2_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_vector3_array", - "return_type": "godot_packed_vector3_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_as_packed_color_array", - "return_type": "godot_packed_color_array", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_call", - "return_type": "godot_variant", - "arguments": [ - ["godot_variant *", "p_self"], - ["const godot_string *", "p_method"], - ["const godot_variant **", "p_args"], - ["const godot_int", "p_argcount"], - ["godot_variant_call_error *", "r_error"] - ] - }, - { - "name": "godot_variant_has_method", - "return_type": "godot_bool", - "arguments": [ - ["const godot_variant *", "p_self"], - ["const godot_string *", "p_method"] - ] - }, - { - "name": "godot_variant_hash", - "return_type": "uint32_t", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_variant *", "p_self"], - ["const godot_variant *", "p_other"] - ] - }, - { - "name": "godot_variant_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_variant *", "p_self"], - ["const godot_variant *", "p_other"] - ] - }, - { - "name": "godot_variant_get_operator_name", - "return_type": "godot_string", - "arguments": [ - ["godot_variant_operator", "p_op"] - ] - }, - { - "name": "godot_variant_evaluate", - "return_type": "void", - "arguments": [ - ["godot_variant_operator", "p_op"], - ["const godot_variant *", "p_a"], - ["const godot_variant *", "p_b"], - ["godot_variant *", "r_ret"], - ["godot_bool *", "r_valid"] - ] - }, - { - "name": "godot_variant_hash_compare", - "return_type": "godot_bool", - "arguments": [ - ["const godot_variant *", "p_self"], - ["const godot_variant *", "p_other"] - ] - }, - { - "name": "godot_variant_booleanize", - "return_type": "godot_bool", - "arguments": [ - ["const godot_variant *", "p_self"] - ] - }, - { - "name": "godot_variant_destroy", - "return_type": "void", - "arguments": [ - ["godot_variant *", "p_self"] - ] - }, - { - "name": "godot_vector2_as_vector2i", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_sign", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_move_toward", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_to"], - ["const godot_real", "p_delta"] - ] - }, - { - "name": "godot_vector2_direction_to", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_to"] - ] - }, - { - "name": "godot_vector2_new", - "return_type": "void", - "arguments": [ - ["godot_vector2 *", "r_dest"], - ["const godot_real", "p_x"], - ["const godot_real", "p_y"] - ] - }, - { - "name": "godot_vector2_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_normalized", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_length", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_angle", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_length_squared", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_is_normalized", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_distance_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_to"] - ] - }, - { - "name": "godot_vector2_distance_squared_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_to"] - ] - }, - { - "name": "godot_vector2_angle_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_to"] - ] - }, - { - "name": "godot_vector2_angle_to_point", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_to"] - ] - }, - { - "name": "godot_vector2_lerp", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_vector2_cubic_interpolate", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"], - ["const godot_vector2 *", "p_pre_a"], - ["const godot_vector2 *", "p_post_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_vector2_rotated", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_real", "p_phi"] - ] - }, - { - "name": "godot_vector2_orthogonal", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_floor", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_snapped", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_by"] - ] - }, - { - "name": "godot_vector2_aspect", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_dot", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_with"] - ] - }, - { - "name": "godot_vector2_slide", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_n"] - ] - }, - { - "name": "godot_vector2_bounce", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_n"] - ] - }, - { - "name": "godot_vector2_reflect", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_n"] - ] - }, - { - "name": "godot_vector2_abs", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_clamped", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_real", "p_length"] - ] - }, - { - "name": "godot_vector2_operator_add", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_subtract", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_multiply_vector", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_multiply_scalar", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_divide_vector", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_divide_scalar", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector2 *", "p_self"], - ["const godot_vector2 *", "p_b"] - ] - }, - { - "name": "godot_vector2_operator_neg", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_set_x", - "return_type": "void", - "arguments": [ - ["godot_vector2 *", "p_self"], - ["const godot_real", "p_x"] - ] - }, - { - "name": "godot_vector2_set_y", - "return_type": "void", - "arguments": [ - ["godot_vector2 *", "p_self"], - ["const godot_real", "p_y"] - ] - }, - { - "name": "godot_vector2_get_x", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2_get_y", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2 *", "p_self"] - ] - }, - { - "name": "godot_vector2i_new", - "return_type": "void", - "arguments": [ - ["godot_vector2i *", "r_dest"], - ["const godot_int", "p_x"], - ["const godot_int", "p_y"] - ] - }, - { - "name": "godot_vector2i_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_as_vector2", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_aspect", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_abs", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_sign", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_operator_add", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_vector2i *", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_subtract", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_vector2i *", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_multiply_vector", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_vector2i *", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_multiply_scalar", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_int", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_divide_vector", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_vector2i *", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_divide_scalar", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_int", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_vector2i *", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector2i *", "p_self"], - ["const godot_vector2i *", "p_b"] - ] - }, - { - "name": "godot_vector2i_operator_neg", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_set_x", - "return_type": "void", - "arguments": [ - ["godot_vector2i *", "p_self"], - ["const godot_int", "p_x"] - ] - }, - { - "name": "godot_vector2i_set_y", - "return_type": "void", - "arguments": [ - ["godot_vector2i *", "p_self"], - ["const godot_int", "p_y"] - ] - }, - { - "name": "godot_vector2i_get_x", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector2i_get_y", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector2i *", "p_self"] - ] - }, - { - "name": "godot_vector3_as_vector3i", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_sign", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_move_toward", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_to"], - ["const godot_real", "p_delta"] - ] - }, - { - "name": "godot_vector3_direction_to", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_to"] - ] - }, - { - "name": "godot_vector3_new", - "return_type": "void", - "arguments": [ - ["godot_vector3 *", "r_dest"], - ["const godot_real", "p_x"], - ["const godot_real", "p_y"], - ["const godot_real", "p_z"] - ] - }, - { - "name": "godot_vector3_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_min_axis", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_max_axis", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_length", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_length_squared", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_is_normalized", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_normalized", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_inverse", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_snapped", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_by"] - ] - }, - { - "name": "godot_vector3_rotated", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_axis"], - ["const godot_real", "p_phi"] - ] - }, - { - "name": "godot_vector3_lerp", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_vector3_cubic_interpolate", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"], - ["const godot_vector3 *", "p_pre_a"], - ["const godot_vector3 *", "p_post_b"], - ["const godot_real", "p_t"] - ] - }, - { - "name": "godot_vector3_dot", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_cross", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_outer", - "return_type": "godot_basis", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_to_diagonal_matrix", - "return_type": "godot_basis", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_abs", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_floor", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_ceil", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_distance_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_distance_squared_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_angle_to", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_to"] - ] - }, - { - "name": "godot_vector3_slide", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_n"] - ] - }, - { - "name": "godot_vector3_bounce", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_n"] - ] - }, - { - "name": "godot_vector3_reflect", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_n"] - ] - }, - { - "name": "godot_vector3_operator_add", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_subtract", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_multiply_vector", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_multiply_scalar", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_divide_vector", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_divide_scalar", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_real", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3 *", "p_b"] - ] - }, - { - "name": "godot_vector3_operator_neg", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3 *", "p_self"] - ] - }, - { - "name": "godot_vector3_set_axis", - "return_type": "void", - "arguments": [ - ["godot_vector3 *", "p_self"], - ["const godot_vector3_axis", "p_axis"], - ["const godot_real", "p_val"] - ] - }, - { - "name": "godot_vector3_get_axis", - "return_type": "godot_real", - "arguments": [ - ["const godot_vector3 *", "p_self"], - ["const godot_vector3_axis", "p_axis"] - ] - }, - { - "name": "godot_vector3i_new", - "return_type": "void", - "arguments": [ - ["godot_vector3i *", "r_dest"], - ["const godot_int", "p_x"], - ["const godot_int", "p_y"], - ["const godot_int", "p_z"] - ] - }, - { - "name": "godot_vector3i_as_string", - "return_type": "godot_string", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_as_vector3", - "return_type": "godot_vector3", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_min_axis", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_max_axis", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_abs", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_sign", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_operator_add", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3i *", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_subtract", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3i *", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_multiply_vector", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3i *", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_multiply_scalar", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_int", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_divide_vector", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3i *", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_divide_scalar", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_int", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_equal", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3i *", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_less", - "return_type": "godot_bool", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3i *", "p_b"] - ] - }, - { - "name": "godot_vector3i_operator_neg", - "return_type": "godot_vector3i", - "arguments": [ - ["const godot_vector3i *", "p_self"] - ] - }, - { - "name": "godot_vector3i_set_axis", - "return_type": "void", - "arguments": [ - ["godot_vector3i *", "p_self"], - ["const godot_vector3_axis", "p_axis"], - ["const godot_int", "p_val"] - ] - }, - { - "name": "godot_vector3i_get_axis", - "return_type": "godot_int", - "arguments": [ - ["const godot_vector3i *", "p_self"], - ["const godot_vector3_axis", "p_axis"] - ] - }, - { - "name": "godot_global_get_singleton", - "return_type": "godot_object *", - "arguments": [ - ["char *", "p_name"] - ] - }, - { - "name": "godot_get_class_tag", - "return_type": "void *", - "arguments": [ - ["const godot_string_name *", "p_class"] - ] - }, - { - "name": "godot_object_cast_to", - "return_type": "godot_object *", - "arguments": [ - ["const godot_object *", "p_object"], - ["void *", "p_class_tag"] - ] - }, - { - "name": "godot_object_get_instance_id", - "return_type": "uint64_t", - "arguments": [ - ["const godot_object *", "p_object"] - ] - }, - { - "name": "godot_instance_from_id", - "return_type": "godot_object *", - "arguments": [ - ["uint64_t", "p_instance_id"] - ] - }, - { - "name": "godot_object_destroy", - "return_type": "void", - "arguments": [ - ["godot_object *", "p_o"] - ] - }, - { - "name": "godot_method_bind_get_method", - "return_type": "godot_method_bind *", - "arguments": [ - ["const char *", "p_classname"], - ["const char *", "p_methodname"] - ] - }, - { - "name": "godot_method_bind_ptrcall", - "return_type": "void", - "arguments": [ - ["godot_method_bind *", "p_method_bind"], - ["godot_object *", "p_instance"], - ["const void **", "p_args"], - ["void *", "p_ret"] - ] - }, - { - "name": "godot_method_bind_call", - "return_type": "godot_variant", - "arguments": [ - ["godot_method_bind *", "p_method_bind"], - ["godot_object *", "p_instance"], - ["const godot_variant **", "p_args"], - ["const int", "p_arg_count"], - ["godot_variant_call_error *", "p_call_error"] - ] - }, - { - "name": "godot_get_class_constructor", - "return_type": "godot_class_constructor", - "arguments": [ - ["const char *", "p_classname"] - ] - }, - { - "name": "godot_get_global_constants", - "return_type": "godot_dictionary", - "arguments": [ - ] - }, - { - "name": "godot_register_native_call_type", - "return_type": "void", - "arguments": [ - ["const char *", "call_type"], - ["native_call_cb", "p_callback"] - ] - }, - { - "name": "godot_alloc", - "return_type": "void *", - "arguments": [ - ["int", "p_bytes"] - ] - }, - { - "name": "godot_realloc", - "return_type": "void *", - "arguments": [ - ["void *", "p_ptr"], - ["int", "p_bytes"] - ] - }, - { - "name": "godot_free", - "return_type": "void", - "arguments": [ - ["void *", "p_ptr"] - ] - }, - { - "name": "godot_print_error", - "return_type": "void", - "arguments": [ - ["const char *", "p_description"], - ["const char *", "p_function"], - ["const char *", "p_file"], - ["int", "p_line"] - ] - }, - { - "name": "godot_print_warning", - "return_type": "void", - "arguments": [ - ["const char *", "p_description"], - ["const char *", "p_function"], - ["const char *", "p_file"], - ["int", "p_line"] - ] - }, - { - "name": "godot_print", - "return_type": "void", - "arguments": [ - ["const godot_string *", "p_message"] - ] - } - ] - }, - "extensions": [ - { - "name": "nativescript", - "type": "NATIVESCRIPT", - "version": { - "major": 4, - "minor": 0 - }, - "next": null, - "api": [ - { - "name": "godot_nativescript_register_class", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_base"], - ["godot_nativescript_instance_create_func", "p_create_func"], - ["godot_nativescript_instance_destroy_func", "p_destroy_func"] - ] - }, - { - "name": "godot_nativescript_register_tool_class", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_base"], - ["godot_nativescript_instance_create_func", "p_create_func"], - ["godot_nativescript_instance_destroy_func", "p_destroy_func"] - ] - }, - { - "name": "godot_nativescript_register_method", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_function_name"], - ["godot_nativescript_method_attributes", "p_attr"], - ["godot_nativescript_instance_method", "p_method"] - ] - }, - { - "name": "godot_nativescript_set_method_argument_information", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_function_name"], - ["int", "p_num_args"], - ["const godot_nativescript_method_argument *", "p_args"] - ] - }, - { - "name": "godot_nativescript_register_property", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_path"], - ["godot_nativescript_property_attributes *", "p_attr"], - ["godot_nativescript_property_set_func", "p_set_func"], - ["godot_nativescript_property_get_func", "p_get_func"] - ] - }, - { - "name": "godot_nativescript_register_signal", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const godot_nativescript_signal *", "p_signal"] - ] - }, - { - "name": "godot_nativescript_get_userdata", - "return_type": "void *", - "arguments": [ - ["godot_object *", "p_instance"] - ] - }, - { - "name": "godot_nativescript_set_class_documentation", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["godot_string", "p_documentation"] - ] - }, - { - "name": "godot_nativescript_set_method_documentation", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_function_name"], - ["godot_string", "p_documentation"] - ] - }, - { - "name": "godot_nativescript_set_property_documentation", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_path"], - ["godot_string", "p_documentation"] - ] - }, - { - "name": "godot_nativescript_set_signal_documentation", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const char *", "p_signal_name"], - ["godot_string", "p_documentation"] - ] - }, - { - "name": "godot_nativescript_set_global_type_tag", - "return_type": "void", - "arguments": [ - ["int", "p_idx"], - ["const char *", "p_name"], - ["const void *", "p_type_tag"] - ] - }, - { - "name": "godot_nativescript_get_global_type_tag", - "return_type": "const void *", - "arguments": [ - ["int", "p_idx"], - ["const char *", "p_name"] - ] - }, - { - "name": "godot_nativescript_set_type_tag", - "return_type": "void", - "arguments": [ - ["void *", "p_gdnative_handle"], - ["const char *", "p_name"], - ["const void *", "p_type_tag"] - ] - }, - { - "name": "godot_nativescript_get_type_tag", - "return_type": "const void *", - "arguments": [ - ["const godot_object *", "p_object"] - ] - }, - { - "name": "godot_nativescript_register_instance_binding_data_functions", - "return_type": "int", - "arguments": [ - ["godot_nativescript_instance_binding_functions", "p_binding_functions"] - ] - }, - { - "name": "godot_nativescript_unregister_instance_binding_data_functions", - "return_type": "void", - "arguments": [ - ["int", "p_idx"] - ] - }, - { - "name": "godot_nativescript_get_instance_binding_data", - "return_type": "void *", - "arguments": [ - ["int", "p_idx"], - ["godot_object *", "p_object"] - ] - }, - { - "name": "godot_nativescript_profiling_add_data", - "return_type": "void", - "arguments": [ - ["const char *", "p_signature"], - ["uint64_t", "p_line"] - ] - } - ] - }, - { - "name": "pluginscript", - "type": "PLUGINSCRIPT", - "version": { - "major": 1, - "minor": 0 - }, - "next": null, - "api": [ - { - "name": "godot_pluginscript_register_language", - "return_type": "void", - "arguments": [ - ["const godot_pluginscript_language_desc *", "language_desc"] - ] - } - ] - }, - { - "name": "android", - "type": "ANDROID", - "version": { - "major": 1, - "minor": 1 - }, - "next": null, - "api": [ - { - "name": "godot_android_get_env", - "return_type": "JNIEnv*", - "arguments": [ - ] - }, - { - "name": "godot_android_get_activity", - "return_type": "jobject", - "arguments": [ - ] - }, - { - "name": "godot_android_get_surface", - "return_type": "jobject", - "arguments": [ - ] - }, - { - "name": "godot_android_is_activity_resumed", - "return_type": "bool", - "arguments": [ - ] - } - ] - }, - { - "name": "xr", - "type": "XR", - "version": { - "major": 1, - "minor": 1 - }, - "next": null, - "api": [ - { - "name": "godot_xr_register_interface", - "return_type": "void", - "arguments": [ - ["const godot_xr_interface_gdnative *", "p_interface"] - ] - }, - { - "name": "godot_xr_get_worldscale", - "return_type": "godot_real", - "arguments": [] - }, - { - "name": "godot_xr_get_reference_frame", - "return_type": "godot_transform", - "arguments": [] - }, - { - "name": "godot_xr_blit", - "return_type": "void", - "arguments": [ - ["godot_int", "p_eye"], - ["godot_rid *", "p_render_target"], - ["godot_rect2 *", "p_screen_rect"] - ] - }, - { - "name": "godot_xr_get_texid", - "return_type": "godot_int", - "arguments": [ - ["godot_rid *", "p_render_target"] - ] - }, - { - "name": "godot_xr_add_controller", - "return_type": "godot_int", - "arguments": [ - ["char *", "p_device_name"], - ["godot_int", "p_hand"], - ["godot_bool", "p_tracks_orientation"], - ["godot_bool", "p_tracks_position"] - ] - }, - { - "name": "godot_xr_remove_controller", - "return_type": "void", - "arguments": [ - ["godot_int", "p_controller_id"] - ] - }, - { - "name": "godot_xr_set_controller_transform", - "return_type": "void", - "arguments": [ - ["godot_int", "p_controller_id"], - ["godot_transform *", "p_transform"], - ["godot_bool", "p_tracks_orientation"], - ["godot_bool", "p_tracks_position"] - ] - }, - { - "name": "godot_xr_set_controller_button", - "return_type": "void", - "arguments": [ - ["godot_int", "p_controller_id"], - ["godot_int", "p_button"], - ["godot_bool", "p_is_pressed"] - ] - }, - { - "name": "godot_xr_set_controller_axis", - "return_type": "void", - "arguments": [ - ["godot_int", "p_controller_id"], - ["godot_int", "p_exis"], - ["godot_real", "p_value"], - ["godot_bool", "p_can_be_negative"] - ] - }, - { - "name": "godot_xr_get_controller_rumble", - "return_type": "godot_real", - "arguments": [ - ["godot_int", "p_controller_id"] - ] - } - ] - }, - { - "name": "videodecoder", - "type": "VIDEODECODER", - "version": { - "major": 0, - "minor": 1 - }, - "next": null, - "api": [ - { - "name": "godot_videodecoder_file_read", - "return_type": "godot_int", - "arguments": [ - ["void *", "file_ptr"], - ["uint8_t *", "buf"], - ["int", "buf_size"] - ] - }, - { - "name": "godot_videodecoder_file_seek", - "return_type": "int64_t", - "arguments": [ - [ "void *", "file_ptr"], - ["int64_t", "pos"], - ["int", "whence"] - ] - }, - { - "name": "godot_videodecoder_register_decoder", - "return_type": "void", - "arguments": [ - ["const godot_videodecoder_interface_gdnative *", "p_interface"] - ] - } - ] - }, - { - "name": "net", - "type": "NET", - "version": { - "major": 4, - "minor": 0 - }, - "next": null, - "api": [ - { - "name": "godot_net_bind_stream_peer", - "return_type": "void", - "arguments": [ - ["godot_object *", "p_obj"], - ["const godot_net_stream_peer *", "p_interface"] - ] - }, - { - "name": "godot_net_bind_packet_peer", - "return_type": "void", - "arguments": [ - ["godot_object *", "p_obj"], - ["const godot_net_packet_peer *", "p_interface"] - ] - }, - { - "name": "godot_net_bind_multiplayer_peer", - "return_type": "void", - "arguments": [ - ["godot_object *", "p_obj"], - ["const godot_net_multiplayer_peer *", "p_interface"] - ] - }, - { - "name": "godot_net_set_webrtc_library", - "return_type": "godot_error", - "arguments": [ - ["const godot_net_webrtc_library *", "p_library"] - ] - }, - { - "name": "godot_net_bind_webrtc_peer_connection", - "return_type": "void", - "arguments": [ - ["godot_object *", "p_obj"], - ["const godot_net_webrtc_peer_connection *", "p_interface"] - ] - }, - { - "name": "godot_net_bind_webrtc_data_channel", - "return_type": "void", - "arguments": [ - ["godot_object *", "p_obj"], - ["const godot_net_webrtc_data_channel *", "p_interface"] - ] - } - ] - }, - { - "name": "text", - "type": "TEXT", - "version": { - "major": 1, - "minor": 0 - }, - "next": null, - "api": [ - { - "name": "godot_text_register_interface", - "return_type": "void", - "arguments": [ - ["const godot_text_interface_gdnative *", "p_interface"], - ["const godot_string *", "p_name"], - ["uint32_t", "p_features"] - ] - }, - { - "name": "godot_glyph_new", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "r_dest"] - ] - }, - { - "name": "godot_glyph_get_range", - "return_type": "godot_vector2i", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_range", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["const godot_vector2i *", "p_range"] - ] - }, - { - "name": "godot_glyph_get_count", - "return_type": "godot_int", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_count", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_int", "p_count"] - ] - }, - { - "name": "godot_glyph_get_repeat", - "return_type": "godot_int", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_repeat", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_int", "p_repeat"] - ] - }, - { - "name": "godot_glyph_get_flags", - "return_type": "godot_int", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_flags", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_int", "p_flags"] - ] - }, - { - "name": "godot_glyph_get_offset", - "return_type": "godot_vector2", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_offset", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["const godot_vector2 *", "p_offset"] - ] - }, - { - "name": "godot_glyph_get_advance", - "return_type": "godot_real", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_advance", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_real", "p_advance"] - ] - }, - { - "name": "godot_glyph_get_font", - "return_type": "godot_rid", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_font", - "return_type": "void ", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_rid *", "p_font"] - ] - }, - { - "name": "godot_glyph_get_font_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_font_size", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_int", "p_size"] - ] - }, - { - "name": "godot_glyph_get_index", - "return_type": "godot_int", - "arguments": [ - ["const godot_glyph *", "p_self"] - ] - }, - { - "name": "godot_glyph_set_index", - "return_type": "void", - "arguments": [ - ["godot_glyph *", "p_self"], - ["godot_int", "p_index"] - ] - }, - { - "name": "godot_packed_glyph_array_new", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "r_dest"] - ] - }, - { - "name": "godot_packed_glyph_array_new_copy", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "r_dest"], - ["const godot_packed_glyph_array *", "p_src"] - ] - }, - { - "name": "godot_packed_glyph_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - ["const godot_packed_glyph_array *", "p_self"] - ] - }, - { - "name": "godot_packed_glyph_array_append", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_glyph *", "p_data"] - ] - }, - { - "name": "godot_packed_glyph_array_append_array", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_packed_glyph_array *", "p_array"] - ] - }, - { - "name": "godot_packed_glyph_array_insert", - "return_type": "godot_error", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_glyph *", "p_data"] - ] - }, - { - "name": "godot_packed_glyph_array_has", - "return_type": "godot_bool", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_glyph *", "p_value"] - ] - }, - { - "name": "godot_packed_glyph_array_sort", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"] - ] - }, - { - "name": "godot_packed_glyph_array_invert", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"] - ] - }, - { - "name": "godot_packed_glyph_array_push_back", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_glyph *", "p_data"] - ] - }, - { - "name": "godot_packed_glyph_array_remove", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_glyph_array_resize", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_int", "p_size"] - ] - }, - { - "name": "godot_packed_glyph_array_ptr", - "return_type": "const godot_glyph *", - "arguments": [ - ["const godot_packed_glyph_array *", "p_self"] - ] - }, - { - "name": "godot_packed_glyph_array_ptrw", - "return_type": "godot_glyph *", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"] - ] - }, - { - "name": "godot_packed_glyph_array_set", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"], - ["const godot_int", "p_idx"], - ["const godot_glyph *", "p_data"] - ] - }, - { - "name": "godot_packed_glyph_array_get", - "return_type": "godot_glyph", - "arguments": [ - ["const godot_packed_glyph_array *", "p_self"], - ["const godot_int", "p_idx"] - ] - }, - { - "name": "godot_packed_glyph_array_size", - "return_type": "godot_int", - "arguments": [ - ["const godot_packed_glyph_array *", "p_self"] - ] - }, - { - "name": "godot_packed_glyph_array_destroy", - "return_type": "void", - "arguments": [ - ["godot_packed_glyph_array *", "p_self"] - ] - } - ] - } - ] + "core": { + "type": "CORE", + "version": { + "major": 4, + "minor": 0 + }, + "next": null, + "api": [ + { + "name": "godot_object_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_object *", + "p_o" + ] + ] + }, + { + "name": "godot_global_get_singleton", + "return_type": "godot_object *", + "arguments": [ + [ + "char *", + "p_name" + ] + ] + }, + { + "name": "godot_method_bind_get_method", + "return_type": "godot_method_bind *", + "arguments": [ + [ + "const char *", + "p_classname" + ], + [ + "const char *", + "p_methodname" + ] + ] + }, + { + "name": "godot_method_bind_ptrcall", + "return_type": "void", + "arguments": [ + [ + "godot_method_bind *", + "p_method_bind" + ], + [ + "godot_object *", + "p_instance" + ], + [ + "const void **", + "p_args" + ], + [ + "void *", + "p_ret" + ] + ] + }, + { + "name": "godot_method_bind_call", + "return_type": "godot_variant", + "arguments": [ + [ + "godot_method_bind *", + "p_method_bind" + ], + [ + "godot_object *", + "p_instance" + ], + [ + "const godot_variant **", + "p_args" + ], + [ + "const int", + "p_arg_count" + ], + [ + "godot_variant_call_error *", + "p_call_error" + ] + ] + }, + { + "name": "godot_get_class_constructor", + "return_type": "godot_class_constructor", + "arguments": [ + [ + "const char *", + "p_classname" + ] + ] + }, + { + "name": "godot_get_global_constants", + "return_type": "godot_dictionary", + "arguments": [] + }, + { + "name": "godot_register_native_call_type", + "return_type": "void", + "arguments": [ + [ + "const char *", + "call_type" + ], + [ + "native_call_cb", + "p_callback" + ] + ] + }, + { + "name": "godot_alloc", + "return_type": "void *", + "arguments": [ + [ + "int", + "p_bytes" + ] + ] + }, + { + "name": "godot_realloc", + "return_type": "void *", + "arguments": [ + [ + "void *", + "p_ptr" + ], + [ + "int", + "p_bytes" + ] + ] + }, + { + "name": "godot_free", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_ptr" + ] + ] + }, + { + "name": "godot_print_error", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_description" + ], + [ + "const char *", + "p_function" + ], + [ + "const char *", + "p_file" + ], + [ + "int", + "p_line" + ] + ] + }, + { + "name": "godot_print_warning", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_description" + ], + [ + "const char *", + "p_function" + ], + [ + "const char *", + "p_file" + ], + [ + "int", + "p_line" + ] + ] + }, + { + "name": "godot_print_script_error", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_description" + ], + [ + "const char *", + "p_function" + ], + [ + "const char *", + "p_file" + ], + [ + "int", + "p_line" + ] + ] + }, + { + "name": "godot_get_class_tag", + "return_type": "void *", + "arguments": [ + [ + "const godot_string_name *", + "p_class" + ] + ] + }, + { + "name": "godot_object_cast_to", + "return_type": "godot_object *", + "arguments": [ + [ + "const godot_object *", + "p_object" + ], + [ + "void *", + "p_class_tag" + ] + ] + }, + { + "name": "godot_instance_from_id", + "return_type": "godot_object *", + "arguments": [ + [ + "uint64_t", + "p_instance_id" + ] + ] + }, + { + "name": "godot_object_get_instance_id", + "return_type": "uint64_t", + "arguments": [ + [ + "const godot_object *", + "p_object" + ] + ] + }, + { + "name": "godot_variant_new_copy", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_variant *", + "p_src" + ] + ] + }, + { + "name": "godot_variant_new_nil", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ] + ] + }, + { + "name": "godot_variant_new_bool", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_bool", + "p_b" + ] + ] + }, + { + "name": "godot_variant_new_int", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const int64_t", + "p_i" + ] + ] + }, + { + "name": "godot_variant_new_float", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const double", + "p_f" + ] + ] + }, + { + "name": "godot_variant_new_string", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_string *", + "p_s" + ] + ] + }, + { + "name": "godot_variant_new_string_name", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_string_name *", + "p_s" + ] + ] + }, + { + "name": "godot_variant_new_vector2", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_vector2 *", + "p_v2" + ] + ] + }, + { + "name": "godot_variant_new_vector2i", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_vector2i *", + "p_v2" + ] + ] + }, + { + "name": "godot_variant_new_rect2", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_rect2 *", + "p_rect2" + ] + ] + }, + { + "name": "godot_variant_new_rect2i", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_rect2i *", + "p_rect2" + ] + ] + }, + { + "name": "godot_variant_new_vector3", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_vector3 *", + "p_v3" + ] + ] + }, + { + "name": "godot_variant_new_vector3i", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_vector3i *", + "p_v3" + ] + ] + }, + { + "name": "godot_variant_new_transform2d", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_transform2d *", + "p_t2d" + ] + ] + }, + { + "name": "godot_variant_new_plane", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_plane *", + "p_plane" + ] + ] + }, + { + "name": "godot_variant_new_quat", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_quat *", + "p_quat" + ] + ] + }, + { + "name": "godot_variant_new_aabb", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_aabb *", + "p_aabb" + ] + ] + }, + { + "name": "godot_variant_new_basis", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_basis *", + "p_basis" + ] + ] + }, + { + "name": "godot_variant_new_transform", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_transform *", + "p_trans" + ] + ] + }, + { + "name": "godot_variant_new_color", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_color *", + "p_color" + ] + ] + }, + { + "name": "godot_variant_new_node_path", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_node_path *", + "p_np" + ] + ] + }, + { + "name": "godot_variant_new_rid", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_rid *", + "p_rid" + ] + ] + }, + { + "name": "godot_variant_new_object", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_object *", + "p_obj" + ] + ] + }, + { + "name": "godot_variant_new_callable", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_callable *", + "p_cb" + ] + ] + }, + { + "name": "godot_variant_new_signal", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_signal *", + "p_signal" + ] + ] + }, + { + "name": "godot_variant_new_dictionary", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_dictionary *", + "p_dict" + ] + ] + }, + { + "name": "godot_variant_new_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_array *", + "p_arr" + ] + ] + }, + { + "name": "godot_variant_new_packed_byte_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_byte_array *", + "p_pba" + ] + ] + }, + { + "name": "godot_variant_new_packed_int32_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_int32_array *", + "p_pia" + ] + ] + }, + { + "name": "godot_variant_new_packed_int64_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_int64_array *", + "p_pia" + ] + ] + }, + { + "name": "godot_variant_new_packed_float32_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_float32_array *", + "p_pra" + ] + ] + }, + { + "name": "godot_variant_new_packed_float64_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_float64_array *", + "p_pra" + ] + ] + }, + { + "name": "godot_variant_new_packed_string_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_string_array *", + "p_psa" + ] + ] + }, + { + "name": "godot_variant_new_packed_vector2_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_vector2_array *", + "p_pv2a" + ] + ] + }, + { + "name": "godot_variant_new_packed_vector3_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_vector3_array *", + "p_pv3a" + ] + ] + }, + { + "name": "godot_variant_new_packed_color_array", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "r_dest" + ], + [ + "const godot_packed_color_array *", + "p_pca" + ] + ] + }, + { + "name": "godot_variant_as_bool", + "return_type": "godot_bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_int", + "return_type": "int64_t", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_float", + "return_type": "double", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_string", + "return_type": "godot_string", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_string_name", + "return_type": "godot_string_name", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_vector2", + "return_type": "godot_vector2", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_vector2i", + "return_type": "godot_vector2i", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_rect2", + "return_type": "godot_rect2", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_rect2i", + "return_type": "godot_rect2i", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_vector3", + "return_type": "godot_vector3", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_vector3i", + "return_type": "godot_vector3i", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_transform2d", + "return_type": "godot_transform2d", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_plane", + "return_type": "godot_plane", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_quat", + "return_type": "godot_quat", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_aabb", + "return_type": "godot_aabb", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_basis", + "return_type": "godot_basis", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_transform", + "return_type": "godot_transform", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_color", + "return_type": "godot_color", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_node_path", + "return_type": "godot_node_path", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_rid", + "return_type": "godot_rid", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_object", + "return_type": "godot_object *", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_callable", + "return_type": "godot_callable", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_signal", + "return_type": "godot_signal", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_dictionary", + "return_type": "godot_dictionary", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_array", + "return_type": "godot_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_byte_array", + "return_type": "godot_packed_byte_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_int32_array", + "return_type": "godot_packed_int32_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_int64_array", + "return_type": "godot_packed_int64_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_float32_array", + "return_type": "godot_packed_float32_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_float64_array", + "return_type": "godot_packed_float64_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_string_array", + "return_type": "godot_packed_string_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_vector2_array", + "return_type": "godot_packed_vector2_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_vector3_array", + "return_type": "godot_packed_vector3_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_as_packed_color_array", + "return_type": "godot_packed_color_array", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_call", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "p_self" + ], + [ + "const godot_string_name *", + "p_method" + ], + [ + "const godot_variant **", + "p_args" + ], + [ + "const godot_int", + "p_argument_count" + ], + [ + "godot_variant *", + "r_return" + ], + [ + "godot_variant_call_error *", + "r_error" + ] + ] + }, + { + "name": "godot_variant_evaluate", + "return_type": "void", + "arguments": [ + [ + "godot_variant_operator", + "p_op" + ], + [ + "const godot_variant *", + "p_a" + ], + [ + "const godot_variant *", + "p_b" + ], + [ + "godot_variant *", + "r_return" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_set", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ], + [ + "const godot_variant *", + "p_value" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_set_named", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "p_self" + ], + [ + "const godot_string_name *", + "p_name" + ], + [ + "const godot_variant *", + "p_value" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_set_keyed", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ], + [ + "const godot_variant *", + "p_value" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_set_indexed", + "return_type": "void", + "arguments": [ + [ + "godot_variant *", + "p_self" + ], + [ + "godot_int", + "p_index" + ], + [ + "const godot_variant *", + "p_value" + ], + [ + "bool *", + "r_valid" + ], + [ + "bool *", + "r_oob" + ] + ] + }, + { + "name": "godot_variant_get", + "return_type": "godot_variant", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_get_named", + "return_type": "godot_variant", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "const godot_string_name *", + "p_key" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_get_keyed", + "return_type": "godot_variant", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_get_indexed", + "return_type": "godot_variant", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "godot_int", + "p_index" + ], + [ + "bool *", + "r_valid" + ], + [ + "bool *", + "r_oob" + ] + ] + }, + { + "name": "godot_variant_iter_init", + "return_type": "bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "godot_variant *", + "r_iter" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_iter_next", + "return_type": "bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "godot_variant *", + "r_iter" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_iter_get", + "return_type": "godot_variant", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "godot_variant *", + "r_iter" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_hash_compare", + "return_type": "godot_bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "const godot_variant *", + "p_other" + ] + ] + }, + { + "name": "godot_variant_booleanize", + "return_type": "godot_bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_blend", + "return_type": "void", + "arguments": [ + [ + "const godot_variant *", + "p_a" + ], + [ + "const godot_variant *", + "p_b" + ], + [ + "float", + "p_c" + ], + [ + "godot_variant *", + "r_dst" + ] + ] + }, + { + "name": "godot_variant_interpolate", + "return_type": "void", + "arguments": [ + [ + "const godot_variant *", + "p_a" + ], + [ + "const godot_variant *", + "p_b" + ], + [ + "float", + "p_c" + ], + [ + "godot_variant *", + "r_dst" + ] + ] + }, + { + "name": "godot_variant_duplicate", + "return_type": "godot_variant", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "godot_bool", + "p_deep" + ] + ] + }, + { + "name": "godot_variant_stringify", + "return_type": "godot_string", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_get_validated_operator_evaluator", + "return_type": "godot_validated_operator_evaluator", + "arguments": [ + [ + "godot_variant_operator", + "p_operator" + ], + [ + "godot_variant_type", + "p_type_a" + ], + [ + "godot_variant_type", + "p_type_b" + ] + ] + }, + { + "name": "godot_variant_get_ptr_operator_evaluator", + "return_type": "godot_ptr_operator_evaluator", + "arguments": [ + [ + "godot_variant_operator", + "p_operator" + ], + [ + "godot_variant_type", + "p_type_a" + ], + [ + "godot_variant_type", + "p_type_b" + ] + ] + }, + { + "name": "godot_variant_get_operator_return_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_operator", + "p_operator" + ], + [ + "godot_variant_type", + "p_type_a" + ], + [ + "godot_variant_type", + "p_type_b" + ] + ] + }, + { + "name": "godot_variant_get_operator_name", + "return_type": "godot_string", + "arguments": [ + [ + "godot_variant_operator", + "p_operator" + ] + ] + }, + { + "name": "godot_variant_has_builtin_method", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_has_builtin_method_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_validated_builtin_method", + "return_type": "godot_validated_builtin_method", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_validated_builtin_method_with_cstring", + "return_type": "godot_validated_builtin_method", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_ptr_builtin_method", + "return_type": "godot_ptr_builtin_method", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_ptr_builtin_method_with_cstring", + "return_type": "godot_ptr_builtin_method", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_argument_count", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_argument_count_with_cstring", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_argument_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_argument_type_with_cstring", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_argument_name", + "return_type": "godot_string", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_argument_name_with_cstring", + "return_type": "godot_string", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_has_builtin_method_return_value", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_has_builtin_method_return_value_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_return_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_return_type_with_cstring", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_is_builtin_method_const", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_is_builtin_method_const_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_is_builtin_method_vararg", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_is_builtin_method_vararg_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_count", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_builtin_method_list", + "return_type": "void", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "godot_string_name *", + "r_list" + ] + ] + }, + { + "name": "godot_variant_get_constructor_count", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_validated_constructor", + "return_type": "godot_validated_constructor", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "int", + "p_constructor" + ] + ] + }, + { + "name": "godot_variant_get_ptr_constructor", + "return_type": "godot_ptr_constructor", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "int", + "p_constructor" + ] + ] + }, + { + "name": "godot_variant_get_constructor_argument_count", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "int", + "p_constructor" + ] + ] + }, + { + "name": "godot_variant_get_constructor_argument_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "int", + "p_constructor" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_constructor_argument_name", + "return_type": "godot_string", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "int", + "p_constructor" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_construct", + "return_type": "void", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "godot_variant *", + "p_base" + ], + [ + "const godot_variant **", + "p_args" + ], + [ + "int", + "p_argument_count" + ], + [ + "godot_variant_call_error *", + "r_error" + ] + ] + }, + { + "name": "godot_variant_get_member_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_member_type_with_cstring", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_member_count", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_member_list", + "return_type": "void", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "godot_string_name *", + "r_list" + ] + ] + }, + { + "name": "godot_variant_get_validated_setter", + "return_type": "godot_validated_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_validated_setter_with_cstring", + "return_type": "godot_validated_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_validated_getter", + "return_type": "godot_validated_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_validated_getter_with_cstring", + "return_type": "godot_validated_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_ptr_setter", + "return_type": "godot_ptr_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_ptr_setter_with_cstring", + "return_type": "godot_ptr_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_ptr_getter", + "return_type": "godot_ptr_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_get_ptr_getter_with_cstring", + "return_type": "godot_ptr_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_has_indexing", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_indexed_element_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_validated_indexed_setter", + "return_type": "godot_validated_indexed_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_validated_indexed_getter", + "return_type": "godot_validated_indexed_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_ptr_indexed_setter", + "return_type": "godot_ptr_indexed_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_ptr_indexed_getter", + "return_type": "godot_ptr_indexed_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_indexed_size", + "return_type": "uint64_t", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_is_keyed", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_validated_keyed_setter", + "return_type": "godot_validated_keyed_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_validated_keyed_getter", + "return_type": "godot_validated_keyed_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_validated_keyed_checker", + "return_type": "godot_validated_keyed_checker", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_ptr_keyed_setter", + "return_type": "godot_ptr_keyed_setter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_ptr_keyed_getter", + "return_type": "godot_ptr_keyed_getter", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_ptr_keyed_checker", + "return_type": "godot_ptr_keyed_checker", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_constants_count", + "return_type": "int", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_get_constants_list", + "return_type": "void", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "godot_string_name *", + "r_list" + ] + ] + }, + { + "name": "godot_variant_has_constant", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_constant" + ] + ] + }, + { + "name": "godot_variant_has_constant_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_constant" + ] + ] + }, + { + "name": "godot_variant_get_constant_value", + "return_type": "godot_variant", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_constant" + ] + ] + }, + { + "name": "godot_variant_get_constant_value_with_cstring", + "return_type": "godot_variant", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const char *", + "p_constant" + ] + ] + }, + { + "name": "godot_variant_has_utility_function", + "return_type": "bool", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_has_utility_function_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_call_utility_function", + "return_type": "void", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ], + [ + "godot_variant *", + "r_ret" + ], + [ + "const godot_variant **", + "p_args" + ], + [ + "int", + "p_argument_count" + ], + [ + "godot_variant_call_error *", + "r_error" + ] + ] + }, + { + "name": "godot_variant_call_utility_function_with_cstring", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_function" + ], + [ + "godot_variant *", + "r_ret" + ], + [ + "const godot_variant **", + "p_args" + ], + [ + "int", + "p_argument_count" + ], + [ + "godot_variant_call_error *", + "r_error" + ] + ] + }, + { + "name": "godot_variant_get_ptr_utility_function", + "return_type": "godot_ptr_utility_function", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_ptr_utility_function_with_cstring", + "return_type": "godot_ptr_utility_function", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_validated_utility_function", + "return_type": "godot_validated_utility_function", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_validated_utility_function_with_cstring", + "return_type": "godot_validated_utility_function", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_type", + "return_type": "godot_variant_utility_function_type", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_type_with_cstring", + "return_type": "godot_variant_utility_function_type", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_argument_count", + "return_type": "int", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_argument_count_with_cstring", + "return_type": "int", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_argument_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_argument_type_with_cstring", + "return_type": "godot_variant_type", + "arguments": [ + [ + "const char *", + "p_function" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_argument_name", + "return_type": "godot_string", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_argument_name_with_cstring", + "return_type": "godot_string", + "arguments": [ + [ + "const char *", + "p_function" + ], + [ + "int", + "p_argument" + ] + ] + }, + { + "name": "godot_variant_has_utility_function_return_value", + "return_type": "bool", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_has_utility_function_return_value_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_return_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_return_type_with_cstring", + "return_type": "godot_variant_type", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_is_utility_function_vararg", + "return_type": "bool", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_is_utility_function_vararg_with_cstring", + "return_type": "bool", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_utility_function_count", + "return_type": "int", + "arguments": [] + }, + { + "name": "godot_variant_get_utility_function_list", + "return_type": "void", + "arguments": [ + [ + "godot_string_name *", + "r_functions" + ] + ] + }, + { + "name": "godot_variant_get_type", + "return_type": "godot_variant_type", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ] + ] + }, + { + "name": "godot_variant_has_method", + "return_type": "bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "const godot_string_name *", + "p_method" + ] + ] + }, + { + "name": "godot_variant_has_member", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ], + [ + "const godot_string_name *", + "p_member" + ] + ] + }, + { + "name": "godot_variant_has_key", + "return_type": "bool", + "arguments": [ + [ + "const godot_variant *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ], + [ + "bool *", + "r_valid" + ] + ] + }, + { + "name": "godot_variant_get_type_name", + "return_type": "godot_string", + "arguments": [ + [ + "godot_variant_type", + "p_type" + ] + ] + }, + { + "name": "godot_variant_can_convert", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_from" + ], + [ + "godot_variant_type", + "p_to" + ] + ] + }, + { + "name": "godot_variant_can_convert_strict", + "return_type": "bool", + "arguments": [ + [ + "godot_variant_type", + "p_from" + ], + [ + "godot_variant_type", + "p_to" + ] + ] + }, + { + "name": "godot_aabb_new", + "return_type": "void", + "arguments": [ + [ + "godot_aabb *", + "p_self" + ] + ] + }, + { + "name": "godot_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_array *", + "p_self" + ] + ] + }, + { + "name": "godot_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_array *", + "p_self" + ] + ] + }, + { + "name": "godot_array_operator_index", + "return_type": "godot_variant *", + "arguments": [ + [ + "godot_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_array_operator_index_const", + "return_type": "const godot_variant *", + "arguments": [ + [ + "const godot_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_basis_new", + "return_type": "void", + "arguments": [ + [ + "godot_basis *", + "p_self" + ] + ] + }, + { + "name": "godot_basis_operator_index", + "return_type": "godot_vector3 *", + "arguments": [ + [ + "godot_basis *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_basis_operator_index_const", + "return_type": "const godot_vector3 *", + "arguments": [ + [ + "const godot_basis *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_callable_new", + "return_type": "void", + "arguments": [ + [ + "godot_callable *", + "p_self" + ] + ] + }, + { + "name": "godot_callable_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_callable *", + "p_self" + ] + ] + }, + { + "name": "godot_color_new", + "return_type": "void", + "arguments": [ + [ + "godot_color *", + "p_self" + ] + ] + }, + { + "name": "godot_color_operator_index", + "return_type": "float *", + "arguments": [ + [ + "godot_color *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_color_operator_index_const", + "return_type": "const float *", + "arguments": [ + [ + "const godot_color *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_dictionary_new", + "return_type": "void", + "arguments": [ + [ + "godot_dictionary *", + "p_self" + ] + ] + }, + { + "name": "godot_dictionary_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_dictionary *", + "p_self" + ] + ] + }, + { + "name": "godot_dictionary_operator_index", + "return_type": "godot_variant *", + "arguments": [ + [ + "godot_dictionary *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ] + ] + }, + { + "name": "godot_dictionary_operator_index_const", + "return_type": "const godot_variant *", + "arguments": [ + [ + "const godot_dictionary *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ] + ] + }, + { + "name": "godot_node_path_new", + "return_type": "void", + "arguments": [ + [ + "godot_node_path *", + "p_self" + ] + ] + }, + { + "name": "godot_node_path_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_node_path *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_byte_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_byte_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_byte_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_byte_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_byte_array_operator_index", + "return_type": "uint8_t *", + "arguments": [ + [ + "godot_packed_byte_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_byte_array_operator_index_const", + "return_type": "const uint8_t *", + "arguments": [ + [ + "const godot_packed_byte_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_int32_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_int32_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_int32_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_int32_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_int32_array_operator_index", + "return_type": "int32_t *", + "arguments": [ + [ + "godot_packed_int32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_int32_array_operator_index_const", + "return_type": "const int32_t *", + "arguments": [ + [ + "const godot_packed_int32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_int64_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_int64_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_int64_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_int64_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_int64_array_operator_index", + "return_type": "int64_t *", + "arguments": [ + [ + "godot_packed_int64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_int64_array_operator_index_const", + "return_type": "const int64_t *", + "arguments": [ + [ + "const godot_packed_int64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_float32_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_float32_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_float32_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_float32_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_float32_array_operator_index", + "return_type": "float *", + "arguments": [ + [ + "godot_packed_float32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_float32_array_operator_index_const", + "return_type": "const float *", + "arguments": [ + [ + "const godot_packed_float32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_float64_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_float64_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_float64_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_float64_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_float64_array_operator_index", + "return_type": "double *", + "arguments": [ + [ + "godot_packed_float64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_float64_array_operator_index_const", + "return_type": "const double *", + "arguments": [ + [ + "const godot_packed_float64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_string_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_string_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_string_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_string_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_string_array_operator_index", + "return_type": "godot_string *", + "arguments": [ + [ + "godot_packed_string_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_string_array_operator_index_const", + "return_type": "const godot_string *", + "arguments": [ + [ + "const godot_packed_string_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector2_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector2_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector2_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector2_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector2_array_operator_index", + "return_type": "godot_vector2 *", + "arguments": [ + [ + "godot_packed_vector2_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector2_array_operator_index_const", + "return_type": "const godot_vector2 *", + "arguments": [ + [ + "const godot_packed_vector2_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector2i_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector2i_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector2i_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector2i_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector2i_array_operator_index", + "return_type": "godot_vector2i *", + "arguments": [ + [ + "godot_packed_vector2i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector2i_array_operator_index_const", + "return_type": "const godot_vector2i *", + "arguments": [ + [ + "const godot_packed_vector2i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector3_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector3_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector3_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector3_array_operator_index", + "return_type": "godot_vector3 *", + "arguments": [ + [ + "godot_packed_vector3_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3_array_operator_index_const", + "return_type": "const godot_vector3 *", + "arguments": [ + [ + "const godot_packed_vector3_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector3i_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector3i_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_operator_index", + "return_type": "godot_vector3i *", + "arguments": [ + [ + "godot_packed_vector3i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_operator_index_const", + "return_type": "const godot_vector3i *", + "arguments": [ + [ + "const godot_packed_vector3i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_color_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_color_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_color_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_color_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_color_array_operator_index", + "return_type": "godot_color *", + "arguments": [ + [ + "godot_packed_color_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_color_array_operator_index_const", + "return_type": "const godot_color *", + "arguments": [ + [ + "const godot_packed_color_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_plane_new", + "return_type": "void", + "arguments": [ + [ + "godot_plane *", + "p_self" + ] + ] + }, + { + "name": "godot_quat_new", + "return_type": "void", + "arguments": [ + [ + "godot_quat *", + "p_self" + ] + ] + }, + { + "name": "godot_quat_operator_index", + "return_type": "godot_real_t *", + "arguments": [ + [ + "godot_quat *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_quat_operator_index_const", + "return_type": "const godot_real_t *", + "arguments": [ + [ + "const godot_quat *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_rect2_new", + "return_type": "void", + "arguments": [ + [ + "godot_rect2 *", + "p_self" + ] + ] + }, + { + "name": "godot_rect2i_new", + "return_type": "void", + "arguments": [ + [ + "godot_rect2i *", + "p_self" + ] + ] + }, + { + "name": "godot_rid_new", + "return_type": "void", + "arguments": [ + [ + "godot_rid *", + "p_self" + ] + ] + }, + { + "name": "godot_signal_new", + "return_type": "void", + "arguments": [ + [ + "godot_signal *", + "p_self" + ] + ] + }, + { + "name": "godot_signal_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_signal *", + "p_self" + ] + ] + }, + { + "name": "godot_string_new", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ] + ] + }, + { + "name": "godot_string_new_copy", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const godot_string *", + "p_src" + ] + ] + }, + { + "name": "godot_string_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "p_self" + ] + ] + }, + { + "name": "godot_string_new_with_latin1_chars", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char *", + "p_contents" + ] + ] + }, + { + "name": "godot_string_new_with_utf8_chars", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char *", + "p_contents" + ] + ] + }, + { + "name": "godot_string_new_with_utf16_chars", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char16_t *", + "p_contents" + ] + ] + }, + { + "name": "godot_string_new_with_utf32_chars", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char32_t *", + "p_contents" + ] + ] + }, + { + "name": "godot_string_new_with_wide_chars", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const wchar_t *", + "p_contents" + ] + ] + }, + { + "name": "godot_string_new_with_latin1_chars_and_len", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char *", + "p_contents" + ], + [ + "const int", + "p_size" + ] + ] + }, + { + "name": "godot_string_new_with_utf8_chars_and_len", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char *", + "p_contents" + ], + [ + "const int", + "p_size" + ] + ] + }, + { + "name": "godot_string_new_with_utf16_chars_and_len", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char16_t *", + "p_contents" + ], + [ + "const int", + "p_size" + ] + ] + }, + { + "name": "godot_string_new_with_utf32_chars_and_len", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const char32_t *", + "p_contents" + ], + [ + "const int", + "p_size" + ] + ] + }, + { + "name": "godot_string_new_with_wide_chars_and_len", + "return_type": "void", + "arguments": [ + [ + "godot_string *", + "r_dest" + ], + [ + "const wchar_t *", + "p_contents" + ], + [ + "const int", + "p_size" + ] + ] + }, + { + "name": "godot_string_name_new", + "return_type": "void", + "arguments": [ + [ + "godot_string_name *", + "r_dest" + ] + ] + }, + { + "name": "godot_string_name_new_copy", + "return_type": "void", + "arguments": [ + [ + "godot_string_name *", + "r_dest" + ], + [ + "const godot_string_name *", + "p_src" + ] + ] + }, + { + "name": "godot_string_name_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_string_name *", + "p_self" + ] + ] + }, + { + "name": "godot_string_name_new_with_latin1_chars", + "return_type": "void", + "arguments": [ + [ + "godot_string_name *", + "r_dest" + ], + [ + "const char *", + "p_contents" + ] + ] + }, + { + "name": "godot_transform_new", + "return_type": "void", + "arguments": [ + [ + "godot_transform *", + "r_dest" + ] + ] + }, + { + "name": "godot_transform2d_new", + "return_type": "void", + "arguments": [ + [ + "godot_transform2d *", + "r_dest" + ] + ] + }, + { + "name": "godot_transform2d_operator_index", + "return_type": "godot_vector2 *", + "arguments": [ + [ + "godot_transform2d *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_transform2d_operator_index_const", + "return_type": "const godot_vector2 *", + "arguments": [ + [ + "const godot_transform2d *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector2_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector2 *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector2_operator_index", + "return_type": "godot_real_t *", + "arguments": [ + [ + "godot_vector2 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector2_operator_index_const", + "return_type": "const godot_real_t *", + "arguments": [ + [ + "const godot_vector2 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector2i_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector2i *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector2i_operator_index", + "return_type": "int32_t *", + "arguments": [ + [ + "godot_vector2i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector2i_operator_index_const", + "return_type": "const int32_t *", + "arguments": [ + [ + "const godot_vector2i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector3_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector3 *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector3_operator_index", + "return_type": "godot_real_t *", + "arguments": [ + [ + "godot_vector3 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector3_operator_index_const", + "return_type": "const godot_real_t *", + "arguments": [ + [ + "const godot_vector3 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector3i_new", + "return_type": "void", + "arguments": [ + [ + "godot_vector3i *", + "r_dest" + ] + ] + }, + { + "name": "godot_vector3i_operator_index", + "return_type": "int32_t *", + "arguments": [ + [ + "godot_vector3i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector3i_operator_index_const", + "return_type": "const int32_t *", + "arguments": [ + [ + "const godot_vector3i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + } + ] + }, + "extensions": [ + { + "name": "nativescript", + "type": "NATIVESCRIPT", + "version": { + "major": 4, + "minor": 0 + }, + "next": null, + "api": [ + { + "name": "godot_nativescript_register_class", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_base" + ], + [ + "godot_nativescript_instance_create_func", + "p_create_func" + ], + [ + "godot_nativescript_instance_destroy_func", + "p_destroy_func" + ] + ] + }, + { + "name": "godot_nativescript_register_tool_class", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_base" + ], + [ + "godot_nativescript_instance_create_func", + "p_create_func" + ], + [ + "godot_nativescript_instance_destroy_func", + "p_destroy_func" + ] + ] + }, + { + "name": "godot_nativescript_register_method", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_function_name" + ], + [ + "godot_nativescript_method_attributes", + "p_attr" + ], + [ + "godot_nativescript_instance_method", + "p_method" + ] + ] + }, + { + "name": "godot_nativescript_set_method_argument_information", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_function_name" + ], + [ + "int", + "p_num_args" + ], + [ + "const godot_nativescript_method_argument *", + "p_args" + ] + ] + }, + { + "name": "godot_nativescript_register_property", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_path" + ], + [ + "godot_nativescript_property_attributes *", + "p_attr" + ], + [ + "godot_nativescript_property_set_func", + "p_set_func" + ], + [ + "godot_nativescript_property_get_func", + "p_get_func" + ] + ] + }, + { + "name": "godot_nativescript_register_signal", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const godot_nativescript_signal *", + "p_signal" + ] + ] + }, + { + "name": "godot_nativescript_get_userdata", + "return_type": "void *", + "arguments": [ + [ + "godot_object *", + "p_instance" + ] + ] + }, + { + "name": "godot_nativescript_set_class_documentation", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "godot_string", + "p_documentation" + ] + ] + }, + { + "name": "godot_nativescript_set_method_documentation", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_function_name" + ], + [ + "godot_string", + "p_documentation" + ] + ] + }, + { + "name": "godot_nativescript_set_property_documentation", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_path" + ], + [ + "godot_string", + "p_documentation" + ] + ] + }, + { + "name": "godot_nativescript_set_signal_documentation", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const char *", + "p_signal_name" + ], + [ + "godot_string", + "p_documentation" + ] + ] + }, + { + "name": "godot_nativescript_set_global_type_tag", + "return_type": "void", + "arguments": [ + [ + "int", + "p_idx" + ], + [ + "const char *", + "p_name" + ], + [ + "const void *", + "p_type_tag" + ] + ] + }, + { + "name": "godot_nativescript_get_global_type_tag", + "return_type": "const void *", + "arguments": [ + [ + "int", + "p_idx" + ], + [ + "const char *", + "p_name" + ] + ] + }, + { + "name": "godot_nativescript_set_type_tag", + "return_type": "void", + "arguments": [ + [ + "void *", + "p_gdnative_handle" + ], + [ + "const char *", + "p_name" + ], + [ + "const void *", + "p_type_tag" + ] + ] + }, + { + "name": "godot_nativescript_get_type_tag", + "return_type": "const void *", + "arguments": [ + [ + "const godot_object *", + "p_object" + ] + ] + }, + { + "name": "godot_nativescript_register_instance_binding_data_functions", + "return_type": "int", + "arguments": [ + [ + "godot_nativescript_instance_binding_functions", + "p_binding_functions" + ] + ] + }, + { + "name": "godot_nativescript_unregister_instance_binding_data_functions", + "return_type": "void", + "arguments": [ + [ + "int", + "p_idx" + ] + ] + }, + { + "name": "godot_nativescript_get_instance_binding_data", + "return_type": "void *", + "arguments": [ + [ + "int", + "p_idx" + ], + [ + "godot_object *", + "p_object" + ] + ] + }, + { + "name": "godot_nativescript_profiling_add_data", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_signature" + ], + [ + "uint64_t", + "p_line" + ] + ] + } + ] + }, + { + "name": "pluginscript", + "type": "PLUGINSCRIPT", + "version": { + "major": 1, + "minor": 0 + }, + "next": null, + "api": [ + { + "name": "godot_pluginscript_register_language", + "return_type": "void", + "arguments": [ + [ + "const godot_pluginscript_language_desc *", + "language_desc" + ] + ] + } + ] + }, + { + "name": "android", + "type": "ANDROID", + "version": { + "major": 1, + "minor": 1 + }, + "next": null, + "api": [ + { + "name": "godot_android_get_env", + "return_type": "JNIEnv*", + "arguments": [] + }, + { + "name": "godot_android_get_activity", + "return_type": "jobject", + "arguments": [] + }, + { + "name": "godot_android_get_surface", + "return_type": "jobject", + "arguments": [] + }, + { + "name": "godot_android_is_activity_resumed", + "return_type": "bool", + "arguments": [] + } + ] + }, + { + "name": "xr", + "type": "XR", + "version": { + "major": 1, + "minor": 1 + }, + "next": null, + "api": [ + { + "name": "godot_xr_register_interface", + "return_type": "void", + "arguments": [ + [ + "const godot_xr_interface_gdnative *", + "p_interface" + ] + ] + }, + { + "name": "godot_xr_get_worldscale", + "return_type": "godot_float", + "arguments": [] + }, + { + "name": "godot_xr_get_reference_frame", + "return_type": "godot_transform", + "arguments": [] + }, + { + "name": "godot_xr_blit", + "return_type": "void", + "arguments": [ + [ + "godot_int", + "p_eye" + ], + [ + "godot_rid *", + "p_render_target" + ], + [ + "godot_rect2 *", + "p_screen_rect" + ] + ] + }, + { + "name": "godot_xr_get_texid", + "return_type": "godot_int", + "arguments": [ + [ + "godot_rid *", + "p_render_target" + ] + ] + }, + { + "name": "godot_xr_add_controller", + "return_type": "godot_int", + "arguments": [ + [ + "char *", + "p_device_name" + ], + [ + "godot_int", + "p_hand" + ], + [ + "godot_bool", + "p_tracks_orientation" + ], + [ + "godot_bool", + "p_tracks_position" + ] + ] + }, + { + "name": "godot_xr_remove_controller", + "return_type": "void", + "arguments": [ + [ + "godot_int", + "p_controller_id" + ] + ] + }, + { + "name": "godot_xr_set_controller_transform", + "return_type": "void", + "arguments": [ + [ + "godot_int", + "p_controller_id" + ], + [ + "godot_transform *", + "p_transform" + ], + [ + "godot_bool", + "p_tracks_orientation" + ], + [ + "godot_bool", + "p_tracks_position" + ] + ] + }, + { + "name": "godot_xr_set_controller_button", + "return_type": "void", + "arguments": [ + [ + "godot_int", + "p_controller_id" + ], + [ + "godot_int", + "p_button" + ], + [ + "godot_bool", + "p_is_pressed" + ] + ] + }, + { + "name": "godot_xr_set_controller_axis", + "return_type": "void", + "arguments": [ + [ + "godot_int", + "p_controller_id" + ], + [ + "godot_int", + "p_exis" + ], + [ + "godot_float", + "p_value" + ], + [ + "godot_bool", + "p_can_be_negative" + ] + ] + }, + { + "name": "godot_xr_get_controller_rumble", + "return_type": "godot_float", + "arguments": [ + [ + "godot_int", + "p_controller_id" + ] + ] + } + ] + }, + { + "name": "videodecoder", + "type": "VIDEODECODER", + "version": { + "major": 0, + "minor": 1 + }, + "next": null, + "api": [ + { + "name": "godot_videodecoder_file_read", + "return_type": "godot_int", + "arguments": [ + [ + "void *", + "file_ptr" + ], + [ + "uint8_t *", + "buf" + ], + [ + "int", + "buf_size" + ] + ] + }, + { + "name": "godot_videodecoder_file_seek", + "return_type": "int64_t", + "arguments": [ + [ + "void *", + "file_ptr" + ], + [ + "int64_t", + "pos" + ], + [ + "int", + "whence" + ] + ] + }, + { + "name": "godot_videodecoder_register_decoder", + "return_type": "void", + "arguments": [ + [ + "const godot_videodecoder_interface_gdnative *", + "p_interface" + ] + ] + } + ] + }, + { + "name": "net", + "type": "NET", + "version": { + "major": 4, + "minor": 0 + }, + "next": null, + "api": [ + { + "name": "godot_net_bind_stream_peer", + "return_type": "void", + "arguments": [ + [ + "godot_object *", + "p_obj" + ], + [ + "const godot_net_stream_peer *", + "p_interface" + ] + ] + }, + { + "name": "godot_net_bind_packet_peer", + "return_type": "void", + "arguments": [ + [ + "godot_object *", + "p_obj" + ], + [ + "const godot_net_packet_peer *", + "p_interface" + ] + ] + }, + { + "name": "godot_net_bind_multiplayer_peer", + "return_type": "void", + "arguments": [ + [ + "godot_object *", + "p_obj" + ], + [ + "const godot_net_multiplayer_peer *", + "p_interface" + ] + ] + }, + { + "name": "godot_net_set_webrtc_library", + "return_type": "godot_error", + "arguments": [ + [ + "const godot_net_webrtc_library *", + "p_library" + ] + ] + }, + { + "name": "godot_net_bind_webrtc_peer_connection", + "return_type": "void", + "arguments": [ + [ + "godot_object *", + "p_obj" + ], + [ + "const godot_net_webrtc_peer_connection *", + "p_interface" + ] + ] + }, + { + "name": "godot_net_bind_webrtc_data_channel", + "return_type": "void", + "arguments": [ + [ + "godot_object *", + "p_obj" + ], + [ + "const godot_net_webrtc_data_channel *", + "p_interface" + ] + ] + } + ] + }, + { + "name": "text", + "type": "TEXT", + "version": { + "major": 1, + "minor": 0 + }, + "next": null, + "api": [ + { + "name": "godot_text_register_interface", + "return_type": "void", + "arguments": [ + [ + "const godot_text_interface_gdnative *", + "p_interface" + ], + [ + "const godot_string *", + "p_name" + ], + [ + "uint32_t", + "p_features" + ] + ] + }, + { + "name": "godot_glyph_new", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "r_dest" + ] + ] + }, + { + "name": "godot_glyph_get_range", + "return_type": "godot_vector2i", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_range", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "const godot_vector2i *", + "p_range" + ] + ] + }, + { + "name": "godot_glyph_get_count", + "return_type": "godot_int", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_count", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_int", + "p_count" + ] + ] + }, + { + "name": "godot_glyph_get_repeat", + "return_type": "godot_int", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_repeat", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_int", + "p_repeat" + ] + ] + }, + { + "name": "godot_glyph_get_flags", + "return_type": "godot_int", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_flags", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_int", + "p_flags" + ] + ] + }, + { + "name": "godot_glyph_get_offset", + "return_type": "godot_vector2", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_offset", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "const godot_vector2 *", + "p_offset" + ] + ] + }, + { + "name": "godot_glyph_get_advance", + "return_type": "godot_float", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_advance", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_float", + "p_advance" + ] + ] + }, + { + "name": "godot_glyph_get_font", + "return_type": "godot_rid", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_font", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_rid *", + "p_font" + ] + ] + }, + { + "name": "godot_glyph_get_font_size", + "return_type": "godot_int", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_font_size", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_int", + "p_size" + ] + ] + }, + { + "name": "godot_glyph_get_index", + "return_type": "godot_int", + "arguments": [ + [ + "const godot_glyph *", + "p_self" + ] + ] + }, + { + "name": "godot_glyph_set_index", + "return_type": "void", + "arguments": [ + [ + "godot_glyph *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_glyph_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "r_dest" + ] + ] + }, + { + "name": "godot_packed_glyph_array_new_copy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "r_dest" + ], + [ + "const godot_packed_glyph_array *", + "p_src" + ] + ] + }, + { + "name": "godot_packed_glyph_array_is_empty", + "return_type": "godot_bool", + "arguments": [ + [ + "const godot_packed_glyph_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_glyph_array_append", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_glyph *", + "p_data" + ] + ] + }, + { + "name": "godot_packed_glyph_array_append_array", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_packed_glyph_array *", + "p_array" + ] + ] + }, + { + "name": "godot_packed_glyph_array_insert", + "return_type": "godot_error", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_int", + "p_idx" + ], + [ + "const godot_glyph *", + "p_data" + ] + ] + }, + { + "name": "godot_packed_glyph_array_has", + "return_type": "godot_bool", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_glyph *", + "p_value" + ] + ] + }, + { + "name": "godot_packed_glyph_array_sort", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_glyph_array_invert", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_glyph_array_push_back", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_glyph *", + "p_data" + ] + ] + }, + { + "name": "godot_packed_glyph_array_remove", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_int", + "p_idx" + ] + ] + }, + { + "name": "godot_packed_glyph_array_resize", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_int", + "p_size" + ] + ] + }, + { + "name": "godot_packed_glyph_array_ptr", + "return_type": "const godot_glyph *", + "arguments": [ + [ + "const godot_packed_glyph_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_glyph_array_ptrw", + "return_type": "godot_glyph *", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_glyph_array_set", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_int", + "p_idx" + ], + [ + "const godot_glyph *", + "p_data" + ] + ] + }, + { + "name": "godot_packed_glyph_array_get", + "return_type": "godot_glyph", + "arguments": [ + [ + "const godot_packed_glyph_array *", + "p_self" + ], + [ + "const godot_int", + "p_idx" + ] + ] + }, + { + "name": "godot_packed_glyph_array_size", + "return_type": "godot_int", + "arguments": [ + [ + "const godot_packed_glyph_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_glyph_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_glyph_array *", + "p_self" + ] + ] + } + ] + } + ] } diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp index d3cca5b1be..dfb26c13e3 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.cpp +++ b/modules/gdnative/gdnative_library_editor_plugin.cpp @@ -257,7 +257,7 @@ void GDNativeLibraryEditor::_translate_to_config_file() { } } - library->_change_notify(); + library->notify_property_list_changed(); } } diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h index 184db3d817..61afb1aaaa 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.h +++ b/modules/gdnative/gdnative_library_editor_plugin.h @@ -95,9 +95,9 @@ public: class GDNativeLibraryEditorPlugin : public EditorPlugin { GDCLASS(GDNativeLibraryEditorPlugin, EditorPlugin); - GDNativeLibraryEditor *library_editor; - EditorNode *editor; - Button *button; + GDNativeLibraryEditor *library_editor = nullptr; + EditorNode *editor = nullptr; + Button *button = nullptr; public: virtual String get_name() const override { return "GDNativeLibrary"; } diff --git a/modules/gdnative/include/gdnative/aabb.h b/modules/gdnative/include/gdnative/aabb.h index daf5ebfdd8..be0235221f 100644 --- a/modules/gdnative/include/gdnative/aabb.h +++ b/modules/gdnative/include/gdnative/aabb.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_AABB_SIZE 24 +#define GODOT_AABB_SIZE (sizeof(godot_real_t) * 6) #ifndef GODOT_CORE_API_GODOT_AABB_TYPE_DEFINED #define GODOT_CORE_API_GODOT_AABB_TYPE_DEFINED @@ -46,72 +46,9 @@ typedef struct { } godot_aabb; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/plane.h> -#include <gdnative/vector3.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size); - -godot_vector3 GDAPI godot_aabb_get_position(const godot_aabb *p_self); -void GDAPI godot_aabb_set_position(const godot_aabb *p_self, const godot_vector3 *p_v); - -godot_vector3 GDAPI godot_aabb_get_size(const godot_aabb *p_self); -void GDAPI godot_aabb_set_size(const godot_aabb *p_self, const godot_vector3 *p_v); - -godot_string GDAPI godot_aabb_as_string(const godot_aabb *p_self); - -godot_aabb GDAPI godot_aabb_abs(const godot_aabb *p_self); - -godot_real GDAPI godot_aabb_get_area(const godot_aabb *p_self); - -godot_bool GDAPI godot_aabb_has_no_area(const godot_aabb *p_self); - -godot_bool GDAPI godot_aabb_has_no_surface(const godot_aabb *p_self); - -godot_bool GDAPI godot_aabb_intersects(const godot_aabb *p_self, const godot_aabb *p_with); - -godot_bool GDAPI godot_aabb_encloses(const godot_aabb *p_self, const godot_aabb *p_with); - -godot_aabb GDAPI godot_aabb_merge(const godot_aabb *p_self, const godot_aabb *p_with); - -godot_aabb GDAPI godot_aabb_intersection(const godot_aabb *p_self, const godot_aabb *p_with); - -godot_bool GDAPI godot_aabb_intersects_plane(const godot_aabb *p_self, const godot_plane *p_plane); - -godot_bool GDAPI godot_aabb_intersects_segment(const godot_aabb *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to); - -godot_bool GDAPI godot_aabb_has_point(const godot_aabb *p_self, const godot_vector3 *p_point); - -godot_vector3 GDAPI godot_aabb_get_support(const godot_aabb *p_self, const godot_vector3 *p_dir); - -godot_vector3 GDAPI godot_aabb_get_longest_axis(const godot_aabb *p_self); - -godot_int GDAPI godot_aabb_get_longest_axis_index(const godot_aabb *p_self); - -godot_real GDAPI godot_aabb_get_longest_axis_size(const godot_aabb *p_self); - -godot_vector3 GDAPI godot_aabb_get_shortest_axis(const godot_aabb *p_self); - -godot_int GDAPI godot_aabb_get_shortest_axis_index(const godot_aabb *p_self); - -godot_real GDAPI godot_aabb_get_shortest_axis_size(const godot_aabb *p_self); - -godot_aabb GDAPI godot_aabb_expand(const godot_aabb *p_self, const godot_vector3 *p_to_point); - -godot_aabb GDAPI godot_aabb_grow(const godot_aabb *p_self, const godot_real p_by); - -godot_vector3 GDAPI godot_aabb_get_endpoint(const godot_aabb *p_self, const godot_int p_idx); -godot_bool GDAPI godot_aabb_operator_equal(const godot_aabb *p_self, const godot_aabb *p_b); +void GDAPI godot_aabb_new(godot_aabb *p_self); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h index 9cc5bdfad5..7603edaa73 100644 --- a/modules/gdnative/include/gdnative/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -46,102 +46,13 @@ typedef struct { } godot_array; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/packed_arrays.h> -#include <gdnative/variant.h> - #include <gdnative/gdnative.h> +#include <gdnative/variant_struct.h> -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_array_new(godot_array *r_dest); -void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src); -void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_packed_color_array *p_pca); -void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a); -void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a); -void GDAPI godot_array_new_packed_vector2i_array(godot_array *r_dest, const godot_packed_vector2i_array *p_pv2a); -void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa); -void GDAPI godot_array_new_packed_float32_array(godot_array *r_dest, const godot_packed_float32_array *p_pra); -void GDAPI godot_array_new_packed_float64_array(godot_array *r_dest, const godot_packed_float64_array *p_pra); -void GDAPI godot_array_new_packed_int32_array(godot_array *r_dest, const godot_packed_int32_array *p_pia); -void GDAPI godot_array_new_packed_int64_array(godot_array *r_dest, const godot_packed_int64_array *p_pia); -void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba); - -void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value); - -godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx); - -godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx); - -const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx); - -void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value); - -void GDAPI godot_array_clear(godot_array *p_self); - -godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value); - -godot_bool GDAPI godot_array_is_empty(const godot_array *p_self); - -void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value); - -godot_variant GDAPI godot_array_front(const godot_array *p_self); - -godot_variant GDAPI godot_array_back(const godot_array *p_self); - -godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from); - -godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what); - -godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value); - -godot_int GDAPI godot_array_hash(const godot_array *p_self); - -void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value); - -void GDAPI godot_array_invert(godot_array *p_self); - -godot_variant GDAPI godot_array_pop_back(godot_array *p_self); - -godot_variant GDAPI godot_array_pop_front(godot_array *p_self); - -void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value); - -void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value); - -void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx); - -void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size); - -godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from); - -godot_int GDAPI godot_array_size(const godot_array *p_self); - -void GDAPI godot_array_sort(godot_array *p_self); - -void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func); - -godot_int GDAPI godot_array_bsearch(godot_array *p_self, const godot_variant *p_value, const godot_bool p_before); - -godot_int GDAPI godot_array_bsearch_custom(godot_array *p_self, const godot_variant *p_value, godot_object *p_obj, const godot_string *p_func, const godot_bool p_before); - +void GDAPI godot_array_new(godot_array *p_self); void GDAPI godot_array_destroy(godot_array *p_self); - -godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep); - -godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep); - -godot_variant GDAPI godot_array_max(const godot_array *p_self); - -godot_variant GDAPI godot_array_min(const godot_array *p_self); - -void GDAPI godot_array_shuffle(godot_array *p_self); +godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, godot_int p_index); +const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h index c6dab4c3c1..af8d7cbdd3 100644 --- a/modules/gdnative/include/gdnative/basis.h +++ b/modules/gdnative/include/gdnative/basis.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_BASIS_SIZE 36 +#define GODOT_BASIS_SIZE (sizeof(godot_real_t) * 9) #ifndef GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED #define GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED @@ -46,88 +46,11 @@ typedef struct { } godot_basis; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/quat.h> -#include <gdnative/vector3.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis); -void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi); -void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler); -void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler); - -godot_string GDAPI godot_basis_as_string(const godot_basis *p_self); - -godot_basis GDAPI godot_basis_inverse(const godot_basis *p_self); - -godot_basis GDAPI godot_basis_transposed(const godot_basis *p_self); - -godot_basis GDAPI godot_basis_orthonormalized(const godot_basis *p_self); - -godot_real GDAPI godot_basis_determinant(const godot_basis *p_self); - -godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_phi); - -godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale); - -godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self); - -godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self); - -godot_quat GDAPI godot_basis_get_quat(const godot_basis *p_self); - -void GDAPI godot_basis_set_quat(godot_basis *p_self, const godot_quat *p_quat); - -void GDAPI godot_basis_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale); - -void GDAPI godot_basis_set_euler_scale(godot_basis *p_self, const godot_vector3 *p_euler, const godot_vector3 *p_scale); - -void GDAPI godot_basis_set_quat_scale(godot_basis *p_self, const godot_quat *p_quat, const godot_vector3 *p_scale); - -godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with); - -godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with); - -godot_real GDAPI godot_basis_tdotz(const godot_basis *p_self, const godot_vector3 *p_with); - -godot_vector3 GDAPI godot_basis_xform(const godot_basis *p_self, const godot_vector3 *p_v); - -godot_vector3 GDAPI godot_basis_xform_inv(const godot_basis *p_self, const godot_vector3 *p_v); - -godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self); - -void GDAPI godot_basis_new(godot_basis *r_dest); - -// p_elements is a pointer to an array of 3 (!!) vector3 -void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements); - -godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis); - -void GDAPI godot_basis_set_axis(godot_basis *p_self, const godot_int p_axis, const godot_vector3 *p_value); - -godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_self, const godot_int p_row); - -void GDAPI godot_basis_set_row(godot_basis *p_self, const godot_int p_row, const godot_vector3 *p_value); - -godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const godot_basis *p_b); - -godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b); - -godot_basis GDAPI godot_basis_operator_subtract(const godot_basis *p_self, const godot_basis *p_b); - -godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b); - -godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b); -godot_basis GDAPI godot_basis_slerp(const godot_basis *p_self, const godot_basis *p_b, const godot_real p_t); +void GDAPI godot_basis_new(godot_basis *p_self); +godot_vector3 GDAPI *godot_basis_operator_index(godot_basis *p_self, godot_int p_index); +const godot_vector3 GDAPI *godot_basis_operator_index_const(const godot_basis *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/callable.h b/modules/gdnative/include/gdnative/callable.h index b3daaa7d0c..6f359ada5e 100644 --- a/modules/gdnative/include/gdnative/callable.h +++ b/modules/gdnative/include/gdnative/callable.h @@ -46,79 +46,11 @@ typedef struct { } godot_callable; #endif -#define GODOT_SIGNAL_SIZE (16) - -#ifndef GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_SIGNAL_SIZE]; -} godot_signal; -#endif - -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/string_name.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// Callable - -void GDAPI godot_callable_new_with_object(godot_callable *r_dest, const godot_object *p_object, const godot_string_name *p_method); -void GDAPI godot_callable_new_with_object_id(godot_callable *r_dest, uint64_t p_objectid, const godot_string_name *p_method); -void GDAPI godot_callable_new_copy(godot_callable *r_dest, const godot_callable *p_src); +void GDAPI godot_callable_new(godot_callable *p_self); void GDAPI godot_callable_destroy(godot_callable *p_self); -godot_int GDAPI godot_callable_call(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount, godot_variant *r_return_value); -void GDAPI godot_callable_call_deferred(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount); - -godot_bool GDAPI godot_callable_is_null(const godot_callable *p_self); -godot_bool GDAPI godot_callable_is_custom(const godot_callable *p_self); -godot_bool GDAPI godot_callable_is_standard(const godot_callable *p_self); - -godot_object GDAPI *godot_callable_get_object(const godot_callable *p_self); -uint64_t GDAPI godot_callable_get_object_id(const godot_callable *p_self); -godot_string_name GDAPI godot_callable_get_method(const godot_callable *p_self); - -uint32_t GDAPI godot_callable_hash(const godot_callable *p_self); - -godot_string GDAPI godot_callable_as_string(const godot_callable *p_self); - -godot_bool GDAPI godot_callable_operator_equal(const godot_callable *p_self, const godot_callable *p_other); -godot_bool GDAPI godot_callable_operator_less(const godot_callable *p_self, const godot_callable *p_other); - -// Signal - -void GDAPI godot_signal_new_with_object(godot_signal *r_dest, const godot_object *p_object, const godot_string_name *p_name); -void GDAPI godot_signal_new_with_object_id(godot_signal *r_dest, uint64_t p_objectid, const godot_string_name *p_name); -void GDAPI godot_signal_new_copy(godot_signal *r_dest, const godot_signal *p_src); - -void GDAPI godot_signal_destroy(godot_signal *p_self); - -godot_int GDAPI godot_signal_emit(const godot_signal *p_self, const godot_variant **p_arguments, godot_int p_argcount); - -godot_int GDAPI godot_signal_connect(godot_signal *p_self, const godot_callable *p_callable, const godot_array *p_binds, uint32_t p_flags); -void GDAPI godot_signal_disconnect(godot_signal *p_self, const godot_callable *p_callable); - -godot_bool GDAPI godot_signal_is_null(const godot_signal *p_self); -godot_bool GDAPI godot_signal_is_connected(const godot_signal *p_self, const godot_callable *p_callable); - -godot_array GDAPI godot_signal_get_connections(const godot_signal *p_self); - -godot_object GDAPI *godot_signal_get_object(const godot_signal *p_self); -uint64_t GDAPI godot_signal_get_object_id(const godot_signal *p_self); -godot_string_name GDAPI godot_signal_get_name(const godot_signal *p_self); - -godot_string GDAPI godot_signal_as_string(const godot_signal *p_self); - -godot_bool GDAPI godot_signal_operator_equal(const godot_signal *p_self, const godot_signal *p_other); -godot_bool GDAPI godot_signal_operator_less(const godot_signal *p_self, const godot_signal *p_other); - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h index c6ef921ad9..17a021e6ea 100644 --- a/modules/gdnative/include/gdnative/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -35,9 +35,10 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_COLOR_SIZE 16 +// Colors should always use 32-bit floats, so don't use real_t here. +#define GODOT_COLOR_SIZE (sizeof(float) * 4) #ifndef GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED #define GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED @@ -46,68 +47,11 @@ typedef struct { } godot_color; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/string.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a); -void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b); - -godot_real godot_color_get_r(const godot_color *p_self); -void godot_color_set_r(godot_color *p_self, const godot_real r); - -godot_real godot_color_get_g(const godot_color *p_self); -void godot_color_set_g(godot_color *p_self, const godot_real g); - -godot_real godot_color_get_b(const godot_color *p_self); -void godot_color_set_b(godot_color *p_self, const godot_real b); - -godot_real godot_color_get_a(const godot_color *p_self); -void godot_color_set_a(godot_color *p_self, const godot_real a); - -godot_real godot_color_get_h(const godot_color *p_self); -godot_real godot_color_get_s(const godot_color *p_self); -godot_real godot_color_get_v(const godot_color *p_self); - -godot_string GDAPI godot_color_as_string(const godot_color *p_self); - -godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self); - -godot_int GDAPI godot_color_to_abgr32(const godot_color *p_self); - -godot_int GDAPI godot_color_to_abgr64(const godot_color *p_self); - -godot_int GDAPI godot_color_to_argb64(const godot_color *p_self); - -godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self); - -godot_int GDAPI godot_color_to_argb32(const godot_color *p_self); - -godot_color GDAPI godot_color_inverted(const godot_color *p_self); - -godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t); - -godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over); - -godot_color GDAPI godot_color_darkened(const godot_color *p_self, const godot_real p_amount); - -godot_color GDAPI godot_color_from_hsv(const godot_color *p_self, const godot_real p_h, const godot_real p_s, const godot_real p_v, const godot_real p_a); - -godot_color GDAPI godot_color_lightened(const godot_color *p_self, const godot_real p_amount); - -godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha); - -godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b); -godot_bool GDAPI godot_color_operator_less(const godot_color *p_self, const godot_color *p_b); +void GDAPI godot_color_new(godot_color *p_self); +float GDAPI *godot_color_operator_index(godot_color *p_self, godot_int p_index); +const float GDAPI *godot_color_operator_index_const(const godot_color *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index 3f664567d8..d2afbc4c94 100644 --- a/modules/gdnative/include/gdnative/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -46,62 +46,14 @@ typedef struct { } godot_dictionary; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/array.h> #include <gdnative/gdnative.h> -#include <gdnative/variant.h> - -#ifdef __cplusplus -extern "C" { -#endif +#include <gdnative/variant_struct.h> -void GDAPI godot_dictionary_new(godot_dictionary *r_dest); -void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src); +void GDAPI godot_dictionary_new(godot_dictionary *p_self); void GDAPI godot_dictionary_destroy(godot_dictionary *p_self); - -godot_dictionary GDAPI godot_dictionary_duplicate(const godot_dictionary *p_self, const godot_bool p_deep); - -godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self); - -godot_bool GDAPI godot_dictionary_is_empty(const godot_dictionary *p_self); - -void GDAPI godot_dictionary_clear(godot_dictionary *p_self); - -godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_self, const godot_variant *p_key); - -godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_self, const godot_array *p_keys); - -void GDAPI godot_dictionary_erase(godot_dictionary *p_self, const godot_variant *p_key); - -godot_int GDAPI godot_dictionary_hash(const godot_dictionary *p_self); - -godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_self); - -godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_self); - -godot_variant GDAPI godot_dictionary_get(const godot_dictionary *p_self, const godot_variant *p_key); -void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_value); - godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key); - const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key); -godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key); - -godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b); - -godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self); - -// GDNative core 1.1 - -godot_bool GDAPI godot_dictionary_erase_with_return(godot_dictionary *p_self, const godot_variant *p_key); - -godot_variant GDAPI godot_dictionary_get_with_default(const godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_default); - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index cc8bf52fe4..a4ed7ebb8c 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -62,8 +62,6 @@ extern "C" { #include <stdbool.h> #include <stdint.h> -#define GODOT_API_VERSION 1 - ////// Error typedef enum { @@ -118,21 +116,6 @@ typedef enum { GODOT_ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames } godot_error; -////// bool - -typedef bool godot_bool; - -#define GODOT_TRUE 1 -#define GODOT_FALSE 0 - -/////// int - -typedef int64_t godot_int; - -/////// real - -typedef float godot_real; - /////// Object (forward declared) typedef void godot_object; @@ -215,7 +198,7 @@ void GDAPI godot_object_destroy(godot_object *p_o); ////// Singleton API -godot_object GDAPI *godot_global_get_singleton(char *p_name); // result shouldn't be freed +godot_object GDAPI *godot_global_get_singleton(char *p_name); // Result shouldn't be freed. ////// MethodBind API @@ -281,12 +264,10 @@ void GDAPI *godot_alloc(int p_bytes); void GDAPI *godot_realloc(void *p_ptr, int p_bytes); void GDAPI godot_free(void *p_ptr); -//print using Godot's error handler list +// Helper print functions. void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line); void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line); -void GDAPI godot_print(const godot_string *p_message); - -// GDNATIVE CORE 1.0.2? +void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line); //tags used for safe dynamic casting void GDAPI *godot_get_class_tag(const godot_string_name *p_class); @@ -301,4 +282,4 @@ uint64_t GDAPI godot_object_get_instance_id(const godot_object *p_object); } #endif -#endif // GODOT_C_H +#endif // GODOT_GDNATIVE_H diff --git a/modules/gamecenter/game_center_module.cpp b/modules/gdnative/include/gdnative/math_defs.h index 8f6ef291c0..b5cf389506 100644 --- a/modules/gamecenter/game_center_module.cpp +++ b/modules/gdnative/include/gdnative/math_defs.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* game_center_module.cpp */ +/* math_defs.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,39 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "game_center_module.h" +#ifndef GODOT_GDNATIVE_MATH_DEFS_H +#define GODOT_GDNATIVE_MATH_DEFS_H -#include "core/config/engine.h" +#ifdef __cplusplus +extern "C" { +#endif -#include "game_center.h" +#include <stdbool.h> +#include <stdint.h> -GameCenter *game_center; +////// bool -void register_gamecenter_types() { - game_center = memnew(GameCenter); - Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); -} +typedef bool godot_bool; + +#define GODOT_TRUE 1 +#define GODOT_FALSE 0 + +/////// int + +typedef int64_t godot_int; -void unregister_gamecenter_types() { - if (game_center) { - memdelete(game_center); - } +/////// float + +typedef double godot_float; + +#ifdef REAL_T_IS_DOUBLE +typedef double godot_real_t; +#else +typedef float godot_real_t; +#endif + +#ifdef __cplusplus } +#endif + +#endif // GODOT_C_H diff --git a/modules/gdnative/include/gdnative/node_path.h b/modules/gdnative/include/gdnative/node_path.h index 052e4469a2..3c31b9a98f 100644 --- a/modules/gdnative/include/gdnative/node_path.h +++ b/modules/gdnative/include/gdnative/node_path.h @@ -46,42 +46,11 @@ typedef struct { } godot_node_path; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/string.h> -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from); -void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src); +void GDAPI godot_node_path_new(godot_node_path *p_self); void GDAPI godot_node_path_destroy(godot_node_path *p_self); -godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_self); - -godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_self); - -godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_self); - -godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_self, const godot_int p_idx); - -godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_self); - -godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_self, const godot_int p_idx); - -godot_string GDAPI godot_node_path_get_concatenated_subnames(const godot_node_path *p_self); - -godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self); - -godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b); - -godot_node_path godot_node_path_get_as_property_path(const godot_node_path *p_self); - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/include/gdnative/packed_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h index f5b95eadd3..621ed60cdf 100644 --- a/modules/gdnative/include/gdnative/packed_arrays.h +++ b/modules/gdnative/include/gdnative/packed_arrays.h @@ -136,6 +136,17 @@ typedef struct { } godot_packed_vector3_array; #endif +/////// PackedVector3iArray + +#define GODOT_PACKED_VECTOR3I_ARRAY_SIZE (2 * sizeof(void *)) + +#ifndef GODOT_CORE_API_GODOT_PACKED_VECTOR3I_ARRAY_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_PACKED_VECTOR3I_ARRAY_TYPE_DEFINED +typedef struct { + uint8_t _dont_touch_that[GODOT_PACKED_VECTOR3I_ARRAY_SIZE]; +} godot_packed_vector3i_array; +#endif + /////// PackedColorArray #define GODOT_PACKED_COLOR_ARRAY_SIZE (2 * sizeof(void *)) @@ -147,384 +158,87 @@ typedef struct { } godot_packed_color_array; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/array.h> -#include <gdnative/color.h> -#include <gdnative/vector2.h> -#include <gdnative/vector3.h> - #include <gdnative/gdnative.h> -#ifdef __cplusplus -extern "C" { -#endif - -// byte - -void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *r_dest); -void GDAPI godot_packed_byte_array_new_copy(godot_packed_byte_array *r_dest, const godot_packed_byte_array *p_src); -void GDAPI godot_packed_byte_array_new_with_array(godot_packed_byte_array *r_dest, const godot_array *p_a); - -const uint8_t GDAPI *godot_packed_byte_array_ptr(const godot_packed_byte_array *p_self); -uint8_t GDAPI *godot_packed_byte_array_ptrw(godot_packed_byte_array *p_self); - -void GDAPI godot_packed_byte_array_append(godot_packed_byte_array *p_self, const uint8_t p_data); - -void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, const godot_packed_byte_array *p_array); - -godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data); - -godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value); - -void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self); - -void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self); - -void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data); - -void GDAPI godot_packed_byte_array_remove(godot_packed_byte_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_byte_array_resize(godot_packed_byte_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_byte_array_set(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data); -uint8_t GDAPI godot_packed_byte_array_get(const godot_packed_byte_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_byte_array_size(const godot_packed_byte_array *p_self); - -godot_bool GDAPI godot_packed_byte_array_is_empty(const godot_packed_byte_array *p_self); +// Byte. +void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *p_self); void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self); +uint8_t GDAPI *godot_packed_byte_array_operator_index(godot_packed_byte_array *p_self, godot_int p_index); +const uint8_t GDAPI *godot_packed_byte_array_operator_index_const(const godot_packed_byte_array *p_self, godot_int p_index); -// int32 - -void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *r_dest); -void GDAPI godot_packed_int32_array_new_copy(godot_packed_int32_array *r_dest, const godot_packed_int32_array *p_src); -void GDAPI godot_packed_int32_array_new_with_array(godot_packed_int32_array *r_dest, const godot_array *p_a); - -const int32_t GDAPI *godot_packed_int32_array_ptr(const godot_packed_int32_array *p_self); -int32_t GDAPI *godot_packed_int32_array_ptrw(godot_packed_int32_array *p_self); - -void GDAPI godot_packed_int32_array_append(godot_packed_int32_array *p_self, const int32_t p_data); - -void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_self, const godot_packed_int32_array *p_array); - -godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data); - -godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value); - -void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self); - -void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self); - -void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data); - -void GDAPI godot_packed_int32_array_remove(godot_packed_int32_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_int32_array_resize(godot_packed_int32_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_int32_array_set(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data); -int32_t GDAPI godot_packed_int32_array_get(const godot_packed_int32_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_int32_array_size(const godot_packed_int32_array *p_self); - -godot_bool GDAPI godot_packed_int32_array_is_empty(const godot_packed_int32_array *p_self); +// Int32. +void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *p_self); void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self); +int32_t GDAPI *godot_packed_int32_array_operator_index(godot_packed_int32_array *p_self, godot_int p_index); +const int32_t GDAPI *godot_packed_int32_array_operator_index_const(const godot_packed_int32_array *p_self, godot_int p_index); -// int64 - -void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *r_dest); -void GDAPI godot_packed_int64_array_new_copy(godot_packed_int64_array *r_dest, const godot_packed_int64_array *p_src); -void GDAPI godot_packed_int64_array_new_with_array(godot_packed_int64_array *r_dest, const godot_array *p_a); - -const int64_t GDAPI *godot_packed_int64_array_ptr(const godot_packed_int64_array *p_self); -int64_t GDAPI *godot_packed_int64_array_ptrw(godot_packed_int64_array *p_self); - -void GDAPI godot_packed_int64_array_append(godot_packed_int64_array *p_self, const int64_t p_data); - -void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_self, const godot_packed_int64_array *p_array); - -godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data); - -godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value); - -void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self); - -void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self); - -void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data); - -void GDAPI godot_packed_int64_array_remove(godot_packed_int64_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_int64_array_resize(godot_packed_int64_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_int64_array_set(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data); -int64_t GDAPI godot_packed_int64_array_get(const godot_packed_int64_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_int64_array_size(const godot_packed_int64_array *p_self); - -godot_bool GDAPI godot_packed_int64_array_is_empty(const godot_packed_int64_array *p_self); +// Int64. +void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *p_self); void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self); +int64_t GDAPI *godot_packed_int64_array_operator_index(godot_packed_int64_array *p_self, godot_int p_index); +const int64_t GDAPI *godot_packed_int64_array_operator_index_const(const godot_packed_int64_array *p_self, godot_int p_index); -// float32 - -void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *r_dest); -void GDAPI godot_packed_float32_array_new_copy(godot_packed_float32_array *r_dest, const godot_packed_float32_array *p_src); -void GDAPI godot_packed_float32_array_new_with_array(godot_packed_float32_array *r_dest, const godot_array *p_a); - -const float GDAPI *godot_packed_float32_array_ptr(const godot_packed_float32_array *p_self); -float GDAPI *godot_packed_float32_array_ptrw(godot_packed_float32_array *p_self); - -void GDAPI godot_packed_float32_array_append(godot_packed_float32_array *p_self, const float p_data); - -void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p_self, const godot_packed_float32_array *p_array); - -godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data); - -godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value); - -void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self); - -void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self); - -void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data); - -void GDAPI godot_packed_float32_array_remove(godot_packed_float32_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_float32_array_resize(godot_packed_float32_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_float32_array_set(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data); -float GDAPI godot_packed_float32_array_get(const godot_packed_float32_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_float32_array_size(const godot_packed_float32_array *p_self); - -godot_bool GDAPI godot_packed_float32_array_is_empty(const godot_packed_float32_array *p_self); +// Float32. +void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *p_self); void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self); +float GDAPI *godot_packed_float32_array_operator_index(godot_packed_float32_array *p_self, godot_int p_index); +const float GDAPI *godot_packed_float32_array_operator_index_const(const godot_packed_float32_array *p_self, godot_int p_index); -// float64 - -void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *r_dest); -void GDAPI godot_packed_float64_array_new_copy(godot_packed_float64_array *r_dest, const godot_packed_float64_array *p_src); -void GDAPI godot_packed_float64_array_new_with_array(godot_packed_float64_array *r_dest, const godot_array *p_a); - -const double GDAPI *godot_packed_float64_array_ptr(const godot_packed_float64_array *p_self); -double GDAPI *godot_packed_float64_array_ptrw(godot_packed_float64_array *p_self); - -void GDAPI godot_packed_float64_array_append(godot_packed_float64_array *p_self, const double p_data); - -void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p_self, const godot_packed_float64_array *p_array); - -godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data); - -godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value); - -void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self); - -void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self); - -void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data); - -void GDAPI godot_packed_float64_array_remove(godot_packed_float64_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_float64_array_resize(godot_packed_float64_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_float64_array_set(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data); -double GDAPI godot_packed_float64_array_get(const godot_packed_float64_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_float64_array_size(const godot_packed_float64_array *p_self); - -godot_bool GDAPI godot_packed_float64_array_is_empty(const godot_packed_float64_array *p_self); +// Float64. +void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *p_self); void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self); +double GDAPI *godot_packed_float64_array_operator_index(godot_packed_float64_array *p_self, godot_int p_index); +const double GDAPI *godot_packed_float64_array_operator_index_const(const godot_packed_float64_array *p_self, godot_int p_index); -// string - -void GDAPI godot_packed_string_array_new(godot_packed_string_array *r_dest); -void GDAPI godot_packed_string_array_new_copy(godot_packed_string_array *r_dest, const godot_packed_string_array *p_src); -void GDAPI godot_packed_string_array_new_with_array(godot_packed_string_array *r_dest, const godot_array *p_a); - -const godot_string GDAPI *godot_packed_string_array_ptr(const godot_packed_string_array *p_self); -godot_string GDAPI *godot_packed_string_array_ptrw(godot_packed_string_array *p_self); - -void GDAPI godot_packed_string_array_append(godot_packed_string_array *p_self, const godot_string *p_data); - -void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_self, const godot_packed_string_array *p_array); - -godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data); - -godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value); - -void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self); - -void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self); - -void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data); - -void GDAPI godot_packed_string_array_remove(godot_packed_string_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_string_array_resize(godot_packed_string_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_string_array_set(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data); -godot_string GDAPI godot_packed_string_array_get(const godot_packed_string_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_string_array_size(const godot_packed_string_array *p_self); - -godot_bool GDAPI godot_packed_string_array_is_empty(const godot_packed_string_array *p_self); +// String. +void GDAPI godot_packed_string_array_new(godot_packed_string_array *p_self); void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self); +godot_string GDAPI *godot_packed_string_array_operator_index(godot_packed_string_array *p_self, godot_int p_index); +const godot_string GDAPI *godot_packed_string_array_operator_index_const(const godot_packed_string_array *p_self, godot_int p_index); -// vector2 - -void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *r_dest); -void GDAPI godot_packed_vector2_array_new_copy(godot_packed_vector2_array *r_dest, const godot_packed_vector2_array *p_src); -void GDAPI godot_packed_vector2_array_new_with_array(godot_packed_vector2_array *r_dest, const godot_array *p_a); - -const godot_vector2 GDAPI *godot_packed_vector2_array_ptr(const godot_packed_vector2_array *p_self); -godot_vector2 GDAPI *godot_packed_vector2_array_ptrw(godot_packed_vector2_array *p_self); - -void GDAPI godot_packed_vector2_array_append(godot_packed_vector2_array *p_self, const godot_vector2 *p_data); - -void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p_self, const godot_packed_vector2_array *p_array); - -godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data); - -godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value); - -void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self); - -void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self); - -void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data); - -void GDAPI godot_packed_vector2_array_remove(godot_packed_vector2_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_vector2_array_resize(godot_packed_vector2_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_vector2_array_set(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data); -godot_vector2 GDAPI godot_packed_vector2_array_get(const godot_packed_vector2_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_vector2_array_size(const godot_packed_vector2_array *p_self); - -godot_bool GDAPI godot_packed_vector2_array_is_empty(const godot_packed_vector2_array *p_self); +// Vector2. +void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *p_self); void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self); +godot_vector2 GDAPI *godot_packed_vector2_array_operator_index(godot_packed_vector2_array *p_self, godot_int p_index); +const godot_vector2 GDAPI *godot_packed_vector2_array_operator_index_const(const godot_packed_vector2_array *p_self, godot_int p_index); -// vector2i - -void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *r_dest); -void GDAPI godot_packed_vector2i_array_new_copy(godot_packed_vector2i_array *r_dest, const godot_packed_vector2i_array *p_src); -void GDAPI godot_packed_vector2i_array_new_with_array(godot_packed_vector2i_array *r_dest, const godot_array *p_a); - -const godot_vector2i GDAPI *godot_packed_vector2i_array_ptr(const godot_packed_vector2i_array *p_self); -godot_vector2i GDAPI *godot_packed_vector2i_array_ptrw(godot_packed_vector2i_array *p_self); - -void GDAPI godot_packed_vector2i_array_append(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data); - -void GDAPI godot_packed_vector2i_array_append_array(godot_packed_vector2i_array *p_self, const godot_packed_vector2i_array *p_array); - -godot_error GDAPI godot_packed_vector2i_array_insert(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data); - -godot_bool GDAPI godot_packed_vector2i_array_has(godot_packed_vector2i_array *p_self, const godot_vector2i *p_value); - -void GDAPI godot_packed_vector2i_array_sort(godot_packed_vector2i_array *p_self); - -void GDAPI godot_packed_vector2i_array_invert(godot_packed_vector2i_array *p_self); - -void GDAPI godot_packed_vector2i_array_push_back(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data); - -void GDAPI godot_packed_vector2i_array_remove(godot_packed_vector2i_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_vector2i_array_resize(godot_packed_vector2i_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_vector2i_array_set(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data); -godot_vector2i GDAPI godot_packed_vector2i_array_get(const godot_packed_vector2i_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_vector2i_array_size(const godot_packed_vector2i_array *p_self); - -godot_bool GDAPI godot_packed_vector2i_array_is_empty(const godot_packed_vector2i_array *p_self); +// Vector2i. +void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *p_self); void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self); +godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index(godot_packed_vector2i_array *p_self, godot_int p_index); +const godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index_const(const godot_packed_vector2i_array *p_self, godot_int p_index); -// vector3 - -void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *r_dest); -void GDAPI godot_packed_vector3_array_new_copy(godot_packed_vector3_array *r_dest, const godot_packed_vector3_array *p_src); -void GDAPI godot_packed_vector3_array_new_with_array(godot_packed_vector3_array *r_dest, const godot_array *p_a); - -const godot_vector3 GDAPI *godot_packed_vector3_array_ptr(const godot_packed_vector3_array *p_self); -godot_vector3 GDAPI *godot_packed_vector3_array_ptrw(godot_packed_vector3_array *p_self); - -void GDAPI godot_packed_vector3_array_append(godot_packed_vector3_array *p_self, const godot_vector3 *p_data); - -void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p_self, const godot_packed_vector3_array *p_array); - -godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data); - -godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value); - -void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self); - -void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self); - -void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data); - -void GDAPI godot_packed_vector3_array_remove(godot_packed_vector3_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_vector3_array_resize(godot_packed_vector3_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_vector3_array_set(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data); -godot_vector3 GDAPI godot_packed_vector3_array_get(const godot_packed_vector3_array *p_self, const godot_int p_idx); - -godot_int GDAPI godot_packed_vector3_array_size(const godot_packed_vector3_array *p_self); - -godot_bool GDAPI godot_packed_vector3_array_is_empty(const godot_packed_vector3_array *p_self); +// Vector3. +void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *p_self); void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self); +godot_vector3 GDAPI *godot_packed_vector3_array_operator_index(godot_packed_vector3_array *p_self, godot_int p_index); +const godot_vector3 GDAPI *godot_packed_vector3_array_operator_index_const(const godot_packed_vector3_array *p_self, godot_int p_index); -// color - -void GDAPI godot_packed_color_array_new(godot_packed_color_array *r_dest); -void GDAPI godot_packed_color_array_new_copy(godot_packed_color_array *r_dest, const godot_packed_color_array *p_src); -void GDAPI godot_packed_color_array_new_with_array(godot_packed_color_array *r_dest, const godot_array *p_a); - -const godot_color GDAPI *godot_packed_color_array_ptr(const godot_packed_color_array *p_self); -godot_color GDAPI *godot_packed_color_array_ptrw(godot_packed_color_array *p_self); - -void GDAPI godot_packed_color_array_append(godot_packed_color_array *p_self, const godot_color *p_data); - -void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_self, const godot_packed_color_array *p_array); - -godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data); - -godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value); - -void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self); - -void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self); - -void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data); - -void GDAPI godot_packed_color_array_remove(godot_packed_color_array *p_self, const godot_int p_idx); - -void GDAPI godot_packed_color_array_resize(godot_packed_color_array *p_self, const godot_int p_size); - -void GDAPI godot_packed_color_array_set(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data); -godot_color GDAPI godot_packed_color_array_get(const godot_packed_color_array *p_self, const godot_int p_idx); +// Vector3i. -godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self); +void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self); +void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_self); +godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index(godot_packed_vector3i_array *p_self, godot_int p_index); +const godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index_const(const godot_packed_vector3i_array *p_self, godot_int p_index); -godot_bool GDAPI godot_packed_color_array_is_empty(const godot_packed_color_array *p_self); +// Color. +void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self); void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self); +godot_color GDAPI *godot_packed_color_array_operator_index(godot_packed_color_array *p_self, godot_int p_index); +const godot_color GDAPI *godot_packed_color_array_operator_index_const(const godot_packed_color_array *p_self, godot_int p_index); #ifdef __cplusplus } #endif -#endif // GODOT_POOL_ARRAYS_H +#endif // GODOT_PACKED_ARRAYS_H diff --git a/modules/gdnative/include/gdnative/plane.h b/modules/gdnative/include/gdnative/plane.h index a8625d4cd6..ed10955e5f 100644 --- a/modules/gdnative/include/gdnative/plane.h +++ b/modules/gdnative/include/gdnative/plane.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_PLANE_SIZE 16 +#define GODOT_PLANE_SIZE (sizeof(godot_real_t) * 4) #ifndef GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED #define GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED @@ -46,53 +46,9 @@ typedef struct { } godot_plane; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/vector3.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d); -void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3); -void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d); - -godot_string GDAPI godot_plane_as_string(const godot_plane *p_self); - -godot_plane GDAPI godot_plane_normalized(const godot_plane *p_self); - -godot_vector3 GDAPI godot_plane_center(const godot_plane *p_self); - -godot_bool GDAPI godot_plane_is_point_over(const godot_plane *p_self, const godot_vector3 *p_point); - -godot_real GDAPI godot_plane_distance_to(const godot_plane *p_self, const godot_vector3 *p_point); - -godot_bool GDAPI godot_plane_has_point(const godot_plane *p_self, const godot_vector3 *p_point, const godot_real p_epsilon); - -godot_vector3 GDAPI godot_plane_project(const godot_plane *p_self, const godot_vector3 *p_point); - -godot_bool GDAPI godot_plane_intersect_3(const godot_plane *p_self, godot_vector3 *r_dest, const godot_plane *p_b, const godot_plane *p_c); - -godot_bool GDAPI godot_plane_intersects_ray(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_from, const godot_vector3 *p_dir); - -godot_bool GDAPI godot_plane_intersects_segment(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_begin, const godot_vector3 *p_end); - -godot_plane GDAPI godot_plane_operator_neg(const godot_plane *p_self); - -godot_bool GDAPI godot_plane_operator_equal(const godot_plane *p_self, const godot_plane *p_b); - -void GDAPI godot_plane_set_normal(godot_plane *p_self, const godot_vector3 *p_normal); - -godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_self); - -godot_real GDAPI godot_plane_get_d(const godot_plane *p_self); -void GDAPI godot_plane_set_d(godot_plane *p_self, const godot_real p_d); +void GDAPI godot_plane_new(godot_plane *p_self); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h index 68ca1765dd..69bf427611 100644 --- a/modules/gdnative/include/gdnative/quat.h +++ b/modules/gdnative/include/gdnative/quat.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_QUAT_SIZE 16 +#define GODOT_QUAT_SIZE (sizeof(godot_real_t) * 4) #ifndef GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED #define GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED @@ -46,70 +46,11 @@ typedef struct { } godot_quat; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/vector3.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w); -void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle); -void GDAPI godot_quat_new_with_basis(godot_quat *r_dest, const godot_basis *p_basis); -void GDAPI godot_quat_new_with_euler(godot_quat *r_dest, const godot_vector3 *p_euler); - -godot_real GDAPI godot_quat_get_x(const godot_quat *p_self); -void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val); - -godot_real GDAPI godot_quat_get_y(const godot_quat *p_self); -void GDAPI godot_quat_set_y(godot_quat *p_self, const godot_real val); - -godot_real GDAPI godot_quat_get_z(const godot_quat *p_self); -void GDAPI godot_quat_set_z(godot_quat *p_self, const godot_real val); - -godot_real GDAPI godot_quat_get_w(const godot_quat *p_self); -void GDAPI godot_quat_set_w(godot_quat *p_self, const godot_real val); - -godot_string GDAPI godot_quat_as_string(const godot_quat *p_self); - -godot_real GDAPI godot_quat_length(const godot_quat *p_self); - -godot_real GDAPI godot_quat_length_squared(const godot_quat *p_self); - -godot_quat GDAPI godot_quat_normalized(const godot_quat *p_self); - -godot_bool GDAPI godot_quat_is_normalized(const godot_quat *p_self); - -godot_quat GDAPI godot_quat_inverse(const godot_quat *p_self); - -godot_real GDAPI godot_quat_dot(const godot_quat *p_self, const godot_quat *p_b); - -godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v); - -godot_quat GDAPI godot_quat_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t); - -godot_quat GDAPI godot_quat_slerpni(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t); - -godot_quat GDAPI godot_quat_cubic_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_quat *p_pre_a, const godot_quat *p_post_b, const godot_real p_t); - -godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const godot_real p_b); - -godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b); - -godot_quat GDAPI godot_quat_operator_subtract(const godot_quat *p_self, const godot_quat *p_b); - -godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b); - -godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot_quat *p_b); - -godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self); -void GDAPI godot_quat_set_axis_angle(godot_quat *p_self, const godot_vector3 *p_axis, const godot_real p_angle); +void GDAPI godot_quat_new(godot_quat *p_self); +godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h index d3cb276e14..9e51254cfe 100644 --- a/modules/gdnative/include/gdnative/rect2.h +++ b/modules/gdnative/include/gdnative/rect2.h @@ -35,119 +35,30 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> + +#define GODOT_RECT2_SIZE (sizeof(godot_real_t) * 4) #ifndef GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED #define GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED typedef struct godot_rect2 { - uint8_t _dont_touch_that[16]; + uint8_t _dont_touch_that[GODOT_RECT2_SIZE]; } godot_rect2; #endif +#define GODOT_RECT2I_SIZE (sizeof(int32_t) * 4) + #ifndef GODOT_CORE_API_GODOT_RECT2I_TYPE_DEFINED #define GODOT_CORE_API_GODOT_RECT2I_TYPE_DEFINED typedef struct godot_rect2i { - uint8_t _dont_touch_that[16]; + uint8_t _dont_touch_that[GODOT_RECT2I_SIZE]; } godot_rect2i; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/vector2.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// Rect2 - -void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size); -void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height); - -godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self); - -godot_rect2i GDAPI godot_rect2_as_rect2i(const godot_rect2 *p_self); - -godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self); - -godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b); - -godot_bool GDAPI godot_rect2_encloses(const godot_rect2 *p_self, const godot_rect2 *p_b); - -godot_bool GDAPI godot_rect2_has_no_area(const godot_rect2 *p_self); - -godot_rect2 GDAPI godot_rect2_intersection(const godot_rect2 *p_self, const godot_rect2 *p_b); - -godot_rect2 GDAPI godot_rect2_merge(const godot_rect2 *p_self, const godot_rect2 *p_b); - -godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_vector2 *p_point); - -godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by); - -godot_rect2 GDAPI godot_rect2_grow_individual(const godot_rect2 *p_self, const godot_real p_left, const godot_real p_top, const godot_real p_right, const godot_real p_bottom); - -godot_rect2 GDAPI godot_rect2_grow_side(const godot_rect2 *p_self, const godot_int p_margin, const godot_real p_by); - -godot_rect2 GDAPI godot_rect2_abs(const godot_rect2 *p_self); - -godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to); - -godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b); - -godot_vector2 GDAPI godot_rect2_get_position(const godot_rect2 *p_self); - -godot_vector2 GDAPI godot_rect2_get_size(const godot_rect2 *p_self); - -void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_pos); - -void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size); - -// Rect2I - -void GDAPI godot_rect2i_new_with_position_and_size(godot_rect2i *r_dest, const godot_vector2i *p_pos, const godot_vector2i *p_size); -void GDAPI godot_rect2i_new(godot_rect2i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_width, const godot_int p_height); - -godot_string GDAPI godot_rect2i_as_string(const godot_rect2i *p_self); - -godot_rect2 GDAPI godot_rect2i_as_rect2(const godot_rect2i *p_self); - -godot_int GDAPI godot_rect2i_get_area(const godot_rect2i *p_self); - -godot_bool GDAPI godot_rect2i_intersects(const godot_rect2i *p_self, const godot_rect2i *p_b); - -godot_bool GDAPI godot_rect2i_encloses(const godot_rect2i *p_self, const godot_rect2i *p_b); - -godot_bool GDAPI godot_rect2i_has_no_area(const godot_rect2i *p_self); - -godot_rect2i GDAPI godot_rect2i_intersection(const godot_rect2i *p_self, const godot_rect2i *p_b); - -godot_rect2i GDAPI godot_rect2i_merge(const godot_rect2i *p_self, const godot_rect2i *p_b); - -godot_bool GDAPI godot_rect2i_has_point(const godot_rect2i *p_self, const godot_vector2i *p_point); - -godot_rect2i GDAPI godot_rect2i_grow(const godot_rect2i *p_self, const godot_int p_by); - -godot_rect2i GDAPI godot_rect2i_grow_individual(const godot_rect2i *p_self, const godot_int p_left, const godot_int p_top, const godot_int p_right, const godot_int p_bottom); - -godot_rect2i GDAPI godot_rect2i_grow_side(const godot_rect2i *p_self, const godot_int p_margin, const godot_int p_by); - -godot_rect2i GDAPI godot_rect2i_abs(const godot_rect2i *p_self); - -godot_rect2i GDAPI godot_rect2i_expand(const godot_rect2i *p_self, const godot_vector2i *p_to); - -godot_bool GDAPI godot_rect2i_operator_equal(const godot_rect2i *p_self, const godot_rect2i *p_b); - -godot_vector2i GDAPI godot_rect2i_get_position(const godot_rect2i *p_self); - -godot_vector2i GDAPI godot_rect2i_get_size(const godot_rect2i *p_self); - -void GDAPI godot_rect2i_set_position(godot_rect2i *p_self, const godot_vector2i *p_pos); -void GDAPI godot_rect2i_set_size(godot_rect2i *p_self, const godot_vector2i *p_size); +void GDAPI godot_rect2_new(godot_rect2 *p_self); +void GDAPI godot_rect2i_new(godot_rect2i *p_self); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/rid.h b/modules/gdnative/include/gdnative/rid.h index cbf066d47f..7ea8cfd174 100644 --- a/modules/gdnative/include/gdnative/rid.h +++ b/modules/gdnative/include/gdnative/rid.h @@ -46,26 +46,9 @@ typedef struct { } godot_rid; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_rid_new(godot_rid *r_dest); - -godot_int GDAPI godot_rid_get_id(const godot_rid *p_self); - -void GDAPI godot_rid_new_with_resource(godot_rid *r_dest, const godot_object *p_from); - -godot_bool GDAPI godot_rid_operator_equal(const godot_rid *p_self, const godot_rid *p_b); - -godot_bool GDAPI godot_rid_operator_less(const godot_rid *p_self, const godot_rid *p_b); +void GDAPI godot_rid_new(godot_rid *p_self); #ifdef __cplusplus } diff --git a/modules/icloud/icloud_module.cpp b/modules/gdnative/include/gdnative/signal.h index 8a2c41a38c..ad84542677 100644 --- a/modules/icloud/icloud_module.cpp +++ b/modules/gdnative/include/gdnative/signal.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* icloud_module.cpp */ +/* signal.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "icloud_module.h" +#ifndef GODOT_SIGNAL_H +#define GODOT_SIGNAL_H -#include "core/config/engine.h" +#ifdef __cplusplus +extern "C" { +#endif -#include "icloud.h" +#include <stdint.h> -ICloud *icloud; +#define GODOT_SIGNAL_SIZE (16) -void register_icloud_types() { - icloud = memnew(ICloud); - Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud)); -} +#ifndef GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED +typedef struct { + uint8_t _dont_touch_that[GODOT_SIGNAL_SIZE]; +} godot_signal; +#endif + +#include <gdnative/gdnative.h> -void unregister_icloud_types() { - if (icloud) { - memdelete(icloud); - } +void GDAPI godot_signal_new(godot_signal *p_self); +void GDAPI godot_signal_destroy(godot_signal *p_self); + +#ifdef __cplusplus } +#endif + +#endif diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h index e58be18b21..10fbb2c078 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -39,61 +39,26 @@ extern "C" { #include <stdint.h> #ifndef __cplusplus -typedef uint32_t char32_t; typedef uint16_t char16_t; +typedef uint32_t char32_t; #endif typedef char32_t godot_char_type; #define GODOT_STRING_SIZE sizeof(void *) -#define GODOT_CHAR_STRING_SIZE sizeof(void *) -#define GODOT_CHAR16_STRING_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED #define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED typedef struct { uint8_t _dont_touch_that[GODOT_STRING_SIZE]; } godot_string; - -#endif - -#ifndef GODOT_CORE_API_GODOT_CHAR_STRING_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_CHAR_STRING_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_CHAR_STRING_SIZE]; -} godot_char_string; -#endif - -#ifndef GODOT_CORE_API_GODOT_CHAR16_STRING_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_CHAR16_STRING_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_CHAR16_STRING_SIZE]; -} godot_char16_string; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/array.h> #include <gdnative/gdnative.h> -#include <gdnative/variant.h> - -#ifdef __cplusplus -extern "C" { -#endif - -godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs); -const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs); -void GDAPI godot_char_string_destroy(godot_char_string *p_cs); - -godot_int GDAPI godot_char16_string_length(const godot_char16_string *p_cs); -const char16_t GDAPI *godot_char16_string_get_data(const godot_char16_string *p_cs); -void GDAPI godot_char16_string_destroy(godot_char16_string *p_cs); void GDAPI godot_string_new(godot_string *r_dest); void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src); +void GDAPI godot_string_destroy(godot_string *p_self); void GDAPI godot_string_new_with_latin1_chars(godot_string *r_dest, const char *p_contents); void GDAPI godot_string_new_with_utf8_chars(godot_string *r_dest, const char *p_contents); @@ -107,198 +72,6 @@ void GDAPI godot_string_new_with_utf16_chars_and_len(godot_string *r_dest, const void GDAPI godot_string_new_with_utf32_chars_and_len(godot_string *r_dest, const char32_t *p_contents, const int p_size); void GDAPI godot_string_new_with_wide_chars_and_len(godot_string *r_dest, const wchar_t *p_contents, const int p_size); -const godot_char_type GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx); -godot_char_type GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx); -const godot_char_type GDAPI *godot_string_get_data(const godot_string *p_self); - -godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b); -godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b); -godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b); - -/* Standard size stuff */ - -/*+++*/ godot_int GDAPI godot_string_length(const godot_string *p_self); - -/* Helpers */ - -signed char GDAPI godot_string_casecmp_to(const godot_string *p_self, const godot_string *p_str); -signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const godot_string *p_str); -signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str); - -godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string); -godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array); -godot_packed_string_array GDAPI godot_string_bigrams(const godot_string *p_self); -godot_string GDAPI godot_string_chr(godot_char_type p_character); -godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string); -godot_bool GDAPI godot_string_ends_with_char_array(const godot_string *p_self, const char *p_char_array); -godot_int GDAPI godot_string_count(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to); -godot_int GDAPI godot_string_countn(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to); -godot_int GDAPI godot_string_find(const godot_string *p_self, const godot_string *p_what); -godot_int GDAPI godot_string_find_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from); -godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_packed_string_array *p_keys); -godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from); -godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from, godot_int *r_key); -godot_int GDAPI godot_string_findn(const godot_string *p_self, const godot_string *p_what); -godot_int GDAPI godot_string_findn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from); -godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values); -godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder); -godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len); -godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self); -godot_int GDAPI godot_string_hex_to_int_with_prefix(const godot_string *p_self); -godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, const godot_string *p_string); -godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self); -godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string); -godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string); -godot_string GDAPI godot_string_lpad(const godot_string *p_self, godot_int p_min_length); -godot_string GDAPI godot_string_lpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character); -godot_bool GDAPI godot_string_match(const godot_string *p_self, const godot_string *p_wildcard); -godot_bool GDAPI godot_string_matchn(const godot_string *p_self, const godot_string *p_wildcard); -godot_string GDAPI godot_string_md5(const uint8_t *p_md5); -godot_string GDAPI godot_string_num(double p_num); -godot_string GDAPI godot_string_num_int64(int64_t p_num, godot_int p_base); -godot_string GDAPI godot_string_num_int64_capitalized(int64_t p_num, godot_int p_base, godot_bool p_capitalize_hex); -godot_string GDAPI godot_string_num_real(double p_num); -godot_string GDAPI godot_string_num_scientific(double p_num); -godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals); -godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits); -godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits); -godot_string GDAPI godot_string_replace_first(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with); -godot_string GDAPI godot_string_replace(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with); -godot_string GDAPI godot_string_replacen(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with); -godot_int GDAPI godot_string_rfind(const godot_string *p_self, const godot_string *p_what); -godot_int GDAPI godot_string_rfindn(const godot_string *p_self, const godot_string *p_what); -godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from); -godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from); -godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length); -godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character); -godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string); -godot_string GDAPI godot_string_sprintf(const godot_string *p_self, const godot_array *p_values, godot_bool *p_error); -godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_from, godot_int p_chars); -double GDAPI godot_string_to_float(const godot_string *p_self); -godot_int GDAPI godot_string_to_int(const godot_string *p_self); - -godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self); -godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self); -godot_string GDAPI godot_string_capitalize(const godot_string *p_self); - -double GDAPI godot_string_char_to_float(const char *p_what); -double GDAPI godot_string_wchar_to_float(const wchar_t *p_str, const wchar_t **r_end); - -godot_int GDAPI godot_string_char_to_int(const char *p_what); -godot_int GDAPI godot_string_wchar_to_int(const wchar_t *p_str); - -godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len); -godot_int GDAPI godot_string_wchar_to_int_with_len(const wchar_t *p_str, int p_len); - -godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, const godot_string *p_splitter); -godot_string GDAPI godot_string_get_slice(const godot_string *p_self, const godot_string *p_splitter, godot_int p_slice); -godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, godot_char_type p_splitter, godot_int p_slice); - -godot_packed_string_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_string_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_string_array GDAPI godot_string_split_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit); - -godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_string_array GDAPI godot_string_rsplit_allow_empty(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_string_array GDAPI godot_string_rsplit_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit); - -godot_packed_float32_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_float32_array GDAPI godot_string_split_floats_allow_empty(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_float32_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters); -godot_packed_float32_array GDAPI godot_string_split_floats_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters); -godot_packed_int32_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_int32_array GDAPI godot_string_split_ints_allow_empty(const godot_string *p_self, const godot_string *p_splitter); -godot_packed_int32_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters); -godot_packed_int32_array GDAPI godot_string_split_ints_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters); - -godot_packed_string_array GDAPI godot_string_split_spaces(const godot_string *p_self); - -godot_char_type GDAPI godot_string_char_lowercase(godot_char_type p_char); -godot_char_type GDAPI godot_string_char_uppercase(godot_char_type p_char); -godot_string GDAPI godot_string_to_lower(const godot_string *p_self); -godot_string GDAPI godot_string_to_upper(const godot_string *p_self); - -godot_string GDAPI godot_string_get_basename(const godot_string *p_self); -godot_string GDAPI godot_string_get_extension(const godot_string *p_self); -godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos); -godot_char_type GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx); -godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file); -godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos); -godot_string GDAPI godot_string_repeat(const godot_string *p_self, godot_int p_count); -godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right); -godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self); - -void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars); - -godot_char_string GDAPI godot_string_ascii(const godot_string *p_self); -godot_char_string GDAPI godot_string_latin1(const godot_string *p_self); - -godot_char_string GDAPI godot_string_utf8(const godot_string *p_self); -godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8); -godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len); - -godot_char16_string GDAPI godot_string_utf16(const godot_string *p_self); -godot_bool GDAPI godot_string_parse_utf16(godot_string *p_self, const char16_t *p_utf16); -godot_bool GDAPI godot_string_parse_utf16_with_len(godot_string *p_self, const char16_t *p_utf16, godot_int p_len); - -uint32_t GDAPI godot_string_hash(const godot_string *p_self); -uint64_t GDAPI godot_string_hash64(const godot_string *p_self); - -uint32_t GDAPI godot_string_hash_chars(const char *p_cstr); -uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len); -uint32_t GDAPI godot_string_hash_wide_chars(const wchar_t *p_str); -uint32_t GDAPI godot_string_hash_wide_chars_with_len(const wchar_t *p_str, godot_int p_len); - -godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self); -godot_string GDAPI godot_string_md5_text(const godot_string *p_self); -godot_packed_byte_array GDAPI godot_string_sha1_buffer(const godot_string *p_self); -godot_string GDAPI godot_string_sha1_text(const godot_string *p_self); -godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self); -godot_string GDAPI godot_string_sha256_text(const godot_string *p_self); - -godot_bool godot_string_is_empty(const godot_string *p_self); - -// path functions -godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self); -godot_string GDAPI godot_string_get_file(const godot_string *p_self); -godot_string GDAPI godot_string_humanize_size(uint64_t p_size); -godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self); -godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self); -godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self); -godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path); -godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path); -godot_string GDAPI godot_string_simplify_path(const godot_string *p_self); - -godot_string GDAPI godot_string_c_escape(const godot_string *p_self); -godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self); -godot_string GDAPI godot_string_c_unescape(const godot_string *p_self); -godot_string GDAPI godot_string_http_escape(const godot_string *p_self); -godot_string GDAPI godot_string_http_unescape(const godot_string *p_self); -godot_string GDAPI godot_string_json_escape(const godot_string *p_self); -godot_string GDAPI godot_string_xml_escape(const godot_string *p_self); -godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self); -godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self); - -godot_string GDAPI godot_string_percent_decode(const godot_string *p_self); -godot_string GDAPI godot_string_percent_encode(const godot_string *p_self); -godot_string GDAPI godot_string_join(const godot_string *p_self, const godot_packed_string_array *p_parts); - -godot_bool GDAPI godot_string_is_valid_filename(const godot_string *p_self); -godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self); -godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix); -godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self); -godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self); -godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self); -godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self); - -godot_string GDAPI godot_string_dedent(const godot_string *p_self); -godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix); -godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix); -godot_string GDAPI godot_string_lstrip(const godot_string *p_self, const godot_string *p_chars); -godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars); - -void GDAPI godot_string_destroy(godot_string *p_self); - #ifdef __cplusplus } #endif diff --git a/modules/gdnative/include/gdnative/string_name.h b/modules/gdnative/include/gdnative/string_name.h index b468f716e1..346f626e81 100644 --- a/modules/gdnative/include/gdnative/string_name.h +++ b/modules/gdnative/include/gdnative/string_name.h @@ -47,30 +47,14 @@ typedef struct { } godot_string_name; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name); -void GDAPI godot_string_name_new_data(godot_string_name *r_dest, const char *p_name); - -godot_string GDAPI godot_string_name_get_name(const godot_string_name *p_self); - -uint32_t GDAPI godot_string_name_get_hash(const godot_string_name *p_self); -const void GDAPI *godot_string_name_get_data_unique_pointer(const godot_string_name *p_self); - -godot_bool GDAPI godot_string_name_operator_equal(const godot_string_name *p_self, const godot_string_name *p_other); -godot_bool GDAPI godot_string_name_operator_less(const godot_string_name *p_self, const godot_string_name *p_other); - +void GDAPI godot_string_name_new(godot_string_name *r_dest); +void GDAPI godot_string_name_new_copy(godot_string_name *r_dest, const godot_string_name *p_src); void GDAPI godot_string_name_destroy(godot_string_name *p_self); +void GDAPI godot_string_name_new_with_latin1_chars(godot_string_name *r_dest, const char *p_contents); + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h index 948cb2ecfd..e67862d140 100644 --- a/modules/gdnative/include/gdnative/transform.h +++ b/modules/gdnative/include/gdnative/transform.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_TRANSFORM_SIZE 48 +#define GODOT_TRANSFORM_SIZE (sizeof(godot_real_t) * 12) #ifndef GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED #define GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED @@ -46,63 +46,9 @@ typedef struct { } godot_transform; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/basis.h> #include <gdnative/gdnative.h> -#include <gdnative/variant.h> -#include <gdnative/vector3.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin); -void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin); -void GDAPI godot_transform_new_with_quat(godot_transform *r_dest, const godot_quat *p_quat); - -godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self); -void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v); - -godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self); -void GDAPI godot_transform_set_origin(godot_transform *p_self, const godot_vector3 *p_v); - -godot_string GDAPI godot_transform_as_string(const godot_transform *p_self); - -godot_transform GDAPI godot_transform_inverse(const godot_transform *p_self); - -godot_transform GDAPI godot_transform_affine_inverse(const godot_transform *p_self); - -godot_transform GDAPI godot_transform_orthonormalized(const godot_transform *p_self); - -godot_transform GDAPI godot_transform_rotated(const godot_transform *p_self, const godot_vector3 *p_axis, const godot_real p_phi); - -godot_transform GDAPI godot_transform_scaled(const godot_transform *p_self, const godot_vector3 *p_scale); - -godot_transform GDAPI godot_transform_translated(const godot_transform *p_self, const godot_vector3 *p_ofs); - -godot_transform GDAPI godot_transform_looking_at(const godot_transform *p_self, const godot_vector3 *p_target, const godot_vector3 *p_up); - -godot_plane GDAPI godot_transform_xform_plane(const godot_transform *p_self, const godot_plane *p_v); - -godot_plane GDAPI godot_transform_xform_inv_plane(const godot_transform *p_self, const godot_plane *p_v); - -void GDAPI godot_transform_new_identity(godot_transform *r_dest); - -godot_bool GDAPI godot_transform_operator_equal(const godot_transform *p_self, const godot_transform *p_b); - -godot_transform GDAPI godot_transform_operator_multiply(const godot_transform *p_self, const godot_transform *p_b); - -godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, const godot_vector3 *p_v); - -godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v); - -godot_aabb GDAPI godot_transform_xform_aabb(const godot_transform *p_self, const godot_aabb *p_v); -godot_aabb GDAPI godot_transform_xform_inv_aabb(const godot_transform *p_self, const godot_aabb *p_v); +void GDAPI godot_transform_new(godot_transform *p_self); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h index 51c5306c7d..4a2bca7cfc 100644 --- a/modules/gdnative/include/gdnative/transform2d.h +++ b/modules/gdnative/include/gdnative/transform2d.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_TRANSFORM2D_SIZE 24 +#define GODOT_TRANSFORM2D_SIZE (sizeof(godot_real_t) * 6) #ifndef GODOT_CORE_API_GODOT_TRANSFORM2D_TYPE_DEFINED #define GODOT_CORE_API_GODOT_TRANSFORM2D_TYPE_DEFINED @@ -46,61 +46,11 @@ typedef struct { } godot_transform2d; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#include <gdnative/variant.h> -#include <gdnative/vector2.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos); -void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin); - -godot_string GDAPI godot_transform2d_as_string(const godot_transform2d *p_self); - -godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_self); - -godot_transform2d GDAPI godot_transform2d_affine_inverse(const godot_transform2d *p_self); - -godot_real GDAPI godot_transform2d_get_rotation(const godot_transform2d *p_self); - -godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self); - -godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self); - -godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self); - -godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi); - -godot_transform2d GDAPI godot_transform2d_scaled(const godot_transform2d *p_self, const godot_vector2 *p_scale); - -godot_transform2d GDAPI godot_transform2d_translated(const godot_transform2d *p_self, const godot_vector2 *p_offset); - -godot_vector2 GDAPI godot_transform2d_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v); - -godot_vector2 GDAPI godot_transform2d_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v); - -godot_vector2 GDAPI godot_transform2d_basis_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v); - -godot_vector2 GDAPI godot_transform2d_basis_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v); - -godot_transform2d GDAPI godot_transform2d_interpolate_with(const godot_transform2d *p_self, const godot_transform2d *p_m, const godot_real p_c); - -godot_bool GDAPI godot_transform2d_operator_equal(const godot_transform2d *p_self, const godot_transform2d *p_b); - -godot_transform2d GDAPI godot_transform2d_operator_multiply(const godot_transform2d *p_self, const godot_transform2d *p_b); - -void GDAPI godot_transform2d_new_identity(godot_transform2d *r_dest); - -godot_rect2 GDAPI godot_transform2d_xform_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v); -godot_rect2 GDAPI godot_transform2d_xform_inv_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v); +void GDAPI godot_transform2d_new(godot_transform2d *p_self); +godot_vector2 GDAPI *godot_transform2d_operator_index(godot_transform2d *p_self, godot_int p_index); +const godot_vector2 GDAPI *godot_transform2d_operator_index_const(const godot_transform2d *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index a50947cb72..329a6faf51 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -35,16 +35,8 @@ extern "C" { #endif -#include <stdint.h> - -#define GODOT_VARIANT_SIZE (16 + sizeof(int64_t)) - -#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_VARIANT_SIZE]; -} godot_variant; -#endif +#include <gdnative/math_defs.h> +#include <gdnative/variant_struct.h> typedef enum godot_variant_type { GODOT_VARIANT_TYPE_NIL, @@ -146,10 +138,35 @@ typedef enum godot_variant_operator { GODOT_VARIANT_OP_MAX, } godot_variant_operator; -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif +typedef enum godot_variant_utility_function_type { + GODOT_UTILITY_FUNC_TYPE_MATH, + GODOT_UTILITY_FUNC_TYPE_RANDOM, + GODOT_UTILITY_FUNC_TYPE_GENERAL, +} godot_variant_utility_function_type; + +// Types for function pointers. +typedef void (*godot_validated_operator_evaluator)(const godot_variant *p_left, const godot_variant *p_right, godot_variant *r_result); +typedef void (*godot_ptr_operator_evaluator)(const void *p_left, const void *p_right, void *r_result); +typedef void (*godot_validated_builtin_method)(godot_variant *p_base, const godot_variant **p_args, int p_argument_count, godot_variant *r_return); +typedef void (*godot_ptr_builtin_method)(void *p_base, const void **p_args, void *r_return, int p_argument_count); +typedef void (*godot_validated_constructor)(godot_variant *p_base, const godot_variant **p_args); +typedef void (*godot_ptr_constructor)(void *p_base, const void **p_args); +typedef void (*godot_validated_setter)(godot_variant *p_base, const godot_variant *p_value); +typedef void (*godot_validated_getter)(const godot_variant *p_base, godot_variant *r_value); +typedef void (*godot_ptr_setter)(void *p_base, const void *p_value); +typedef void (*godot_ptr_getter)(const void *p_base, void *r_value); +typedef void (*godot_validated_indexed_setter)(godot_variant *p_base, godot_int p_index, const godot_variant *p_value, bool *r_oob); +typedef void (*godot_validated_indexed_getter)(const godot_variant *p_base, godot_int p_index, godot_variant *r_value, bool *r_oob); +typedef void (*godot_ptr_indexed_setter)(void *p_base, godot_int p_index, const void *p_value); +typedef void (*godot_ptr_indexed_getter)(const void *p_base, godot_int p_index, void *r_value); +typedef void (*godot_validated_keyed_setter)(godot_variant *p_base, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid); +typedef void (*godot_validated_keyed_getter)(const godot_variant *p_base, const godot_variant *p_key, godot_variant *r_value, bool *r_valid); +typedef bool (*godot_validated_keyed_checker)(const godot_variant *p_base, const godot_variant *p_key, bool *r_valid); +typedef void (*godot_ptr_keyed_setter)(void *p_base, const void *p_key, const void *p_value); +typedef void (*godot_ptr_keyed_getter)(const void *p_base, const void *p_key, void *r_value); +typedef bool (*godot_ptr_keyed_checker)(const godot_variant *p_base, const godot_variant *p_key); +typedef void (*godot_validated_utility_function)(godot_variant *r_return, const godot_variant **p_arguments, int p_argument_count); +typedef void (*godot_ptr_utility_function)(void *r_return, const void **p_arguments, int p_argument_count); #include <gdnative/aabb.h> #include <gdnative/array.h> @@ -163,6 +180,7 @@ typedef enum godot_variant_operator { #include <gdnative/quat.h> #include <gdnative/rect2.h> #include <gdnative/rid.h> +#include <gdnative/signal.h> #include <gdnative/string.h> #include <gdnative/string_name.h> #include <gdnative/transform.h> @@ -173,22 +191,15 @@ typedef enum godot_variant_operator { #include <gdnative/gdnative.h> -#ifdef __cplusplus -extern "C" { -#endif - -godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v); +// Memory. void GDAPI godot_variant_new_copy(godot_variant *r_dest, const godot_variant *p_src); void GDAPI godot_variant_new_nil(godot_variant *r_dest); - void GDAPI godot_variant_new_bool(godot_variant *r_dest, const godot_bool p_b); -void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i); -void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i); -void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r); +void GDAPI godot_variant_new_int(godot_variant *r_dest, const godot_int p_i); +void GDAPI godot_variant_new_float(godot_variant *r_dest, const godot_float p_f); void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s); -void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s); void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2); void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2); void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2); @@ -202,11 +213,12 @@ void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aab void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis); void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans); void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color); +void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s); void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np); void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid); +void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj); void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_callable); void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal); -void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj); void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict); void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr); void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba); @@ -220,11 +232,9 @@ void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const g void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca); godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self); -uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self); -int64_t GDAPI godot_variant_as_int(const godot_variant *p_self); -double GDAPI godot_variant_as_real(const godot_variant *p_self); +godot_int GDAPI godot_variant_as_int(const godot_variant *p_self); +godot_float GDAPI godot_variant_as_float(const godot_variant *p_self); godot_string GDAPI godot_variant_as_string(const godot_variant *p_self); -godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self); godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self); godot_vector2i GDAPI godot_variant_as_vector2i(const godot_variant *p_self); godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self); @@ -238,11 +248,12 @@ godot_aabb GDAPI godot_variant_as_aabb(const godot_variant *p_self); godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self); godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self); godot_color GDAPI godot_variant_as_color(const godot_variant *p_self); +godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self); godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_self); godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self); +godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self); godot_callable GDAPI godot_variant_as_callable(const godot_variant *p_self); godot_signal GDAPI godot_variant_as_signal(const godot_variant *p_self); -godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self); godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_self); godot_array GDAPI godot_variant_as_array(const godot_variant *p_self); godot_packed_byte_array GDAPI godot_variant_as_packed_byte_array(const godot_variant *p_self); @@ -255,24 +266,153 @@ godot_packed_vector2_array GDAPI godot_variant_as_packed_vector2_array(const god godot_packed_vector3_array GDAPI godot_variant_as_packed_vector3_array(const godot_variant *p_self); godot_packed_color_array GDAPI godot_variant_as_packed_color_array(const godot_variant *p_self); -godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error); - -godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string *p_method); - -godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other); -godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other); +void GDAPI godot_variant_destroy(godot_variant *p_self); -uint32_t GDAPI godot_variant_hash(const godot_variant *p_self); +// Dynamic interaction. + +void GDAPI godot_variant_call(godot_variant *p_self, const godot_string_name *p_method, const godot_variant **p_args, const godot_int p_argument_count, godot_variant *r_return, godot_variant_call_error *r_error); +void GDAPI godot_variant_call_with_cstring(godot_variant *p_self, const char *p_method, const godot_variant **p_args, const godot_int p_argument_count, godot_variant *r_return, godot_variant_call_error *r_error); +void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_return, bool *r_valid); +void GDAPI godot_variant_set(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid); +void GDAPI godot_variant_set_named(godot_variant *p_self, const godot_string_name *p_name, const godot_variant *p_value, bool *r_valid); +void GDAPI godot_variant_set_named_with_cstring(godot_variant *p_self, const char *p_name, const godot_variant *p_value, bool *r_valid); +void GDAPI godot_variant_set_keyed(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid); +void GDAPI godot_variant_set_indexed(godot_variant *p_self, godot_int p_index, const godot_variant *p_value, bool *r_valid, bool *r_oob); +godot_variant GDAPI godot_variant_get(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid); +godot_variant GDAPI godot_variant_get_named(const godot_variant *p_self, const godot_string_name *p_key, bool *r_valid); +godot_variant GDAPI godot_variant_get_named_with_cstring(const godot_variant *p_self, const char *p_key, bool *r_valid); +godot_variant GDAPI godot_variant_get_keyed(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid); +godot_variant GDAPI godot_variant_get_indexed(const godot_variant *p_self, godot_int p_index, bool *r_valid, bool *r_oob); +/// Iteration. +bool GDAPI godot_variant_iter_init(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid); +bool GDAPI godot_variant_iter_next(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid); +godot_variant GDAPI godot_variant_iter_get(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid); + +/// Variant functions. godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other); - godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self); - -void GDAPI godot_variant_destroy(godot_variant *p_self); - -// GDNative core 1.1 - -godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_op); -void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_ret, godot_bool *r_valid); +void GDAPI godot_variant_blend(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst); +void GDAPI godot_variant_interpolate(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst); +godot_variant GDAPI godot_variant_duplicate(const godot_variant *p_self, godot_bool p_deep); +godot_string GDAPI godot_variant_stringify(const godot_variant *p_self); + +// Discovery API. + +/// Operators. +godot_validated_operator_evaluator GDAPI godot_variant_get_validated_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b); +godot_ptr_operator_evaluator GDAPI godot_variant_get_ptr_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b); +godot_variant_type GDAPI godot_variant_get_operator_return_type(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b); +godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_operator); + +/// Built-in methods. +bool GDAPI godot_variant_has_builtin_method(godot_variant_type p_type, const godot_string_name *p_method); +bool GDAPI godot_variant_has_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method); +godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method(godot_variant_type p_type, const godot_string_name *p_method); +godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method); +godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method(godot_variant_type p_type, const godot_string_name *p_method); +godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method); +int GDAPI godot_variant_get_builtin_method_argument_count(godot_variant_type p_type, const godot_string_name *p_method); +int GDAPI godot_variant_get_builtin_method_argument_count_with_cstring(godot_variant_type p_type, const char *p_method); +godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type(godot_variant_type p_type, const godot_string_name *p_method, int p_argument); +godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument); +godot_string GDAPI godot_variant_get_builtin_method_argument_name(godot_variant_type p_type, const godot_string_name *p_method, int p_argument); +godot_string GDAPI godot_variant_get_builtin_method_argument_name_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument); +bool GDAPI godot_variant_has_builtin_method_return_value(godot_variant_type p_type, const godot_string_name *p_method); +bool GDAPI godot_variant_has_builtin_method_return_value_with_cstring(godot_variant_type p_type, const char *p_method); +godot_variant_type GDAPI godot_variant_get_builtin_method_return_type(godot_variant_type p_type, const godot_string_name *p_method); +godot_variant_type GDAPI godot_variant_get_builtin_method_return_type_with_cstring(godot_variant_type p_type, const char *p_method); +bool GDAPI godot_variant_is_builtin_method_const(godot_variant_type p_type, const godot_string_name *p_method); +bool GDAPI godot_variant_is_builtin_method_const_with_cstring(godot_variant_type p_type, const char *p_method); +bool GDAPI godot_variant_is_builtin_method_vararg(godot_variant_type p_type, const godot_string_name *p_method); +bool GDAPI godot_variant_is_builtin_method_vararg_with_cstring(godot_variant_type p_type, const char *p_method); +int GDAPI godot_variant_get_builtin_method_count(godot_variant_type p_type); +void GDAPI godot_variant_get_builtin_method_list(godot_variant_type p_type, godot_string_name *r_list); + +/// Constructors. +int GDAPI godot_variant_get_constructor_count(godot_variant_type p_type); +godot_validated_constructor GDAPI godot_variant_get_validated_constructor(godot_variant_type p_type, int p_constructor); +godot_ptr_constructor GDAPI godot_variant_get_ptr_constructor(godot_variant_type p_type, int p_constructor); +int GDAPI godot_variant_get_constructor_argument_count(godot_variant_type p_type, int p_constructor); +godot_variant_type GDAPI godot_variant_get_constructor_argument_type(godot_variant_type p_type, int p_constructor, int p_argument); +godot_string GDAPI godot_variant_get_constructor_argument_name(godot_variant_type p_type, int p_constructor, int p_argument); +void GDAPI godot_variant_construct(godot_variant_type p_type, godot_variant *p_base, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error); + +/// Properties. +godot_variant_type GDAPI godot_variant_get_member_type(godot_variant_type p_type, const godot_string_name *p_member); +godot_variant_type GDAPI godot_variant_get_member_type_with_cstring(godot_variant_type p_type, const char *p_member); +int GDAPI godot_variant_get_member_count(godot_variant_type p_type); +void GDAPI godot_variant_get_member_list(godot_variant_type p_type, godot_string_name *r_list); +godot_validated_setter GDAPI godot_variant_get_validated_setter(godot_variant_type p_type, const godot_string_name *p_member); +godot_validated_setter GDAPI godot_variant_get_validated_setter_with_cstring(godot_variant_type p_type, const char *p_member); +godot_validated_getter GDAPI godot_variant_get_validated_getter(godot_variant_type p_type, const godot_string_name *p_member); +godot_validated_getter GDAPI godot_variant_get_validated_getter_with_cstring(godot_variant_type p_type, const char *p_member); +godot_ptr_setter GDAPI godot_variant_get_ptr_setter(godot_variant_type p_type, const godot_string_name *p_member); +godot_ptr_setter GDAPI godot_variant_get_ptr_setter_with_cstring(godot_variant_type p_type, const char *p_member); +godot_ptr_getter GDAPI godot_variant_get_ptr_getter(godot_variant_type p_type, const godot_string_name *p_member); +godot_ptr_getter GDAPI godot_variant_get_ptr_getter_with_cstring(godot_variant_type p_type, const char *p_member); + +/// Indexing. +bool GDAPI godot_variant_has_indexing(godot_variant_type p_type); +godot_variant_type GDAPI godot_variant_get_indexed_element_type(godot_variant_type p_type); +godot_validated_indexed_setter GDAPI godot_variant_get_validated_indexed_setter(godot_variant_type p_type); +godot_validated_indexed_getter GDAPI godot_variant_get_validated_indexed_getter(godot_variant_type p_type); +godot_ptr_indexed_setter GDAPI godot_variant_get_ptr_indexed_setter(godot_variant_type p_type); +godot_ptr_indexed_getter GDAPI godot_variant_get_ptr_indexed_getter(godot_variant_type p_type); +uint64_t GDAPI godot_variant_get_indexed_size(const godot_variant *p_self); + +/// Keying. +bool GDAPI godot_variant_is_keyed(godot_variant_type p_type); +godot_validated_keyed_setter GDAPI godot_variant_get_validated_keyed_setter(godot_variant_type p_type); +godot_validated_keyed_getter GDAPI godot_variant_get_validated_keyed_getter(godot_variant_type p_type); +godot_validated_keyed_checker GDAPI godot_variant_get_validated_keyed_checker(godot_variant_type p_type); +godot_ptr_keyed_setter GDAPI godot_variant_get_ptr_keyed_setter(godot_variant_type p_type); +godot_ptr_keyed_getter GDAPI godot_variant_get_ptr_keyed_getter(godot_variant_type p_type); +godot_ptr_keyed_checker GDAPI godot_variant_get_ptr_keyed_checker(godot_variant_type p_type); + +/// Constants. +int GDAPI godot_variant_get_constants_count(godot_variant_type p_type); +void GDAPI godot_variant_get_constants_list(godot_variant_type p_type, godot_string_name *r_list); +bool GDAPI godot_variant_has_constant(godot_variant_type p_type, const godot_string_name *p_constant); +bool GDAPI godot_variant_has_constant_with_cstring(godot_variant_type p_type, const char *p_constant); +godot_variant GDAPI godot_variant_get_constant_value(godot_variant_type p_type, const godot_string_name *p_constant); +godot_variant GDAPI godot_variant_get_constant_value_with_cstring(godot_variant_type p_type, const char *p_constant); + +/// Utilities. +bool GDAPI godot_variant_has_utility_function(const godot_string_name *p_function); +bool GDAPI godot_variant_has_utility_function_with_cstring(const char *p_function); +void GDAPI godot_variant_call_utility_function(const godot_string_name *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error); +void GDAPI godot_variant_call_utility_function_with_cstring(const char *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error); +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function(const godot_string_name *p_function); +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function_with_cstring(const char *p_function); +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function(const godot_string_name *p_function); +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function_with_cstring(const char *p_function); +godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type(const godot_string_name *p_function); +godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type_with_cstring(const char *p_function); +int GDAPI godot_variant_get_utility_function_argument_count(const godot_string_name *p_function); +int GDAPI godot_variant_get_utility_function_argument_count_with_cstring(const char *p_function); +godot_variant_type GDAPI godot_variant_get_utility_function_argument_type(const godot_string_name *p_function, int p_argument); +godot_variant_type GDAPI godot_variant_get_utility_function_argument_type_with_cstring(const char *p_function, int p_argument); +godot_string GDAPI godot_variant_get_utility_function_argument_name(const godot_string_name *p_function, int p_argument); +godot_string GDAPI godot_variant_get_utility_function_argument_name_with_cstring(const char *p_function, int p_argument); +bool GDAPI godot_variant_has_utility_function_return_value(const godot_string_name *p_function); +bool GDAPI godot_variant_has_utility_function_return_value_with_cstring(const char *p_function); +godot_variant_type GDAPI godot_variant_get_utility_function_return_type(const godot_string_name *p_function); +godot_variant_type GDAPI godot_variant_get_utility_function_return_type_with_cstring(const char *p_function); +bool GDAPI godot_variant_is_utility_function_vararg(const godot_string_name *p_function); +bool GDAPI godot_variant_is_utility_function_vararg_with_cstring(const char *p_function); +int GDAPI godot_variant_get_utility_function_count(); +void GDAPI godot_variant_get_utility_function_list(godot_string_name *r_functions); + +// Introspection. + +godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self); +bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string_name *p_method); +bool GDAPI godot_variant_has_member(godot_variant_type p_type, const godot_string_name *p_member); +bool GDAPI godot_variant_has_key(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid); + +godot_string GDAPI godot_variant_get_type_name(godot_variant_type p_type); +bool GDAPI godot_variant_can_convert(godot_variant_type p_from, godot_variant_type p_to); +bool GDAPI godot_variant_can_convert_strict(godot_variant_type p_from, godot_variant_type p_to); #ifdef __cplusplus } diff --git a/core/os/rw_lock.cpp b/modules/gdnative/include/gdnative/variant_struct.h index 26db0aab30..321c76c206 100644 --- a/core/os/rw_lock.cpp +++ b/modules/gdnative/include/gdnative/variant_struct.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rw_lock.cpp */ +/* variant_struct.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,26 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rw_lock.h" +#ifndef GODOT_VARIANT_STRUCT_H +#define GODOT_VARIANT_STRUCT_H -#include "core/error/error_macros.h" +#ifdef __cplusplus +extern "C" { +#endif -#include <stddef.h> +#include <gdnative/math_defs.h> -RWLock *(*RWLock::create_func)() = nullptr; +#define GODOT_VARIANT_SIZE (sizeof(godot_real_t) * 4 + sizeof(int64_t)) -RWLock *RWLock::create() { - ERR_FAIL_COND_V(!create_func, nullptr); +#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED +typedef struct { + uint8_t _dont_touch_that[GODOT_VARIANT_SIZE]; +} godot_variant; +#endif - return create_func(); +#ifdef __cplusplus } +#endif + +#endif diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h index eb146a9232..5ebb705ba4 100644 --- a/modules/gdnative/include/gdnative/vector2.h +++ b/modules/gdnative/include/gdnative/vector2.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_VECTOR2_SIZE 8 +#define GODOT_VECTOR2_SIZE (sizeof(godot_real_t) * 2) #ifndef GODOT_CORE_API_GODOT_VECTOR2_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VECTOR2_TYPE_DEFINED @@ -46,7 +46,7 @@ typedef struct { } godot_vector2; #endif -#define GODOT_VECTOR2I_SIZE 8 +#define GODOT_VECTOR2I_SIZE (sizeof(int32_t) * 2) #ifndef GODOT_CORE_API_GODOT_VECTOR2I_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VECTOR2I_TYPE_DEFINED @@ -55,140 +55,14 @@ typedef struct { } godot_vector2i; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - #include <gdnative/gdnative.h> -#ifdef __cplusplus -extern "C" { -#endif - -// Vector2 - -void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y); - -godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self); - -godot_vector2i GDAPI godot_vector2_as_vector2i(const godot_vector2 *p_self); - -godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self); - -godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self); - -godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_self); - -godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self); - -godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self); - -godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to); - -godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to); - -godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot_vector2 *p_to); - -godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to); - -godot_vector2 GDAPI godot_vector2_lerp(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t); - -godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t); - -godot_vector2 GDAPI godot_vector2_move_toward(const godot_vector2 *p_self, const godot_vector2 *p_to, const godot_real p_delta); - -godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi); - -godot_vector2 GDAPI godot_vector2_orthogonal(const godot_vector2 *p_self); - -godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self); - -godot_vector2 GDAPI godot_vector2_sign(const godot_vector2 *p_self); - -godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by); - -godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self); - -godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_self, const godot_vector2 *p_with); - -godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_self, const godot_vector2 *p_n); - -godot_vector2 GDAPI godot_vector2_bounce(const godot_vector2 *p_self, const godot_vector2 *p_n); - -godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_self, const godot_vector2 *p_n); - -godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_self); - -godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const godot_real p_length); - -godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_self, const godot_real p_b); - -godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_self, const godot_real p_b); - -godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_self, const godot_vector2 *p_b); - -godot_vector2 GDAPI godot_vector2_operator_neg(const godot_vector2 *p_self); - -void GDAPI godot_vector2_set_x(godot_vector2 *p_self, const godot_real p_x); - -void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y); - -godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self); - -godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self); - -// Vector2i - -void GDAPI godot_vector2i_new(godot_vector2i *r_dest, const godot_int p_x, const godot_int p_y); - -godot_string GDAPI godot_vector2i_as_string(const godot_vector2i *p_self); - -godot_vector2 GDAPI godot_vector2i_as_vector2(const godot_vector2i *p_self); - -godot_real GDAPI godot_vector2i_aspect(const godot_vector2i *p_self); - -godot_vector2i GDAPI godot_vector2i_abs(const godot_vector2i *p_self); - -godot_vector2i GDAPI godot_vector2i_sign(const godot_vector2i *p_self); - -godot_vector2i GDAPI godot_vector2i_operator_add(const godot_vector2i *p_self, const godot_vector2i *p_b); - -godot_vector2i GDAPI godot_vector2i_operator_subtract(const godot_vector2i *p_self, const godot_vector2i *p_b); - -godot_vector2i GDAPI godot_vector2i_operator_multiply_vector(const godot_vector2i *p_self, const godot_vector2i *p_b); - -godot_vector2i GDAPI godot_vector2i_operator_multiply_scalar(const godot_vector2i *p_self, const godot_int p_b); - -godot_vector2i GDAPI godot_vector2i_operator_divide_vector(const godot_vector2i *p_self, const godot_vector2i *p_b); - -godot_vector2i GDAPI godot_vector2i_operator_divide_scalar(const godot_vector2i *p_self, const godot_int p_b); - -godot_bool GDAPI godot_vector2i_operator_equal(const godot_vector2i *p_self, const godot_vector2i *p_b); - -godot_bool GDAPI godot_vector2i_operator_less(const godot_vector2i *p_self, const godot_vector2i *p_b); - -godot_vector2i GDAPI godot_vector2i_operator_neg(const godot_vector2i *p_self); - -void GDAPI godot_vector2i_set_x(godot_vector2i *p_self, const godot_int p_x); - -void GDAPI godot_vector2i_set_y(godot_vector2i *p_self, const godot_int p_y); - -godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self); - -godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self); +void GDAPI godot_vector2_new(godot_vector2 *p_self); +void GDAPI godot_vector2i_new(godot_vector2i *p_self); +godot_real_t GDAPI *godot_vector2_operator_index(godot_vector2 *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_vector2_operator_index_const(const godot_vector2 *p_self, godot_int p_index); +int32_t GDAPI *godot_vector2i_operator_index(godot_vector2i *p_self, godot_int p_index); +const int32_t GDAPI *godot_vector2i_operator_index_const(const godot_vector2i *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h index e0205c2fc7..d37ebd3cc9 100644 --- a/modules/gdnative/include/gdnative/vector3.h +++ b/modules/gdnative/include/gdnative/vector3.h @@ -35,9 +35,9 @@ extern "C" { #endif -#include <stdint.h> +#include <gdnative/math_defs.h> -#define GODOT_VECTOR3_SIZE 12 +#define GODOT_VECTOR3_SIZE (sizeof(godot_real_t) * 3) #ifndef GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED @@ -46,7 +46,7 @@ typedef struct { } godot_vector3; #endif -#define GODOT_VECTOR3I_SIZE 12 +#define GODOT_VECTOR3I_SIZE (sizeof(int32_t) * 3) #ifndef GODOT_CORE_API_GODOT_VECTOR3I_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VECTOR3I_TYPE_DEFINED @@ -55,145 +55,14 @@ typedef struct { } godot_vector3i; #endif -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/basis.h> #include <gdnative/gdnative.h> -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - GODOT_VECTOR3_AXIS_X, - GODOT_VECTOR3_AXIS_Y, - GODOT_VECTOR3_AXIS_Z, -} godot_vector3_axis; - -// Vector3 - -void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z); - -godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self); - -godot_vector3i GDAPI godot_vector3_as_vector3i(const godot_vector3 *p_self); - -godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self); - -godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self); - -godot_real GDAPI godot_vector3_length(const godot_vector3 *p_self); - -godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_self); - -godot_bool GDAPI godot_vector3_is_normalized(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const godot_vector3 *p_by); - -godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi); - -godot_vector3 GDAPI godot_vector3_lerp(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t); - -godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t); - -godot_vector3 GDAPI godot_vector3_move_toward(const godot_vector3 *p_self, const godot_vector3 *p_to, const godot_real p_delta); - -godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_sign(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self); - -godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_self, const godot_vector3 *p_to); - -godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_self, const godot_vector3 *p_n); - -godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_self, const godot_vector3 *p_n); - -godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const godot_vector3 *p_n); - -godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_self, const godot_real p_b); - -godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_self, const godot_real p_b); - -godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_self, const godot_vector3 *p_b); - -godot_vector3 GDAPI godot_vector3_operator_neg(const godot_vector3 *p_self); - -void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val); - -godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis); - -// Vector3i - -void GDAPI godot_vector3i_new(godot_vector3i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_z); - -godot_string GDAPI godot_vector3i_as_string(const godot_vector3i *p_self); - -godot_vector3 GDAPI godot_vector3i_as_vector3(const godot_vector3i *p_self); - -godot_int GDAPI godot_vector3i_min_axis(const godot_vector3i *p_self); - -godot_int GDAPI godot_vector3i_max_axis(const godot_vector3i *p_self); - -godot_vector3i GDAPI godot_vector3i_abs(const godot_vector3i *p_self); - -godot_vector3i GDAPI godot_vector3i_sign(const godot_vector3i *p_self); - -godot_vector3i GDAPI godot_vector3i_operator_add(const godot_vector3i *p_self, const godot_vector3i *p_b); - -godot_vector3i GDAPI godot_vector3i_operator_subtract(const godot_vector3i *p_self, const godot_vector3i *p_b); - -godot_vector3i GDAPI godot_vector3i_operator_multiply_vector(const godot_vector3i *p_self, const godot_vector3i *p_b); - -godot_vector3i GDAPI godot_vector3i_operator_multiply_scalar(const godot_vector3i *p_self, const godot_int p_b); - -godot_vector3i GDAPI godot_vector3i_operator_divide_vector(const godot_vector3i *p_self, const godot_vector3i *p_b); - -godot_vector3i GDAPI godot_vector3i_operator_divide_scalar(const godot_vector3i *p_self, const godot_int p_b); - -godot_bool GDAPI godot_vector3i_operator_equal(const godot_vector3i *p_self, const godot_vector3i *p_b); - -godot_bool GDAPI godot_vector3i_operator_less(const godot_vector3i *p_self, const godot_vector3i *p_b); - -godot_vector3i GDAPI godot_vector3i_operator_neg(const godot_vector3i *p_self); - -void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val); - -godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis); +void GDAPI godot_vector3_new(godot_vector3 *p_self); +void GDAPI godot_vector3i_new(godot_vector3i *p_self); +godot_real_t GDAPI *godot_vector3_operator_index(godot_vector3 *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_vector3_operator_index_const(const godot_vector3 *p_self, godot_int p_index); +int32_t GDAPI *godot_vector3i_operator_index(godot_vector3i *p_self, godot_int p_index); +const int32_t GDAPI *godot_vector3i_operator_index_const(const godot_vector3i *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h index 9de47edf87..86fc745134 100644 --- a/modules/gdnative/include/text/godot_text.h +++ b/modules/gdnative/include/text/godot_text.h @@ -74,11 +74,19 @@ typedef struct { godot_rid (*create_font_system)(void *, const godot_string *, int); godot_rid (*create_font_resource)(void *, const godot_string *, int); godot_rid (*create_font_memory)(void *, const uint8_t *, size_t, godot_string *, int); + godot_rid (*create_font_bitmap)(void *, float, float, int); + void (*font_bitmap_add_texture)(void *, godot_rid *, const godot_object *); + void (*font_bitmap_add_char)(void *, godot_rid *, char32_t, int, const godot_rect2 *, const godot_vector2 *, float); + void (*font_bitmap_add_kerning_pair)(void *, godot_rid *, char32_t, char32_t, int); float (*font_get_height)(void *, godot_rid *, int); float (*font_get_ascent)(void *, godot_rid *, int); float (*font_get_descent)(void *, godot_rid *, int); float (*font_get_underline_position)(void *, godot_rid *, int); float (*font_get_underline_thickness)(void *, godot_rid *, int); + int (*font_get_spacing_space)(void *, godot_rid *); + void (*font_set_spacing_space)(void *, godot_rid *, int); + int (*font_get_spacing_glyph)(void *, godot_rid *); + void (*font_set_spacing_glyph)(void *, godot_rid *, int); void (*font_set_antialiased)(void *, godot_rid *, bool); bool (*font_get_antialiased)(void *, godot_rid *); godot_dictionary (*font_get_feature_list)(void *, godot_rid *); @@ -175,8 +183,8 @@ void GDAPI godot_glyph_set_flags(godot_glyph *p_self, godot_int p_flags); godot_vector2 GDAPI godot_glyph_get_offset(const godot_glyph *p_self); void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_offset); -godot_real GDAPI godot_glyph_get_advance(const godot_glyph *p_self); -void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real p_advance); +godot_float GDAPI godot_glyph_get_advance(const godot_glyph *p_self); +void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_float p_advance); godot_rid GDAPI godot_glyph_get_font(const godot_glyph *p_self); void GDAPI godot_glyph_set_font(godot_glyph *p_self, godot_rid *p_font); diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h index e5a2657997..dc2cf5ec07 100644 --- a/modules/gdnative/include/videodecoder/godot_videodecoder.h +++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h @@ -49,11 +49,11 @@ typedef struct const char *(*get_plugin_name)(); const char **(*get_supported_extensions)(int *count); godot_bool (*open_file)(void *, void *); // data struct, and a FileAccess pointer - godot_real (*get_length)(const void *); - godot_real (*get_playback_position)(const void *); - void (*seek)(void *, godot_real); + godot_float (*get_length)(const void *); + godot_float (*get_playback_position)(const void *); + void (*seek)(void *, godot_float); void (*set_audio_track)(void *, godot_int); - void (*update)(void *, godot_real); + void (*update)(void *, godot_float); godot_packed_byte_array *(*get_videoframe)(void *); godot_int (*get_audioframe)(void *, float *, int); godot_int (*get_channels)(const void *); diff --git a/modules/gdnative/include/xr/godot_xr.h b/modules/gdnative/include/xr/godot_xr.h index 235242bc84..7eaf1c7ec3 100644 --- a/modules/gdnative/include/xr/godot_xr.h +++ b/modules/gdnative/include/xr/godot_xr.h @@ -58,7 +58,7 @@ typedef struct { void (*uninitialize)(void *); godot_vector2 (*get_render_targetsize)(const void *); godot_transform (*get_transform_for_eye)(void *, godot_int, godot_transform *); - void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real); + void (*fill_projection_for_eye)(void *, godot_float *, godot_int, godot_float, godot_float, godot_float); void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *); void (*process)(void *); godot_int (*get_external_texture_for_eye)(void *, godot_int); @@ -69,7 +69,7 @@ typedef struct { void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface); // helper functions to access XRServer data -godot_real GDAPI godot_xr_get_worldscale(); +godot_float GDAPI godot_xr_get_worldscale(); godot_transform GDAPI godot_xr_get_reference_frame(); // helper functions for rendering @@ -81,8 +81,8 @@ godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, g void GDAPI godot_xr_remove_controller(godot_int p_controller_id); void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position); void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed); -void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative); -godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id); +void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_float p_value, godot_bool p_can_be_negative); +godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id); #ifdef __cplusplus } diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 6b46c9418a..3e75478cd8 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -36,6 +36,7 @@ #include "core/core_constants.h" #include "core/object/class_db.h" #include "core/os/file_access.h" +#include "core/string/string_builder.h" #include "core/templates/pair.h" // helper stuff @@ -65,14 +66,14 @@ struct MethodAPI { Map<int, Variant> default_arguments; - int argument_count; - bool has_varargs; - bool is_editor; - bool is_noscript; - bool is_const; - bool is_reverse; - bool is_virtual; - bool is_from_script; + int argument_count = 0; + bool has_varargs = false; + bool is_editor = false; + bool is_noscript = false; + bool is_const = false; + bool is_reverse = false; + bool is_virtual = false; + bool is_from_script = false; }; struct PropertyAPI { @@ -80,12 +81,14 @@ struct PropertyAPI { String getter; String setter; String type; - int index; + int index = 0; }; struct ConstantAPI { String constant_name; - int constant_value; + int constant_value = 0; + Variant builtin_constant_value; // For builtin types; + String builtin_constant_type; // For builtin types; }; struct SignalAPI { @@ -100,23 +103,35 @@ struct EnumAPI { List<Pair<int, String>> values; }; +struct OperatorAPI { // For builtin types; + String name; + int oper = Variant::OP_MAX; + String other_type; + String return_type; +}; + struct ClassAPI { String class_name; String super_class_name; - ClassDB::APIType api_type; + ClassDB::APIType api_type = ClassDB::API_NONE; - bool is_singleton; + bool is_singleton = false; String singleton_name; - bool is_instanciable; + bool is_instantiable = false; // @Unclear - bool is_reference; + bool is_reference = false; + bool has_indexing = false; // For builtin types. + String indexed_type; // For builtin types. + bool is_keyed = false; // For builtin types. List<MethodAPI> methods; + List<MethodAPI> constructors; // For builtin types. List<PropertyAPI> properties; List<ConstantAPI> constants; List<SignalAPI> signals_; List<EnumAPI> enums; + List<OperatorAPI> operators; // For builtin types. }; static String get_type_name(const PropertyInfo &info) { @@ -127,7 +142,7 @@ static String get_type_name(const PropertyInfo &info) { return info.class_name; } if (info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - return info.hint_string; + return info.class_name; } if (info.type == Variant::NIL && (info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) { return "Variant"; @@ -180,13 +195,34 @@ List<ClassAPI> generate_c_api_classes() { global_constants_api.api_type = ClassDB::API_CORE; global_constants_api.is_singleton = true; global_constants_api.singleton_name = "CoreConstants"; - global_constants_api.is_instanciable = false; + global_constants_api.is_instantiable = false; const int constants_count = CoreConstants::get_global_constant_count(); + + Map<StringName, EnumAPI> enum_api_map; for (int i = 0; i < constants_count; ++i) { - ConstantAPI constant_api; - constant_api.constant_name = CoreConstants::get_global_constant_name(i); - constant_api.constant_value = CoreConstants::get_global_constant_value(i); - global_constants_api.constants.push_back(constant_api); + StringName enum_name = CoreConstants::get_global_constant_enum(i); + String name = String(CoreConstants::get_global_constant_name(i)); + int value = CoreConstants::get_global_constant_value(i); + + if (enum_name == StringName()) { + ConstantAPI constant_api; + constant_api.constant_name = name; + constant_api.constant_value = value; + global_constants_api.constants.push_back(constant_api); + } else { + EnumAPI enum_api; + if (enum_api_map.has(enum_name)) { + enum_api = enum_api_map[enum_name]; + } else { + enum_api.name = String(enum_name); + } + enum_api.values.push_back(Pair(value, name)); + + enum_api_map[enum_name] = enum_api; + } + } + for (const Map<StringName, EnumAPI>::Element *E = enum_api_map.front(); E; E = E->next()) { + global_constants_api.enums.push_back(E->get()); } global_constants_api.constants.sort_custom<ConstantAPIComparator>(); api.push_back(global_constants_api); @@ -195,6 +231,10 @@ List<ClassAPI> generate_c_api_classes() { for (List<StringName>::Element *e = classes.front(); e != nullptr; e = e->next()) { StringName class_name = e->get(); + if (!ClassDB::is_class_exposed(class_name)) { + continue; + } + ClassAPI class_api; class_api.api_type = ClassDB::get_api_type(e->get()); class_api.class_name = class_name; @@ -209,7 +249,7 @@ List<ClassAPI> generate_c_api_classes() { class_api.singleton_name = name; } } - class_api.is_instanciable = !class_api.is_singleton && ClassDB::can_instance(class_name); + class_api.is_instantiable = !class_api.is_singleton && ClassDB::can_instance(class_name); { List<StringName> inheriters; @@ -290,7 +330,9 @@ List<ClassAPI> generate_c_api_classes() { property_api.type = p->get().name.get_slice(":", 1); property_api.name = p->get().name.get_slice(":", 0); } else { - property_api.type = get_type_name(p->get()); + MethodInfo minfo; + ClassDB::get_method_info(class_name, property_api.getter, &minfo, true, false); + property_api.type = get_type_name(minfo.return_val); } property_api.index = ClassDB::get_property_index(class_name, p->get().name); @@ -352,7 +394,7 @@ List<ClassAPI> generate_c_api_classes() { arg_type = arg_info.name.get_slice(":", 1); arg_name = arg_info.name.get_slice(":", 0); } else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - arg_type = arg_info.hint_string; + arg_type = arg_info.class_name; } else if (arg_info.type == Variant::NIL) { arg_type = "Variant"; } else if (arg_info.type == Variant::OBJECT) { @@ -402,6 +444,192 @@ List<ClassAPI> generate_c_api_classes() { } /* + * Reads the builtin Variant API to a list + */ +List<ClassAPI> generate_c_builtin_api_types() { + List<ClassAPI> api; + + // Special class for the utility methods. + { + ClassAPI utility_api; + utility_api.class_name = "Utilities"; + utility_api.is_instantiable = false; + + List<StringName> utility_functions; + Variant::get_utility_function_list(&utility_functions); + for (const List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { + const StringName &function_name = E->get(); + + MethodAPI function_api; + function_api.method_name = function_name; + function_api.has_varargs = Variant::is_utility_function_vararg(function_name); + function_api.argument_count = function_api.has_varargs ? 0 : Variant::get_utility_function_argument_count(function_name); + function_api.is_const = Variant::get_utility_function_type(function_name) == Variant::UTILITY_FUNC_TYPE_MATH; + + for (int i = 0; i < function_api.argument_count; i++) { + function_api.argument_names.push_back(Variant::get_utility_function_argument_name(function_name, i)); + Variant::Type arg_type = Variant::get_utility_function_argument_type(function_name, i); + function_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type)); + } + + if (Variant::has_utility_function_return_value(function_name)) { + Variant::Type ret_type = Variant::get_utility_function_return_type(function_name); + function_api.return_type = ret_type == Variant::NIL ? "Variant" : Variant::get_type_name(ret_type); + } else { + function_api.return_type = "void"; + } + + utility_api.methods.push_back(function_api); + } + + api.push_back(utility_api); + } + + for (int t = 0; t < Variant::VARIANT_MAX; t++) { + Variant::Type type = (Variant::Type)t; + + ClassAPI class_api; + class_api.class_name = Variant::get_type_name(type); + class_api.is_instantiable = true; + class_api.has_indexing = Variant::has_indexing(type); + class_api.indexed_type = Variant::get_type_name(Variant::get_indexed_element_type(type)); + class_api.is_keyed = Variant::is_keyed(type); + // Types that are passed by reference. + switch (type) { + case Variant::OBJECT: + case Variant::DICTIONARY: + case Variant::ARRAY: + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: + case Variant::PACKED_COLOR_ARRAY: + class_api.is_reference = true; + break; + default: + class_api.is_reference = false; + break; + } + + // Methods. + + List<StringName> methods; + Variant::get_builtin_method_list(type, &methods); + for (const List<StringName>::Element *E = methods.front(); E; E = E->next()) { + const StringName &method_name = E->get(); + + MethodAPI method_api; + + method_api.method_name = method_name; + method_api.argument_count = Variant::get_builtin_method_argument_count(type, method_name); + method_api.has_varargs = Variant::is_builtin_method_vararg(type, method_name); + method_api.is_const = Variant::is_builtin_method_const(type, method_name); + + for (int i = 0; i < method_api.argument_count; i++) { + method_api.argument_names.push_back(Variant::get_builtin_method_argument_name(type, method_name, i)); + Variant::Type arg_type = Variant::get_builtin_method_argument_type(type, method_name, i); + method_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type)); + } + + Vector<Variant> default_arguments = Variant::get_builtin_method_default_arguments(type, method_name); + + int default_start = method_api.argument_names.size() - default_arguments.size(); + + for (int i = 0; i < default_arguments.size(); i++) { + method_api.default_arguments[default_start + i] = default_arguments[i]; + } + + if (Variant::has_builtin_method_return_value(type, method_name)) { + Variant::Type ret_type = Variant::get_builtin_method_return_type(type, method_name); + method_api.return_type = ret_type == Variant::NIL ? "Variant" : Variant::get_type_name(ret_type); + } else { + method_api.return_type = "void"; + } + + class_api.methods.push_back(method_api); + } + + // Constructors. + + for (int c = 0; c < Variant::get_constructor_count(type); c++) { + MethodAPI constructor_api; + + constructor_api.method_name = Variant::get_type_name(type); + constructor_api.argument_count = Variant::get_constructor_argument_count(type, c); + constructor_api.return_type = Variant::get_type_name(type); + + for (int i = 0; i < constructor_api.argument_count; i++) { + constructor_api.argument_names.push_back(Variant::get_constructor_argument_name(type, c, i)); + Variant::Type arg_type = Variant::get_constructor_argument_type(type, c, i); + constructor_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type)); + } + + class_api.constructors.push_back(constructor_api); + } + + // Constants. + + List<StringName> constants; + Variant::get_constants_for_type(type, &constants); + for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) { + const StringName &constant_name = E->get(); + ConstantAPI constant_api; + + constant_api.constant_name = constant_name; + constant_api.builtin_constant_value = Variant::get_constant_value(type, constant_name); + constant_api.builtin_constant_type = Variant::get_type_name(constant_api.builtin_constant_value.get_type()); + + class_api.constants.push_back(constant_api); + } + + // Members. + + List<StringName> members; + Variant::get_member_list(type, &members); + for (const List<StringName>::Element *E = members.front(); E; E = E->next()) { + const StringName &member_name = E->get(); + + PropertyAPI member_api; + member_api.name = member_name; + Variant::Type member_type = Variant::get_member_type(type, member_name); + member_api.type = member_type == Variant::NIL ? "Variant" : Variant::get_type_name(member_type); + + class_api.properties.push_back(member_api); + } + + // Operators. + + for (int op = 0; op < Variant::OP_MAX; op++) { + Variant::Operator oper = (Variant::Operator)op; + + for (int ot = 0; ot < Variant::VARIANT_MAX; ot++) { + Variant::Type other_type = (Variant::Type)ot; + + if (!Variant::get_validated_operator_evaluator(oper, type, other_type)) { + continue; + } + + OperatorAPI oper_api; + oper_api.name = Variant::get_operator_name(oper); + oper_api.oper = oper; + oper_api.other_type = Variant::get_type_name(other_type); + oper_api.return_type = Variant::get_type_name(Variant::get_operator_return_type(oper, type, other_type)); + + class_api.operators.push_back(oper_api); + } + } + + api.push_back(class_api); + } + + return api; +} + +/* * Generates the JSON source from the API in p_api */ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { @@ -421,9 +649,8 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { source.push_back(String("\t\t\"api_type\": \"") + (api.api_type == ClassDB::API_CORE ? "core" : (api.api_type == ClassDB::API_EDITOR ? "tools" : "none")) + "\",\n"); source.push_back(String("\t\t\"singleton\": ") + (api.is_singleton ? "true" : "false") + ",\n"); source.push_back("\t\t\"singleton_name\": \"" + api.singleton_name + "\",\n"); - source.push_back(String("\t\t\"instanciable\": ") + (api.is_instanciable ? "true" : "false") + ",\n"); + source.push_back(String("\t\t\"instantiable\": ") + (api.is_instantiable ? "true" : "false") + ",\n"); source.push_back(String("\t\t\"is_reference\": ") + (api.is_reference ? "true" : "false") + ",\n"); - // @Unclear source.push_back("\t\t\"constants\": {\n"); for (List<ConstantAPI>::Element *e = api.constants.front(); e; e = e->next()) { @@ -508,6 +735,165 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) { return source; } +static int indent_level = 0; + +static void append_indented(StringBuilder &p_source, const String &p_text) { + for (int i = 0; i < indent_level; i++) { + p_source.append("\t"); + } + p_source.append(p_text); + p_source.append("\n"); +} + +static void append_indented(StringBuilder &p_source, const char *p_text) { + for (int i = 0; i < indent_level; i++) { + p_source.append("\t"); + } + p_source.append(p_text); + p_source.append("\n"); +} + +static void write_builtin_method(StringBuilder &p_source, const MethodAPI &p_method) { + append_indented(p_source, vformat(R"("name": "%s",)", p_method.method_name)); + append_indented(p_source, vformat(R"("return_type": "%s",)", p_method.return_type)); + append_indented(p_source, vformat(R"("is_const": %s,)", p_method.is_const ? "true" : "false")); + append_indented(p_source, vformat(R"("has_varargs": %s,)", p_method.has_varargs ? "true" : "false")); + + append_indented(p_source, R"("arguments": [)"); + indent_level++; + for (int i = 0; i < p_method.argument_count; i++) { + append_indented(p_source, "{"); + indent_level++; + + append_indented(p_source, vformat(R"("name": "%s",)", p_method.argument_names[i])); + append_indented(p_source, vformat(R"("type": "%s",)", p_method.argument_types[i])); + append_indented(p_source, vformat(R"("has_default_value": %s,)", p_method.default_arguments.has(i) ? "true" : "false")); + append_indented(p_source, vformat(R"("default_value": "%s")", p_method.default_arguments.has(i) ? p_method.default_arguments[i].operator String() : "")); + + indent_level--; + append_indented(p_source, i < p_method.argument_count - 1 ? "}," : "}"); + } + indent_level--; + append_indented(p_source, "]"); +} + +static List<String> generate_c_builtin_api_json(const List<ClassAPI> &p_api) { + StringBuilder source; + + source.append("[\n"); + + indent_level = 1; + + for (const List<ClassAPI>::Element *C = p_api.front(); C; C = C->next()) { + const ClassAPI &class_api = C->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", class_api.class_name)); + append_indented(source, vformat(R"("is_instantiable": %s,)", class_api.is_instantiable ? "true" : "false")); + append_indented(source, vformat(R"("is_reference": %s,)", class_api.is_reference ? "true" : "false")); + append_indented(source, vformat(R"("has_indexing": %s,)", class_api.has_indexing ? "true" : "false")); + append_indented(source, vformat(R"("indexed_type": "%s",)", class_api.has_indexing && class_api.indexed_type == "Nil" ? "Variant" : class_api.indexed_type)); + append_indented(source, vformat(R"("is_keyed": %s,)", class_api.is_keyed ? "true" : "false")); + + // Constructors. + append_indented(source, R"("constructors": [)"); + indent_level++; + for (const List<MethodAPI>::Element *E = class_api.constructors.front(); E; E = E->next()) { + const MethodAPI &constructor = E->get(); + append_indented(source, "{"); + indent_level++; + + write_builtin_method(source, constructor); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Constants. + append_indented(source, R"("constants": [)"); + indent_level++; + for (const List<ConstantAPI>::Element *E = class_api.constants.front(); E; E = E->next()) { + const ConstantAPI &constant = E->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", constant.constant_name)); + append_indented(source, vformat(R"("type": "%s",)", constant.builtin_constant_type)); + append_indented(source, vformat(R"("value": "%s")", constant.builtin_constant_value.operator String())); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Methods. + append_indented(source, R"("methods": [)"); + indent_level++; + for (const List<MethodAPI>::Element *E = class_api.methods.front(); E; E = E->next()) { + const MethodAPI &method = E->get(); + append_indented(source, "{"); + indent_level++; + + write_builtin_method(source, method); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Members. + append_indented(source, R"("members": [)"); + indent_level++; + for (const List<PropertyAPI>::Element *E = class_api.properties.front(); E; E = E->next()) { + const PropertyAPI &member = E->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", member.name)); + append_indented(source, vformat(R"("type": "%s")", member.type)); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "],"); + + // Operators. + append_indented(source, R"("operators": [)"); + indent_level++; + for (const List<OperatorAPI>::Element *E = class_api.operators.front(); E; E = E->next()) { + const OperatorAPI &oper = E->get(); + append_indented(source, "{"); + indent_level++; + + append_indented(source, vformat(R"("name": "%s",)", oper.name)); + append_indented(source, vformat(R"("operator": %d,)", oper.oper)); + append_indented(source, vformat(R"("other_type": "%s",)", oper.other_type)); + append_indented(source, vformat(R"("return_type": "%s")", oper.return_type)); + + indent_level--; + append_indented(source, E->next() ? "}," : "}"); + } + indent_level--; + append_indented(source, "]"); + + indent_level--; + append_indented(source, C->next() ? "}," : "}"); + } + + indent_level--; + source.append("]\n"); + + List<String> result; + result.push_back(source.as_string()); + return result; +} + #endif /* @@ -526,3 +912,19 @@ Error generate_c_api(const String &p_path) { return save_file(p_path, json_source); #endif } +/* + * Saves the builtin Godot API to a JSON file located at + * p_path + */ +Error generate_c_builtin_api(const String &p_path) { +#ifndef TOOLS_ENABLED + return ERR_BUG; +#else + + List<ClassAPI> api = generate_c_builtin_api_types(); + + List<String> json_source = generate_c_builtin_api_json(api); + + return save_file(p_path, json_source); +#endif +} diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h index a324ded4a9..611abb2a2d 100644 --- a/modules/gdnative/nativescript/api_generator.h +++ b/modules/gdnative/nativescript/api_generator.h @@ -35,5 +35,6 @@ #include "core/typedefs.h" Error generate_c_api(const String &p_path); +Error generate_c_builtin_api(const String &p_path); #endif // API_GENERATOR_H diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index e08961564d..1bdbb0b03b 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1196,13 +1196,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; -#ifndef NO_THREADS - has_objects_to_register = false; -#endif - -#ifdef DEBUG_ENABLED - profiling = false; -#endif _init_call_type = "nativescript_init"; _init_call_name = "nativescript_init"; @@ -1257,6 +1250,15 @@ void NativeScriptLanguage::init() { } exit(0); } + + E = args.find("--gdnative-generate-json-builtin-api"); + + if (E && E->next()) { + if (generate_c_builtin_api(E->next()->get()) != OK) { + ERR_PRINT("Failed to generate C builtin API\n"); + } + exit(0); + } #endif #ifdef TOOLS_ENABLED @@ -1668,7 +1670,7 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc MutexLock lock(mutex); libs_to_init.insert(lib); scripts_to_register.insert(script); - has_objects_to_register = true; + has_objects_to_register.set(); } #endif @@ -1724,6 +1726,12 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) { S->get().erase(script); if (S->get().size() == 0) { library_script_users.erase(S); + + Map<String, Ref<GDNative>>::Element *G = library_gdnatives.find(script->lib_path); + if (G && G->get()->get_library()->is_reloadable()) { + G->get()->terminate(); + library_gdnatives.erase(G); + } } } #ifndef NO_THREADS @@ -1751,7 +1759,7 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) { void NativeScriptLanguage::frame() { #ifndef NO_THREADS - if (has_objects_to_register) { + if (has_objects_to_register.is_set()) { MutexLock lock(mutex); for (Set<Ref<GDNativeLibrary>>::Element *L = libs_to_init.front(); L; L = L->next()) { init_library(L->get()); @@ -1761,7 +1769,7 @@ void NativeScriptLanguage::frame() { register_script(S->get()); } scripts_to_register.clear(); - has_objects_to_register = false; + has_objects_to_register.clear(); } #endif @@ -1932,7 +1940,7 @@ void NativeReloadNode::_notification(int p_what) { #endif } -RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_no_cache) { return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 9d72bf39d1..d6ba2bbec1 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -40,6 +40,7 @@ #include "core/os/thread_safe.h" #include "core/templates/oa_hash_map.h" #include "core/templates/ordered_hash_map.h" +#include "core/templates/safe_refcount.h" #include "core/templates/self_list.h" #include "scene/main/node.h" @@ -51,8 +52,8 @@ struct NativeScriptDesc { struct Method { godot_nativescript_instance_method method; MethodInfo info; - int rpc_mode; - uint16_t rpc_method_id; + int rpc_mode = 0; + uint16_t rpc_method_id = 0; String documentation; }; @@ -61,7 +62,7 @@ struct NativeScriptDesc { godot_nativescript_property_get_func getter; PropertyInfo info; Variant default_value; - int rset_mode; + int rset_mode = 0; uint16_t rset_property_id; String documentation; }; @@ -78,7 +79,7 @@ struct NativeScriptDesc { Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals StringName base; StringName base_native_type; - NativeScriptDesc *base_data; + NativeScriptDesc *base_data = nullptr; godot_nativescript_instance_create_func create_func; godot_nativescript_instance_destroy_func destroy_func; @@ -86,7 +87,7 @@ struct NativeScriptDesc { const void *type_tag = nullptr; - bool is_tool; + bool is_tool = false; inline NativeScriptDesc() { zeromem(&create_func, sizeof(godot_nativescript_instance_create_func)); @@ -254,7 +255,7 @@ class NativeScriptLanguage : public ScriptLanguage { private: static NativeScriptLanguage *singleton; - int lang_idx; + int lang_idx = 0; void _unload_stuff(bool p_reload = false); @@ -262,7 +263,7 @@ private: #ifndef NO_THREADS Set<Ref<GDNativeLibrary>> libs_to_init; Set<NativeScript *> scripts_to_register; - volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed + SafeFlag has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed void defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script); #endif @@ -279,19 +280,19 @@ private: struct ProfileData { StringName signature; - uint64_t call_count; - uint64_t self_time; - uint64_t total_time; - uint64_t frame_call_count; - uint64_t frame_self_time; - uint64_t frame_total_time; - uint64_t last_frame_call_count; - uint64_t last_frame_self_time; - uint64_t last_frame_total_time; + uint64_t call_count = 0; + uint64_t self_time = 0; + uint64_t total_time = 0; + uint64_t frame_call_count = 0; + uint64_t frame_self_time = 0; + uint64_t frame_total_time = 0; + uint64_t last_frame_call_count = 0; + uint64_t last_frame_self_time = 0; + uint64_t last_frame_total_time = 0; }; Map<StringName, ProfileData> profile_data; - bool profiling; + bool profiling = false; public: // These two maps must only be touched on the main thread @@ -402,7 +403,7 @@ public: class ResourceFormatLoaderNativeScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index 865080fddf..536eb550e0 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -44,10 +44,10 @@ class PluginScriptInstance : public ScriptInstance { private: Ref<PluginScript> _script; - Object *_owner; + Object *_owner = nullptr; Variant _owner_variant; - godot_pluginscript_instance_data *_data; - const godot_pluginscript_instance_desc *_desc; + godot_pluginscript_instance_data *_data = nullptr; + const godot_pluginscript_instance_desc *_desc = nullptr; public: _FORCE_INLINE_ Object *get_owner() { return _owner; } diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp index cd1879a13e..f2165cd225 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.cpp +++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp @@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL _language = language; } -RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index 7b1a7f5423..e5d665c186 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -43,7 +43,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader { public: ResourceFormatLoaderPluginScript(PluginScriptLanguage *language); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/tests/test_string.h b/modules/gdnative/tests/test_string.h deleted file mode 100644 index 3e2ba7451b..0000000000 --- a/modules/gdnative/tests/test_string.h +++ /dev/null @@ -1,1979 +0,0 @@ -/*************************************************************************/ -/* test_string.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef TEST_GDNATIVE_STRING_H -#define TEST_GDNATIVE_STRING_H - -namespace TestGDNativeString { - -#include "gdnative/string.h" - -#include "tests/test_macros.h" - -int u32scmp(const char32_t *l, const char32_t *r) { - for (; *l == *r && *l && *r; l++, r++) - ; - return *l - *r; -} - -TEST_CASE("[GDNative String] Construct from Latin-1 char string") { - godot_string s; - - godot_string_new_with_latin1_chars(&s, "Hello"); - CHECK(u32scmp(godot_string_get_data(&s), U"Hello") == 0); - godot_string_destroy(&s); - - godot_string_new_with_latin1_chars_and_len(&s, "Hello", 3); - CHECK(u32scmp(godot_string_get_data(&s), U"Hel") == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Construct from wchar_t string") { - godot_string s; - - godot_string_new_with_wide_chars(&s, L"Give me"); - CHECK(u32scmp(godot_string_get_data(&s), U"Give me") == 0); - godot_string_destroy(&s); - - godot_string_new_with_wide_chars_and_len(&s, L"Give me", 3); - CHECK(u32scmp(godot_string_get_data(&s), U"Giv") == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Construct from UTF-8 char string") { - static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; - static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x304A, 0 }; - static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 }; - - godot_string s; - - godot_string_new_with_utf8_chars(&s, (const char *)u8str); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf8_chars_and_len(&s, (const char *)u8str, 5); - CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf32_chars(&s, u32str); - godot_char_string cs = godot_string_utf8(&s); - godot_string_parse_utf8(&s, godot_char_string_get_data(&cs)); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - godot_char_string_destroy(&cs); - - godot_string_new_with_utf32_chars(&s, u32str); - cs = godot_string_utf8(&s); - godot_string_parse_utf8_with_len(&s, godot_char_string_get_data(&cs), godot_char_string_length(&cs)); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - godot_char_string_destroy(&cs); -} - -TEST_CASE("[GDNative String] Construct from UTF-8 string with BOM") { - static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; - static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x304A, 0 }; - static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 }; - - godot_string s; - - godot_string_new_with_utf8_chars(&s, (const char *)u8str); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf8_chars_and_len(&s, (const char *)u8str, 8); - CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Construct from UTF-16 string") { - static const char32_t u32str[] = { 0x0045, 0x0020, 0x1F3A4, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; - static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x1F3A4, 0 }; - static const char16_t u16str[] = { 0x0045, 0x0020, 0xD83C, 0xDFA4, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 }; - - godot_string s; - - godot_string_new_with_utf16_chars(&s, u16str); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf16_chars_and_len(&s, u16str, 4); - CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf32_chars(&s, u32str); - godot_char16_string cs = godot_string_utf16(&s); - godot_string_parse_utf16(&s, godot_char16_string_get_data(&cs)); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - godot_char16_string_destroy(&cs); - - godot_string_new_with_utf32_chars(&s, u32str); - cs = godot_string_utf16(&s); - godot_string_parse_utf16_with_len(&s, godot_char16_string_get_data(&cs), godot_char16_string_length(&cs)); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - godot_char16_string_destroy(&cs); -} - -TEST_CASE("[GDNative String] Construct from UTF-16 string with BOM ") { - static const char32_t u32str[] = { 0x0045, 0x0020, 0x1F3A4, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; - static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x1F3A4, 0 }; - static const char16_t u16str[] = { 0xFEFF, 0x0045, 0x0020, 0xD83C, 0xDFA4, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 }; - static const char16_t u16str_swap[] = { 0xFFFE, 0x4500, 0x2000, 0x3CD8, 0xA4DF, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 }; - - godot_string s; - - godot_string_new_with_utf16_chars(&s, u16str); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf16_chars(&s, u16str_swap); - CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf16_chars_and_len(&s, u16str, 5); - CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0); - godot_string_destroy(&s); - - godot_string_new_with_utf16_chars_and_len(&s, u16str_swap, 5); - CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Construct string copy") { - godot_string s, t; - - godot_string_new_with_latin1_chars(&s, "Hello"); - godot_string_new_copy(&t, &s); - CHECK(u32scmp(godot_string_get_data(&t), U"Hello") == 0); - godot_string_destroy(&t); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Construct empty string") { - godot_string s; - - godot_string_new(&s); - CHECK(u32scmp(godot_string_get_data(&s), U"") == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] ASCII/Latin-1") { - godot_string s; - godot_string_new_with_utf32_chars(&s, U"Primero Leche"); - - godot_char_string cs = godot_string_ascii(&s); - CHECK(strcmp(godot_char_string_get_data(&cs), "Primero Leche") == 0); - godot_char_string_destroy(&cs); - - cs = godot_string_latin1(&s); - CHECK(strcmp(godot_char_string_get_data(&cs), "Primero Leche") == 0); - godot_char_string_destroy(&cs); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Comparisons (equal)") { - godot_string s, t; - - godot_string_new_with_latin1_chars(&s, "Test Compare"); - godot_string_new_with_latin1_chars(&t, "Test Compare"); - CHECK(godot_string_operator_equal(&s, &t)); - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] Comparisons (operator <)") { - godot_string s, t; - - godot_string_new_with_latin1_chars(&s, "Bees"); - - godot_string_new_with_latin1_chars(&t, "Elephant"); - CHECK(godot_string_operator_less(&s, &t)); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Amber"); - CHECK(!godot_string_operator_less(&s, &t)); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Beatrix"); - CHECK(!godot_string_operator_less(&s, &t)); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Concatenation (operator +)") { - godot_string s, t, x; - - godot_string_new_with_latin1_chars(&s, "Hel"); - godot_string_new_with_latin1_chars(&t, "lo"); - x = godot_string_operator_plus(&s, &t); - CHECK(u32scmp(godot_string_get_data(&x), U"Hello") == 0); - godot_string_destroy(&x); - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] Testing size and length of string") { - godot_string s; - - godot_string_new_with_latin1_chars(&s, "Mellon"); - CHECK(godot_string_length(&s) == 6); - godot_string_destroy(&s); - - godot_string_new_with_latin1_chars(&s, "Mellon1"); - CHECK(godot_string_length(&s) == 7); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Testing for empty string") { - godot_string s; - - godot_string_new_with_latin1_chars(&s, "Mellon"); - CHECK(!godot_string_is_empty(&s)); - godot_string_destroy(&s); - - godot_string_new_with_latin1_chars(&s, ""); - CHECK(godot_string_is_empty(&s)); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Test chr") { - godot_string s; - - s = godot_string_chr('H'); - CHECK(u32scmp(godot_string_get_data(&s), U"H") == 0); - godot_string_destroy(&s); - - s = godot_string_chr(0x3012); - CHECK(godot_string_operator_index_const(&s, 0) == 0x3012); - godot_string_destroy(&s); - - ERR_PRINT_OFF - s = godot_string_chr(0xd812); - CHECK(godot_string_operator_index_const(&s, 0) == 0xfffd); // Unpaired UTF-16 surrogate - godot_string_destroy(&s); - - s = godot_string_chr(0x20d812); - CHECK(godot_string_operator_index_const(&s, 0) == 0xfffd); // Outside UTF-32 range - godot_string_destroy(&s); - ERR_PRINT_ON -} - -TEST_CASE("[GDNative String] Operator []") { - godot_string s; - - godot_string_new_with_latin1_chars(&s, "Hello"); - CHECK(*godot_string_operator_index(&s, 1) == 'e'); - CHECK(godot_string_operator_index_const(&s, 0) == 'H'); - CHECK(godot_string_ord_at(&s, 0) == 'H'); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Case function test") { - godot_string s, t; - - godot_string_new_with_latin1_chars(&s, "MoMoNgA"); - - t = godot_string_to_upper(&s); - CHECK(u32scmp(godot_string_get_data(&t), U"MOMONGA") == 0); - godot_string_destroy(&t); - - t = godot_string_to_lower(&s); - CHECK(u32scmp(godot_string_get_data(&t), U"momonga") == 0); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Case compare function test") { - godot_string s, t; - - godot_string_new_with_latin1_chars(&s, "MoMoNgA"); - godot_string_new_with_latin1_chars(&t, "momonga"); - - CHECK(godot_string_casecmp_to(&s, &t) != 0); - CHECK(godot_string_nocasecmp_to(&s, &t) == 0); - - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] Natural compare function test") { - godot_string s, t; - - godot_string_new_with_latin1_chars(&s, "img2.png"); - godot_string_new_with_latin1_chars(&t, "img10.png"); - - CHECK(godot_string_nocasecmp_to(&s, &t) > 0); - CHECK(godot_string_naturalnocasecmp_to(&s, &t) < 0); - - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] hex_encode_buffer") { - static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3 }; - godot_string s = godot_string_hex_encode_buffer(u8str, 6); - CHECK(u32scmp(godot_string_get_data(&s), U"45e3818a8fe3") == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Substr") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "Killer Baby"); - t = godot_string_substr(&s, 3, 4); - CHECK(u32scmp(godot_string_get_data(&t), U"ler ") == 0); - godot_string_destroy(&t); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Find") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "Pretty Woman Woman"); - - godot_string_new_with_latin1_chars(&t, "Revenge of the Monster Truck"); - CHECK(godot_string_find(&s, &t) == -1); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "tty"); - CHECK(godot_string_find(&s, &t) == 3); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Wo"); - CHECK(godot_string_find_from(&s, &t, 9) == 13); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "man"); - CHECK(godot_string_rfind(&s, &t) == 15); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Find no case") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "Pretty Whale Whale"); - - godot_string_new_with_latin1_chars(&t, "WHA"); - CHECK(godot_string_findn(&s, &t) == 7); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "WHA"); - CHECK(godot_string_findn_from(&s, &t, 9) == 13); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "WHA"); - CHECK(godot_string_rfindn(&s, &t) == 13); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Revenge of the Monster SawFish"); - CHECK(godot_string_findn(&s, &t) == -1); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Find MK") { - godot_packed_string_array keys; - godot_packed_string_array_new(&keys); - -#define PUSH_KEY(x) \ - { \ - godot_string t; \ - godot_string_new_with_latin1_chars(&t, x); \ - godot_packed_string_array_push_back(&keys, &t); \ - godot_string_destroy(&t); \ - } - - PUSH_KEY("sty") - PUSH_KEY("tty") - PUSH_KEY("man") - - godot_string s; - godot_string_new_with_latin1_chars(&s, "Pretty Woman"); - godot_int key = 0; - - CHECK(godot_string_findmk(&s, &keys) == 3); - CHECK(godot_string_findmk_from_in_place(&s, &keys, 0, &key) == 3); - CHECK(key == 1); - - CHECK(godot_string_findmk_from(&s, &keys, 5) == 9); - CHECK(godot_string_findmk_from_in_place(&s, &keys, 5, &key) == 9); - CHECK(key == 2); - - godot_string_destroy(&s); - godot_packed_string_array_destroy(&keys); - -#undef PUSH_KEY -} - -TEST_CASE("[GDNative String] Find and replace") { - godot_string s, c, w; - godot_string_new_with_latin1_chars(&s, "Happy Birthday, Anna!"); - godot_string_new_with_latin1_chars(&c, "Birthday"); - godot_string_new_with_latin1_chars(&w, "Halloween"); - godot_string t = godot_string_replace(&s, &c, &w); - CHECK(u32scmp(godot_string_get_data(&t), U"Happy Halloween, Anna!") == 0); - godot_string_destroy(&s); - godot_string_destroy(&c); - godot_string_destroy(&w); - - godot_string_new_with_latin1_chars(&c, "H"); - godot_string_new_with_latin1_chars(&w, "W"); - s = godot_string_replace_first(&t, &c, &w); - godot_string_destroy(&t); - godot_string_destroy(&c); - godot_string_destroy(&w); - - CHECK(u32scmp(godot_string_get_data(&s), U"Wappy Halloween, Anna!") == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Insertion") { - godot_string s, t, r, u; - godot_string_new_with_latin1_chars(&s, "Who is Frederic?"); - godot_string_new_with_latin1_chars(&t, "?"); - godot_string_new_with_latin1_chars(&r, " Chopin"); - - u = godot_string_insert(&s, godot_string_find(&s, &t), &r); - CHECK(u32scmp(godot_string_get_data(&u), U"Who is Frederic Chopin?") == 0); - - godot_string_destroy(&s); - godot_string_destroy(&t); - godot_string_destroy(&r); - godot_string_destroy(&u); -} - -TEST_CASE("[GDNative String] Number to string") { - godot_string s; - s = godot_string_num(3.141593); - CHECK(u32scmp(godot_string_get_data(&s), U"3.141593") == 0); - godot_string_destroy(&s); - - s = godot_string_num_with_decimals(3.141593, 3); - CHECK(u32scmp(godot_string_get_data(&s), U"3.142") == 0); - godot_string_destroy(&s); - - s = godot_string_num_real(3.141593); - CHECK(u32scmp(godot_string_get_data(&s), U"3.141593") == 0); - godot_string_destroy(&s); - - s = godot_string_num_scientific(30000000); - CHECK(u32scmp(godot_string_get_data(&s), U"3e+07") == 0); - godot_string_destroy(&s); - - s = godot_string_num_int64(3141593, 10); - CHECK(u32scmp(godot_string_get_data(&s), U"3141593") == 0); - godot_string_destroy(&s); - - s = godot_string_num_int64(0xA141593, 16); - CHECK(u32scmp(godot_string_get_data(&s), U"a141593") == 0); - godot_string_destroy(&s); - - s = godot_string_num_int64_capitalized(0xA141593, 16, true); - CHECK(u32scmp(godot_string_get_data(&s), U"A141593") == 0); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] String to integer") { - static const wchar_t *wnums[4] = { L"1237461283", L"- 22", L"0", L" - 1123412" }; - static const char *nums[4] = { "1237461283", "- 22", "0", " - 1123412" }; - static const int num[4] = { 1237461283, -22, 0, -1123412 }; - - for (int i = 0; i < 4; i++) { - godot_string s; - godot_string_new_with_latin1_chars(&s, nums[i]); - CHECK(godot_string_to_int(&s) == num[i]); - godot_string_destroy(&s); - - CHECK(godot_string_char_to_int(nums[i]) == num[i]); - CHECK(godot_string_wchar_to_int(wnums[i]) == num[i]); - } -} - -TEST_CASE("[GDNative String] Hex to integer") { - static const char *nums[4] = { "0xFFAE", "22", "0", "AADDAD" }; - static const int64_t num[4] = { 0xFFAE, 0x22, 0, 0xAADDAD }; - static const bool wo_prefix[4] = { false, true, true, true }; - static const bool w_prefix[4] = { true, false, true, false }; - - for (int i = 0; i < 4; i++) { - godot_string s; - godot_string_new_with_latin1_chars(&s, nums[i]); - CHECK((godot_string_hex_to_int_with_prefix(&s) == num[i]) == w_prefix[i]); - CHECK((godot_string_hex_to_int(&s) == num[i]) == wo_prefix[i]); - godot_string_destroy(&s); - } -} - -TEST_CASE("[GDNative String] String to float") { - static const wchar_t *wnums[4] = { L"-12348298412.2", L"0.05", L"2.0002", L" -0.0001" }; - static const char *nums[4] = { "-12348298412.2", "0.05", "2.0002", " -0.0001" }; - static const double num[4] = { -12348298412.2, 0.05, 2.0002, -0.0001 }; - - for (int i = 0; i < 4; i++) { - godot_string s; - godot_string_new_with_latin1_chars(&s, nums[i]); - CHECK(!(ABS(godot_string_to_float(&s) - num[i]) > 0.00001)); - godot_string_destroy(&s); - - CHECK(!(ABS(godot_string_char_to_float(nums[i]) - num[i]) > 0.00001)); - CHECK(!(ABS(godot_string_wchar_to_float(wnums[i], nullptr) - num[i]) > 0.00001)); - } -} - -TEST_CASE("[GDNative String] CamelCase to underscore") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "TestTestStringGD"); - - t = godot_string_camelcase_to_underscore(&s); - CHECK(u32scmp(godot_string_get_data(&t), U"Test_Test_String_GD") == 0); - godot_string_destroy(&t); - - t = godot_string_camelcase_to_underscore_lowercased(&s); - CHECK(u32scmp(godot_string_get_data(&t), U"test_test_string_gd") == 0); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Slicing") { - godot_string s, c; - godot_string_new_with_latin1_chars(&s, "Mars,Jupiter,Saturn,Uranus"); - godot_string_new_with_latin1_chars(&c, ","); - - const char32_t *slices[4] = { U"Mars", U"Jupiter", U"Saturn", U"Uranus" }; - for (int i = 0; i < godot_string_get_slice_count(&s, &c); i++) { - godot_string t; - t = godot_string_get_slice(&s, &c, i); - CHECK(u32scmp(godot_string_get_data(&t), slices[i]) == 0); - godot_string_destroy(&t); - - t = godot_string_get_slicec(&s, U',', i); - CHECK(u32scmp(godot_string_get_data(&t), slices[i]) == 0); - godot_string_destroy(&t); - } - - godot_string_destroy(&c); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Splitting") { - godot_string s, c; - godot_string_new_with_latin1_chars(&s, "Mars,Jupiter,Saturn,Uranus"); - godot_string_new_with_latin1_chars(&c, ","); - - godot_packed_string_array l; - - const char32_t *slices_l[3] = { U"Mars", U"Jupiter", U"Saturn,Uranus" }; - const char32_t *slices_r[3] = { U"Mars,Jupiter", U"Saturn", U"Uranus" }; - - l = godot_string_split_with_maxsplit(&s, &c, true, 2); - CHECK(godot_packed_string_array_size(&l) == 3); - for (int i = 0; i < godot_packed_string_array_size(&l); i++) { - godot_string t = godot_packed_string_array_get(&l, i); - CHECK(u32scmp(godot_string_get_data(&t), slices_l[i]) == 0); - godot_string_destroy(&t); - } - godot_packed_string_array_destroy(&l); - - l = godot_string_rsplit_with_maxsplit(&s, &c, true, 2); - CHECK(godot_packed_string_array_size(&l) == 3); - for (int i = 0; i < godot_packed_string_array_size(&l); i++) { - godot_string t = godot_packed_string_array_get(&l, i); - CHECK(u32scmp(godot_string_get_data(&t), slices_r[i]) == 0); - godot_string_destroy(&t); - } - godot_packed_string_array_destroy(&l); - godot_string_destroy(&s); - - godot_string_new_with_latin1_chars(&s, "Mars Jupiter Saturn Uranus"); - const char32_t *slices_s[4] = { U"Mars", U"Jupiter", U"Saturn", U"Uranus" }; - l = godot_string_split_spaces(&s); - for (int i = 0; i < godot_packed_string_array_size(&l); i++) { - godot_string t = godot_packed_string_array_get(&l, i); - CHECK(u32scmp(godot_string_get_data(&t), slices_s[i]) == 0); - godot_string_destroy(&t); - } - godot_packed_string_array_destroy(&l); - godot_string_destroy(&s); - - godot_string c1, c2; - godot_string_new_with_latin1_chars(&c1, ";"); - godot_string_new_with_latin1_chars(&c2, " "); - - godot_string_new_with_latin1_chars(&s, "1.2;2.3 4.5"); - const double slices_d[3] = { 1.2, 2.3, 4.5 }; - - godot_packed_float32_array lf = godot_string_split_floats_allow_empty(&s, &c1); - CHECK(godot_packed_float32_array_size(&lf) == 2); - for (int i = 0; i < godot_packed_float32_array_size(&lf); i++) { - CHECK(ABS(godot_packed_float32_array_get(&lf, i) - slices_d[i]) <= 0.00001); - } - godot_packed_float32_array_destroy(&lf); - - godot_packed_string_array keys; - godot_packed_string_array_new(&keys); - godot_packed_string_array_push_back(&keys, &c1); - godot_packed_string_array_push_back(&keys, &c2); - - lf = godot_string_split_floats_mk_allow_empty(&s, &keys); - CHECK(godot_packed_float32_array_size(&lf) == 3); - for (int i = 0; i < godot_packed_float32_array_size(&lf); i++) { - CHECK(ABS(godot_packed_float32_array_get(&lf, i) - slices_d[i]) <= 0.00001); - } - godot_packed_float32_array_destroy(&lf); - - godot_string_destroy(&s); - godot_string_new_with_latin1_chars(&s, "1;2 4"); - const int slices_i[3] = { 1, 2, 4 }; - - godot_packed_int32_array li = godot_string_split_ints_allow_empty(&s, &c1); - CHECK(godot_packed_int32_array_size(&li) == 2); - for (int i = 0; i < godot_packed_int32_array_size(&li); i++) { - CHECK(godot_packed_int32_array_get(&li, i) == slices_i[i]); - } - godot_packed_int32_array_destroy(&li); - - li = godot_string_split_ints_mk_allow_empty(&s, &keys); - CHECK(godot_packed_int32_array_size(&li) == 3); - for (int i = 0; i < godot_packed_int32_array_size(&li); i++) { - CHECK(godot_packed_int32_array_get(&li, i) == slices_i[i]); - } - godot_packed_int32_array_destroy(&li); - - godot_string_destroy(&s); - godot_string_destroy(&c); - godot_string_destroy(&c1); - godot_string_destroy(&c2); - godot_packed_string_array_destroy(&keys); -} - -TEST_CASE("[GDNative String] Erasing") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "Josephine is such a cute girl!"); - godot_string_new_with_latin1_chars(&t, "cute "); - - godot_string_erase(&s, godot_string_find(&s, &t), godot_string_length(&t)); - - CHECK(u32scmp(godot_string_get_data(&s), U"Josephine is such a girl!") == 0); - - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -struct test_27_data { - char const *data; - char const *part; - bool expected; -}; - -TEST_CASE("[GDNative String] Begins with") { - test_27_data tc[] = { - { "res://foobar", "res://", true }, - { "res", "res://", false }, - { "abc", "abc", true } - }; - size_t count = sizeof(tc) / sizeof(tc[0]); - bool state = true; - for (size_t i = 0; state && i < count; ++i) { - godot_string s; - godot_string_new_with_latin1_chars(&s, tc[i].data); - - state = godot_string_begins_with_char_array(&s, tc[i].part) == tc[i].expected; - if (state) { - godot_string t; - godot_string_new_with_latin1_chars(&t, tc[i].part); - state = godot_string_begins_with(&s, &t) == tc[i].expected; - godot_string_destroy(&t); - } - godot_string_destroy(&s); - - CHECK(state); - if (!state) { - break; - } - }; - CHECK(state); -} - -TEST_CASE("[GDNative String] Ends with") { - test_27_data tc[] = { - { "res://foobar", "foobar", true }, - { "res", "res://", false }, - { "abc", "abc", true } - }; - size_t count = sizeof(tc) / sizeof(tc[0]); - bool state = true; - for (size_t i = 0; state && i < count; ++i) { - godot_string s; - godot_string_new_with_latin1_chars(&s, tc[i].data); - - state = godot_string_ends_with_char_array(&s, tc[i].part) == tc[i].expected; - if (state) { - godot_string t; - godot_string_new_with_latin1_chars(&t, tc[i].part); - state = godot_string_ends_with(&s, &t) == tc[i].expected; - godot_string_destroy(&t); - } - godot_string_destroy(&s); - - CHECK(state); - if (!state) { - break; - } - }; - CHECK(state); -} - -TEST_CASE("[GDNative String] format") { - godot_string value_format, t; - godot_string_new_with_latin1_chars(&value_format, "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\""); - - godot_variant key_v, val_v; - godot_dictionary value_dictionary; - godot_dictionary_new(&value_dictionary); - - godot_string_new_with_latin1_chars(&t, "red"); - godot_variant_new_string(&key_v, &t); - godot_string_destroy(&t); - godot_variant_new_int(&val_v, 10); - godot_dictionary_set(&value_dictionary, &key_v, &val_v); - godot_variant_destroy(&key_v); - godot_variant_destroy(&val_v); - - godot_string_new_with_latin1_chars(&t, "green"); - godot_variant_new_string(&key_v, &t); - godot_string_destroy(&t); - godot_variant_new_int(&val_v, 20); - godot_dictionary_set(&value_dictionary, &key_v, &val_v); - godot_variant_destroy(&key_v); - godot_variant_destroy(&val_v); - - godot_string_new_with_latin1_chars(&t, "blue"); - godot_variant_new_string(&key_v, &t); - godot_string_destroy(&t); - godot_string_new_with_latin1_chars(&t, "bla"); - godot_variant_new_string(&val_v, &t); - godot_string_destroy(&t); - godot_dictionary_set(&value_dictionary, &key_v, &val_v); - godot_variant_destroy(&key_v); - godot_variant_destroy(&val_v); - - godot_string_new_with_latin1_chars(&t, "alpha"); - godot_variant_new_string(&key_v, &t); - godot_string_destroy(&t); - godot_variant_new_real(&val_v, 0.4); - godot_dictionary_set(&value_dictionary, &key_v, &val_v); - godot_variant_destroy(&key_v); - godot_variant_destroy(&val_v); - - godot_variant dict_v; - godot_variant_new_dictionary(&dict_v, &value_dictionary); - godot_string s = godot_string_format_with_custom_placeholder(&value_format, &dict_v, "$_"); - - CHECK(u32scmp(godot_string_get_data(&s), U"red=\"10\" green=\"20\" blue=\"bla\" alpha=\"0.4\"") == 0); - - godot_dictionary_destroy(&value_dictionary); - godot_string_destroy(&s); - godot_variant_destroy(&dict_v); - godot_string_destroy(&value_format); -} - -TEST_CASE("[GDNative String] sprintf") { - //godot_string GDAPI (const godot_string *p_self, const godot_array *p_values, godot_bool *p_error); - godot_string format, output; - godot_array args; - bool error; - -#define ARRAY_PUSH_STRING(x) \ - { \ - godot_variant v; \ - godot_string t; \ - godot_string_new_with_latin1_chars(&t, x); \ - godot_variant_new_string(&v, &t); \ - godot_string_destroy(&t); \ - godot_array_push_back(&args, &v); \ - godot_variant_destroy(&v); \ - } - -#define ARRAY_PUSH_INT(x) \ - { \ - godot_variant v; \ - godot_variant_new_int(&v, x); \ - godot_array_push_back(&args, &v); \ - godot_variant_destroy(&v); \ - } - -#define ARRAY_PUSH_REAL(x) \ - { \ - godot_variant v; \ - godot_variant_new_real(&v, x); \ - godot_array_push_back(&args, &v); \ - godot_variant_destroy(&v); \ - } - - godot_array_new(&args); - - // %% - godot_string_new_with_latin1_chars(&format, "fish %% frog"); - godot_array_clear(&args); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish % frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - //////// INTS - - // Int - godot_string_new_with_latin1_chars(&format, "fish %d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(5); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Int left padded with zeroes. - godot_string_new_with_latin1_chars(&format, "fish %05d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(5); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 00005 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Int left padded with spaces. - godot_string_new_with_latin1_chars(&format, "fish %5d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(5); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Int right padded with spaces. - godot_string_new_with_latin1_chars(&format, "fish %-5d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(5); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Int with sign (positive). - godot_string_new_with_latin1_chars(&format, "fish %+d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(5); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish +5 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Negative int. - godot_string_new_with_latin1_chars(&format, "fish %d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(-5); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish -5 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Hex (lower) - godot_string_new_with_latin1_chars(&format, "fish %x frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(45); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 2d frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Hex (upper) - godot_string_new_with_latin1_chars(&format, "fish %X frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(45); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 2D frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Octal - godot_string_new_with_latin1_chars(&format, "fish %o frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 143 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - ////// REALS - - // Real - godot_string_new_with_latin1_chars(&format, "fish %f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real left-padded - godot_string_new_with_latin1_chars(&format, "fish %11f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real right-padded - godot_string_new_with_latin1_chars(&format, "fish %-11f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real given int. - godot_string_new_with_latin1_chars(&format, "fish %f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.000000 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real with sign (positive). - godot_string_new_with_latin1_chars(&format, "fish %+f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish +99.990000 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real with 1 decimals. - godot_string_new_with_latin1_chars(&format, "fish %.1f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 100.0 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real with 12 decimals. - godot_string_new_with_latin1_chars(&format, "fish %.12f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000000000 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Real with no decimals. - godot_string_new_with_latin1_chars(&format, "fish %.f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 100 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - /////// Strings. - - // String - godot_string_new_with_latin1_chars(&format, "fish %s frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // String left-padded - godot_string_new_with_latin1_chars(&format, "fish %10s frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // String right-padded - godot_string_new_with_latin1_chars(&format, "fish %-10s frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - ///// Characters - - // Character as string. - godot_string_new_with_latin1_chars(&format, "fish %c frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("A"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish A frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Character as int. - godot_string_new_with_latin1_chars(&format, "fish %c frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(65); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish A frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - ///// Dynamic width - - // String dynamic width - godot_string_new_with_latin1_chars(&format, "fish %*s frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(10); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - REQUIRE(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Int dynamic width - godot_string_new_with_latin1_chars(&format, "fish %*d frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(10); - ARRAY_PUSH_INT(99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - REQUIRE(u32scmp(godot_string_get_data(&output), U"fish 99 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Float dynamic width - godot_string_new_with_latin1_chars(&format, "fish %*.*f frog"); - godot_array_clear(&args); - ARRAY_PUSH_INT(10); - ARRAY_PUSH_INT(3); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error == false); - CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990 frog") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - ///// Errors - - // More formats than arguments. - godot_string_new_with_latin1_chars(&format, "fish %s %s frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"not enough arguments for format string") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // More arguments than formats. - godot_string_new_with_latin1_chars(&format, "fish %s frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("hello"); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"not all arguments converted during string formatting") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Incomplete format. - godot_string_new_with_latin1_chars(&format, "fish %10"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"incomplete format") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Bad character in format string - godot_string_new_with_latin1_chars(&format, "fish %&f frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"unsupported format character") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Too many decimals. - godot_string_new_with_latin1_chars(&format, "fish %2.2.2f frog"); - godot_array_clear(&args); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"too many decimal points in format") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // * not a number - godot_string_new_with_latin1_chars(&format, "fish %*f frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("cheese"); - ARRAY_PUSH_REAL(99.99); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"* wants number") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Character too long. - godot_string_new_with_latin1_chars(&format, "fish %c frog"); - godot_array_clear(&args); - ARRAY_PUSH_STRING("sc"); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"%c requires number or single-character string") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - // Character bad type. - godot_string_new_with_latin1_chars(&format, "fish %c frog"); - godot_array_clear(&args); - godot_array t; - godot_array_new(&t); - godot_variant v; - godot_variant_new_array(&v, &t); - godot_array_destroy(&t); - godot_array_push_back(&args, &v); - godot_variant_destroy(&v); - output = godot_string_sprintf(&format, &args, &error); - REQUIRE(error); - CHECK(u32scmp(godot_string_get_data(&output), U"%c requires number or single-character string") == 0); - godot_string_destroy(&format); - godot_string_destroy(&output); - - godot_array_destroy(&args); -#undef ARRAY_PUSH_INT -#undef ARRAY_PUSH_REAL -#undef ARRAY_PUSH_STRING -} - -TEST_CASE("[GDNative String] is_numeric") { -#define IS_NUM_TEST(x, r) \ - { \ - godot_string t; \ - godot_string_new_with_latin1_chars(&t, x); \ - CHECK(godot_string_is_numeric(&t) == r); \ - godot_string_destroy(&t); \ - } - - IS_NUM_TEST("12", true); - IS_NUM_TEST("1.2", true); - IS_NUM_TEST("AF", false); - IS_NUM_TEST("-12", true); - IS_NUM_TEST("-1.2", true); - -#undef IS_NUM_TEST -} - -TEST_CASE("[GDNative String] pad") { - godot_string s, c; - godot_string_new_with_latin1_chars(&s, "test"); - godot_string_new_with_latin1_chars(&c, "x"); - - godot_string l = godot_string_lpad_with_custom_character(&s, 10, &c); - CHECK(u32scmp(godot_string_get_data(&l), U"xxxxxxtest") == 0); - godot_string_destroy(&l); - - godot_string r = godot_string_rpad_with_custom_character(&s, 10, &c); - CHECK(u32scmp(godot_string_get_data(&r), U"testxxxxxx") == 0); - godot_string_destroy(&r); - - godot_string_destroy(&s); - godot_string_destroy(&c); - - godot_string_new_with_latin1_chars(&s, "10.10"); - c = godot_string_pad_decimals(&s, 4); - CHECK(u32scmp(godot_string_get_data(&c), U"10.1000") == 0); - godot_string_destroy(&c); - c = godot_string_pad_zeros(&s, 4); - CHECK(u32scmp(godot_string_get_data(&c), U"0010.10") == 0); - godot_string_destroy(&c); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] is_subsequence_of") { - godot_string a, t; - godot_string_new_with_latin1_chars(&a, "is subsequence of"); - - godot_string_new_with_latin1_chars(&t, "sub"); - CHECK(godot_string_is_subsequence_of(&t, &a)); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Sub"); - CHECK(!godot_string_is_subsequence_of(&t, &a)); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Sub"); - CHECK(godot_string_is_subsequence_ofi(&t, &a)); - godot_string_destroy(&t); - - godot_string_destroy(&a); -} - -TEST_CASE("[GDNative String] match") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "*.png"); - - godot_string_new_with_latin1_chars(&t, "img1.png"); - CHECK(godot_string_match(&t, &s)); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "img1.jpeg"); - CHECK(!godot_string_match(&t, &s)); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "img1.Png"); - CHECK(!godot_string_match(&t, &s)); - CHECK(godot_string_matchn(&t, &s)); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] IPVX address to string") { - godot_string ip; - - godot_string_new_with_latin1_chars(&ip, "192.168.0.1"); - CHECK(godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); - - godot_string_new_with_latin1_chars(&ip, "192.368.0.1"); - CHECK(!godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); - - godot_string_new_with_latin1_chars(&ip, "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); - CHECK(godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); - - godot_string_new_with_latin1_chars(&ip, "2001:0db8:85j3:0000:0000:8a2e:0370:7334"); - CHECK(!godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); - - godot_string_new_with_latin1_chars(&ip, "2001:0db8:85f345:0000:0000:8a2e:0370:7334"); - CHECK(!godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); - - godot_string_new_with_latin1_chars(&ip, "2001:0db8::0:8a2e:370:7334"); - CHECK(godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); - - godot_string_new_with_latin1_chars(&ip, "::ffff:192.168.0.1"); - CHECK(godot_string_is_valid_ip_address(&ip)); - godot_string_destroy(&ip); -} - -TEST_CASE("[GDNative String] Capitalize against many strings") { -#define CAP_TEST(i, o) \ - godot_string_new_with_latin1_chars(&input, i); \ - godot_string_new_with_latin1_chars(&output, o); \ - test = godot_string_capitalize(&input); \ - CHECK(u32scmp(godot_string_get_data(&output), godot_string_get_data(&test)) == 0); \ - godot_string_destroy(&input); \ - godot_string_destroy(&output); \ - godot_string_destroy(&test); - - godot_string input, output, test; - - CAP_TEST("bytes2var", "Bytes 2 Var"); - CAP_TEST("linear2db", "Linear 2 Db"); - CAP_TEST("vector3", "Vector 3"); - CAP_TEST("sha256", "Sha 256"); - CAP_TEST("2db", "2 Db"); - CAP_TEST("PascalCase", "Pascal Case"); - CAP_TEST("PascalPascalCase", "Pascal Pascal Case"); - CAP_TEST("snake_case", "Snake Case"); - CAP_TEST("snake_snake_case", "Snake Snake Case"); - CAP_TEST("sha256sum", "Sha 256 Sum"); - CAP_TEST("cat2dog", "Cat 2 Dog"); - CAP_TEST("function(name)", "Function(name)"); - CAP_TEST("snake_case_function(snake_case_arg)", "Snake Case Function(snake Case Arg)"); - CAP_TEST("snake_case_function( snake_case_arg )", "Snake Case Function( Snake Case Arg )"); - -#undef CAP_TEST -} - -TEST_CASE("[GDNative String] lstrip and rstrip") { -#define LSTRIP_TEST(x, y, z) \ - { \ - godot_string xx, yy, zz, rr; \ - godot_string_new_with_latin1_chars(&xx, x); \ - godot_string_new_with_latin1_chars(&yy, y); \ - godot_string_new_with_latin1_chars(&zz, z); \ - rr = godot_string_lstrip(&xx, &yy); \ - state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \ - godot_string_destroy(&xx); \ - godot_string_destroy(&yy); \ - godot_string_destroy(&zz); \ - godot_string_destroy(&rr); \ - } - -#define RSTRIP_TEST(x, y, z) \ - { \ - godot_string xx, yy, zz, rr; \ - godot_string_new_with_latin1_chars(&xx, x); \ - godot_string_new_with_latin1_chars(&yy, y); \ - godot_string_new_with_latin1_chars(&zz, z); \ - rr = godot_string_rstrip(&xx, &yy); \ - state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \ - godot_string_destroy(&xx); \ - godot_string_destroy(&yy); \ - godot_string_destroy(&zz); \ - godot_string_destroy(&rr); \ - } - -#define LSTRIP_UTF8_TEST(x, y, z) \ - { \ - godot_string xx, yy, zz, rr; \ - godot_string_new_with_utf8_chars(&xx, x); \ - godot_string_new_with_utf8_chars(&yy, y); \ - godot_string_new_with_utf8_chars(&zz, z); \ - rr = godot_string_lstrip(&xx, &yy); \ - state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \ - godot_string_destroy(&xx); \ - godot_string_destroy(&yy); \ - godot_string_destroy(&zz); \ - godot_string_destroy(&rr); \ - } - -#define RSTRIP_UTF8_TEST(x, y, z) \ - { \ - godot_string xx, yy, zz, rr; \ - godot_string_new_with_utf8_chars(&xx, x); \ - godot_string_new_with_utf8_chars(&yy, y); \ - godot_string_new_with_utf8_chars(&zz, z); \ - rr = godot_string_rstrip(&xx, &yy); \ - state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \ - godot_string_destroy(&xx); \ - godot_string_destroy(&yy); \ - godot_string_destroy(&zz); \ - godot_string_destroy(&rr); \ - } - - bool state = true; - - // strip none - LSTRIP_TEST("abc", "", "abc"); - RSTRIP_TEST("abc", "", "abc"); - // strip one - LSTRIP_TEST("abc", "a", "bc"); - RSTRIP_TEST("abc", "c", "ab"); - // strip lots - LSTRIP_TEST("bababbababccc", "ab", "ccc"); - RSTRIP_TEST("aaabcbcbcbbcbbc", "cb", "aaa"); - // strip empty string - LSTRIP_TEST("", "", ""); - RSTRIP_TEST("", "", ""); - // strip to empty string - LSTRIP_TEST("abcabcabc", "bca", ""); - RSTRIP_TEST("abcabcabc", "bca", ""); - // don't strip wrong end - LSTRIP_TEST("abc", "c", "abc"); - LSTRIP_TEST("abca", "a", "bca"); - RSTRIP_TEST("abc", "a", "abc"); - RSTRIP_TEST("abca", "a", "abc"); - // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5) - // and the same second as "ÿ" (\u00ff) - LSTRIP_UTF8_TEST("¿", "µÿ", "¿"); - RSTRIP_UTF8_TEST("¿", "µÿ", "¿"); - LSTRIP_UTF8_TEST("樘", "µÿ", "¿ÿ"); - RSTRIP_UTF8_TEST("樘", "µÿ", "µ¿"); - - // the above tests repeated with additional superfluous strip chars - - // strip none - LSTRIP_TEST("abc", "qwjkl", "abc"); - RSTRIP_TEST("abc", "qwjkl", "abc"); - // strip one - LSTRIP_TEST("abc", "qwajkl", "bc"); - RSTRIP_TEST("abc", "qwcjkl", "ab"); - // strip lots - LSTRIP_TEST("bababbababccc", "qwabjkl", "ccc"); - RSTRIP_TEST("aaabcbcbcbbcbbc", "qwcbjkl", "aaa"); - // strip empty string - LSTRIP_TEST("", "qwjkl", ""); - RSTRIP_TEST("", "qwjkl", ""); - // strip to empty string - LSTRIP_TEST("abcabcabc", "qwbcajkl", ""); - RSTRIP_TEST("abcabcabc", "qwbcajkl", ""); - // don't strip wrong end - LSTRIP_TEST("abc", "qwcjkl", "abc"); - LSTRIP_TEST("abca", "qwajkl", "bca"); - RSTRIP_TEST("abc", "qwajkl", "abc"); - RSTRIP_TEST("abca", "qwajkl", "abc"); - // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5) - // and the same second as "ÿ" (\u00ff) - LSTRIP_UTF8_TEST("¿", "qwaµÿjkl", "¿"); - RSTRIP_UTF8_TEST("¿", "qwaµÿjkl", "¿"); - LSTRIP_UTF8_TEST("樘", "qwaµÿjkl", "¿ÿ"); - RSTRIP_UTF8_TEST("樘", "qwaµÿjkl", "µ¿"); - - CHECK(state); - -#undef LSTRIP_TEST -#undef RSTRIP_TEST -#undef LSTRIP_UTF8_TEST -#undef RSTRIP_UTF8_TEST -} - -TEST_CASE("[GDNative String] Cyrillic to_lower()") { - godot_string upper, lower, test; - godot_string_new_with_utf8_chars(&upper, "ÐБВГДЕÐЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬÐЮЯ"); - godot_string_new_with_utf8_chars(&lower, "абвгдеёжзийклмнопрÑтуфхцчшщъыьÑÑŽÑ"); - - test = godot_string_to_lower(&upper); - - CHECK((u32scmp(godot_string_get_data(&test), godot_string_get_data(&lower)) == 0)); - - godot_string_destroy(&upper); - godot_string_destroy(&lower); - godot_string_destroy(&test); -} - -TEST_CASE("[GDNative String] Count and countn functionality") { -#define COUNT_TEST(x, y, r) \ - { \ - godot_string s, t; \ - godot_string_new_with_latin1_chars(&s, x); \ - godot_string_new_with_latin1_chars(&t, y); \ - state = state && (godot_string_count(&s, &t, 0, 0) == r); \ - godot_string_destroy(&s); \ - godot_string_destroy(&t); \ - } - -#define COUNTR_TEST(x, y, a, b, r) \ - { \ - godot_string s, t; \ - godot_string_new_with_latin1_chars(&s, x); \ - godot_string_new_with_latin1_chars(&t, y); \ - state = state && (godot_string_count(&s, &t, a, b) == r); \ - godot_string_destroy(&s); \ - godot_string_destroy(&t); \ - } - -#define COUNTN_TEST(x, y, r) \ - { \ - godot_string s, t; \ - godot_string_new_with_latin1_chars(&s, x); \ - godot_string_new_with_latin1_chars(&t, y); \ - state = state && (godot_string_countn(&s, &t, 0, 0) == r); \ - godot_string_destroy(&s); \ - godot_string_destroy(&t); \ - } - -#define COUNTNR_TEST(x, y, a, b, r) \ - { \ - godot_string s, t; \ - godot_string_new_with_latin1_chars(&s, x); \ - godot_string_new_with_latin1_chars(&t, y); \ - state = state && (godot_string_countn(&s, &t, a, b) == r); \ - godot_string_destroy(&s); \ - godot_string_destroy(&t); \ - } - bool state = true; - - COUNT_TEST("", "Test", 0); - COUNT_TEST("Test", "", 0); - COUNT_TEST("Test", "test", 0); - COUNT_TEST("Test", "TEST", 0); - COUNT_TEST("TEST", "TEST", 1); - COUNT_TEST("Test", "Test", 1); - COUNT_TEST("aTest", "Test", 1); - COUNT_TEST("Testa", "Test", 1); - COUNT_TEST("TestTestTest", "Test", 3); - COUNT_TEST("TestTestTest", "TestTest", 1); - COUNT_TEST("TestGodotTestGodotTestGodot", "Test", 3); - - COUNTR_TEST("TestTestTestTest", "Test", 4, 8, 1); - COUNTR_TEST("TestTestTestTest", "Test", 4, 12, 2); - COUNTR_TEST("TestTestTestTest", "Test", 4, 16, 3); - COUNTR_TEST("TestTestTestTest", "Test", 4, 0, 3); - - COUNTN_TEST("Test", "test", 1); - COUNTN_TEST("Test", "TEST", 1); - COUNTN_TEST("testTest-Testatest", "tEst", 4); - COUNTNR_TEST("testTest-TeStatest", "tEsT", 4, 16, 2); - - CHECK(state); - -#undef COUNT_TEST -#undef COUNTR_TEST -#undef COUNTN_TEST -#undef COUNTNR_TEST -} - -TEST_CASE("[GDNative String] Bigrams") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, "abcd"); - godot_packed_string_array bigr = godot_string_bigrams(&s); - godot_string_destroy(&s); - - CHECK(godot_packed_string_array_size(&bigr) == 3); - - t = godot_packed_string_array_get(&bigr, 0); - CHECK(u32scmp(godot_string_get_data(&t), U"ab") == 0); - godot_string_destroy(&t); - - t = godot_packed_string_array_get(&bigr, 1); - CHECK(u32scmp(godot_string_get_data(&t), U"bc") == 0); - godot_string_destroy(&t); - - t = godot_packed_string_array_get(&bigr, 2); - CHECK(u32scmp(godot_string_get_data(&t), U"cd") == 0); - godot_string_destroy(&t); - - godot_packed_string_array_destroy(&bigr); -} - -TEST_CASE("[GDNative String] c-escape/unescape") { - godot_string s; - godot_string_new_with_latin1_chars(&s, "\\1\a2\b\f3\n45\r6\t7\v8\'9\?0\""); - godot_string t = godot_string_c_escape(&s); - godot_string u = godot_string_c_unescape(&t); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] dedent") { - godot_string s, t; - godot_string_new_with_latin1_chars(&s, " aaa\n bbb"); - godot_string_new_with_latin1_chars(&t, "aaa\nbbb"); - godot_string u = godot_string_dedent(&s); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Path functions") { - static const char *path[4] = { "C:\\Godot\\project\\test.tscn", "/Godot/project/test.xscn", "../Godot/project/test.scn", "Godot\\test.doc" }; - static const char *base_dir[4] = { "C:\\Godot\\project", "/Godot/project", "../Godot/project", "Godot" }; - static const char *base_name[4] = { "C:\\Godot\\project\\test", "/Godot/project/test", "../Godot/project/test", "Godot\\test" }; - static const char *ext[4] = { "tscn", "xscn", "scn", "doc" }; - static const char *file[4] = { "test.tscn", "test.xscn", "test.scn", "test.doc" }; - static const bool abs[4] = { true, true, false, false }; - - for (int i = 0; i < 4; i++) { - godot_string s, t, u, f; - godot_string_new_with_latin1_chars(&s, path[i]); - - t = godot_string_get_base_dir(&s); - godot_string_new_with_latin1_chars(&u, base_dir[i]); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - t = godot_string_get_basename(&s); - godot_string_new_with_latin1_chars(&u, base_name[i]); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - t = godot_string_get_extension(&s); - godot_string_new_with_latin1_chars(&u, ext[i]); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - t = godot_string_get_file(&s); - godot_string_new_with_latin1_chars(&u, file[i]); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string s_simp; - s_simp = godot_string_simplify_path(&s); - t = godot_string_get_base_dir(&s_simp); - godot_string_new_with_latin1_chars(&u, file[i]); - f = godot_string_plus_file(&t, &u); - CHECK(u32scmp(godot_string_get_data(&f), godot_string_get_data(&s_simp)) == 0); - godot_string_destroy(&f); - godot_string_destroy(&u); - godot_string_destroy(&t); - godot_string_destroy(&s_simp); - - CHECK(godot_string_is_abs_path(&s) == abs[i]); - CHECK(godot_string_is_rel_path(&s) != abs[i]); - - godot_string_destroy(&s); - } - - static const char *file_name[3] = { "test.tscn", "test://.xscn", "?tes*t.scn" }; - static const bool valid[3] = { true, false, false }; - for (int i = 0; i < 3; i++) { - godot_string s; - godot_string_new_with_latin1_chars(&s, file_name[i]); - CHECK(godot_string_is_valid_filename(&s) == valid[i]); - godot_string_destroy(&s); - } -} - -TEST_CASE("[GDNative String] hash") { - godot_string a, b, c; - godot_string_new_with_latin1_chars(&a, "Test"); - godot_string_new_with_latin1_chars(&b, "Test"); - godot_string_new_with_latin1_chars(&c, "West"); - CHECK(godot_string_hash(&a) == godot_string_hash(&b)); - CHECK(godot_string_hash(&a) != godot_string_hash(&c)); - - CHECK(godot_string_hash64(&a) == godot_string_hash64(&b)); - CHECK(godot_string_hash64(&a) != godot_string_hash64(&c)); - - godot_string_destroy(&a); - godot_string_destroy(&b); - godot_string_destroy(&c); -} - -TEST_CASE("[GDNative String] http_escape/unescape") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, "Godot Engine:'docs'"); - godot_string_new_with_latin1_chars(&t, "Godot%20Engine%3A%27docs%27"); - - u = godot_string_http_escape(&s); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - - u = godot_string_http_unescape(&t); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0); - godot_string_destroy(&u); - - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] percent_encode/decode") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, "Godot Engine:'docs'"); - godot_string_new_with_latin1_chars(&t, "Godot%20Engine%3a%27docs%27"); - - u = godot_string_percent_encode(&s); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - - u = godot_string_percent_decode(&t); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0); - godot_string_destroy(&u); - - godot_string_destroy(&s); - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] xml_escape/unescape") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, "\"Test\" <test@test&'test'>"); - - t = godot_string_xml_escape_with_quotes(&s); - u = godot_string_xml_unescape(&t); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - t = godot_string_xml_escape(&s); - u = godot_string_xml_unescape(&t); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Strip escapes") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, "\t\tTest Test\r\n Test"); - godot_string_new_with_latin1_chars(&t, "Test Test Test"); - - u = godot_string_strip_escapes(&s); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - - godot_string_destroy(&t); - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Strip edges") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, "\t Test Test "); - - godot_string_new_with_latin1_chars(&t, "Test Test "); - u = godot_string_strip_edges(&s, true, false); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "\t Test Test"); - u = godot_string_strip_edges(&s, false, true); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "Test Test"); - u = godot_string_strip_edges(&s, true, true); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Similarity") { - godot_string a, b, c; - godot_string_new_with_latin1_chars(&a, "Test"); - godot_string_new_with_latin1_chars(&b, "West"); - godot_string_new_with_latin1_chars(&c, "Toad"); - - CHECK(godot_string_similarity(&a, &b) > godot_string_similarity(&a, &c)); - - godot_string_destroy(&a); - godot_string_destroy(&b); - godot_string_destroy(&c); -} - -TEST_CASE("[GDNative String] Trim") { - godot_string s, t, u, p; - godot_string_new_with_latin1_chars(&s, "aaaTestbbb"); - - godot_string_new_with_latin1_chars(&p, "aaa"); - godot_string_new_with_latin1_chars(&t, "Testbbb"); - u = godot_string_trim_prefix(&s, &p); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - godot_string_destroy(&p); - - godot_string_new_with_latin1_chars(&p, "bbb"); - godot_string_new_with_latin1_chars(&t, "aaaTest"); - u = godot_string_trim_suffix(&s, &p); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - godot_string_destroy(&p); - - godot_string_new_with_latin1_chars(&p, "Test"); - u = godot_string_trim_suffix(&s, &p); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&p); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Right/Left") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, "aaaTestbbb"); - // ^ - - godot_string_new_with_latin1_chars(&t, "tbbb"); - u = godot_string_right(&s, 6); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&t, "aaaTes"); - u = godot_string_left(&s, 6); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_destroy(&s); -} - -TEST_CASE("[GDNative String] Repeat") { - godot_string t, u; - godot_string_new_with_latin1_chars(&t, "ab"); - - u = godot_string_repeat(&t, 4); - CHECK(u32scmp(godot_string_get_data(&u), U"abababab") == 0); - godot_string_destroy(&u); - - godot_string_destroy(&t); -} - -TEST_CASE("[GDNative String] SHA1/SHA256/MD5") { - godot_string s, t, sha1, sha256, md5; - godot_string_new_with_latin1_chars(&s, "Godot"); - godot_string_new_with_latin1_chars(&sha1, "a1e91f39b9fce6a9998b14bdbe2aa2b39dc2d201"); - static uint8_t sha1_buf[20] = { - 0xA1, 0xE9, 0x1F, 0x39, 0xB9, 0xFC, 0xE6, 0xA9, 0x99, 0x8B, 0x14, 0xBD, 0xBE, 0x2A, 0xA2, 0xB3, - 0x9D, 0xC2, 0xD2, 0x01 - }; - godot_string_new_with_latin1_chars(&sha256, "2a02b2443f7985d89d09001086ae3dcfa6eb0f55c6ef170715d42328e16e6cb8"); - static uint8_t sha256_buf[32] = { - 0x2A, 0x02, 0xB2, 0x44, 0x3F, 0x79, 0x85, 0xD8, 0x9D, 0x09, 0x00, 0x10, 0x86, 0xAE, 0x3D, 0xCF, - 0xA6, 0xEB, 0x0F, 0x55, 0xC6, 0xEF, 0x17, 0x07, 0x15, 0xD4, 0x23, 0x28, 0xE1, 0x6E, 0x6C, 0xB8 - }; - godot_string_new_with_latin1_chars(&md5, "4a336d087aeb0390da10ee2ea7cb87f8"); - static uint8_t md5_buf[16] = { - 0x4A, 0x33, 0x6D, 0x08, 0x7A, 0xEB, 0x03, 0x90, 0xDA, 0x10, 0xEE, 0x2E, 0xA7, 0xCB, 0x87, 0xF8 - }; - - godot_packed_byte_array buf = godot_string_sha1_buffer(&s); - CHECK(memcmp(sha1_buf, godot_packed_byte_array_ptr(&buf), 20) == 0); - godot_packed_byte_array_destroy(&buf); - - t = godot_string_sha1_text(&s); - CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&sha1)) == 0); - godot_string_destroy(&t); - - buf = godot_string_sha256_buffer(&s); - CHECK(memcmp(sha256_buf, godot_packed_byte_array_ptr(&buf), 32) == 0); - godot_packed_byte_array_destroy(&buf); - - t = godot_string_sha256_text(&s); - CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&sha256)) == 0); - godot_string_destroy(&t); - - buf = godot_string_md5_buffer(&s); - CHECK(memcmp(md5_buf, godot_packed_byte_array_ptr(&buf), 16) == 0); - godot_packed_byte_array_destroy(&buf); - - t = godot_string_md5_text(&s); - CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&md5)) == 0); - godot_string_destroy(&t); - - godot_string_destroy(&s); - godot_string_destroy(&sha1); - godot_string_destroy(&sha256); - godot_string_destroy(&md5); -} - -TEST_CASE("[GDNative String] Join") { - godot_string s, t, u; - godot_string_new_with_latin1_chars(&s, ", "); - - godot_packed_string_array parts; - godot_packed_string_array_new(&parts); - godot_string_new_with_latin1_chars(&t, "One"); - godot_packed_string_array_push_back(&parts, &t); - godot_string_destroy(&t); - godot_string_new_with_latin1_chars(&t, "B"); - godot_packed_string_array_push_back(&parts, &t); - godot_string_destroy(&t); - godot_string_new_with_latin1_chars(&t, "C"); - godot_packed_string_array_push_back(&parts, &t); - godot_string_destroy(&t); - - godot_string_new_with_latin1_chars(&u, "One, B, C"); - t = godot_string_join(&s, &parts); - CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0); - godot_string_destroy(&u); - godot_string_destroy(&t); - - godot_string_destroy(&s); - godot_packed_string_array_destroy(&parts); -} - -TEST_CASE("[GDNative String] Is_*") { - static const char *data[12] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1" }; - static bool isnum[12] = { true, true, true, false, false, false, false, false, false, false, false, false }; - static bool isint[12] = { true, true, false, false, false, false, false, false, false, false, false, false }; - static bool ishex[12] = { true, true, false, false, true, false, true, false, true, false, false, false }; - static bool ishex_p[12] = { false, false, false, false, false, false, false, true, false, false, false, false }; - static bool isflt[12] = { true, true, true, false, true, true, false, false, false, false, false, false }; - static bool isid[12] = { false, false, false, false, false, false, false, false, true, true, false, false }; - - for (int i = 0; i < 12; i++) { - godot_string s; - godot_string_new_with_latin1_chars(&s, data[i]); - CHECK(godot_string_is_numeric(&s) == isnum[i]); - CHECK(godot_string_is_valid_integer(&s) == isint[i]); - CHECK(godot_string_is_valid_hex_number(&s, false) == ishex[i]); - CHECK(godot_string_is_valid_hex_number(&s, true) == ishex_p[i]); - CHECK(godot_string_is_valid_float(&s) == isflt[i]); - CHECK(godot_string_is_valid_identifier(&s) == isid[i]); - godot_string_destroy(&s); - } -} - -TEST_CASE("[GDNative String] humanize_size") { - godot_string s; - - s = godot_string_humanize_size(1000); - CHECK(u32scmp(godot_string_get_data(&s), U"1000 B") == 0); - godot_string_destroy(&s); - - s = godot_string_humanize_size(1025); - CHECK(u32scmp(godot_string_get_data(&s), U"1.00 KiB") == 0); - godot_string_destroy(&s); - - s = godot_string_humanize_size(1025300); - CHECK(u32scmp(godot_string_get_data(&s), U"1001.2 KiB") == 0); - godot_string_destroy(&s); - - s = godot_string_humanize_size(100523550); - CHECK(u32scmp(godot_string_get_data(&s), U"95.86 MiB") == 0); - godot_string_destroy(&s); - - s = godot_string_humanize_size(5345555000); - CHECK(u32scmp(godot_string_get_data(&s), U"4.97 GiB") == 0); - godot_string_destroy(&s); -} -} // namespace TestGDNativeString - -#endif // TEST_GDNATIVE_STRING_H diff --git a/modules/gdnative/tests/test_variant.h b/modules/gdnative/tests/test_variant.h new file mode 100644 index 0000000000..aeceb6e68f --- /dev/null +++ b/modules/gdnative/tests/test_variant.h @@ -0,0 +1,205 @@ +/*************************************************************************/ +/* test_variant.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_GDNATIVE_VARIANT_H +#define TEST_GDNATIVE_VARIANT_H + +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> + +#include "tests/test_macros.h" + +namespace TestGDNativeVariant { + +TEST_CASE("[GDNative Variant] New Variant with copy") { + godot_variant src; + godot_variant_new_int(&src, 42); + + godot_variant copy; + godot_variant_new_copy(©, &src); + + CHECK(godot_variant_as_int(©) == 42); + CHECK(godot_variant_get_type(©) == GODOT_VARIANT_TYPE_INT); + + godot_variant_destroy(&src); + godot_variant_destroy(©); +} + +TEST_CASE("[GDNative Variant] New Variant with Nil") { + godot_variant val; + godot_variant_new_nil(&val); + + CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_NIL); + + godot_variant_destroy(&val); +} + +TEST_CASE("[GDNative Variant] New Variant with bool") { + godot_variant val; + godot_variant_new_bool(&val, true); + + CHECK(godot_variant_as_bool(&val)); + CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_BOOL); + + godot_variant_destroy(&val); +} + +TEST_CASE("[GDNative Variant] New Variant with float") { + godot_variant val; + godot_variant_new_float(&val, 4.2); + + CHECK(godot_variant_as_float(&val) == 4.2); + CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_FLOAT); + + godot_variant_destroy(&val); +} + +TEST_CASE("[GDNative Variant] New Variant with String") { + String str = "something"; + + godot_variant val; + godot_variant_new_string(&val, (godot_string *)&str); + godot_string gd_str = godot_variant_as_string(&val); + String *result = (String *)&gd_str; + + CHECK(*result == String("something")); + CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_STRING); + + godot_variant_destroy(&val); + godot_string_destroy(&gd_str); +} + +TEST_CASE("[GDNative Variant] Variant call") { + String str("something"); + godot_variant self; + godot_variant_new_string(&self, (godot_string *)&str); + + godot_variant ret; + + godot_string_name method; + godot_string_name_new_with_latin1_chars(&method, "is_valid_identifier"); + + godot_variant_call_error error; + godot_variant_call(&self, &method, NULL, 0, &ret, &error); + + CHECK(godot_variant_get_type(&ret) == GODOT_VARIANT_TYPE_BOOL); + CHECK(godot_variant_as_bool(&ret)); + + godot_variant_destroy(&ret); + godot_variant_destroy(&self); + godot_string_name_destroy(&method); +} + +TEST_CASE("[GDNative Variant] Variant evaluate") { + godot_variant one; + godot_variant_new_int(&one, 1); + godot_variant two; + godot_variant_new_int(&two, 2); + + godot_variant three; + godot_variant_new_nil(&three); + bool valid = false; + + godot_variant_evaluate(GODOT_VARIANT_OP_ADD, &one, &two, &three, &valid); + + CHECK(godot_variant_get_type(&three) == GODOT_VARIANT_TYPE_INT); + CHECK(godot_variant_as_int(&three) == 3); + CHECK(valid); + + godot_variant_destroy(&one); + godot_variant_destroy(&two); + godot_variant_destroy(&three); +} + +TEST_CASE("[GDNative Variant] Variant set/get named") { + godot_string_name x; + godot_string_name_new_with_latin1_chars(&x, "x"); + + Vector2 vec(0, 0); + godot_variant self; + godot_variant_new_vector2(&self, (godot_vector2 *)&vec); + + godot_variant set; + godot_variant_new_float(&set, 1.0); + + bool set_valid = false; + godot_variant_set_named(&self, &x, &set, &set_valid); + + bool get_valid = false; + godot_variant get = godot_variant_get_named(&self, &x, &get_valid); + + CHECK(get_valid); + CHECK(set_valid); + CHECK(godot_variant_get_type(&get) == GODOT_VARIANT_TYPE_FLOAT); + CHECK(godot_variant_as_float(&get) == 1.0); + + godot_string_name_destroy(&x); + godot_variant_destroy(&self); + godot_variant_destroy(&set); + godot_variant_destroy(&get); +} + +TEST_CASE("[GDNative Variant] Get utility function argument name") { + godot_string_name function; + godot_string_name_new_with_latin1_chars(&function, "pow"); + + godot_string arg_name = godot_variant_get_utility_function_argument_name(&function, 0); + + String *arg_name_str = (String *)&arg_name; + + CHECK(*arg_name_str == "base"); + + godot_string_destroy(&arg_name); + godot_string_name_destroy(&function); +} + +TEST_CASE("[GDNative Variant] Get utility function list") { + int count = godot_variant_get_utility_function_count(); + + godot_string_name *c_list = (godot_string_name *)godot_alloc(count * sizeof(godot_string_name)); + godot_variant_get_utility_function_list(c_list); + + List<StringName> cpp_list; + Variant::get_utility_function_list(&cpp_list); + + godot_string_name *cur = c_list; + + for (const List<StringName>::Element *E = cpp_list.front(); E; E = E->next()) { + const StringName &cpp_name = E->get(); + StringName *c_name = (StringName *)cur++; + + CHECK(*c_name == cpp_name); + } + + godot_free(c_list); +} +} // namespace TestGDNativeVariant + +#endif // TEST_GDNATIVE_VARIANT_H diff --git a/modules/gdnative/text/text_server_gdnative.cpp b/modules/gdnative/text/text_server_gdnative.cpp index f670d4af6f..7cd8de5f2e 100644 --- a/modules/gdnative/text/text_server_gdnative.cpp +++ b/modules/gdnative/text/text_server_gdnative.cpp @@ -113,6 +113,28 @@ RID TextServerGDNative::create_font_memory(const uint8_t *p_data, size_t p_size, return rid; } +RID TextServerGDNative::create_font_bitmap(float p_height, float p_ascent, int p_base_size) { + ERR_FAIL_COND_V(interface == nullptr, RID()); + godot_rid result = interface->create_font_bitmap(data, p_height, p_ascent, p_base_size); + RID rid = *(RID *)&result; + return rid; +} + +void TextServerGDNative::font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) { + ERR_FAIL_COND(interface == nullptr); + interface->font_bitmap_add_texture(data, (godot_rid *)&p_font, (const godot_object *)p_texture.ptr()); +} + +void TextServerGDNative::font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { + ERR_FAIL_COND(interface == nullptr); + interface->font_bitmap_add_char(data, (godot_rid *)&p_font, p_char, p_texture_idx, (const godot_rect2 *)&p_rect, (const godot_vector2 *)&p_align, p_advance); +} + +void TextServerGDNative::font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) { + ERR_FAIL_COND(interface == nullptr); + interface->font_bitmap_add_kerning_pair(data, (godot_rid *)&p_font, p_A, p_B, p_kerning); +} + float TextServerGDNative::font_get_height(RID p_font, int p_size) const { ERR_FAIL_COND_V(interface == nullptr, 0.f); return interface->font_get_height(data, (godot_rid *)&p_font, p_size); @@ -138,6 +160,26 @@ float TextServerGDNative::font_get_underline_thickness(RID p_font, int p_size) c return interface->font_get_underline_thickness(data, (godot_rid *)&p_font, p_size); } +int TextServerGDNative::font_get_spacing_space(RID p_font) const { + ERR_FAIL_COND_V(interface == nullptr, 0); + return interface->font_get_spacing_space(data, (godot_rid *)&p_font); +} + +void TextServerGDNative::font_set_spacing_space(RID p_font, int p_value) { + ERR_FAIL_COND(interface == nullptr); + interface->font_set_spacing_space(data, (godot_rid *)&p_font, p_value); +} + +int TextServerGDNative::font_get_spacing_glyph(RID p_font) const { + ERR_FAIL_COND_V(interface == nullptr, 0); + return interface->font_get_spacing_glyph(data, (godot_rid *)&p_font); +} + +void TextServerGDNative::font_set_spacing_glyph(RID p_font, int p_value) { + ERR_FAIL_COND(interface == nullptr); + interface->font_set_spacing_glyph(data, (godot_rid *)&p_font, p_value); +} + void TextServerGDNative::font_set_antialiased(RID p_font, bool p_antialiased) { ERR_FAIL_COND(interface == nullptr); interface->font_set_antialiased(data, (godot_rid *)&p_font, p_antialiased); @@ -703,12 +745,12 @@ void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_of self->y_off = offset->y; } -godot_real GDAPI godot_glyph_get_advance(const godot_glyph *p_self) { +godot_float GDAPI godot_glyph_get_advance(const godot_glyph *p_self) { const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; return self->advance; } -void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real p_advance) { +void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_float p_advance) { TextServer::Glyph *self = (TextServer::Glyph *)p_self; self->advance = p_advance; } diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h index 9cbb94217e..931bb44885 100644 --- a/modules/gdnative/text/text_server_gdnative.h +++ b/modules/gdnative/text/text_server_gdnative.h @@ -64,6 +64,11 @@ public: virtual RID create_font_system(const String &p_name, int p_base_size = 16) override; virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) override; virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) override; + virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) override; + + virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) override; + virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override; + virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) override; virtual float font_get_height(RID p_font, int p_size) const override; virtual float font_get_ascent(RID p_font, int p_size) const override; @@ -72,6 +77,12 @@ public: virtual float font_get_underline_position(RID p_font, int p_size) const override; virtual float font_get_underline_thickness(RID p_font, int p_size) const override; + virtual int font_get_spacing_space(RID p_font) const override; + virtual void font_set_spacing_space(RID p_font, int p_value) override; + + virtual int font_get_spacing_glyph(RID p_font) const override; + virtual void font_set_spacing_glyph(RID p_font, int p_value) override; + virtual void font_set_antialiased(RID p_font, bool p_antialiased) override; virtual bool font_get_antialiased(RID p_font) const override; diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 18d26a9528..f2fb0a2fdc 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -250,7 +250,7 @@ void VideoStreamPlaybackGDNative::play() { playing = true; - delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms"); + delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms"); delay_compensation /= 1000.0; } @@ -360,7 +360,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) { /* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */ -RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index e64cda6602..140888cd4b 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -118,7 +118,7 @@ class VideoStreamPlaybackGDNative : public VideoStreamPlayback { AudioMixCallback mix_callback = nullptr; int num_channels = -1; - float time = 0; + float time = 0.0; bool seek_backward = false; int mix_rate = 0; double delay_compensation = 0; @@ -196,7 +196,7 @@ public: class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp index d4fd2876b5..5bbf70174c 100644 --- a/modules/gdnative/xr/xr_interface_gdnative.cpp +++ b/modules/gdnative/xr/xr_interface_gdnative.cpp @@ -190,7 +190,7 @@ CameraMatrix XRInterfaceGDNative::get_projection_for_eye(XRInterface::Eyes p_eye ERR_FAIL_COND_V(interface == nullptr, CameraMatrix()); - interface->fill_projection_for_eye(data, (godot_real *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far); + interface->fill_projection_for_eye(data, (godot_float *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far); return cm; } @@ -234,7 +234,7 @@ void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_inte XRServer::get_singleton()->add_interface(new_interface); } -godot_real GDAPI godot_xr_get_worldscale() { +godot_float GDAPI godot_xr_get_worldscale() { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, 1.0); @@ -249,7 +249,7 @@ godot_transform GDAPI godot_xr_get_reference_frame() { if (xr_server != nullptr) { *reference_frame_ptr = xr_server->get_reference_frame(); } else { - godot_transform_new_identity(&reference_frame); + memnew_placement(&reference_frame, Transform); } return reference_frame; @@ -387,7 +387,7 @@ void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p } } -void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) { +void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_float p_value, godot_bool p_can_be_negative) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); @@ -406,7 +406,7 @@ void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_a } } -godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) { +godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, 0.0); diff --git a/modules/gdnavigation/nav_utils.h b/modules/gdnavigation/nav_utils.h index d1d1687a1f..d257a95ef1 100644 --- a/modules/gdnavigation/nav_utils.h +++ b/modules/gdnavigation/nav_utils.h @@ -51,7 +51,7 @@ union PointKey { int64_t z : 21; }; - uint64_t key; + uint64_t key = 0; bool operator<(const PointKey &p_key) const { return key < p_key.key; } }; @@ -86,8 +86,6 @@ struct Edge { /// The other `Polygon` at this edge id has this `Polygon`. int other_edge = -1; - - Edge() {} }; struct Polygon { @@ -111,8 +109,6 @@ struct Connection { int A_edge = -1; Polygon *B = nullptr; int B_edge = -1; - - Connection() {} }; struct NavigationPoly { @@ -141,12 +137,12 @@ struct NavigationPoly { }; struct FreeEdge { - bool is_free; - Polygon *poly; - uint32_t edge_id; + bool is_free = false; + Polygon *poly = nullptr; + uint32_t edge_id = 0; Vector3 edge_center; Vector3 edge_dir; - float edge_len_squared; + float edge_len_squared = 0.0; }; } // namespace gd diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h index d9e3345498..369cb1f9a3 100644 --- a/modules/gdnavigation/rvo_agent.h +++ b/modules/gdnavigation/rvo_agent.h @@ -53,7 +53,7 @@ class RvoAgent : public NavRid { NavMap *map = nullptr; RVO::Agent agent; AvoidanceComputedCallback callback; - uint32_t map_update_id; + uint32_t map_update_id = 0; public: RvoAgent(); diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index b792ff54d6..ccc942d86b 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -269,19 +269,21 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) col = keywords[word]; } else if (member_keywords.has(word)) { col = member_keywords[word]; + } + + if (col != Color()) { for (int k = j - 1; k >= 0; k--) { if (str[k] == '.') { - col = Color(); //member indexing not allowed + col = Color(); // keyword & member indexing not allowed break; } else if (str[k] > 32) { break; } } - } - - if (col != Color()) { - in_keyword = true; - keyword_color = col; + if (col != Color()) { + in_keyword = true; + keyword_color = col; + } } } diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp index 6e930b6bf4..9d0d91162c 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp @@ -44,7 +44,7 @@ Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Ve // Search strings in AssignmentNode -> text = "__", hint_tooltip = "__" etc. Error err; - RES loaded_res = ResourceLoader::load(p_path, "", false, &err); + RES loaded_res = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index 5358a77140..fcf438422a 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -39,8 +39,8 @@ class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlugin { GDCLASS(GDScriptEditorTranslationParserPlugin, EditorTranslationParserPlugin); - Vector<String> *ids; - Vector<Vector<String>> *ids_ctx_plural; + Vector<String> *ids = nullptr; + Vector<Vector<String>> *ids_ctx_plural = nullptr; // List of patterns used for extracting translation strings. StringName tr_func = "tr"; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 502e294275..a129b73c1a 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -219,7 +219,7 @@ StringName GDScript::get_instance_base_type() const { } struct _GDScriptMemberSort { - int index; + int index = 0; StringName name; _FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; } }; @@ -1162,17 +1162,6 @@ String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript) GDScript::GDScript() : script_list(this) { - valid = false; - subclass_count = 0; - initializer = nullptr; - _base = nullptr; - _owner = nullptr; - tool = false; -#ifdef TOOLS_ENABLED - source_changed_cache = false; - placeholder_fallback_enabled = false; -#endif - #ifdef DEBUG_ENABLED { MutexLock lock(GDScriptLanguage::get_singleton()->lock); @@ -2327,7 +2316,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na /*************** RESOURCE ***************/ -RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 37f01b2571..12c909fd4f 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -57,11 +57,11 @@ public: class GDScript : public Script { GDCLASS(GDScript, Script); - bool tool; - bool valid; + bool tool = false; + bool valid = false; struct MemberInfo { - int index; + int index = 0; StringName setter; StringName getter; MultiplayerAPI::RPCMode rpc_mode; @@ -77,8 +77,8 @@ class GDScript : public Script { Ref<GDScriptNativeClass> native; Ref<GDScript> base; - GDScript *_base; //fast pointer access - GDScript *_owner; //for subclasses + GDScript *_base = nullptr; //fast pointer access + GDScript *_owner = nullptr; //for subclasses Set<StringName> members; //members are just indices to the instanced script. Map<StringName, Variant> constants; @@ -97,8 +97,8 @@ class GDScript : public Script { Map<StringName, Variant> member_default_values_cache; Ref<GDScript> base_cache; Set<ObjectID> inheriters_cache; - bool source_changed_cache; - bool placeholder_fallback_enabled; + bool source_changed_cache = false; + bool placeholder_fallback_enabled = false; void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); DocData::ClassDoc doc; @@ -121,7 +121,7 @@ class GDScript : public Script { GDScriptFunction *implicit_initializer = nullptr; GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate - int subclass_count; + int subclass_count = 0; Set<Object *> instances; //exported members String source; @@ -529,7 +529,7 @@ public: class ResourceFormatLoaderGDScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 5fc5b88ef8..a6138cc564 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1163,24 +1163,26 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable void GDScriptAnalyzer::resolve_constant(GDScriptParser::ConstantNode *p_constant) { GDScriptParser::DataType type; - reduce_expression(p_constant->initializer); - if (p_constant->initializer->type == GDScriptParser::Node::ARRAY) { - const_fold_array(static_cast<GDScriptParser::ArrayNode *>(p_constant->initializer)); - } else if (p_constant->initializer->type == GDScriptParser::Node::DICTIONARY) { - const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(p_constant->initializer)); - } + if (p_constant->initializer != nullptr) { + reduce_expression(p_constant->initializer); + if (p_constant->initializer->type == GDScriptParser::Node::ARRAY) { + const_fold_array(static_cast<GDScriptParser::ArrayNode *>(p_constant->initializer)); + } else if (p_constant->initializer->type == GDScriptParser::Node::DICTIONARY) { + const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(p_constant->initializer)); + } - if (!p_constant->initializer->is_constant) { - push_error(vformat(R"(Assigned value for constant "%s" isn't a constant expression.)", p_constant->identifier->name), p_constant->initializer); - } + if (!p_constant->initializer->is_constant) { + push_error(vformat(R"(Assigned value for constant "%s" isn't a constant expression.)", p_constant->identifier->name), p_constant->initializer); + } - type = p_constant->initializer->get_datatype(); + type = p_constant->initializer->get_datatype(); #ifdef DEBUG_ENABLED - if (p_constant->initializer->type == GDScriptParser::Node::CALL && type.kind == GDScriptParser::DataType::BUILTIN && type.builtin_type == Variant::NIL) { - parser->push_warning(p_constant->initializer, GDScriptWarning::VOID_ASSIGNMENT, static_cast<GDScriptParser::CallNode *>(p_constant->initializer)->function_name); - } + if (p_constant->initializer->type == GDScriptParser::Node::CALL && type.kind == GDScriptParser::DataType::BUILTIN && type.builtin_type == Variant::NIL) { + parser->push_warning(p_constant->initializer, GDScriptWarning::VOID_ASSIGNMENT, static_cast<GDScriptParser::CallNode *>(p_constant->initializer)->function_name); + } #endif + } if (p_constant->datatype_specifier != nullptr) { GDScriptParser::DataType explicit_type = resolve_datatype(p_constant->datatype_specifier); @@ -1215,7 +1217,10 @@ void GDScriptAnalyzer::resolve_constant(GDScriptParser::ConstantNode *p_constant void GDScriptAnalyzer::resolve_assert(GDScriptParser::AssertNode *p_assert) { reduce_expression(p_assert->condition); if (p_assert->message != nullptr) { - reduce_literal(p_assert->message); + reduce_expression(p_assert->message); + if (!p_assert->message->is_constant || p_assert->message->reduced_value.get_type() != Variant::STRING) { + push_error(R"(Expected constant string for assert error message.)", p_assert->message); + } } p_assert->set_datatype(p_assert->condition->get_datatype()); @@ -1752,6 +1757,8 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa // Those are stored by reference so not suited for compile-time construction. // Because in this case they would be the same reference in all constructed values. case Variant::OBJECT: + case Variant::DICTIONARY: + case Variant::ARRAY: case Variant::PACKED_BYTE_ARRAY: case Variant::PACKED_INT32_ARRAY: case Variant::PACKED_INT64_ARRAY: @@ -2029,14 +2036,14 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa push_error(vformat(R"*(Name "%s" called as a function but is a "%s".)*", p_call->function_name, callee_datatype.to_string()), p_call->callee); } #ifdef DEBUG_ENABLED - } else if (!is_self) { + } else if (!is_self && !(base_type.is_hard_type() && base_type.kind == GDScriptParser::DataType::BUILTIN)) { parser->push_warning(p_call, GDScriptWarning::UNSAFE_METHOD_ACCESS, p_call->function_name, base_type.to_string()); mark_node_unsafe(p_call); #endif } } } - if (!found && is_self) { + if (!found && (is_self || (base_type.is_hard_type() && base_type.kind == GDScriptParser::DataType::BUILTIN))) { String base_name = is_self && !p_call->is_super ? "self" : base_type.to_string(); push_error(vformat(R"*(Function "%s()" not found in base %s.)*", p_call->function_name, base_name), p_call->is_super ? p_call : p_call->callee); } diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 873d2b0183..58c6b31a77 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -899,6 +899,17 @@ void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const S append(p_function_name); } +void GDScriptByteCodeGenerator::write_call_self_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) { + append(GDScriptFunction::OPCODE_CALL_ASYNC, 2 + p_arguments.size()); + for (int i = 0; i < p_arguments.size(); i++) { + append(p_arguments[i]); + } + append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); + append(p_target); + append(p_arguments.size()); + append(p_function_name); +} + void GDScriptByteCodeGenerator::write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) { append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN, 2 + p_arguments.size()); for (int i = 0; i < p_arguments.size(); i++) { diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index df1ecfff6d..1e66af269a 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -441,6 +441,7 @@ public: virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override; virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override; virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override; + virtual void write_call_self_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override; virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override; virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) override; virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) override; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index d9ad7e058e..d72bd12033 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -133,6 +133,7 @@ public: virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0; virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0; virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0; + virtual void write_call_self_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0; virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0; virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) = 0; virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) = 0; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index e8be310375..7f873ccd7a 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -255,36 +255,59 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } // Try class constants. - GDScript *owner = codegen.script; - while (owner) { - GDScript *scr = owner; - GDScriptNativeClass *nc = nullptr; - while (scr) { - if (scr->constants.has(identifier)) { - return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here. + { + GDScript *owner = codegen.script; + while (owner) { + GDScript *scr = owner; + GDScriptNativeClass *nc = nullptr; + while (scr) { + if (scr->constants.has(identifier)) { + return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here. + } + if (scr->native.is_valid()) { + nc = scr->native.ptr(); + } + scr = scr->_base; } - if (scr->native.is_valid()) { - nc = scr->native.ptr(); + + // Class C++ integer constant. + if (nc) { + bool success = false; + int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success); + if (success) { + return codegen.add_constant(constant); + } } - scr = scr->_base; + + owner = owner->_owner; } + } - // Class C++ integer constant. - if (nc) { - bool success = false; - int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success); - if (success) { - return codegen.add_constant(constant); + // Try signals and methods (can be made callables). + { + if (codegen.class_node->members_indices.has(identifier)) { + const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]]; + if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) { + // Get like it was a property. + GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here. + GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF); + + gen->write_get_named(temp, identifier, self); + return temp; } } - owner = owner->_owner; - } + // Try in native base. + GDScript *scr = codegen.script; + GDScriptNativeClass *nc = nullptr; + while (scr) { + if (scr->native.is_valid()) { + nc = scr->native.ptr(); + } + scr = scr->_base; + } - // Try signals and methods (can be made callables); - if (codegen.class_node->members_indices.has(identifier)) { - const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]]; - if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) { + if (nc && (ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) { // Get like it was a property. GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here. GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF); @@ -494,9 +517,17 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } else if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") { GDScriptCodeGenerator::Address self; self.mode = GDScriptCodeGenerator::Address::CLASS; - gen->write_call(result, self, call->function_name, arguments); + if (within_await) { + gen->write_call_async(result, self, call->function_name, arguments); + } else { + gen->write_call(result, self, call->function_name, arguments); + } } else { - gen->write_call_self(result, call->function_name, arguments); + if (within_await) { + gen->write_call_self_async(result, call->function_name, arguments); + } else { + gen->write_call_self(result, call->function_name, arguments); + } } } else if (callee->type == GDScriptParser::Node::SUBSCRIPT) { const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee); diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 00953ad752..651391f972 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -133,8 +133,8 @@ class GDScriptCompiler { Error _parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); Error _parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); void _make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); - int err_line; - int err_column; + int err_line = 0; + int err_column = 0; StringName source; String error; bool within_await = false; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 8ea51c61fb..b17971cf93 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2345,7 +2345,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c GDScriptParser::DataType base_type; bool _static = false; const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_call); - GDScriptParser::Node::Type callee_type = GDScriptParser::Node::NONE; + GDScriptParser::Node::Type callee_type = call->get_callee_type(); GDScriptCompletionIdentifier connect_base; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 2171426e6f..c6c9a439df 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -77,14 +77,14 @@ int GDScriptFunction::get_max_stack_size() const { } struct _GDFKC { - int order; + int order = 0; List<int> pos; }; struct _GDFKCS { - int order; + int order = 0; StringName id; - int pos; + int pos = 0; bool operator<(const _GDFKCS &p_r) const { return order < p_r.order; @@ -294,7 +294,6 @@ void GDScriptFunctionState::_bind_methods() { GDScriptFunctionState::GDScriptFunctionState() : scripts_list(this), instances_list(this) { - function = nullptr; } GDScriptFunctionState::~GDScriptFunctionState() { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 6c791836b9..e64630a743 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -420,19 +420,19 @@ private: public: struct CallState { - GDScript *script; - GDScriptInstance *instance; + GDScript *script = nullptr; + GDScriptInstance *instance = nullptr; #ifdef DEBUG_ENABLED StringName function_name; String script_path; #endif Vector<uint8_t> stack; - int stack_size; + int stack_size = 0; Variant self; - uint32_t alloca_size; - int ip; - int line; - int defarg; + uint32_t alloca_size = 0; + int ip = 0; + int line = 0; + int defarg = 0; Variant result; }; @@ -488,7 +488,7 @@ public: class GDScriptFunctionState : public Reference { GDCLASS(GDScriptFunctionState, Reference); friend class GDScriptFunction; - GDScriptFunction *function; + GDScriptFunction *function = nullptr; GDScriptFunction::CallState state; Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Ref<GDScriptFunctionState> first_state; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 0a017e6730..a77fb14064 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -976,6 +976,8 @@ GDScriptParser::ConstantNode *GDScriptParser::parse_constant() { push_error(R"(Expected initializer expression for constant.)"); return nullptr; } + } else { + return nullptr; } end_statement("constant declaration"); @@ -1501,12 +1503,9 @@ GDScriptParser::AssertNode *GDScriptParser::parse_assert() { if (match(GDScriptTokenizer::Token::COMMA)) { // Error message. - if (consume(GDScriptTokenizer::Token::LITERAL, R"(Expected error message for assert after ",".)")) { - assert->message = parse_literal(); - if (assert->message->value.get_type() != Variant::STRING) { - push_error(R"(Expected string for assert error message.)"); - } - } else { + assert->message = parse_expression(false); + if (assert->message == nullptr) { + push_error(R"(Expected error message for assert after ",".)"); return nullptr; } } @@ -2919,8 +2918,8 @@ GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Ty { nullptr, &GDScriptParser::parse_binary_operator, PREC_BIT_SHIFT }, // LESS_LESS, { nullptr, &GDScriptParser::parse_binary_operator, PREC_BIT_SHIFT }, // GREATER_GREATER, // Math - { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION }, // PLUS, - { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_SUBTRACTION }, // MINUS, + { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION_SUBTRACTION }, // PLUS, + { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION_SUBTRACTION }, // MINUS, { nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // STAR, { nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // SLASH, { nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // PERCENT, diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index cf1ff5eefc..d59b68b602 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -286,7 +286,7 @@ public: struct AssertNode : public Node { ExpressionNode *condition = nullptr; - LiteralNode *message = nullptr; + ExpressionNode *message = nullptr; AssertNode() { type = ASSERT; @@ -351,7 +351,7 @@ public: OP_COMP_GREATER_EQUAL, }; - OpType operation; + OpType operation = OpType::OP_ADDITION; Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *left_operand = nullptr; ExpressionNode *right_operand = nullptr; @@ -753,7 +753,7 @@ public: struct MatchBranchNode : public Node { Vector<PatternNode *> patterns; - SuiteNode *block; + SuiteNode *block = nullptr; bool has_wildcard = false; MatchBranchNode() { @@ -1001,7 +1001,7 @@ public: OP_LOGIC_NOT, }; - OpType operation; + OpType operation = OP_POSITIVE; Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *operand = nullptr; @@ -1172,8 +1172,7 @@ private: PREC_BIT_XOR, PREC_BIT_AND, PREC_BIT_SHIFT, - PREC_SUBTRACTION, - PREC_ADDITION, + PREC_ADDITION_SUBTRACTION, PREC_FACTOR, PREC_SIGN, PREC_BIT_NOT, diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index cdb0072294..bea4b14019 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -178,7 +178,6 @@ public: } Token() { - type = EMPTY; } }; diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 4abd2e00f4..4e098d7a6d 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -476,11 +476,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (p_instance) { - if (p_instance->base_ref && static_cast<Reference *>(p_instance->owner)->is_referenced()) { - self = REF(static_cast<Reference *>(p_instance->owner)); - } else { - self = p_instance->owner; - } + self = p_instance->owner; script = p_instance->script.ptr(); } else { script = _script; @@ -2306,10 +2302,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Dictionary *dict = VariantInternal::get_dictionary(container); const Variant *next = dict->next(nullptr); - *counter = *next; if (!dict->is_empty()) { GET_INSTRUCTION_ARG(iterator, 2); + *counter = *next; *iterator = *next; // Skip regular iterate. diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 5e3d6213d3..912c9a174e 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -163,7 +163,7 @@ void GDScriptLanguageProtocol::_bind_methods() { ClassDB::bind_method(D_METHOD("initialized", "params"), &GDScriptLanguageProtocol::initialized); ClassDB::bind_method(D_METHOD("on_client_connected"), &GDScriptLanguageProtocol::on_client_connected); ClassDB::bind_method(D_METHOD("on_client_disconnected"), &GDScriptLanguageProtocol::on_client_disconnected); - ClassDB::bind_method(D_METHOD("notify_client", "method", "params"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("notify_client", "method", "params", "client_id"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("is_smart_resolve_enabled"), &GDScriptLanguageProtocol::is_smart_resolve_enabled); ClassDB::bind_method(D_METHOD("get_text_document"), &GDScriptLanguageProtocol::get_text_document); ClassDB::bind_method(D_METHOD("get_workspace"), &GDScriptLanguageProtocol::get_workspace); diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index aac9cb7fd7..98ada9de4d 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -36,12 +36,6 @@ #include "editor/editor_node.h" GDScriptLanguageServer::GDScriptLanguageServer() { - thread = nullptr; - thread_running = false; - started = false; - - use_thread = false; - port = 6008; _EDITOR_DEF("network/language_server/remote_port", port); _EDITOR_DEF("network/language_server/enable_smart_resolve", true); _EDITOR_DEF("network/language_server/show_native_symbols_in_editor", false); @@ -87,9 +81,8 @@ void GDScriptLanguageServer::start() { if (protocol.start(port, IP_Address("127.0.0.1")) == OK) { EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR); if (use_thread) { - ERR_FAIL_COND(thread != nullptr); thread_running = true; - thread = Thread::create(GDScriptLanguageServer::thread_main, this); + thread.start(GDScriptLanguageServer::thread_main, this); } set_process_internal(!use_thread); started = true; @@ -98,11 +91,9 @@ void GDScriptLanguageServer::start() { void GDScriptLanguageServer::stop() { if (use_thread) { - ERR_FAIL_COND(nullptr == thread); + ERR_FAIL_COND(!thread.is_started()); thread_running = false; - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread.wait_to_finish(); } protocol.stop(); started = false; diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h index 218f42199e..29c5ddd70e 100644 --- a/modules/gdscript/language_server/gdscript_language_server.h +++ b/modules/gdscript/language_server/gdscript_language_server.h @@ -40,11 +40,11 @@ class GDScriptLanguageServer : public EditorPlugin { GDScriptLanguageProtocol protocol; - Thread *thread; - bool thread_running; - bool started; - bool use_thread; - int port; + Thread thread; + bool thread_running = false; + bool started = false; + bool use_thread = false; + int port = 6008; static void thread_main(void *p_userdata); private: diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 7b502f079b..69cad1a335 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -350,7 +350,7 @@ Error GDScriptWorkspace::parse_local_script(const String &p_path) { String GDScriptWorkspace::get_file_path(const String &p_uri) const { String path = p_uri; path = path.replace(root_uri + "/", "res://"); - path = path.http_unescape(); + path = path.uri_decode(); return path; } diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 6a913edbbf..6635098be2 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -547,7 +547,7 @@ struct TextDocumentItem { * The version number of this document (it will increase after each * change, including undo/redo). */ - int version; + int version = 0; /** * The content of the opened text document. @@ -584,7 +584,7 @@ struct TextDocumentContentChangeEvent { /** * The length of the range that got replaced. */ - int rangeLength; + int rangeLength = 0; /** * The new text of the range/document. @@ -656,12 +656,12 @@ struct Diagnostic { * The diagnostic's severity. Can be omitted. If omitted it is up to the * client to interpret diagnostics as error, warning, info or hint. */ - int severity; + int severity = 0; /** * The diagnostic's code, which might appear in the user interface. */ - int code; + int code = 0; /** * A human-readable string describing the source of this @@ -833,7 +833,7 @@ struct CompletionItem { * an icon is chosen by the editor. The standardized set * of available values is defined in `CompletionItemKind`. */ - int kind; + int kind = 0; /** * A human-readable string with additional information @@ -891,7 +891,7 @@ struct CompletionItem { * The format of the insert text. The format applies to both the `insertText` property * and the `newText` property of a provided `textEdit`. */ - int insertTextFormat; + int insertTextFormat = 0; /** * An edit which is applied to a document when selecting this completion. When an edit is provided the value of @@ -1003,7 +1003,7 @@ struct CompletionList { * This list it not complete. Further typing should result in recomputing * this list. */ - bool isIncomplete; + bool isIncomplete = false; /** * The completion items. @@ -1661,7 +1661,7 @@ struct ServerCapabilities { signatureHelpProvider.triggerCharacters.push_back(","); signatureHelpProvider.triggerCharacters.push_back("("); dict["signatureHelpProvider"] = signatureHelpProvider.to_json(); - dict["codeLensProvider"] = false; // codeLensProvider.to_json(); + //dict["codeLensProvider"] = codeLensProvider.to_json(); dict["documentOnTypeFormattingProvider"] = documentOnTypeFormattingProvider.to_json(); dict["renameProvider"] = renameProvider.to_json(); dict["documentLinkProvider"] = documentLinkProvider.to_json(); diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index a7ae3e6bab..545aa68747 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -53,7 +53,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0; - glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0; + glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_3; glslang::TShader::ForbidIncluder includer; glslang::TShader shader(stages[p_stage]); diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/gltf_camera.h index e5c2041793..bf94b80bef 100644 --- a/modules/gltf/gltf_camera.h +++ b/modules/gltf/gltf_camera.h @@ -38,8 +38,8 @@ class GLTFCamera : public Resource { private: bool perspective = true; - float fov_size = 75; - float zfar = 4000; + float fov_size = 75.0; + float zfar = 4000.0; float znear = 0.05; protected: diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 580bc006f5..4868347a74 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -57,8 +57,12 @@ #include "core/version_hash.gen.h" #include "drivers/png/png_driver_common.h" #include "editor/import/resource_importer_scene.h" +#ifdef MODULE_CSG_ENABLED #include "modules/csg/csg_shape.h" +#endif // MODULE_CSG_ENABLED +#ifdef MODULE_GRIDMAP_ENABLED #include "modules/gridmap/grid_map.h" +#endif // MODULE_GRIDMAP_ENABLED #include "modules/regex/regex.h" #include "scene/2d/node_2d.h" #include "scene/3d/bone_attachment_3d.h" @@ -805,7 +809,9 @@ Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> state) { } Error GLTFDocument::_parse_buffer_views(Ref<GLTFState> state) { - ERR_FAIL_COND_V(!state->json.has("bufferViews"), ERR_FILE_CORRUPT); + if (!state->json.has("bufferViews")) { + return OK; + } const Array &buffers = state->json["bufferViews"]; for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) { const Dictionary &d = buffers[i]; @@ -942,7 +948,9 @@ GLTFDocument::GLTFType GLTFDocument::_get_type_from_str(const String &p_string) } Error GLTFDocument::_parse_accessors(Ref<GLTFState> state) { - ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT); + if (!state->json.has("accessors")) { + return OK; + } const Array &accessors = state->json["accessors"]; for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) { const Dictionary &d = accessors[i]; @@ -2383,7 +2391,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { e["targetNames"] = target_names; for (int j = 0; j < target_names.size(); j++) { - real_t weight = 0; + real_t weight = 0.0; if (j < state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) { weight = state->meshes.write[gltf_mesh_i]->get_blend_weights()[j]; } @@ -5097,7 +5105,6 @@ Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent } void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, Node *p_root, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) { bool retflag = true; - Node3D *spatial = cast_to<Node3D>(p_current); _check_visibility(p_current, retflag); if (retflag) { return; @@ -5106,9 +5113,11 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No gltf_node.instance(); gltf_node->set_name(_gen_unique_name(state, p_current->get_name())); if (cast_to<Node3D>(p_current)) { + Node3D *spatial = cast_to<Node3D>(p_current); _convert_spatial(state, spatial, gltf_node); } if (cast_to<MeshInstance3D>(p_current)) { + Node3D *spatial = cast_to<Node3D>(p_current); _convert_mesh_to_gltf(p_current, state, spatial, gltf_node); } else if (cast_to<BoneAttachment3D>(p_current)) { _convert_bone_attachment_to_gltf(p_current, state, gltf_node, retflag); @@ -5120,18 +5129,22 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No return; } else if (cast_to<MultiMeshInstance3D>(p_current)) { _convert_mult_mesh_instance_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root); +#ifdef MODULE_CSG_ENABLED } else if (cast_to<CSGShape3D>(p_current)) { if (p_current->get_parent() && cast_to<CSGShape3D>(p_current)->is_root_shape()) { _convert_csg_shape_to_gltf(p_current, p_gltf_parent, gltf_node, state); } +#endif // MODULE_CSG_ENABLED +#ifdef MODULE_GRIDMAP_ENABLED } else if (cast_to<GridMap>(p_current)) { _convert_grid_map_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root); +#endif // MODULE_GRIDMAP_ENABLED } else if (cast_to<Camera3D>(p_current)) { Camera3D *camera = Object::cast_to<Camera3D>(p_current); - _convert_camera_to_gltf(camera, state, spatial, gltf_node); + _convert_camera_to_gltf(camera, state, camera, gltf_node); } else if (cast_to<Light3D>(p_current)) { Light3D *light = Object::cast_to<Light3D>(p_current); - _convert_light_to_gltf(light, state, spatial, gltf_node); + _convert_light_to_gltf(light, state, light, gltf_node); } else if (cast_to<AnimationPlayer>(p_current)) { AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current); _convert_animation_player_to_gltf(animation_player, state, p_gltf_parent, p_gltf_root, gltf_node, p_current, p_root); @@ -5150,6 +5163,7 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No } } +#ifdef MODULE_CSG_ENABLED void GLTFDocument::_convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) { CSGShape3D *csg = Object::cast_to<CSGShape3D>(p_current); csg->call("_update_shape"); @@ -5176,6 +5190,7 @@ void GLTFDocument::_convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_g gltf_node->xform = csg->get_meshes()[0]; gltf_node->set_name(_gen_unique_name(state, csg->get_name())); } +#endif // MODULE_CSG_ENABLED void GLTFDocument::_create_gltf_node(Ref<GLTFState> state, Node *p_scene_parent, GLTFNodeIndex current_node_i, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref<GLTFNode> gltf_node) { @@ -5225,6 +5240,7 @@ void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, } } +#ifdef MODULE_GRIDMAP_ENABLED void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) { GridMap *grid_map = Object::cast_to<GridMap>(p_scene_parent); ERR_FAIL_COND(!grid_map); @@ -5256,6 +5272,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNod new_gltf_node->set_name(_gen_unique_name(state, grid_map->get_mesh_library()->get_item_name(cell))); } } +#endif // MODULE_GRIDMAP_ENABLED void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) { MultiMeshInstance3D *multi_mesh_instance = Object::cast_to<MultiMeshInstance3D>(p_scene_parent); @@ -5271,8 +5288,7 @@ void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, con transform.origin = Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y); real_t rotation = xform_2d.get_rotation(); - Quat quat; - quat.set_axis_angle(Vector3(0, 1, 0), rotation); + Quat quat(Vector3(0, 1, 0), rotation); Size2 scale = xform_2d.get_scale(); transform.basis.set_quat_scale(quat, Vector3(scale.x, 0, scale.y)); @@ -5553,7 +5569,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, animation->set_loop(true); } - float length = 0; + float length = 0.0; for (Map<int, GLTFAnimation::Track>::Element *track_i = anim->get_tracks().front(); track_i; track_i = track_i->next()) { const GLTFAnimation::Track &track = track_i->get(); @@ -6024,14 +6040,12 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state p_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { - Quat rotation; Vector3 rotation_degrees = p_animation->track_get_key_value(p_track_i, key_i); Vector3 rotation_radian; rotation_radian.x = Math::deg2rad(rotation_degrees.x); rotation_radian.y = Math::deg2rad(rotation_degrees.y); rotation_radian.z = Math::deg2rad(rotation_degrees.z); - rotation.set_euler(rotation_radian); - p_track.rotation_track.values.write[key_i] = rotation; + p_track.rotation_track.values.write[key_i] = Quat(rotation_radian); } } else if (path.find(":scale") != -1) { p_track.scale_track.times = times; @@ -6283,18 +6297,22 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, } } } else if (String(orig_track_path).find(":") == -1) { - const Node *node = ap->get_parent()->get_node_or_null(orig_track_path); - for (Map<GLTFNodeIndex, Node *>::Element *scene_node_i = state->scene_nodes.front(); scene_node_i; scene_node_i = scene_node_i->next()) { - if (scene_node_i->get() == node) { - GLTFNodeIndex node_index = scene_node_i->key(); - Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index); - GLTFAnimation::Track track; - if (node_track_i) { - track = node_track_i->get(); + ERR_CONTINUE(!ap->get_parent()); + for (int32_t node_i = 0; node_i < ap->get_parent()->get_child_count(); node_i++) { + const Node *child = ap->get_parent()->get_child(node_i); + const Node *node = child->get_node_or_null(orig_track_path); + for (Map<GLTFNodeIndex, Node *>::Element *scene_node_i = state->scene_nodes.front(); scene_node_i; scene_node_i = scene_node_i->next()) { + if (scene_node_i->get() == node) { + GLTFNodeIndex node_index = scene_node_i->key(); + Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index); + GLTFAnimation::Track track; + if (node_track_i) { + track = node_track_i->get(); + } + track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index); + gltf_animation->get_tracks().insert(node_index, track); + break; } - track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index); - gltf_animation->get_tracks().insert(node_index, track); - break; } } } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 111324d1e6..ddf307e6a7 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -34,6 +34,7 @@ #include "editor/import/resource_importer_scene.h" #include "editor/import/scene_importer_mesh_node_3d.h" #include "gltf_animation.h" +#include "modules/modules_enabled.gen.h" #include "scene/2d/node_2d.h" #include "scene/3d/bone_attachment_3d.h" #include "scene/3d/light_3d.h" @@ -377,7 +378,9 @@ public: const GLTFNodeIndex p_gltf_current, const GLTFNodeIndex p_gltf_root); +#ifdef MODULE_CSG_ENABLED void _convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state); +#endif // MODULE_CSG_ENABLED void _create_gltf_node(Ref<GLTFState> state, Node *p_scene_parent, @@ -395,12 +398,14 @@ public: void _convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node); +#ifdef MODULE_GRIDMAP_ENABLED void _convert_grid_map_to_gltf( Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node); +#endif // MODULE_GRIDMAP_ENABLED void _convert_mult_mesh_instance_to_gltf( Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, diff --git a/modules/gltf/gltf_skeleton.cpp b/modules/gltf/gltf_skeleton.cpp index 739779d3bd..d6c7a25eaf 100644 --- a/modules/gltf/gltf_skeleton.cpp +++ b/modules/gltf/gltf_skeleton.cpp @@ -41,7 +41,7 @@ void GLTFSkeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_godot_bone_node"), &GLTFSkeleton::get_godot_bone_node); ClassDB::bind_method(D_METHOD("set_godot_bone_node", "godot_bone_node"), &GLTFSkeleton::set_godot_bone_node); ClassDB::bind_method(D_METHOD("get_bone_attachment_count"), &GLTFSkeleton::get_bone_attachment_count); - ClassDB::bind_method(D_METHOD("get_bone_attachment"), &GLTFSkeleton::get_bone_attachment); + ClassDB::bind_method(D_METHOD("get_bone_attachment", "idx"), &GLTFSkeleton::get_bone_attachment); ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "joints"), "set_joints", "get_joints"); // Vector<GLTFNodeIndex> ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "roots"), "set_roots", "get_roots"); // Vector<GLTFNodeIndex> diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/gltf_skin.cpp index fd39e4f45a..5a61e5778c 100644 --- a/modules/gltf/gltf_skin.cpp +++ b/modules/gltf/gltf_skin.cpp @@ -142,7 +142,7 @@ void GLTFSkin::set_joint_i_to_name(Dictionary p_joint_i_to_name) { joint_i_to_name = Map<int, StringName>(); Array keys = p_joint_i_to_name.keys(); for (int i = 0; i < keys.size(); i++) { - joint_i_to_name[keys[i]] = joint_i_to_name[keys[i]]; + joint_i_to_name[keys[i]] = p_joint_i_to_name[keys[i]]; } } diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index eedc743330..86f8f44612 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -51,8 +51,8 @@ void GLTFState::_bind_methods() { ClassDB::bind_method(D_METHOD("set_accessors", "accessors"), &GLTFState::set_accessors); ClassDB::bind_method(D_METHOD("get_meshes"), &GLTFState::get_meshes); ClassDB::bind_method(D_METHOD("set_meshes", "meshes"), &GLTFState::set_meshes); - ClassDB::bind_method(D_METHOD("get_animation_players_count"), &GLTFState::get_animation_players_count); - ClassDB::bind_method(D_METHOD("get_animation_player"), &GLTFState::get_animation_player); + ClassDB::bind_method(D_METHOD("get_animation_players_count", "idx"), &GLTFState::get_animation_players_count); + ClassDB::bind_method(D_METHOD("get_animation_player", "idx"), &GLTFState::get_animation_player); ClassDB::bind_method(D_METHOD("get_materials"), &GLTFState::get_materials); ClassDB::bind_method(D_METHOD("set_materials", "materials"), &GLTFState::set_materials); ClassDB::bind_method(D_METHOD("get_scene_name"), &GLTFState::get_scene_name); @@ -77,7 +77,7 @@ void GLTFState::_bind_methods() { ClassDB::bind_method(D_METHOD("set_skeleton_to_node", "skeleton_to_node"), &GLTFState::set_skeleton_to_node); ClassDB::bind_method(D_METHOD("get_animations"), &GLTFState::get_animations); ClassDB::bind_method(D_METHOD("set_animations", "animations"), &GLTFState::set_animations); - ClassDB::bind_method(D_METHOD("get_scene_node"), &GLTFState::get_scene_node); + ClassDB::bind_method(D_METHOD("get_scene_node", "idx"), &GLTFState::get_scene_node); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "json"), "set_json", "get_json"); // Dictionary ADD_PROPERTY(PropertyInfo(Variant::INT, "major_version"), "set_major_version", "get_major_version"); // int diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index 85da4a0dd7..dc995c9249 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -60,9 +60,10 @@ static void _editor_init() { void register_gltf_types() { #ifndef _3D_DISABLED #ifdef TOOLS_ENABLED - ClassDB::register_class<EditorSceneImporterGLTF>(); ClassDB::APIType prev_api = ClassDB::get_current_api(); ClassDB::set_current_api(ClassDB::API_EDITOR); + ClassDB::register_class<EditorSceneImporterGLTF>(); + ClassDB::register_class<GLTFMesh>(); EditorPlugins::add_by_type<SceneExporterGLTFPlugin>(); ClassDB::set_current_api(prev_api); EditorNode::add_init_callback(_editor_init); @@ -75,7 +76,6 @@ void register_gltf_types() { ClassDB::register_class<GLTFTexture>(); ClassDB::register_class<GLTFSkeleton>(); ClassDB::register_class<GLTFSkin>(); - ClassDB::register_class<GLTFMesh>(); ClassDB::register_class<GLTFCamera>(); ClassDB::register_class<GLTFLight>(); ClassDB::register_class<GLTFState>(); diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 4dccb03369..e28cc57f9b 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -8,6 +8,7 @@ GridMaps use a [MeshLibrary] which contains a list of tiles. Each tile is a mesh with materials plus optional collision and navigation shapes. A GridMap contains a collection of cells. Each grid cell refers to a tile in the [MeshLibrary]. All cells in the map have the same dimensions. Internally, a GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells. + [b]Note:[/b] GridMap doesn't extend [VisualInstance3D] and therefore can't be hidden or cull masked based on [member VisualInstance3D.layers]. If you make a light not affect the first layer, the whole GridMap won't be lit by the light in question. </description> <tutorials> <link title="Using gridmaps">https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link> @@ -40,6 +41,7 @@ <return type="Array"> </return> <description> + Returns an array of [ArrayMesh]es and [Transform] references of all bake meshes that exist within the current GridMap. </description> </method> <method name="get_cell_item" qualifiers="const"> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 5a17541075..e7c252dc53 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -189,7 +189,6 @@ void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { } _recreate_octant_data(); - _change_notify("mesh_library"); } Ref<MeshLibrary> GridMap::get_mesh_library() const { @@ -286,7 +285,8 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) { //create octant because it does not exist Octant *g = memnew(Octant); g->dirty = true; - g->static_body = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + g->static_body = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(g->static_body, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id()); PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer); PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask); @@ -491,7 +491,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Octant::MultimeshInstance mmi; RID mm = RS::get_singleton()->multimesh_create(); - RS::get_singleton()->multimesh_allocate(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); + RS::get_singleton()->multimesh_allocate_data(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; @@ -700,8 +700,6 @@ void GridMap::_update_visibility() { return; } - _change_notify("visible"); - for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) { Octant *octant = e->value(); for (int i = 0; i < octant->multimesh_instances.size(); i++) { @@ -1046,26 +1044,7 @@ RID GridMap::get_bake_mesh_instance(int p_idx) { } GridMap::GridMap() { - collision_layer = 1; - collision_mask = 1; - - cell_size = Vector3(2, 2, 2); - octant_size = 8; - awaiting_update = false; - _in_tree = false; - center_x = true; - center_y = true; - center_z = true; - - clip = false; - clip_floor = 0; - clip_axis = Vector3::AXIS_Z; - clip_above = true; - cell_scale = 1.0; - - navigation = nullptr; set_notify_transform(true); - recreating_octants = false; } GridMap::~GridMap() { diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 48ad95f9ff..e5ec4bb602 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -53,7 +53,7 @@ class GridMap : public Node3D { int16_t y; int16_t z; }; - uint64_t key; + uint64_t key = 0; _FORCE_INLINE_ bool operator<(const IndexKey &p_key) const { return key < p_key.key; @@ -68,7 +68,7 @@ class GridMap : public Node3D { y = (int16_t)p_vector.y; z = (int16_t)p_vector.z; } - IndexKey() { key = 0; } + IndexKey() {} }; /** @@ -80,13 +80,7 @@ class GridMap : public Node3D { unsigned int rot : 5; unsigned int layer : 8; }; - uint32_t cell; - - Cell() { - item = 0; - rot = 0; - layer = 0; - } + uint32_t cell = 0; }; /** @@ -103,7 +97,7 @@ class GridMap : public Node3D { RID instance; RID multimesh; struct Item { - int index; + int index = 0; Transform transform; IndexKey key; }; @@ -116,7 +110,7 @@ class GridMap : public Node3D { RID collision_debug; RID collision_debug_instance; - bool dirty; + bool dirty = false; RID static_body; Map<IndexKey, NavMesh> navmesh_ids; }; @@ -129,35 +123,37 @@ class GridMap : public Node3D { int16_t empty; }; - uint64_t key; + uint64_t key = 0; _FORCE_INLINE_ bool operator<(const OctantKey &p_key) const { return key < p_key.key; } //OctantKey(const IndexKey& p_k, int p_item) { indexkey=p_k.key; item=p_item; } - OctantKey() { key = 0; } + OctantKey() {} }; - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; Transform last_transform; - bool _in_tree; - Vector3 cell_size; - int octant_size; - bool center_x, center_y, center_z; - float cell_scale; - Navigation3D *navigation; + bool _in_tree = false; + Vector3 cell_size = Vector3(2, 2, 2); + int octant_size = 8; + bool center_x = true; + bool center_y = true; + bool center_z = true; + float cell_scale = 1.0; + Navigation3D *navigation = nullptr; - bool clip; - bool clip_above; - int clip_floor; + bool clip = false; + bool clip_above = true; + int clip_floor = 0; - bool recreating_octants; + bool recreating_octants = false; - Vector3::Axis clip_axis; + Vector3::Axis clip_axis = Vector3::AXIS_Z; Ref<MeshLibrary> mesh_library; @@ -167,10 +163,10 @@ class GridMap : public Node3D { void _recreate_octant_data(); struct BakeLight { - RS::LightType type; + RS::LightType type = RS::LightType::LIGHT_DIRECTIONAL; Vector3 pos; Vector3 dir; - float param[RS::LIGHT_PARAM_MAX]; + float param[RS::LIGHT_PARAM_MAX] = {}; }; _FORCE_INLINE_ Vector3 _octant_get_offset(const OctantKey &p_key) const { @@ -183,7 +179,7 @@ class GridMap : public Node3D { bool _octant_update(const OctantKey &p_key); void _octant_clean_up(const OctantKey &p_key); void _octant_transform(const OctantKey &p_key); - bool awaiting_update; + bool awaiting_update = false; void _queue_octants_dirty(); void _update_octants_callback(); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 4732a3f62d..da9cdb9bc5 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -769,7 +769,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In struct _CGMEItemSort { String name; - int id; + int id = 0; _FORCE_INLINE_ bool operator<(const _CGMEItemSort &r_it) const { return name < r_it.name; } }; @@ -1151,7 +1151,6 @@ void GridMapEditor::_bind_methods() { } GridMapEditor::GridMapEditor(EditorNode *p_editor) { - input_action = INPUT_NONE; editor = p_editor; undo_redo = p_editor->get_undo_redo(); @@ -1173,7 +1172,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { floor->set_min(-32767); floor->set_max(32767); floor->set_step(1); - floor->get_line_edit()->add_theme_constant_override("minimum_spaces", 16); + floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 16); spatial_editor_hb->add_child(floor); floor->connect("value_changed", callable_mp(this, &GridMapEditor::_floor_changed)); @@ -1234,7 +1233,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { settings_pick_distance->set_value(EDITOR_DEF("editors/grid_map/pick_distance", 5000.0)); settings_vbc->add_margin_child(TTR("Pick Distance:"), settings_pick_distance); - clip_mode = CLIP_DISABLED; options->get_popup()->connect("id_pressed", callable_mp(this, &GridMapEditor::_menu_option)); HBoxContainer *hb = memnew(HBoxContainer); @@ -1275,8 +1273,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { EDITOR_DEF("editors/grid_map/preview_size", 64); - display_mode = DISPLAY_THUMBNAIL; - mesh_library_palette = memnew(ItemList); add_child(mesh_library_palette); mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL); @@ -1296,11 +1292,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { edit_floor[1] = -1; edit_floor[2] = -1; - cursor_visible = false; - selected_palette = -1; - lock_view = false; - cursor_rot = 0; - selection_mesh = RenderingServer::get_singleton()->mesh_create(); paste_mesh = RenderingServer::get_singleton()->mesh_create(); @@ -1418,8 +1409,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { } _set_selection(false); - updating = false; - accumulated_floor_delta = 0.0; indicator_mat.instance(); indicator_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 0c0ec64680..6c7f0bedf6 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -65,11 +65,11 @@ class GridMapEditor : public VBoxContainer { }; UndoRedo *undo_redo; - InputAction input_action; + InputAction input_action = INPUT_NONE; Panel *panel; MenuButton *options; SpinBox *floor; - double accumulated_floor_delta; + double accumulated_floor_delta = 0.0; Button *mode_thumbnail; Button *mode_list; LineEdit *search_box; @@ -82,19 +82,19 @@ class GridMapEditor : public VBoxContainer { struct SetItem { Vector3i position; - int new_value; - int new_orientation; - int old_value; - int old_orientation; + int new_value = 0; + int new_orientation = 0; + int old_value = 0; + int old_orientation = 0; }; List<SetItem> set_items; GridMap *node = nullptr; MeshLibrary *last_mesh_library; - ClipMode clip_mode; + ClipMode clip_mode = CLIP_DISABLED; - bool lock_view; + bool lock_view = false; Transform grid_xform; Transform edit_grid_xform; Vector3::Axis edit_axis; @@ -112,9 +112,9 @@ class GridMapEditor : public VBoxContainer { RID paste_instance; struct ClipboardItem { - int cell_item; + int cell_item = 0; Vector3 grid_offset; - int orientation; + int orientation = 0; RID instance; }; @@ -125,14 +125,14 @@ class GridMapEditor : public VBoxContainer { Ref<StandardMaterial3D> outer_mat; Ref<StandardMaterial3D> selection_floor_mat; - bool updating; + bool updating = false; struct Selection { Vector3 click; Vector3 current; Vector3 begin; Vector3 end; - bool active; + bool active = false; } selection; Selection last_selection; @@ -141,18 +141,18 @@ class GridMapEditor : public VBoxContainer { Vector3 current; Vector3 begin; Vector3 end; - int orientation; + int orientation = 0; }; PasteIndicator paste_indicator; - bool cursor_visible; + bool cursor_visible = false; Transform cursor_transform; Vector3 cursor_origin; - int display_mode; - int selected_palette; - int cursor_rot; + int display_mode = DISPLAY_THUMBNAIL; + int selected_palette = -1; + int cursor_rot = 0; enum Menu { MENU_OPTION_NEXT_LEVEL, diff --git a/modules/icloud/SCsub b/modules/icloud/SCsub deleted file mode 100644 index 805a484600..0000000000 --- a/modules/icloud/SCsub +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_icloud = env_modules.Clone() - -# (iOS) Enable module support -env_icloud.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - -# (iOS) Build as separate static library -modules_sources = [] -env_icloud.add_source_files(modules_sources, "*.cpp") -env_icloud.add_source_files(modules_sources, "*.mm") -mod_lib = env_modules.add_library("#bin/libgodot_icloud_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/icloud/config.py b/modules/icloud/config.py deleted file mode 100644 index e68603fc93..0000000000 --- a/modules/icloud/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return platform == "iphone" - - -def configure(env): - pass diff --git a/modules/icloud/icloud.gdip b/modules/icloud/icloud.gdip deleted file mode 100644 index 9f81be8a34..0000000000 --- a/modules/icloud/icloud.gdip +++ /dev/null @@ -1,17 +0,0 @@ -[config] -name="iCloud" -binary="icloud_lib.a" - -initialization="register_icloud_types" -deinitialization="unregister_icloud_types" - -[dependencies] -linked=[] -embedded=[] -system=[] - -capabilities=[] - -files=[] - -[plist] diff --git a/modules/icloud/icloud.h b/modules/icloud/icloud.h deleted file mode 100644 index 7b7aa52b63..0000000000 --- a/modules/icloud/icloud.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************/ -/* icloud.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ICLOUD_H -#define ICLOUD_H - -#include "core/object/class_db.h" - -class ICloud : public Object { - GDCLASS(ICloud, Object); - - static ICloud *instance; - static void _bind_methods(); - - List<Variant> pending_events; - -public: - Error remove_key(String p_param); - Array set_key_values(Dictionary p_params); - Variant get_key_value(String p_param); - Error synchronize_key_values(); - Variant get_all_key_values(); - - int get_pending_event_count(); - Variant pop_pending_event(); - - static ICloud *get_singleton(); - - ICloud(); - ~ICloud(); -}; - -#endif diff --git a/modules/icloud/icloud.mm b/modules/icloud/icloud.mm deleted file mode 100644 index 937ef38018..0000000000 --- a/modules/icloud/icloud.mm +++ /dev/null @@ -1,345 +0,0 @@ -/*************************************************************************/ -/* icloud.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "icloud.h" - -#import "platform/iphone/app_delegate.h" - -#import <Foundation/Foundation.h> - -ICloud *ICloud::instance = NULL; - -void ICloud::_bind_methods() { - ClassDB::bind_method(D_METHOD("remove_key"), &ICloud::remove_key); - - ClassDB::bind_method(D_METHOD("set_key_values"), &ICloud::set_key_values); - ClassDB::bind_method(D_METHOD("get_key_value"), &ICloud::get_key_value); - - ClassDB::bind_method(D_METHOD("synchronize_key_values"), &ICloud::synchronize_key_values); - ClassDB::bind_method(D_METHOD("get_all_key_values"), &ICloud::get_all_key_values); - - ClassDB::bind_method(D_METHOD("get_pending_event_count"), &ICloud::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"), &ICloud::pop_pending_event); -}; - -int ICloud::get_pending_event_count() { - return pending_events.size(); -}; - -Variant ICloud::pop_pending_event() { - Variant front = pending_events.front()->get(); - pending_events.pop_front(); - - return front; -}; - -ICloud *ICloud::get_singleton() { - return instance; -}; - -//convert from apple's abstract type to godot's abstract type.... -Variant nsobject_to_variant(NSObject *object) { - if ([object isKindOfClass:[NSString class]]) { - const char *str = [(NSString *)object UTF8String]; - return String::utf8(str != NULL ? str : ""); - } else if ([object isKindOfClass:[NSData class]]) { - PackedByteArray ret; - NSData *data = (NSData *)object; - if ([data length] > 0) { - ret.resize([data length]); - { - // PackedByteArray::Write w = ret.write(); - copymem((void *)ret.ptr(), [data bytes], [data length]); - } - } - return ret; - } else if ([object isKindOfClass:[NSArray class]]) { - Array result; - NSArray *array = (NSArray *)object; - for (NSUInteger i = 0; i < [array count]; ++i) { - NSObject *value = [array objectAtIndex:i]; - result.push_back(nsobject_to_variant(value)); - } - return result; - } else if ([object isKindOfClass:[NSDictionary class]]) { - Dictionary result; - NSDictionary *dic = (NSDictionary *)object; - - NSArray *keys = [dic allKeys]; - int count = [keys count]; - for (int i = 0; i < count; ++i) { - NSObject *k = [keys objectAtIndex:i]; - NSObject *v = [dic objectForKey:k]; - - result[nsobject_to_variant(k)] = nsobject_to_variant(v); - } - return result; - } else if ([object isKindOfClass:[NSNumber class]]) { - //Every type except numbers can reliably identify its type. The following is comparing to the *internal* representation, which isn't guaranteed to match the type that was used to create it, and is not advised, particularly when dealing with potential platform differences (ie, 32/64 bit) - //To avoid errors, we'll cast as broadly as possible, and only return int or float. - //bool, char, int, uint, longlong -> int - //float, double -> float - NSNumber *num = (NSNumber *)object; - if (strcmp([num objCType], @encode(BOOL)) == 0) { - return Variant((int)[num boolValue]); - } else if (strcmp([num objCType], @encode(char)) == 0) { - return Variant((int)[num charValue]); - } else if (strcmp([num objCType], @encode(int)) == 0) { - return Variant([num intValue]); - } else if (strcmp([num objCType], @encode(unsigned int)) == 0) { - return Variant((int)[num unsignedIntValue]); - } else if (strcmp([num objCType], @encode(long long)) == 0) { - return Variant((int)[num longValue]); - } else if (strcmp([num objCType], @encode(float)) == 0) { - return Variant([num floatValue]); - } else if (strcmp([num objCType], @encode(double)) == 0) { - return Variant((float)[num doubleValue]); - } else { - return Variant(); - } - } else if ([object isKindOfClass:[NSDate class]]) { - //this is a type that icloud supports...but how did you submit it in the first place? - //I guess this is a type that *might* show up, if you were, say, trying to make your game - //compatible with existing cloud data written by another engine's version of your game - WARN_PRINT("NSDate unsupported, returning null Variant"); - return Variant(); - } else if ([object isKindOfClass:[NSNull class]] or object == nil) { - return Variant(); - } else { - WARN_PRINT("Trying to convert unknown NSObject type to Variant"); - return Variant(); - } -} - -NSObject *variant_to_nsobject(Variant v) { - if (v.get_type() == Variant::STRING) { - return [[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()]; - } else if (v.get_type() == Variant::FLOAT) { - return [NSNumber numberWithDouble:(double)v]; - } else if (v.get_type() == Variant::INT) { - return [NSNumber numberWithLongLong:(long)(int)v]; - } else if (v.get_type() == Variant::BOOL) { - return [NSNumber numberWithBool:BOOL((bool)v)]; - } else if (v.get_type() == Variant::DICTIONARY) { - NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; - Dictionary dic = v; - Array keys = dic.keys(); - for (int i = 0; i < keys.size(); ++i) { - NSString *key = [[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()]; - NSObject *value = variant_to_nsobject(dic[keys[i]]); - - if (key == NULL || value == NULL) { - return NULL; - } - - [result setObject:value forKey:key]; - } - return result; - } else if (v.get_type() == Variant::ARRAY) { - NSMutableArray *result = [[NSMutableArray alloc] init]; - Array arr = v; - for (int i = 0; i < arr.size(); ++i) { - NSObject *value = variant_to_nsobject(arr[i]); - if (value == NULL) { - //trying to add something unsupported to the array. cancel the whole array - return NULL; - } - [result addObject:value]; - } - return result; - } else if (v.get_type() == Variant::PACKED_BYTE_ARRAY) { - PackedByteArray arr = v; - // PackedByteArray::Read r = arr.read(); - NSData *result = [NSData dataWithBytes:arr.ptr() length:arr.size()]; - return result; - } - WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type()) + "'").utf8().get_data()); - return NULL; -} - -Error ICloud::remove_key(String p_param) { - NSString *key = [[NSString alloc] initWithUTF8String:p_param.utf8().get_data()]; - - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - - if (![[store dictionaryRepresentation] objectForKey:key]) { - return ERR_INVALID_PARAMETER; - } - - [store removeObjectForKey:key]; - return OK; -} - -//return an array of the keys that could not be set -Array ICloud::set_key_values(Dictionary p_params) { - Array keys = p_params.keys(); - - Array error_keys; - - for (int i = 0; i < keys.size(); ++i) { - String variant_key = keys[i]; - Variant variant_value = p_params[variant_key]; - - NSString *key = [[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()]; - if (key == NULL) { - error_keys.push_back(variant_key); - continue; - } - - NSObject *value = variant_to_nsobject(variant_value); - - if (value == NULL) { - error_keys.push_back(variant_key); - continue; - } - - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - [store setObject:value forKey:key]; - } - - return error_keys; -} - -Variant ICloud::get_key_value(String p_param) { - NSString *key = [[NSString alloc] initWithUTF8String:p_param.utf8().get_data()]; - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - - if (![[store dictionaryRepresentation] objectForKey:key]) { - return Variant(); - } - - Variant result = nsobject_to_variant([[store dictionaryRepresentation] objectForKey:key]); - - return result; -} - -Variant ICloud::get_all_key_values() { - Dictionary result; - - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - NSDictionary *store_dictionary = [store dictionaryRepresentation]; - - NSArray *keys = [store_dictionary allKeys]; - int count = [keys count]; - for (int i = 0; i < count; ++i) { - NSString *k = [keys objectAtIndex:i]; - NSObject *v = [store_dictionary objectForKey:k]; - - const char *str = [k UTF8String]; - if (str != NULL) { - result[String::utf8(str)] = nsobject_to_variant(v); - } - } - - return result; -} - -Error ICloud::synchronize_key_values() { - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - BOOL result = [store synchronize]; - if (result == YES) { - return OK; - } else { - return FAILED; - } -} - -/* -Error ICloud::initial_sync() { - //you sometimes have to write something to the store to get it to download new data. go apple! - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - if ([store boolForKey:@"isb"]) - { - [store setBool:NO forKey:@"isb"]; - } - else - { - [store setBool:YES forKey:@"isb"]; - } - return synchronize(); -} - -*/ -ICloud::ICloud() { - ERR_FAIL_COND(instance != NULL); - instance = this; - //connected = false; - - [[NSNotificationCenter defaultCenter] - addObserverForName:NSUbiquitousKeyValueStoreDidChangeExternallyNotification - object:[NSUbiquitousKeyValueStore defaultStore] - queue:nil - usingBlock:^(NSNotification *notification) { - NSDictionary *userInfo = [notification userInfo]; - NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue]; - - Dictionary ret; - ret["type"] = "key_value_changed"; - - //PackedStringArray result_keys; - //Array result_values; - Dictionary keyValues; - String reason = ""; - - if (change == NSUbiquitousKeyValueStoreServerChange) { - reason = "server"; - } else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) { - reason = "initial_sync"; - } else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) { - reason = "quota_violation"; - } else if (change == NSUbiquitousKeyValueStoreAccountChange) { - reason = "account"; - } - - ret["reason"] = reason; - - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - - NSArray *keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey]; - for (NSString *key in keys) { - const char *str = [key UTF8String]; - if (str == NULL) { - continue; - } - - NSObject *object = [store objectForKey:key]; - - //figure out what kind of object it is - Variant value = nsobject_to_variant(object); - - keyValues[String::utf8(str)] = value; - } - - ret["changed_values"] = keyValues; - pending_events.push_back(ret); - }]; -} - -ICloud::~ICloud() {} diff --git a/modules/icloud/icloud_module.h b/modules/icloud/icloud_module.h deleted file mode 100644 index fb8b5fe66e..0000000000 --- a/modules/icloud/icloud_module.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************/ -/* icloud_module.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -void register_icloud_types(); -void unregister_icloud_types(); diff --git a/modules/inappstore/SCsub b/modules/inappstore/SCsub deleted file mode 100644 index cee6a256d5..0000000000 --- a/modules/inappstore/SCsub +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_inappstore = env_modules.Clone() - -# (iOS) Enable module support -env_inappstore.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) - -# (iOS) Build as separate static library -modules_sources = [] -env_inappstore.add_source_files(modules_sources, "*.cpp") -env_inappstore.add_source_files(modules_sources, "*.mm") -mod_lib = env_modules.add_library("#bin/libgodot_inappstore_module" + env["LIBSUFFIX"], modules_sources) diff --git a/modules/inappstore/config.py b/modules/inappstore/config.py deleted file mode 100644 index e68603fc93..0000000000 --- a/modules/inappstore/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return platform == "iphone" - - -def configure(env): - pass diff --git a/modules/inappstore/in_app_store.h b/modules/inappstore/in_app_store.h deleted file mode 100644 index c66c306319..0000000000 --- a/modules/inappstore/in_app_store.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************/ -/* in_app_store.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef IN_APP_STORE_H -#define IN_APP_STORE_H - -#include "core/object/class_db.h" - -#ifdef __OBJC__ -@class GodotProductsDelegate; -@class GodotTransactionsObserver; - -typedef GodotProductsDelegate InAppStoreProductDelegate; -typedef GodotTransactionsObserver InAppStoreTransactionObserver; -#else -typedef void InAppStoreProductDelegate; -typedef void InAppStoreTransactionObserver; -#endif - -class InAppStore : public Object { - GDCLASS(InAppStore, Object); - - static InAppStore *instance; - static void _bind_methods(); - - List<Variant> pending_events; - - InAppStoreProductDelegate *products_request_delegate; - InAppStoreTransactionObserver *transactions_observer; - -public: - Error request_product_info(Dictionary p_params); - Error restore_purchases(); - Error purchase(Dictionary p_params); - - int get_pending_event_count(); - Variant pop_pending_event(); - void finish_transaction(String product_id); - void set_auto_finish_transaction(bool b); - - void _post_event(Variant p_event); - void _record_purchase(String product_id); - - static InAppStore *get_singleton(); - - InAppStore(); - ~InAppStore(); -}; - -#endif diff --git a/modules/inappstore/in_app_store.mm b/modules/inappstore/in_app_store.mm deleted file mode 100644 index 427808ae75..0000000000 --- a/modules/inappstore/in_app_store.mm +++ /dev/null @@ -1,411 +0,0 @@ -/*************************************************************************/ -/* in_app_store.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "in_app_store.h" - -#import <Foundation/Foundation.h> -#import <StoreKit/StoreKit.h> - -InAppStore *InAppStore::instance = NULL; - -@interface SKProduct (LocalizedPrice) - -@property(nonatomic, readonly) NSString *localizedPrice; - -@end - -//----------------------------------// -// SKProduct extension -//----------------------------------// -@implementation SKProduct (LocalizedPrice) - -- (NSString *)localizedPrice { - NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; - [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; - [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; - [numberFormatter setLocale:self.priceLocale]; - NSString *formattedString = [numberFormatter stringFromNumber:self.price]; - return formattedString; -} - -@end - -@interface GodotProductsDelegate : NSObject <SKProductsRequestDelegate> - -@property(nonatomic, strong) NSMutableArray *loadedProducts; -@property(nonatomic, strong) NSMutableArray *pendingRequests; - -- (void)performRequestWithProductIDs:(NSSet *)productIDs; -- (Error)purchaseProductWithProductID:(NSString *)productID; -- (void)reset; - -@end - -@implementation GodotProductsDelegate - -- (instancetype)init { - self = [super init]; - - if (self) { - [self godot_commonInit]; - } - - return self; -} - -- (void)godot_commonInit { - self.loadedProducts = [NSMutableArray new]; - self.pendingRequests = [NSMutableArray new]; -} - -- (void)performRequestWithProductIDs:(NSSet *)productIDs { - SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIDs]; - - request.delegate = self; - [self.pendingRequests addObject:request]; - [request start]; -} - -- (Error)purchaseProductWithProductID:(NSString *)productID { - SKProduct *product = nil; - - NSLog(@"searching for product!"); - - if (self.loadedProducts) { - for (SKProduct *storedProduct in self.loadedProducts) { - if ([storedProduct.productIdentifier isEqualToString:productID]) { - product = storedProduct; - break; - } - } - } - - if (!product) { - return ERR_INVALID_PARAMETER; - } - - NSLog(@"product found!"); - - SKPayment *payment = [SKPayment paymentWithProduct:product]; - [[SKPaymentQueue defaultQueue] addPayment:payment]; - - NSLog(@"purchase sent!"); - - return OK; -} - -- (void)reset { - [self.loadedProducts removeAllObjects]; - [self.pendingRequests removeAllObjects]; -} - -- (void)request:(SKRequest *)request didFailWithError:(NSError *)error { - [self.pendingRequests removeObject:request]; - - Dictionary ret; - ret["type"] = "product_info"; - ret["result"] = "error"; - ret["error"] = String::utf8([error.localizedDescription UTF8String]); - - InAppStore::get_singleton()->_post_event(ret); -} - -- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { - [self.pendingRequests removeObject:request]; - - NSArray *products = response.products; - [self.loadedProducts addObjectsFromArray:products]; - - Dictionary ret; - ret["type"] = "product_info"; - ret["result"] = "ok"; - PackedStringArray titles; - PackedStringArray descriptions; - PackedFloat32Array prices; - PackedStringArray ids; - PackedStringArray localized_prices; - PackedStringArray currency_codes; - - for (NSUInteger i = 0; i < [products count]; i++) { - SKProduct *product = [products objectAtIndex:i]; - - const char *str = [product.localizedTitle UTF8String]; - titles.push_back(String::utf8(str != NULL ? str : "")); - - str = [product.localizedDescription UTF8String]; - descriptions.push_back(String::utf8(str != NULL ? str : "")); - prices.push_back([product.price doubleValue]); - ids.push_back(String::utf8([product.productIdentifier UTF8String])); - localized_prices.push_back(String::utf8([product.localizedPrice UTF8String])); - currency_codes.push_back(String::utf8([[[product priceLocale] objectForKey:NSLocaleCurrencyCode] UTF8String])); - } - - ret["titles"] = titles; - ret["descriptions"] = descriptions; - ret["prices"] = prices; - ret["ids"] = ids; - ret["localized_prices"] = localized_prices; - ret["currency_codes"] = currency_codes; - - PackedStringArray invalid_ids; - - for (NSString *ipid in response.invalidProductIdentifiers) { - invalid_ids.push_back(String::utf8([ipid UTF8String])); - } - - ret["invalid_ids"] = invalid_ids; - - InAppStore::get_singleton()->_post_event(ret); -} - -@end - -@interface GodotTransactionsObserver : NSObject <SKPaymentTransactionObserver> - -@property(nonatomic, assign) BOOL shouldAutoFinishTransactions; -@property(nonatomic, strong) NSMutableDictionary *pendingTransactions; - -- (void)finishTransactionWithProductID:(NSString *)productID; -- (void)reset; - -@end - -@implementation GodotTransactionsObserver - -- (instancetype)init { - self = [super init]; - - if (self) { - [self godot_commonInit]; - } - - return self; -} - -- (void)godot_commonInit { - self.pendingTransactions = [NSMutableDictionary new]; -} - -- (void)finishTransactionWithProductID:(NSString *)productID { - SKPaymentTransaction *transaction = self.pendingTransactions[productID]; - - if (transaction) { - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } - - self.pendingTransactions[productID] = nil; -} - -- (void)reset { - [self.pendingTransactions removeAllObjects]; -} - -- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { - printf("transactions updated!\n"); - for (SKPaymentTransaction *transaction in transactions) { - switch (transaction.transactionState) { - case SKPaymentTransactionStatePurchased: { - printf("status purchased!\n"); - String pid = String::utf8([transaction.payment.productIdentifier UTF8String]); - String transactionId = String::utf8([transaction.transactionIdentifier UTF8String]); - InAppStore::get_singleton()->_record_purchase(pid); - Dictionary ret; - ret["type"] = "purchase"; - ret["result"] = "ok"; - ret["product_id"] = pid; - ret["transaction_id"] = transactionId; - - NSData *receipt = nil; - int sdk_version = [[[UIDevice currentDevice] systemVersion] intValue]; - - NSBundle *bundle = [NSBundle mainBundle]; - // Get the transaction receipt file path location in the app bundle. - NSURL *receiptFileURL = [bundle appStoreReceiptURL]; - - // Read in the contents of the transaction file. - receipt = [NSData dataWithContentsOfURL:receiptFileURL]; - - NSString *receipt_to_send = nil; - - if (receipt != nil) { - receipt_to_send = [receipt base64EncodedStringWithOptions:0]; - } - Dictionary receipt_ret; - receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : ""); - receipt_ret["sdk"] = sdk_version; - ret["receipt"] = receipt_ret; - - InAppStore::get_singleton()->_post_event(ret); - - if (self.shouldAutoFinishTransactions) { - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } else { - self.pendingTransactions[transaction.payment.productIdentifier] = transaction; - } - - } break; - case SKPaymentTransactionStateFailed: { - printf("status transaction failed!\n"); - String pid = String::utf8([transaction.payment.productIdentifier UTF8String]); - Dictionary ret; - ret["type"] = "purchase"; - ret["result"] = "error"; - ret["product_id"] = pid; - ret["error"] = String::utf8([transaction.error.localizedDescription UTF8String]); - InAppStore::get_singleton()->_post_event(ret); - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } break; - case SKPaymentTransactionStateRestored: { - printf("status transaction restored!\n"); - String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]); - InAppStore::get_singleton()->_record_purchase(pid); - Dictionary ret; - ret["type"] = "restore"; - ret["result"] = "ok"; - ret["product_id"] = pid; - InAppStore::get_singleton()->_post_event(ret); - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } break; - default: { - printf("status default %i!\n", (int)transaction.transactionState); - } break; - } - } -} - -@end - -void InAppStore::_bind_methods() { - ClassDB::bind_method(D_METHOD("request_product_info"), &InAppStore::request_product_info); - ClassDB::bind_method(D_METHOD("restore_purchases"), &InAppStore::restore_purchases); - ClassDB::bind_method(D_METHOD("purchase"), &InAppStore::purchase); - - ClassDB::bind_method(D_METHOD("get_pending_event_count"), &InAppStore::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"), &InAppStore::pop_pending_event); - ClassDB::bind_method(D_METHOD("finish_transaction"), &InAppStore::finish_transaction); - ClassDB::bind_method(D_METHOD("set_auto_finish_transaction"), &InAppStore::set_auto_finish_transaction); -} - -Error InAppStore::request_product_info(Dictionary p_params) { - ERR_FAIL_COND_V(!p_params.has("product_ids"), ERR_INVALID_PARAMETER); - - PackedStringArray pids = p_params["product_ids"]; - printf("************ request product info! %i\n", pids.size()); - - NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:pids.size()]; - for (int i = 0; i < pids.size(); i++) { - printf("******** adding %s to product list\n", pids[i].utf8().get_data()); - NSString *pid = [[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()]; - [array addObject:pid]; - }; - - NSSet *products = [[NSSet alloc] initWithArray:array]; - - [products_request_delegate performRequestWithProductIDs:products]; - - return OK; -} - -Error InAppStore::restore_purchases() { - printf("restoring purchases!\n"); - [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; - - return OK; -} - -Error InAppStore::purchase(Dictionary p_params) { - ERR_FAIL_COND_V(![SKPaymentQueue canMakePayments], ERR_UNAVAILABLE); - if (![SKPaymentQueue canMakePayments]) { - return ERR_UNAVAILABLE; - } - - printf("purchasing!\n"); - Dictionary params = p_params; - ERR_FAIL_COND_V(!params.has("product_id"), ERR_INVALID_PARAMETER); - - NSString *pid = [[NSString alloc] initWithUTF8String:String(params["product_id"]).utf8().get_data()]; - - return [products_request_delegate purchaseProductWithProductID:pid]; -} - -int InAppStore::get_pending_event_count() { - return pending_events.size(); -} - -Variant InAppStore::pop_pending_event() { - Variant front = pending_events.front()->get(); - pending_events.pop_front(); - - return front; -} - -void InAppStore::_post_event(Variant p_event) { - pending_events.push_back(p_event); -} - -void InAppStore::_record_purchase(String product_id) { - String skey = "purchased/" + product_id; - NSString *key = [[NSString alloc] initWithUTF8String:skey.utf8().get_data()]; - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key]; - [[NSUserDefaults standardUserDefaults] synchronize]; -} - -InAppStore *InAppStore::get_singleton() { - return instance; -} - -InAppStore::InAppStore() { - ERR_FAIL_COND(instance != NULL); - instance = this; - - products_request_delegate = [[GodotProductsDelegate alloc] init]; - transactions_observer = [[GodotTransactionsObserver alloc] init]; - - [[SKPaymentQueue defaultQueue] addTransactionObserver:transactions_observer]; -} - -void InAppStore::finish_transaction(String product_id) { - NSString *prod_id = [NSString stringWithCString:product_id.utf8().get_data() encoding:NSUTF8StringEncoding]; - - [transactions_observer finishTransactionWithProductID:prod_id]; -} - -void InAppStore::set_auto_finish_transaction(bool b) { - transactions_observer.shouldAutoFinishTransactions = b; -} - -InAppStore::~InAppStore() { - [products_request_delegate reset]; - [transactions_observer reset]; - - products_request_delegate = nil; - [[SKPaymentQueue defaultQueue] removeTransactionObserver:transactions_observer]; - transactions_observer = nil; -} diff --git a/modules/inappstore/in_app_store_module.cpp b/modules/inappstore/in_app_store_module.cpp deleted file mode 100644 index c89735cd1c..0000000000 --- a/modules/inappstore/in_app_store_module.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ -/* in_app_store_module.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "in_app_store_module.h" - -#include "core/config/engine.h" - -#include "in_app_store.h" - -InAppStore *store_kit; - -void register_inappstore_types() { - store_kit = memnew(InAppStore); - Engine::get_singleton()->add_singleton(Engine::Singleton("InAppStore", store_kit)); -} - -void unregister_inappstore_types() { - if (store_kit) { - memdelete(store_kit); - } -} diff --git a/modules/inappstore/in_app_store_module.h b/modules/inappstore/in_app_store_module.h deleted file mode 100644 index dc38969825..0000000000 --- a/modules/inappstore/in_app_store_module.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************/ -/* in_app_store_module.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -void register_inappstore_types(); -void unregister_inappstore_types(); diff --git a/modules/inappstore/inappstore.gdip b/modules/inappstore/inappstore.gdip deleted file mode 100644 index 7a5efb8ad3..0000000000 --- a/modules/inappstore/inappstore.gdip +++ /dev/null @@ -1,17 +0,0 @@ -[config] -name="InAppStore" -binary="inappstore_lib.a" - -initialization="register_inappstore_types" -deinitialization="unregister_inappstore_types" - -[dependencies] -linked=[] -embedded=[] -system=["StoreKit.framework"] - -capabilities=[] - -files=[] - -[plist] diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 3067e002d8..61ebabdfb6 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -93,8 +93,8 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con l.direction[2] = p_direction.z; l.range = p_range; l.attenuation = p_attenuation; - l.spot_angle = Math::deg2rad(p_spot_angle); - l.spot_attenuation = p_spot_attenuation; + l.cos_spot_angle = Math::cos(Math::deg2rad(p_spot_angle)); + l.inv_spot_attenuation = 1.0f / p_spot_attenuation; l.color[0] = p_color.r; l.color[1] = p_color.g; l.color[2] = p_color.b; @@ -1225,23 +1225,23 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d switch (p_quality) { case BAKE_QUALITY_LOW: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/low_quality_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/low_quality_ray_count"); } break; case BAKE_QUALITY_MEDIUM: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/medium_quality_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/medium_quality_ray_count"); } break; case BAKE_QUALITY_HIGH: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/high_quality_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/high_quality_ray_count"); } break; case BAKE_QUALITY_ULTRA: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/ultra_quality_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/ultra_quality_ray_count"); } break; } push_constant.ray_count = CLAMP(push_constant.ray_count, 16, 8192); - int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/gpu_lightmapper/performance/region_size"))); - int max_rays = GLOBAL_GET("rendering/gpu_lightmapper/performance/max_rays_per_pass"); + int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size"))); + int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_pass"); int x_regions = (atlas_size.width - 1) / max_region_size + 1; int y_regions = (atlas_size.height - 1) / max_region_size + 1; @@ -1347,23 +1347,23 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d switch (p_quality) { case BAKE_QUALITY_LOW: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/low_quality_probe_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/low_quality_probe_ray_count"); } break; case BAKE_QUALITY_MEDIUM: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/medium_quality_probe_ray_count"); } break; case BAKE_QUALITY_HIGH: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/high_quality_probe_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/high_quality_probe_ray_count"); } break; case BAKE_QUALITY_ULTRA: { - push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count"); + push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count"); } break; } push_constant.atlas_size[0] = probe_positions.size(); push_constant.ray_count = CLAMP(push_constant.ray_count, 16, 8192); - int max_rays = GLOBAL_GET("rendering/gpu_lightmapper/performance/max_rays_per_probe_pass"); + int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_probe_pass"); int ray_iterations = (push_constant.ray_count - 1) / max_rays + 1; for (int i = 0; i < ray_iterations; i++) { @@ -1436,7 +1436,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d dst[j + 3] = src[j + 3]; } } - rd->texture_update(light_accum_tex, i, ds, true); + rd->texture_update(light_accum_tex, i, ds); } } } @@ -1537,7 +1537,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d { //pre copy for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) { - rd->texture_copy(light_accum_tex, light_accum_tex2, Vector3(), Vector3(), Vector3(atlas_size.width, atlas_size.height, 1), 0, 0, i, i, true); + rd->texture_copy(light_accum_tex, light_accum_tex2, Vector3(), Vector3(), Vector3(atlas_size.width, atlas_size.height, 1), 0, 0, i, i); } Vector<RID> framebuffers; diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index bb735baf6c..f2a826a447 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -46,18 +46,18 @@ class LightmapperRD : public Lightmapper { }; struct Light { - float position[3]; + float position[3] = {}; uint32_t type = LIGHT_TYPE_DIRECTIONAL; - float direction[3]; - float energy; - float color[3]; - float size; - float range; - float attenuation; - float spot_angle; - float spot_attenuation; - uint32_t static_bake; - uint32_t pad[3]; + float direction[3] = {}; + float energy = 0.0; + float color[3] = {}; + float size = 0.0; + float range = 0.0; + float attenuation = 0.0; + float cos_spot_angle = 0.0; + float inv_spot_attenuation = 0.0; + uint32_t static_bake = 0; + uint32_t pad[3] = {}; bool operator<(const Light &p_light) const { return type < p_light.type; @@ -65,10 +65,10 @@ class LightmapperRD : public Lightmapper { }; struct Vertex { - float position[3]; - float normal_z; - float uv[2]; - float normal_xy[2]; + float position[3] = {}; + float normal_z = 0.0; + float uv[2] = {}; + float normal_xy[2] = {}; bool operator==(const Vertex &p_vtx) const { return (position[0] == p_vtx.position[0]) && @@ -102,7 +102,7 @@ class LightmapperRD : public Lightmapper { }; struct Probe { - float position[4]; + float position[4] = {}; }; Vector<Probe> probe_positions; @@ -158,15 +158,15 @@ class LightmapperRD : public Lightmapper { }; struct Box { - float min_bounds[3]; - float pad0; - float max_bounds[3]; - float pad1; + float min_bounds[3] = {}; + float pad0 = 0.0; + float max_bounds[3] = {}; + float pad1 = 0.0; }; struct Triangle { - uint32_t indices[3]; - uint32_t slice; + uint32_t indices[3] = {}; + uint32_t slice = 0; bool operator<(const Triangle &p_triangle) const { return slice < p_triangle.slice; } @@ -177,8 +177,8 @@ class LightmapperRD : public Lightmapper { Vector<Light> lights; struct TriangleSort { - uint32_t cell_index; - uint32_t triangle_index; + uint32_t cell_index = 0; + uint32_t triangle_index = 0; bool operator<(const TriangleSort &p_triangle_sort) const { return cell_index < p_triangle_sort.cell_index; //sorting by triangle index in this case makes no sense } @@ -187,44 +187,44 @@ class LightmapperRD : public Lightmapper { void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size); struct RasterPushConstant { - float atlas_size[2]; - float uv_offset[2]; - float to_cell_size[3]; - uint32_t base_triangle; - float to_cell_offset[3]; - float bias; - int32_t grid_size[3]; - uint32_t pad2; + float atlas_size[2] = {}; + float uv_offset[2] = {}; + float to_cell_size[3] = {}; + uint32_t base_triangle = 0; + float to_cell_offset[3] = {}; + float bias = 0.0; + int32_t grid_size[3] = {}; + uint32_t pad2 = 0; }; struct RasterSeamsPushConstant { - uint32_t base_index; - uint32_t slice; - float uv_offset[2]; - uint32_t debug; - float blend; - uint32_t pad[2]; + uint32_t base_index = 0; + uint32_t slice = 0; + float uv_offset[2] = {}; + uint32_t debug = 0; + float blend = 0.0; + uint32_t pad[2] = {}; }; struct PushConstant { - int32_t atlas_size[2]; - uint32_t ray_count; - uint32_t ray_to; + int32_t atlas_size[2] = {}; + uint32_t ray_count = 0; + uint32_t ray_to = 0; - float world_size[3]; - float bias; + float world_size[3] = {}; + float bias = 0.0; - float to_cell_offset[3]; - uint32_t ray_from; + float to_cell_offset[3] = {}; + uint32_t ray_from = 0; - float to_cell_size[3]; - uint32_t light_count; + float to_cell_size[3] = {}; + uint32_t light_count = 0; - int32_t grid_size; - int32_t atlas_slice; - int32_t region_ofs[2]; + int32_t grid_size = 0; + int32_t atlas_slice = 0; + int32_t region_ofs[2] = {}; - float environment_xform[12]; + float environment_xform[12] = {}; }; Vector<Ref<Image>> bake_textures; diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl index 0ff455936e..f8a0cd16de 100644 --- a/modules/lightmapper_rd/lm_common_inc.glsl +++ b/modules/lightmapper_rd/lm_common_inc.glsl @@ -56,8 +56,8 @@ struct Light { float range; float attenuation; - float spot_angle; - float spot_attenuation; + float cos_spot_angle; + float inv_spot_attenuation; bool static_bake; uint pad[3]; diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 8a9adbc5cc..eb9d817f99 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -313,13 +313,16 @@ void main() { if (lights.data[i].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(position - light_pos); - float angle = acos(dot(rel, lights.data[i].direction)); - if (angle > lights.data[i].spot_angle) { + float cos_spot_angle = lights.data[i].cos_spot_angle; + float cos_angle = dot(rel, lights.data[i].direction); + + if (cos_angle < cos_spot_angle) { continue; //invisible, dont try } - float d = clamp(angle / lights.data[i].spot_angle, 0, 1); - attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation); + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation); } } diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp index a7b8c063fd..191bb3d765 100644 --- a/modules/lightmapper_rd/register_types.cpp +++ b/modules/lightmapper_rd/register_types.cpp @@ -41,18 +41,18 @@ static Lightmapper *create_lightmapper_rd() { #endif void register_lightmapper_rd_types() { - GLOBAL_DEF("rendering/gpu_lightmapper/quality/low_quality_ray_count", 16); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/medium_quality_ray_count", 64); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/high_quality_ray_count", 256); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/ultra_quality_ray_count", 1024); - GLOBAL_DEF("rendering/gpu_lightmapper/performance/max_rays_per_pass", 32); - GLOBAL_DEF("rendering/gpu_lightmapper/performance/region_size", 512); + GLOBAL_DEF("rendering/lightmapping/bake_quality/low_quality_ray_count", 16); + GLOBAL_DEF("rendering/lightmapping/bake_quality/medium_quality_ray_count", 64); + GLOBAL_DEF("rendering/lightmapping/bake_quality/high_quality_ray_count", 256); + GLOBAL_DEF("rendering/lightmapping/bake_quality/ultra_quality_ray_count", 1024); + GLOBAL_DEF("rendering/lightmapping/bake_performance/max_rays_per_pass", 32); + GLOBAL_DEF("rendering/lightmapping/bake_performance/region_size", 512); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/low_quality_probe_ray_count", 64); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count", 256); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/high_quality_probe_ray_count", 512); - GLOBAL_DEF("rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count", 2048); - GLOBAL_DEF("rendering/gpu_lightmapper/performance/max_rays_per_probe_pass", 64); + GLOBAL_DEF("rendering/lightmapping/bake_quality/low_quality_probe_ray_count", 64); + GLOBAL_DEF("rendering/lightmapping/bake_quality/medium_quality_probe_ray_count", 256); + GLOBAL_DEF("rendering/lightmapping/bake_quality/high_quality_probe_ray_count", 512); + GLOBAL_DEF("rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count", 2048); + GLOBAL_DEF("rendering/lightmapping/bake_performance/max_rays_per_probe_pass", 64); #ifndef _3D_DISABLED ClassDB::register_class<LightmapperRD>(); Lightmapper::create_gpu = create_lightmapper_rd; diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 4fcbe8fb43..4fcbe8fb43 100755..100644 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub diff --git a/modules/mbedtls/config.py b/modules/mbedtls/config.py index d22f9454ed..d22f9454ed 100755..100644 --- a/modules/mbedtls/config.py +++ b/modules/mbedtls/config.py diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp index b2f8d668bf..8a6cdfb131 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.cpp +++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp @@ -246,7 +246,6 @@ int PacketPeerMbedDTLS::get_max_packet_size() const { PacketPeerMbedDTLS::PacketPeerMbedDTLS() { ssl_ctx.instance(); - status = STATUS_DISCONNECTED; } PacketPeerMbedDTLS::~PacketPeerMbedDTLS() { diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h index 0feec04c6e..6554c74a21 100755..100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.h +++ b/modules/mbedtls/packet_peer_mbed_dtls.h @@ -44,7 +44,7 @@ private: uint8_t packet_buffer[PACKET_BUFFER_SIZE]; - Status status; + Status status = STATUS_DISCONNECTED; String hostname; Ref<PacketPeerUDP> base; diff --git a/modules/mbedtls/register_types.h b/modules/mbedtls/register_types.h index 46ffb8522b..46ffb8522b 100755..100644 --- a/modules/mbedtls/register_types.h +++ b/modules/mbedtls/register_types.h diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp index 046f30588a..cbb532587f 100644 --- a/modules/mbedtls/ssl_context_mbedtls.cpp +++ b/modules/mbedtls/ssl_context_mbedtls.cpp @@ -76,7 +76,6 @@ void CookieContextMbedTLS::clear() { } CookieContextMbedTLS::CookieContextMbedTLS() { - inited = false; } CookieContextMbedTLS::~CookieContextMbedTLS() { @@ -205,7 +204,6 @@ mbedtls_ssl_context *SSLContextMbedTLS::get_context() { } SSLContextMbedTLS::SSLContextMbedTLS() { - inited = false; } SSLContextMbedTLS::~SSLContextMbedTLS() { diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h index d243185726..30632018a8 100644 --- a/modules/mbedtls/ssl_context_mbedtls.h +++ b/modules/mbedtls/ssl_context_mbedtls.h @@ -50,7 +50,7 @@ class CookieContextMbedTLS : public Reference { friend class SSLContextMbedTLS; protected: - bool inited; + bool inited = false; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_cookie_ctx cookie_ctx; @@ -65,7 +65,7 @@ public: class SSLContextMbedTLS : public Reference { protected: - bool inited; + bool inited = false; static PackedByteArray _read_file(String p_path); diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp index 1332d0923c..d7597aa435 100644 --- a/modules/mbedtls/stream_peer_mbedtls.cpp +++ b/modules/mbedtls/stream_peer_mbedtls.cpp @@ -274,7 +274,6 @@ int StreamPeerMbedTLS::get_available_bytes() const { StreamPeerMbedTLS::StreamPeerMbedTLS() { ssl_ctx.instance(); - status = STATUS_DISCONNECTED; } StreamPeerMbedTLS::~StreamPeerMbedTLS() { diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h index ccbbebe4f8..b89d7fb238 100755..100644 --- a/modules/mbedtls/stream_peer_mbedtls.h +++ b/modules/mbedtls/stream_peer_mbedtls.h @@ -36,7 +36,7 @@ class StreamPeerMbedTLS : public StreamPeerSSL { private: - Status status; + Status status = STATUS_DISCONNECTED; String hostname; Ref<StreamPeer> base; diff --git a/modules/meshoptimizer/register_types.cpp b/modules/meshoptimizer/register_types.cpp index 71cd9f4dcb..a03310f518 100644 --- a/modules/meshoptimizer/register_types.cpp +++ b/modules/meshoptimizer/register_types.cpp @@ -35,9 +35,13 @@ void register_meshoptimizer_types() { SurfaceTool::optimize_vertex_cache_func = meshopt_optimizeVertexCache; SurfaceTool::simplify_func = meshopt_simplify; + SurfaceTool::simplify_scale_func = meshopt_simplifyScale; + SurfaceTool::simplify_sloppy_func = meshopt_simplifySloppy; } void unregister_meshoptimizer_types() { SurfaceTool::optimize_vertex_cache_func = nullptr; SurfaceTool::simplify_func = nullptr; + SurfaceTool::simplify_scale_func = nullptr; + SurfaceTool::simplify_sloppy_func = nullptr; } diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp index 8627f71987..b128b81000 100644 --- a/modules/minimp3/audio_stream_mp3.cpp +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -159,7 +159,8 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) { const uint8_t *src_datar = p_data.ptr(); mp3dec_ex_t mp3d; - mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE); + int err = mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE); + ERR_FAIL_COND(err != 0); channels = mp3d.info.channels; sample_rate = mp3d.info.hz; diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h index de02ba6003..ce001fc418 100644 --- a/modules/minimp3/audio_stream_mp3.h +++ b/modules/minimp3/audio_stream_mp3.h @@ -78,11 +78,11 @@ class AudioStreamMP3 : public AudioStream { void *data = nullptr; uint32_t data_len = 0; - float sample_rate = 1; + float sample_rate = 1.0; int channels = 1; - float length = 0; + float length = 0.0; bool loop = false; - float loop_offset = 0; + float loop_offset = 0.0; void clear_data(); protected: diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index a9073ea4a0..25b110dc62 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -448,19 +448,7 @@ void MobileVRInterface::process() { }; }; -MobileVRInterface::MobileVRInterface() { - initialized = false; - - // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes - eye_height = 1.85; - intraocular_dist = 6.0; - display_width = 14.5; - display_to_lens = 4.0; - oversample = 1.5; - k1 = 0.215; - k2 = 0.215; - last_ticks = 0; -}; +MobileVRInterface::MobileVRInterface() {} MobileVRInterface::~MobileVRInterface() { // and make sure we cleanup if we haven't already diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index 1afa6c39b6..d28c2196af 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -51,19 +51,21 @@ class MobileVRInterface : public XRInterface { GDCLASS(MobileVRInterface, XRInterface); private: - bool initialized; + bool initialized = false; Basis orientation; - float eye_height; - uint64_t last_ticks; - real_t intraocular_dist; - real_t display_width; - real_t display_to_lens; - real_t oversample; + // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes + float eye_height = 1.85; + uint64_t last_ticks = 0; + + real_t intraocular_dist = 6.0; + real_t display_width = 14.5; + real_t display_to_lens = 4.0; + real_t oversample = 1.5; //@TODO not yet used, these are needed in our distortion shader... - real_t k1; - real_t k2; + real_t k1 = 0.215; + real_t k2 = 0.215; /* logic for processing our sensor data, this was originally in our positional tracker logic but I think @@ -73,9 +75,9 @@ private: Vector3 scale_magneto(const Vector3 &p_magnetometer); Basis combine_acc_mag(const Vector3 &p_grav, const Vector3 &p_magneto); - int mag_count; - bool has_gyro; - bool sensor_first; + int mag_count = 0; + bool has_gyro = false; + bool sensor_first = false; Vector3 last_accerometer_data; Vector3 last_magnetometer_data; Vector3 mag_current_min; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index da4ece8c5c..25cc64393a 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2604,7 +2604,7 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati MonoCustomAttrInfo *event_attrs = mono_custom_attrs_from_event(top->get_mono_ptr(), raw_event); if (event_attrs) { if (mono_custom_attrs_has_attr(event_attrs, CACHED_CLASS(SignalAttribute)->get_mono_ptr())) { - const char *event_name = mono_event_get_name(raw_event); + String event_name = String::utf8(mono_event_get_name(raw_event)); found_event_signals.push_back(StringName(event_name)); } @@ -2808,7 +2808,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage name_only_hint_string += ","; } - String enum_field_name = mono_field_get_name(field); + String enum_field_name = String::utf8(mono_field_get_name(field)); r_hint_string += enum_field_name; name_only_hint_string += enum_field_name; @@ -3584,9 +3584,9 @@ Error CSharpScript::load_source_code(const String &p_path) { ERR_FAIL_COND_V_MSG(ferr != OK, ferr, ferr == ERR_INVALID_DATA ? - "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded." + "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded." " Please ensure that scripts are saved in valid UTF-8 unicode." : - "Failed to read file: '" + p_path + "'."); + "Failed to read file: '" + p_path + "'."); #ifdef TOOLS_ENABLED source_changed_cache = true; @@ -3644,7 +3644,7 @@ void CSharpScript::get_members(Set<StringName> *p_members) { /*************** RESOURCE ***************/ -RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 85edd8b9c6..a31135cd32 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -542,7 +542,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override; + RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; void get_recognized_extensions(List<String> *p_extensions) const override; bool handles_type(const String &p_type) const override; String get_resource_type(const String &p_path) const override; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs index e2feb66e35..774c49e705 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs @@ -86,7 +86,7 @@ namespace GodotTools.Build { case BuildTool.DotnetCli: { - string dotnetCliPath = OS.PathWhich("dotnet"); + string dotnetCliPath = FindBuildEngineOnUnix("dotnet"); if (!string.IsNullOrEmpty(dotnetCliPath)) return (dotnetCliPath, BuildTool.DotnetCli); GD.PushError($"Cannot find executable for '{BuildManager.PropNameDotnetCli}'. Fallback to MSBuild from Mono."); @@ -122,7 +122,11 @@ namespace GodotTools.Build if (OS.IsMacOS) { result.Add("/Library/Frameworks/Mono.framework/Versions/Current/bin/"); + result.Add("/opt/local/bin/"); result.Add("/usr/local/var/homebrew/linked/mono/bin/"); + result.Add("/usr/local/bin/"); + result.Add("/usr/local/bin/dotnet/"); + result.Add("/usr/local/share/dotnet/"); } result.Add("/opt/novell/mono/bin/"); @@ -181,7 +185,7 @@ namespace GodotTools.Build var outputArray = new Godot.Collections.Array<string>(); int exitCode = Godot.OS.Execute(vsWherePath, vsWhereArgs, - blocking: true, output: (Godot.Collections.Array)outputArray); + output: (Godot.Collections.Array)outputArray); if (exitCode != 0) return string.Empty; diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index 5bb8d444c2..5bb8d444c2 100755..100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs index 219b7a698a..93ef837a83 100755..100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs @@ -27,7 +27,7 @@ namespace GodotTools.Export { var outputWrapper = new Godot.Collections.Array(); - int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, blocking: true, output: outputWrapper); + int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, output: outputWrapper); if (exitCode == 0) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs index 16f91a0925..ed25cdaa63 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs @@ -104,7 +104,7 @@ namespace GodotTools.Ides.Rider if (line >= 0) { args.Add("--line"); - args.Add(line.ToString()); + args.Add((line + 1).ToString()); // https://github.com/JetBrains/godot-support/issues/61 } args.Add(scriptPath); try diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 59ce617990..b1875aec3f 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -39,6 +39,7 @@ #include "core/os/file_access.h" #include "core/os/os.h" #include "core/string/ucaps.h" +#include "main/main.h" #include "../glue/cs_glue_version.gen.h" #include "../godotsharp_defs.h" @@ -365,7 +366,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append("</c>"); } else if (link_tag == "enum") { StringName search_cname = !target_itype ? target_cname : - StringName(target_itype->name + "." + (String)target_cname); + StringName(target_itype->name + "." + (String)target_cname); const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname); @@ -783,6 +784,72 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { } } +void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { + p_output.append("using System;\n\n"); + p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); + // The class where we put the extensions doesn't matter, so just use "GD". + p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{"); + +#define ARRAY_IS_EMPTY(m_type) \ + p_output.append("\n" INDENT2 "/// <summary>\n"); \ + p_output.append(INDENT2 "/// Returns true if this " #m_type " array is empty or doesn't exist.\n"); \ + p_output.append(INDENT2 "/// </summary>\n"); \ + p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array check.</param>\n"); \ + p_output.append(INDENT2 "/// <returns>Whether or not the array is empty.</returns>\n"); \ + p_output.append(INDENT2 "public static bool IsEmpty(this " #m_type "[] instance)\n"); \ + p_output.append(INDENT2 OPEN_BLOCK); \ + p_output.append(INDENT3 "return instance == null || instance.Length == 0;\n"); \ + p_output.append(INDENT2 CLOSE_BLOCK); + +#define ARRAY_JOIN(m_type) \ + p_output.append("\n" INDENT2 "/// <summary>\n"); \ + p_output.append(INDENT2 "/// Converts this " #m_type " array to a string delimited by the given string.\n"); \ + p_output.append(INDENT2 "/// </summary>\n"); \ + p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \ + p_output.append(INDENT2 "/// <param name=\"delimiter\">The delimiter to use between items.</param>\n"); \ + p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \ + p_output.append(INDENT2 "public static string Join(this " #m_type "[] instance, string delimiter = \", \")\n"); \ + p_output.append(INDENT2 OPEN_BLOCK); \ + p_output.append(INDENT3 "return String.Join(delimiter, instance);\n"); \ + p_output.append(INDENT2 CLOSE_BLOCK); + +#define ARRAY_STRINGIFY(m_type) \ + p_output.append("\n" INDENT2 "/// <summary>\n"); \ + p_output.append(INDENT2 "/// Converts this " #m_type " array to a string with brackets.\n"); \ + p_output.append(INDENT2 "/// </summary>\n"); \ + p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \ + p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \ + p_output.append(INDENT2 "public static string Stringify(this " #m_type "[] instance)\n"); \ + p_output.append(INDENT2 OPEN_BLOCK); \ + p_output.append(INDENT3 "return \"[\" + instance.Join() + \"]\";\n"); \ + p_output.append(INDENT2 CLOSE_BLOCK); + +#define ARRAY_ALL(m_type) \ + ARRAY_IS_EMPTY(m_type) \ + ARRAY_JOIN(m_type) \ + ARRAY_STRINGIFY(m_type) + + ARRAY_ALL(byte); + ARRAY_ALL(int); + ARRAY_ALL(long); + ARRAY_ALL(float); + ARRAY_ALL(double); + ARRAY_ALL(string); + ARRAY_ALL(Color); + ARRAY_ALL(Vector2); + ARRAY_ALL(Vector2i); + ARRAY_ALL(Vector3); + ARRAY_ALL(Vector3i); + +#undef ARRAY_ALL +#undef ARRAY_IS_EMPTY +#undef ARRAY_JOIN +#undef ARRAY_STRINGIFY + + p_output.append(INDENT1 CLOSE_BLOCK); // End of GD class. + p_output.append(CLOSE_BLOCK); // End of namespace. +} + void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { // Constants (in partial GD class) @@ -926,6 +993,19 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { compile_items.push_back(output_file); } + // Generate source file for array extensions + { + StringBuilder extensions_source; + _generate_array_extensions(extensions_source); + String output_file = path::join(base_gen_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_extensions.cs"); + Error save_err = _save_file(output_file, extensions_source); + if (save_err != OK) { + return save_err; + } + + compile_items.push_back(output_file); + } + for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { const TypeInterface &itype = E.get(); @@ -1479,6 +1559,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG, "Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'."); + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(prop_itype->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Property '" + p_itype.name + "." + String(p_iprop.cname) + "' has type '" + prop_itype->name + + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + if (p_iprop.prop_doc && p_iprop.prop_doc->description.size()) { String xml_summary = bbcode_to_xml(fix_doc_description(p_iprop.prop_doc->description), &p_itype); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); @@ -1575,6 +1661,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG, "Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'."); + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(return_type->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Method '" + p_itype.name + "." + p_imethod.name + "' has return type '" + return_type->name + + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + String method_bind_field = "__method_bind_" + itos(p_method_bind_count); String arguments_sig; @@ -1593,6 +1685,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG, "Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'."); + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Argument '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "' has type '" + + arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + if (iarg.default_argument.size()) { CRASH_COND_MSG(!_arg_default_value_is_assignable_to_type(iarg.def_param_value, *arg_type), "Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'."); @@ -1806,7 +1904,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG, - "Argument type is a singleton: '" + iarg.name + "' of signal" + p_itype.name + "." + p_isignal.name + "'."); + "Argument type is a singleton: '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "'."); + + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Argument '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "' has type '" + + arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API."); + } // Add the current arguments to the signature @@ -2932,9 +3036,9 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } break; case Variant::FLOAT: -#ifndef REAL_T_IS_DOUBLE - r_iarg.default_argument += "f"; -#endif + if (r_iarg.type.cname == name_cache.type_float) { + r_iarg.default_argument += "f"; + } break; case Variant::STRING: case Variant::STRING_NAME: @@ -2947,23 +3051,32 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "\"" + r_iarg.default_argument + "\""; } break; - case Variant::TRANSFORM: - if (p_val.operator Transform() == Transform()) { - r_iarg.default_argument.clear(); - } - r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")"; + case Variant::PLANE: { + Plane plane = p_val.operator Plane(); + r_iarg.default_argument = "new Plane(new Vector3(" + plane.normal.operator String() + "), " + rtos(plane.d) + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; - break; - case Variant::PLANE: - case Variant::AABB: + } break; + case Variant::AABB: { + AABB aabb = p_val.operator ::AABB(); + r_iarg.default_argument = "new AABB(new Vector3(" + aabb.position.operator String() + "), new Vector3(" + aabb.position.operator String() + "))"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; + case Variant::RECT2: { + Rect2 rect = p_val.operator Rect2(); + r_iarg.default_argument = "new Rect2(new Vector2(" + rect.position.operator String() + "), new Vector2(" + rect.position.operator String() + "))"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; + case Variant::RECT2I: { + Rect2i rect = p_val.operator Rect2i(); + r_iarg.default_argument = "new Rect2i(new Vector2i(" + rect.position.operator String() + "), new Vector2i(" + rect.position.operator String() + "))"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; case Variant::COLOR: - r_iarg.default_argument = "new Color(1, 1, 1, 1)"; + r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; case Variant::VECTOR2: case Variant::VECTOR2I: - case Variant::RECT2: - case Variant::RECT2I: case Variant::VECTOR3: case Variant::VECTOR3I: r_iarg.default_argument = "new %s" + r_iarg.default_argument; @@ -3001,12 +3114,43 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "new %s {}"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; break; - case Variant::TRANSFORM2D: - case Variant::BASIS: - case Variant::QUAT: - r_iarg.default_argument = Variant::get_type_name(p_val.get_type()) + ".Identity"; + case Variant::TRANSFORM2D: { + Transform2D transform = p_val.operator Transform2D(); + if (transform == Transform2D()) { + r_iarg.default_argument = "Transform2D.Identity"; + } else { + r_iarg.default_argument = "new Transform2D(new Vector2" + transform.elements[0].operator String() + ", new Vector2" + transform.elements[1].operator String() + ", new Vector2" + transform.elements[2].operator String() + ")"; + } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; - break; + } break; + case Variant::TRANSFORM: { + Transform transform = p_val.operator Transform(); + if (transform == Transform()) { + r_iarg.default_argument = "Transform.Identity"; + } else { + Basis basis = transform.basis; + r_iarg.default_argument = "new Transform(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")"; + } + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; + case Variant::BASIS: { + Basis basis = p_val.operator Basis(); + if (basis == Basis()) { + r_iarg.default_argument = "Basis.Identity"; + } else { + r_iarg.default_argument = "new Basis(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ")"; + } + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; + case Variant::QUAT: { + Quat quat = p_val.operator Quat(); + if (quat == Quat()) { + r_iarg.default_argument = "Quat.Identity"; + } else { + r_iarg.default_argument = "new Quat" + quat.operator String(); + } + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; case Variant::CALLABLE: case Variant::SIGNAL: CRASH_NOW_MSG("Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value."); @@ -3546,6 +3690,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) if (!bindings_generator.initialized) { ERR_PRINT("Failed to initialize the bindings generator"); + Main::cleanup(true); ::exit(0); } @@ -3572,6 +3717,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) } // Exit once done + Main::cleanup(true); ::exit(0); } } diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index b18dfb0ec4..876046176b 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -661,6 +661,7 @@ class BindingsGenerator { Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output); Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output); + void _generate_array_extensions(StringBuilder &p_output); void _generate_global_constants(StringBuilder &p_output); Error _generate_glue_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, StringBuilder &p_output); diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp index 8f9a31a5b9..e81cbe4ebd 100644 --- a/modules/mono/editor/script_class_parser.cpp +++ b/modules/mono/editor/script_class_parser.cpp @@ -735,9 +735,9 @@ Error ScriptClassParser::parse_file(const String &p_filepath) { ERR_FAIL_COND_V_MSG(ferr != OK, ferr, ferr == ERR_INVALID_DATA ? - "File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded." + "File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded." " Please ensure that scripts are saved in valid UTF-8 unicode." : - "Failed to read file: '" + p_filepath + "'."); + "Failed to read file: '" + p_filepath + "'."); run_dummy_preprocessor(source, p_filepath); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 90141928ca..0c333d06ef 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -104,7 +104,7 @@ namespace Godot /// <summary> /// The HSV hue of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHSV"/>.</value> public float h { get @@ -145,14 +145,14 @@ namespace Godot } set { - this = FromHsv(value, s, v, a); + this = FromHSV(value, s, v, a); } } /// <summary> /// The HSV saturation of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHSV"/>.</value> public float s { get @@ -166,14 +166,14 @@ namespace Godot } set { - this = FromHsv(h, value, v, a); + this = FromHSV(h, value, v, a); } } /// <summary> /// The HSV value (brightness) of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHSV"/>.</value> public float v { get @@ -182,7 +182,7 @@ namespace Godot } set { - this = FromHsv(h, s, value, a); + this = FromHSV(h, s, value, a); } } @@ -455,7 +455,7 @@ namespace Godot /// </summary> /// <param name="includeAlpha">Whether or not to include alpha. If false, the color is RGB instead of RGBA.</param> /// <returns>A string for the HTML hexadecimal representation of this color.</returns> - public string ToHtml(bool includeAlpha = true) + public string ToHTML(bool includeAlpha = true) { var txt = string.Empty; @@ -532,18 +532,50 @@ namespace Godot } /// <summary> + /// Constructs a color either from an HTML color code or from a + /// standardized color name. Supported + /// color names are the same as the <see cref="Colors"/> constants. + /// </summary> + /// <param name="code">The HTML color code or color name to construct from.</param> + public Color(string code) + { + if (HtmlIsValid(code)) + { + this = FromHTML(code); + } + else + { + this = Named(code); + } + } + + /// <summary> + /// Constructs a color either from an HTML color code or from a + /// standardized color name, with `alpha` on the range of 0 to 1. Supported + /// color names are the same as the <see cref="Colors"/> constants. + /// </summary> + /// <param name="code">The HTML color code or color name to construct from.</param> + /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param> + public Color(string code, float alpha) + { + this = new Color(code); + a = alpha; + } + + /// <summary> /// Constructs a color from the HTML hexadecimal color string in RGBA format. /// </summary> /// <param name="rgba">A string for the HTML hexadecimal representation of this color.</param> - public Color(string rgba) + private static Color FromHTML(string rgba) { + Color c; if (rgba.Length == 0) { - r = 0f; - g = 0f; - b = 0f; - a = 1.0f; - return; + c.r = 0f; + c.g = 0f; + c.b = 0f; + c.a = 1.0f; + return c; } if (rgba[0] == '#') @@ -577,47 +609,48 @@ namespace Godot throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba); } - a = 1.0f; + c.a = 1.0f; if (isShorthand) { - r = ParseCol4(rgba, 0) / 15f; - g = ParseCol4(rgba, 1) / 15f; - b = ParseCol4(rgba, 2) / 15f; + c.r = ParseCol4(rgba, 0) / 15f; + c.g = ParseCol4(rgba, 1) / 15f; + c.b = ParseCol4(rgba, 2) / 15f; if (alpha) { - a = ParseCol4(rgba, 3) / 15f; + c.a = ParseCol4(rgba, 3) / 15f; } } else { - r = ParseCol8(rgba, 0) / 255f; - g = ParseCol8(rgba, 2) / 255f; - b = ParseCol8(rgba, 4) / 255f; + c.r = ParseCol8(rgba, 0) / 255f; + c.g = ParseCol8(rgba, 2) / 255f; + c.b = ParseCol8(rgba, 4) / 255f; if (alpha) { - a = ParseCol8(rgba, 6) / 255f; + c.a = ParseCol8(rgba, 6) / 255f; } } - if (r < 0) + if (c.r < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba); } - if (g < 0) + if (c.g < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba); } - if (b < 0) + if (c.b < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba); } - if (a < 0) + if (c.a < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba); } + return c; } /// <summary> @@ -640,9 +673,8 @@ namespace Godot /// the constants defined in <see cref="Colors"/>. /// </summary> /// <param name="name">The name of the color.</param> - /// <param name="alpha">The alpha (transparency) component represented on the range of 0 to 1. Default: 1.</param> /// <returns>The constructed color.</returns> - public static Color ColorN(string name, float alpha = 1f) + private static Color Named(string name) { name = name.Replace(" ", String.Empty); name = name.Replace("-", String.Empty); @@ -656,9 +688,7 @@ namespace Godot throw new ArgumentOutOfRangeException($"Invalid Color Name: {name}"); } - Color color = Colors.namedColors[name]; - color.a = alpha; - return color; + return Colors.namedColors[name]; } /// <summary> @@ -671,11 +701,11 @@ namespace Godot /// <param name="value">The HSV value (brightness), typically on the range of 0 to 1.</param> /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param> /// <returns>The constructed color.</returns> - public static Color FromHsv(float hue, float saturation, float value, float alpha = 1.0f) + public static Color FromHSV(float hue, float saturation, float value, float alpha = 1.0f) { if (saturation == 0) { - // acp_hromatic (grey) + // Achromatic (grey) return new Color(value, value, value, alpha); } @@ -715,7 +745,7 @@ namespace Godot /// <param name="hue">Output parameter for the HSV hue.</param> /// <param name="saturation">Output parameter for the HSV saturation.</param> /// <param name="value">Output parameter for the HSV value.</param> - public void ToHsv(out float hue, out float saturation, out float value) + public void ToHSV(out float hue, out float saturation, out float value) { float max = (float)Mathf.Max(r, Mathf.Max(g, b)); float min = (float)Mathf.Min(r, Mathf.Min(g, b)); @@ -803,7 +833,8 @@ namespace Godot } // Check if each hex digit is valid. - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) + { if (ParseCol4(color, i) == -1) { return false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs new file mode 100644 index 0000000000..763f470504 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs @@ -0,0 +1,27 @@ +namespace Godot +{ + public partial class PackedScene + { + /// <summary> + /// Instantiates the scene's node hierarchy, erroring on failure. + /// Triggers child scene instantiation(s). Triggers a + /// `Node.NotificationInstanced` notification on the root node. + /// </summary> + /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam> + public T Instance<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class + { + return (T)(object)Instance(editState); + } + + /// <summary> + /// Instantiates the scene's node hierarchy, returning null on failure. + /// Triggers child scene instantiation(s). Triggers a + /// `Node.NotificationInstanced` notification on the root node. + /// </summary> + /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam> + public T InstanceOrNull<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class + { + return Instance(editState) as T; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs index 5f64c09a89..74fa05d1fd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs @@ -2,7 +2,7 @@ namespace Godot { public static partial class ResourceLoader { - public static T Load<T>(string path, string typeHint = null, bool noCache = false) where T : class + public static T Load<T>(string path, string typeHint = null, CacheMode noCache = CacheMode.Reuse) where T : class { return (T)(object)Load(path, typeHint, noCache); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index 0700f197ff..98efa89ef0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -97,6 +97,36 @@ namespace Godot return b; } + /// <summary> + /// Converts a string containing a binary number into an integer. + /// Binary strings can either be prefixed with `0b` or not, + /// and they can also start with a `-` before the optional prefix. + /// </summary> + /// <param name="instance">The string to convert.</param> + /// <returns>The converted string.</returns> + public static int BinToInt(this string instance) + { + if (instance.Length == 0) + { + return 0; + } + + int sign = 1; + + if (instance[0] == '-') + { + sign = -1; + instance = instance.Substring(1); + } + + if (instance.StartsWith("0b")) + { + instance = instance.Substring(2); + } + + return sign * Convert.ToInt32(instance, 2);; + } + // <summary> // Return the amount of substrings in string. // </summary> @@ -432,24 +462,24 @@ namespace Godot } // <summary> - // Hash the string and return a 32 bits integer. + // Hash the string and return a 32 bits unsigned integer. // </summary> - public static int Hash(this string instance) + public static uint Hash(this string instance) { - int index = 0; - int hashv = 5381; - int c; + uint hash = 5381; - while ((c = instance[index++]) != 0) - hashv = (hashv << 5) + hashv + c; // hash * 33 + c + foreach(uint c in instance) + { + hash = (hash << 5) + hash + c; // hash * 33 + c + } - return hashv; + return hash; } /// <summary> /// Returns a hexadecimal representation of this byte as a string. /// </summary> - /// <param name="bytes">The byte to encode.</param> + /// <param name="b">The byte to encode.</param> /// <returns>The hexadecimal representation of this byte.</returns> internal static string HexEncode(this byte b) { @@ -493,11 +523,20 @@ namespace Godot return ret; } - // <summary> - // Convert a string containing an hexadecimal number into an int. - // </summary> + /// <summary> + /// Converts a string containing a hexadecimal number into an integer. + /// Hexadecimal strings can either be prefixed with `0x` or not, + /// and they can also start with a `-` before the optional prefix. + /// </summary> + /// <param name="instance">The string to convert.</param> + /// <returns>The converted string.</returns> public static int HexToInt(this string instance) { + if (instance.Length == 0) + { + return 0; + } + int sign = 1; if (instance[0] == '-') @@ -506,10 +545,12 @@ namespace Godot instance = instance.Substring(1); } - if (!instance.StartsWith("0x")) - return 0; + if (instance.StartsWith("0x")) + { + instance = instance.Substring(2); + } - return sign * int.Parse(instance.Substring(2), NumberStyles.HexNumber); + return sign * int.Parse(instance, NumberStyles.HexNumber); } // <summary> @@ -892,22 +933,6 @@ namespace Godot } // <summary> - // Decode a percent-encoded string. See [method percent_encode]. - // </summary> - public static string PercentDecode(this string instance) - { - return Uri.UnescapeDataString(instance); - } - - // <summary> - // Percent-encode a string. This is meant to encode parameters in a URL when sending a HTTP GET request and bodies of form-urlencoded POST request. - // </summary> - public static string PercentEncode(this string instance) - { - return Uri.EscapeDataString(instance); - } - - // <summary> // If the string is a path, this concatenates [code]file[/code] at the end of the string as a subpath. E.g. [code]"this/is".plus_file("path") == "this/is/path"[/code]. // </summary> public static string PlusFile(this string instance, string file) @@ -1169,6 +1194,33 @@ namespace Godot return Encoding.UTF8.GetBytes(instance); } + /// <summary> + /// Decodes a string in URL encoded format. This is meant to + /// decode parameters in a URL when receiving an HTTP request. + /// This mostly wraps around `System.Uri.UnescapeDataString()`, + /// but also handles `+`. + /// See <see cref="URIEncode"/> for encoding. + /// </summary> + /// <param name="instance">The string to decode.</param> + /// <returns>The unescaped string.</returns> + public static string URIDecode(this string instance) + { + return Uri.UnescapeDataString(instance.Replace("+", "%20")); + } + + /// <summary> + /// Encodes a string to URL friendly format. This is meant to + /// encode parameters in a URL when sending an HTTP request. + /// This wraps around `System.Uri.EscapeDataString()`. + /// See <see cref="URIDecode"/> for decoding. + /// </summary> + /// <param name="instance">The string to encode.</param> + /// <returns>The escaped string.</returns> + public static string URIEncode(this string instance) + { + return Uri.EscapeDataString(instance); + } + // <summary> // Return a copy of the string with special characters escaped using the XML standard. // </summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 42dbdf25c3..3b895bbbf6 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -111,10 +111,10 @@ namespace Godot } /// <summary> - /// Returns the minimum angle to the given vector, in radians. + /// Returns the unsigned minimum angle to the given vector, in radians. /// </summary> /// <param name="to">The other vector to compare this vector to.</param> - /// <returns>The angle between the two vectors, in radians.</returns> + /// <returns>The unsigned angle between the two vectors, in radians.</returns> public real_t AngleTo(Vector3 to) { return Mathf.Atan2(Cross(to).Length(), Dot(to)); @@ -469,6 +469,23 @@ namespace Godot } /// <summary> + /// Returns the signed angle to the given vector, in radians. + /// The sign of the angle is positive in a counter-clockwise + /// direction and negative in a clockwise direction when viewed + /// from the side specified by the `axis`. + /// </summary> + /// <param name="to">The other vector to compare this vector to.</param> + /// <param name="axis">The reference axis to use for the angle sign.</param> + /// <returns>The signed angle between the two vectors, in radians.</returns> + public real_t SignedAngleTo(Vector3 to, Vector3 axis) + { + Vector3 crossTo = Cross(to); + real_t unsignedAngle = Mathf.Atan2(crossTo.Length(), Dot(to)); + real_t sign = crossTo.Dot(axis); + return (sign < 0) ? -unsignedAngle : unsignedAngle; + } + + /// <summary> /// Returns the result of the spherical linear interpolation between /// this vector and `to` by amount `weight`. /// diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 86a16c17f1..7c1a23d510 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -30,6 +30,7 @@ <Compile Include="Core\DynamicObject.cs" /> <Compile Include="Core\Extensions\NodeExtensions.cs" /> <Compile Include="Core\Extensions\ObjectExtensions.cs" /> + <Compile Include="Core\Extensions\PackedSceneExtensions.cs" /> <Compile Include="Core\Extensions\ResourceLoaderExtensions.cs" /> <Compile Include="Core\Extensions\SceneTreeExtensions.cs" /> <Compile Include="Core\GD.cs" /> diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 875d20ebe4..43a39a4966 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -593,8 +593,8 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo ApiAssemblyInfo::Version api_assembly_version; const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE ? - BINDINGS_CLASS_NATIVECALLS : - BINDINGS_CLASS_NATIVECALLS_EDITOR; + BINDINGS_CLASS_NATIVECALLS : + BINDINGS_CLASS_NATIVECALLS_EDITOR; GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name); @@ -757,11 +757,11 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const #define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ ( \ (m_out_of_sync ? \ - String("The assembly is invalidated ") : \ - String("The assembly was not found ")) + \ + String("The assembly is invalidated ") : \ + String("The assembly was not found ")) + \ (m_prebuilt_exists ? \ - String("and the prebuilt assemblies are missing.") : \ - String("and we failed to copy the prebuilt assemblies."))) + String("and the prebuilt assemblies are missing.") : \ + String("and we failed to copy the prebuilt assemblies."))) String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config); @@ -820,8 +820,8 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c // If running the project manager, load it from the prebuilt API directory String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : + GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); @@ -853,8 +853,8 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, // If running the project manager, load it from the prebuilt API directory String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : + GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index c6920814b9..1fe06bfbee 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -379,8 +379,8 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) { return match->value(); } - StringName namespace_name = mono_class_get_namespace(p_mono_class); - StringName class_name = mono_class_get_name(p_mono_class); + StringName namespace_name = String::utf8(mono_class_get_namespace(p_mono_class)); + StringName class_name = String::utf8(mono_class_get_name(p_mono_class)); GDMonoClass *wrapped_class = memnew(GDMonoClass(namespace_name, class_name, p_mono_class, this)); diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 0ed7fcf375..f9fddd931b 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -177,7 +177,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base void *iter = nullptr; MonoMethod *raw_method = nullptr; while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) { - StringName name = mono_method_get_name(raw_method); + StringName name = String::utf8(mono_method_get_name(raw_method)); // get_method implicitly fetches methods and adds them to this->methods GDMonoMethod *method = get_method(raw_method, name); @@ -319,7 +319,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) { MonoMethodSignature *sig = mono_method_signature(p_raw_method); int params_count = mono_signature_get_param_count(sig); - StringName method_name = mono_method_get_name(p_raw_method); + StringName method_name = String::utf8(mono_method_get_name(p_raw_method)); return get_method(p_raw_method, method_name, params_count); } @@ -392,7 +392,7 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() { void *iter = nullptr; MonoClassField *raw_field = nullptr; while ((raw_field = mono_class_get_fields(mono_class, &iter)) != nullptr) { - StringName name = mono_field_get_name(raw_field); + StringName name = String::utf8(mono_field_get_name(raw_field)); Map<StringName, GDMonoField *>::Element *match = fields.find(name); @@ -441,7 +441,7 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() { void *iter = nullptr; MonoProperty *raw_property = nullptr; while ((raw_property = mono_class_get_properties(mono_class, &iter)) != nullptr) { - StringName name = mono_property_get_name(raw_property); + StringName name = String::utf8(mono_property_get_name(raw_property)); Map<StringName, GDMonoProperty *>::Element *match = properties.find(name); @@ -468,14 +468,14 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { MonoClass *raw_class = nullptr; while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) { if (mono_class_is_delegate(raw_class)) { - StringName name = mono_class_get_name(raw_class); + StringName name = String::utf8(mono_class_get_name(raw_class)); Map<StringName, GDMonoClass *>::Element *match = delegates.find(name); if (match) { delegates_list.push_back(match->get()); } else { - GDMonoClass *delegate = memnew(GDMonoClass(mono_class_get_namespace(raw_class), mono_class_get_name(raw_class), raw_class, assembly)); + GDMonoClass *delegate = memnew(GDMonoClass(String::utf8(mono_class_get_namespace(raw_class)), String::utf8(mono_class_get_name(raw_class)), raw_class, assembly)); delegates.insert(name, delegate); delegates_list.push_back(delegate); } @@ -492,7 +492,7 @@ const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() { void *iter = nullptr; MonoMethod *raw_method = nullptr; while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) { - method_list.push_back(memnew(GDMonoMethod(mono_method_get_name(raw_method), raw_method))); + method_list.push_back(memnew(GDMonoMethod(String::utf8(mono_method_get_name(raw_method)), raw_method))); } method_list_fetched = true; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index d91bb8210f..1d4d52dfce 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -509,7 +509,7 @@ IMonoClassMember::Visibility GDMonoField::get_visibility() { GDMonoField::GDMonoField(MonoClassField *p_mono_field, GDMonoClass *p_owner) { owner = p_owner; mono_field = p_mono_field; - name = mono_field_get_name(mono_field); + name = String::utf8(mono_field_get_name(mono_field)); MonoType *field_type = mono_field_get_type(mono_field); type.type_encoding = mono_type_get_type(field_type); MonoClass *field_type_class = mono_class_from_mono_type(field_type); diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index e1d283242c..dafd36c36b 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -189,8 +189,6 @@ void GDMonoLog::initialize() { GDMonoLog::GDMonoLog() { singleton = this; - - log_level_id = -1; } GDMonoLog::~GDMonoLog() { diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h index 9a95e3cb0a..f7a53156ab 100644 --- a/modules/mono/mono_gd/gd_mono_log.h +++ b/modules/mono/mono_gd/gd_mono_log.h @@ -46,9 +46,9 @@ class GDMonoLog { #ifdef GD_MONO_LOG_ENABLED - int log_level_id; + int log_level_id = -1; - FileAccess *log_file; + FileAccess *log_file = nullptr; String log_file_path; bool _try_create_logs_dir(const String &p_logs_dir); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 57fbf5b7e1..359f6bba4d 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -1204,7 +1204,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { MonoReflectionType *elem_reftype = nullptr; GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); - return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype); + return system_generic_list_to_Array_variant(p_obj, p_type.type_class, elem_reftype); } } break; } @@ -1333,15 +1333,22 @@ MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_cl return mono_object; } -Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) { +Variant system_generic_list_to_Array_variant(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) { GDMonoMethod *to_array = p_class->get_method("ToArray", 0); CRASH_COND(to_array == nullptr); MonoException *exc = nullptr; - MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc); + MonoObject *array = to_array->invoke_raw(p_obj, nullptr, &exc); UNHANDLED_EXCEPTION(exc); - return mono_array_to_Array(mono_array); + ERR_FAIL_NULL_V(array, Variant()); + + ManagedType type = ManagedType::from_class(mono_object_get_class(array)); + + bool result_is_array = type.type_encoding != MONO_TYPE_SZARRAY && type.type_encoding != MONO_TYPE_ARRAY; + ERR_FAIL_COND_V(result_is_array, Variant()); + + return mono_object_to_variant(array, type); } MonoArray *Array_to_mono_array(const Array &p_array) { @@ -1677,8 +1684,8 @@ Callable managed_to_callable(const M_Callable &p_managed_callable) { return Callable(managed_callable); } else { Object *target = p_managed_callable.target ? - unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) : - nullptr; + unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) : + nullptr; StringName *method_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)); StringName method = method_ptr ? *method_ptr : StringName(); return Callable(target, method); @@ -1723,8 +1730,8 @@ M_Callable callable_to_managed(const Callable &p_callable) { Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) { Object *owner = p_managed_signal.owner ? - unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) : - nullptr; + unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) : + nullptr; StringName *name_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)); StringName name = name_ptr ? *name_ptr : StringName(); return Signal(owner, name); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 7d0036a1d8..668809ae5d 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -140,7 +140,7 @@ MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoCl Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); -Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); +Variant system_generic_list_to_Array_variant(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); // Array diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index dc3d225082..5391b7775e 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -40,7 +40,7 @@ GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_owner) { owner = p_owner; mono_property = p_mono_property; - name = mono_property_get_name(mono_property); + name = String::utf8(mono_property_get_name(mono_property)); MonoMethod *prop_method = mono_property_get_get_method(mono_property); diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp index 59e1385e7e..cba29d63cd 100644 --- a/modules/mono/mono_gd/support/android_support.cpp +++ b/modules/mono/mono_gd/support/android_support.cpp @@ -109,7 +109,7 @@ bool jni_exception_check(JNIEnv *p_env) { String app_native_lib_dir_cache; String determine_app_native_lib_dir() { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); ScopedLocalRef<jclass> activityThreadClass(env, env->FindClass("android/app/ActivityThread")); jmethodID currentActivityThread = env->GetStaticMethodID(activityThreadClass, "currentActivityThread", "()Landroid/app/ActivityThread;"); @@ -253,7 +253,7 @@ int32_t get_build_version_sdk_int() { // android.os.Build.VERSION.SDK_INT if (build_version_sdk_int == 0) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jclass versionClass = env->FindClass("android/os/Build$VERSION"); ERR_FAIL_NULL_V(versionClass, 0); @@ -281,7 +281,7 @@ MonoBoolean _gd_mono_init_cert_store() { // return false; // } - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore")); @@ -322,7 +322,7 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) { return nullptr; } - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); ScopedLocalRef<jstring> js_alias(env, env->NewStringUTF(alias_utf8)); mono_free(alias_utf8); @@ -380,7 +380,7 @@ void cleanup() { if (godot_dl_handle) gd_mono_android_dlclose(godot_dl_handle, nullptr); - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); if (certStore) { env->DeleteGlobalRef(certStore); @@ -437,7 +437,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_up_state(const char *r_is_up = 0; - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface"); ERR_FAIL_NULL_V(networkInterfaceClass, 0); @@ -469,7 +469,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_supports_multicast( *r_supports_multicast = 0; - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface"); ERR_FAIL_NULL_V(networkInterfaceClass, 0); @@ -507,7 +507,7 @@ static void interop_get_active_network_dns_servers(char **r_dns_servers, int *dn CRASH_COND(get_build_version_sdk_int() < 23); #endif - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); GodotJavaWrapper *godot_java = ((OS_Android *)OS::get_singleton())->get_godot_java(); jobject activity = godot_java->get_activity(); @@ -648,7 +648,7 @@ GD_PINVOKE_EXPORT const char *_monodroid_timezone_get_default_id() { // // TimeZone.getDefault().getID() - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); ScopedLocalRef<jclass> timeZoneClass(env, env->FindClass("java/util/TimeZone")); ERR_FAIL_NULL_V(timeZoneClass, nullptr); diff --git a/modules/mono/mono_gd/support/android_support.h b/modules/mono/mono_gd/support/android_support.h index 0c5dd2764c..0c5dd2764c 100755..100644 --- a/modules/mono/mono_gd/support/android_support.h +++ b/modules/mono/mono_gd/support/android_support.h diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h index 28a8806d0e..28a8806d0e 100755..100644 --- a/modules/mono/mono_gd/support/ios_support.h +++ b/modules/mono/mono_gd/support/ios_support.h diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp index 27c2b2c5c1..bb1265e959 100644 --- a/modules/mono/utils/mono_reg_utils.cpp +++ b/modules/mono/utils/mono_reg_utils.cpp @@ -173,7 +173,7 @@ String find_msbuild_tools_path() { String output; int exit_code; - OS::get_singleton()->execute(vswhere_path, vswhere_args, true, nullptr, &output, &exit_code); + OS::get_singleton()->execute(vswhere_path, vswhere_args, &output, &exit_code); if (exit_code == 0) { Vector<String> lines = output.split("\n"); diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml index 7df261d2ba..86e7f9cc08 100644 --- a/modules/opensimplex/doc_classes/NoiseTexture.xml +++ b/modules/opensimplex/doc_classes/NoiseTexture.xml @@ -32,6 +32,7 @@ </member> <member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false"> Whether the texture can be tiled without visible seams or not. Seamless textures take longer to generate. + [b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise. </member> <member name="width" type="int" setter="set_width" getter="get_width" default="512"> Width of the generated texture. diff --git a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml index dcda5c2324..ad82f87213 100644 --- a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml +++ b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml @@ -109,6 +109,7 @@ </argument> <description> Generate a tileable noise image in [constant Image.FORMAT_L8] format, based on the current noise parameters. Generated seamless images are always square ([code]size[/code] × [code]size[/code]). + [b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise. </description> </method> </methods> diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index 1d75e46747..f5d401b058 100644 --- a/modules/opensimplex/noise_texture.cpp +++ b/modules/opensimplex/noise_texture.cpp @@ -33,16 +33,6 @@ #include "core/core_string_names.h" NoiseTexture::NoiseTexture() { - update_queued = false; - noise_thread = nullptr; - regen_queued = false; - first_time = true; - - size = Vector2i(512, 512); - seamless = false; - as_normal_map = false; - bump_strength = 8.0; - noise = Ref<OpenSimplexNoise>(); _queue_update(); @@ -52,10 +42,7 @@ NoiseTexture::~NoiseTexture() { if (texture.is_valid()) { RS::get_singleton()->free(texture); } - if (noise_thread) { - Thread::wait_to_finish(noise_thread); - memdelete(noise_thread); - } + noise_thread.wait_to_finish(); } void NoiseTexture::_bind_methods() { @@ -109,11 +96,9 @@ void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) { void NoiseTexture::_thread_done(const Ref<Image> &p_image) { _set_texture_data(p_image); - Thread::wait_to_finish(noise_thread); - memdelete(noise_thread); - noise_thread = nullptr; + noise_thread.wait_to_finish(); if (regen_queued) { - noise_thread = Thread::create(_thread_function, this); + noise_thread.start(_thread_function, this); regen_queued = false; } } @@ -165,8 +150,8 @@ void NoiseTexture::_update_texture() { use_thread = false; #endif if (use_thread) { - if (!noise_thread) { - noise_thread = Thread::create(_thread_function, this); + if (!noise_thread.is_started()) { + noise_thread.start(_thread_function, this); regen_queued = false; } else { regen_queued = true; @@ -231,7 +216,7 @@ void NoiseTexture::set_as_normal_map(bool p_as_normal_map) { } as_normal_map = p_as_normal_map; _queue_update(); - _change_notify(); + notify_property_list_changed(); } bool NoiseTexture::is_normal_map() { diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 9f6e2cbf43..e89479d962 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -45,20 +45,20 @@ class NoiseTexture : public Texture2D { private: Ref<Image> data; - Thread *noise_thread; + Thread noise_thread; - bool first_time; - bool update_queued; - bool regen_queued; + bool first_time = true; + bool update_queued = false; + bool regen_queued = false; mutable RID texture; - uint32_t flags; + uint32_t flags = 0; Ref<OpenSimplexNoise> noise; - Vector2i size; - bool seamless; - bool as_normal_map; - float bump_strength; + Vector2i size = Vector2i(512, 512); + bool seamless = false; + bool as_normal_map = false; + float bump_strength = 8.0; void _thread_done(const Ref<Image> &p_image); static void _thread_function(void *p_ud); diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp index e4e2e0613a..3773946112 100644 --- a/modules/opensimplex/open_simplex_noise.cpp +++ b/modules/opensimplex/open_simplex_noise.cpp @@ -33,12 +33,6 @@ #include "core/core_string_names.h" OpenSimplexNoise::OpenSimplexNoise() { - seed = 0; - persistence = 0.5; - octaves = 3; - period = 64; - lacunarity = 2.0; - _init_seeds(); } @@ -131,10 +125,10 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const { float ii = (float)i / (float)p_size; float jj = (float)j / (float)p_size; - ii *= 2.0 * Math_PI; - jj *= 2.0 * Math_PI; + ii *= Math_TAU; + jj *= Math_TAU; - float radius = p_size / (2.0 * Math_PI); + float radius = p_size / Math_TAU; float x = radius * Math::sin(jj); float y = radius * Math::cos(jj); diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h index f18dd4d798..847c157409 100644 --- a/modules/opensimplex/open_simplex_noise.h +++ b/modules/opensimplex/open_simplex_noise.h @@ -48,11 +48,11 @@ class OpenSimplexNoise : public Resource { osn_context contexts[MAX_OCTAVES]; - int seed; - float persistence; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness. - int octaves; // Number of noise layers - float period; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain. - float lacunarity; // Controls period change across octaves. 2 is usually a good value to address all detail levels. + int seed = 0; + float persistence = 0.5; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness. + int octaves = 3; // Number of noise layers + float period = 64.0; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain. + float lacunarity = 2.0; // Controls period change across octaves. 2 is usually a good value to address all detail levels. public: OpenSimplexNoise(); diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 70a3c8b5a9..83f032ca2b 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -46,7 +46,7 @@ enum PVRFLags { PVR_VFLIP = 0x00010000 }; -RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -207,7 +207,7 @@ ResourceFormatPVR::ResourceFormatPVR() { struct PVRTCBlock { //blocks are 64 bits - uint32_t data[2]; + uint32_t data[2] = {}; }; _FORCE_INLINE_ bool is_po2(uint32_t p_input) { diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h index da425c3237..26071ce30f 100644 --- a/modules/pvr/texture_loader_pvr.h +++ b/modules/pvr/texture_loader_pvr.h @@ -36,7 +36,7 @@ class ResourceFormatPVR : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml index 312275842a..b21f5d1e7a 100644 --- a/modules/regex/doc_classes/RegEx.xml +++ b/modules/regex/doc_classes/RegEx.xml @@ -39,8 +39,8 @@ var regex = RegEx.new() regex.compile("\\S+") # Negated whitespace character class. var results = [] - for match in regex.search_all("One Two \n\tThree"): - results.push_back(match.get_string()) + for result in regex.search_all("One Two \n\tThree"): + results.push_back(result.get_string()) # The `results` array now contains "One", "Two", "Three". [/codeblock] [b]Note:[/b] Godot's regex implementation is based on the [url=https://www.pcre.org/]PCRE2[/url] library. You can view the full pattern reference [url=https://www.pcre.org/current/doc/html/pcre2pattern.html]here[/url]. diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index fe8136ef35..6bae12e7e6 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -365,12 +365,10 @@ Array RegEx::get_names() const { RegEx::RegEx() { general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr); - code = nullptr; } RegEx::RegEx(const String &p_pattern) { general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr); - code = nullptr; compile(p_pattern); } diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 46505855d7..f5773042fb 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -42,8 +42,8 @@ class RegExMatch : public Reference { GDCLASS(RegExMatch, Reference); struct Range { - int start; - int end; + int start = 0; + int end = 0; }; String subject; @@ -72,7 +72,7 @@ class RegEx : public Reference { GDCLASS(RegEx, Reference); void *general_ctx; - void *code; + void *code = nullptr; String pattern; void _pattern_info(uint32_t what, void *where) const; diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index 4b2be47e74..6732078efc 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -47,7 +47,7 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra int mixed = stb_vorbis_get_samples_float_interleaved(ogg_stream, 2, buffer, todo * 2); if (vorbis_stream->channels == 1 && mixed > 0) { //mix mono to stereo - for (int i = start_buffer; i < mixed; i++) { + for (int i = start_buffer; i < start_buffer + mixed; i++) { p_buffer[i].r = p_buffer[i].l; } } @@ -263,16 +263,7 @@ void AudioStreamOGGVorbis::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } -AudioStreamOGGVorbis::AudioStreamOGGVorbis() { - data = nullptr; - data_len = 0; - length = 0; - sample_rate = 1; - channels = 1; - loop_offset = 0; - decode_mem_size = 0; - loop = false; -} +AudioStreamOGGVorbis::AudioStreamOGGVorbis() {} AudioStreamOGGVorbis::~AudioStreamOGGVorbis() { clear_data(); diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h index efc8fc6c27..2bd70a2722 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h @@ -41,11 +41,11 @@ class AudioStreamOGGVorbis; class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled { GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlaybackResampled); - stb_vorbis *ogg_stream; + stb_vorbis *ogg_stream = nullptr; stb_vorbis_alloc ogg_alloc; - uint32_t frames_mixed; - bool active; - int loops; + uint32_t frames_mixed = 0; + bool active = false; + int loops = 0; friend class AudioStreamOGGVorbis; @@ -76,15 +76,15 @@ class AudioStreamOGGVorbis : public AudioStream { friend class AudioStreamPlaybackOGGVorbis; - void *data; - uint32_t data_len; + void *data = nullptr; + uint32_t data_len = 0; - int decode_mem_size; - float sample_rate; - int channels; - float length; - bool loop; - float loop_offset; + int decode_mem_size = 0; + float sample_rate = 1.0; + int channels = 1; + float length = 0.0; + bool loop = false; + float loop_offset = 0.0; void clear_data(); protected: diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 3589c8546d..b4067d41c2 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -38,6 +38,7 @@ def make_icu_data(target, source, env): # Thirdparty source files thirdparty_obj = [] +freetype_enabled = env.module_check_dependencies("text_server_adv", ["freetype"]) if env["builtin_harfbuzz"]: env_harfbuzz = env_modules.Clone() @@ -57,11 +58,9 @@ if env["builtin_harfbuzz"]: "src/hb-face.cc", "src/hb-fallback-shape.cc", "src/hb-font.cc", - "src/hb-ft.cc", #'src/hb-gdi.cc', #'src/hb-glib.cc', #'src/hb-gobject-structs.cc', - "src/hb-graphite2.cc", "src/hb-icu.cc", "src/hb-map.cc", "src/hb-number.cc", @@ -109,17 +108,29 @@ if env["builtin_harfbuzz"]: "src/hb-unicode.cc", #'src/hb-uniscribe.cc' ] + + if freetype_enabled: + thirdparty_sources += [ + "src/hb-ft.cc", + "src/hb-graphite2.cc", + ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_harfbuzz.Append( CPPPATH=[ "#thirdparty/harfbuzz/src", - "#thirdparty/freetype/include", - "#thirdparty/graphite/include", "#thirdparty/icu4c/common/", ] ) + if freetype_enabled: + env_harfbuzz.Append( + CPPPATH=[ + "#thirdparty/freetype/include", + "#thirdparty/graphite/include", + ] + ) + if env["platform"] == "android" or env["platform"] == "linuxbsd" or env["platform"] == "server": env_harfbuzz.Append(CCFLAGS=["-DHAVE_PTHREAD"]) @@ -133,12 +144,18 @@ if env["builtin_harfbuzz"]: CCFLAGS=[ "-DHAVE_ICU_BUILTIN", "-DHAVE_ICU", - "-DHAVE_FREETYPE", - "-DHAVE_GRAPHITE2", - "-DGRAPHITE2_STATIC", ] ) + if freetype_enabled: + env_harfbuzz.Append( + CCFLAGS=[ + "-DHAVE_FREETYPE", + "-DHAVE_GRAPHITE2", + "-DGRAPHITE2_STATIC", + ] + ) + lib = env_harfbuzz.add_library("harfbuzz_builtin", thirdparty_sources) thirdparty_obj += lib @@ -156,7 +173,7 @@ if env["builtin_harfbuzz"]: env.Append(LIBS=[lib]) -if env["builtin_graphite"]: +if env["builtin_graphite"] and freetype_enabled: env_graphite = env_modules.Clone() env_graphite.disable_warnings() @@ -488,12 +505,18 @@ if env_text_server_adv["tools"]: env_text_server_adv.Append( CPPPATH=[ "#thirdparty/harfbuzz/src", - "#thirdparty/freetype/include", - "#thirdparty/graphite/include", "#thirdparty/icu4c/common/", ] ) +if freetype_enabled: + env_text_server_adv.Append( + CPPPATH=[ + "#thirdparty/freetype/include", + "#thirdparty/graphite/include", + ] + ) + env_text_server_adv.add_source_files(module_obj, "*.cpp") env.modules_sources += module_obj diff --git a/modules/text_server_adv/bitmap_font_adv.cpp b/modules/text_server_adv/bitmap_font_adv.cpp index 01fa94aa7c..e33556b232 100644 --- a/modules/text_server_adv/bitmap_font_adv.cpp +++ b/modules/text_server_adv/bitmap_font_adv.cpp @@ -36,7 +36,7 @@ struct hb_bmp_font_t { BitmapFontDataAdvanced *face = nullptr; - float font_size = 0; + float font_size = 0.0; bool unref = false; /* Whether to destroy bm_face when done. */ }; @@ -340,7 +340,7 @@ Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_bas char_map[idx] = c; } else if (type == "kerning") { KerningPairKey kpk; - float k = 0; + float k = 0.0; if (keys.has("first")) { kpk.A = keys["first"].to_int(); } @@ -367,61 +367,63 @@ Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_bas return OK; } -Error BitmapFontDataAdvanced::load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) { - _THREAD_SAFE_METHOD_ - ERR_FAIL_COND_V(p_data == nullptr, ERR_CANT_CREATE); - ERR_FAIL_COND_V(p_size != sizeof(TextServer::BitmapFontData), ERR_CANT_CREATE); +Error BitmapFontDataAdvanced::bitmap_new(float p_height, float p_ascent, int p_base_size) { + height = p_height; + ascent = p_ascent; - const TextServer::BitmapFontData *data = (const TextServer::BitmapFontData *)p_data; + base_size = p_base_size; + if (base_size == 0) { + base_size = height; + } - if (RenderingServer::get_singleton() != nullptr) { - Ref<Image> image = memnew(Image(data->img)); - Ref<ImageTexture> tex = memnew(ImageTexture); - tex->create_from_image(image); + char_map.clear(); + textures.clear(); + kerning_map.clear(); - textures.push_back(tex); + for (Map<float, hb_font_t *>::Element *E = cache.front(); E; E = E->next()) { + hb_font_destroy(E->get()); } + cache.clear(); - for (int i = 0; i < data->charcount; i++) { - const int *c = &data->char_rects[i * 8]; + valid = true; - Character chr; - chr.rect.position.x = c[1]; - chr.rect.position.y = c[2]; - chr.rect.size.x = c[3]; - chr.rect.size.y = c[4]; - if (c[7] < 0) { - chr.advance.x = c[3]; - } else { - chr.advance.x = c[7]; - } - chr.align = Vector2(c[6], c[5]); - char_map[c[0]] = chr; - } + return OK; +} - for (int i = 0; i < data->kerning_count; i++) { - KerningPairKey kpk; - kpk.A = data->kernings[i * 3 + 0]; - kpk.B = data->kernings[i * 3 + 1]; +void BitmapFontDataAdvanced::bitmap_add_texture(const Ref<Texture> &p_texture) { + ERR_FAIL_COND(!valid); + ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object."); - if (data->kernings[i * 3 + 2] == 0 && kerning_map.has(kpk)) { - kerning_map.erase(kpk); - } else { - kerning_map[kpk] = data->kernings[i * 3 + 2]; - } - } + textures.push_back(p_texture); +} - height = data->height; - ascent = data->ascent; +void BitmapFontDataAdvanced::bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { + ERR_FAIL_COND(!valid); - base_size = p_base_size; - if (base_size == 0) { - base_size = height; + Character chr; + chr.rect = p_rect; + chr.texture_idx = p_texture_idx; + if (p_advance < 0) { + chr.advance.x = chr.rect.size.x; + } else { + chr.advance.x = p_advance; } + chr.align = p_align; + char_map[p_char] = chr; +} - valid = true; +void BitmapFontDataAdvanced::bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { + ERR_FAIL_COND(!valid); - return OK; + KerningPairKey kpk; + kpk.A = p_A; + kpk.B = p_B; + + if (p_kerning == 0 && kerning_map.has(kpk)) { + kerning_map.erase(kpk); + } else { + kerning_map[kpk] = p_kerning; + } } float BitmapFontDataAdvanced::get_height(int p_size) const { @@ -540,7 +542,7 @@ Vector2 BitmapFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vecto ERR_FAIL_COND_V(c == nullptr, Vector2()); ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2()); if (c->texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += c->align * (float(p_size) / float(base_size)); cpos.y -= ascent * (float(p_size) / float(base_size)); if (RenderingServer::get_singleton() != nullptr) { diff --git a/modules/text_server_adv/bitmap_font_adv.h b/modules/text_server_adv/bitmap_font_adv.h index c314f1b087..da7c2b00ac 100644 --- a/modules/text_server_adv/bitmap_font_adv.h +++ b/modules/text_server_adv/bitmap_font_adv.h @@ -74,7 +74,11 @@ public: virtual void clear_cache() override{}; virtual Error load_from_file(const String &p_filename, int p_base_size) override; - virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) override; + virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) override; + + virtual void bitmap_add_texture(const Ref<Texture> &p_texture) override; + virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override; + virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) override; virtual float get_height(int p_size) const override; virtual float get_ascent(int p_size) const override; diff --git a/modules/text_server_adv/config.py b/modules/text_server_adv/config.py index 22482fce24..d22f9454ed 100644 --- a/modules/text_server_adv/config.py +++ b/modules/text_server_adv/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return env.module_check_dependencies("text_server_adv", ["freetype"]) + return True def configure(env): diff --git a/modules/text_server_adv/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp index fcefa60d98..b60b9ddaec 100644 --- a/modules/text_server_adv/dynamic_font_adv.cpp +++ b/modules/text_server_adv/dynamic_font_adv.cpp @@ -30,6 +30,8 @@ #include "dynamic_font_adv.h" +#ifdef MODULE_FREETYPE_ENABLED + #include FT_STROKER_H #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H @@ -124,8 +126,8 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size( fds->size = p_size; fds->ascent = (fds->face->size->metrics.ascender / 64.0) / oversampling * fds->scale_color_font; fds->descent = (-fds->face->size->metrics.descender / 64.0) / oversampling * fds->scale_color_font; - fds->underline_position = -fds->face->underline_position / 64.0 / oversampling * fds->scale_color_font; - fds->underline_thickness = fds->face->underline_thickness / 64.0 / oversampling * fds->scale_color_font; + fds->underline_position = (-FT_MulFix(fds->face->underline_position, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font; + fds->underline_thickness = (FT_MulFix(fds->face->underline_thickness, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font; //Load os2 TTF pable fds->os2 = (TT_OS2 *)FT_Get_Sfnt_Table(fds->face, FT_SFNT_OS2); @@ -946,7 +948,7 @@ Vector2 DynamicFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vect ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; if (FT_HAS_COLOR(fds->face)) { @@ -977,7 +979,7 @@ Vector2 DynamicFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, in ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; if (FT_HAS_COLOR(fds->face)) { @@ -1001,3 +1003,5 @@ DynamicFontDataAdvanced::~DynamicFontDataAdvanced() { FT_Done_FreeType(library); } } + +#endif // MODULE_FREETYPE_ENABLED diff --git a/modules/text_server_adv/dynamic_font_adv.h b/modules/text_server_adv/dynamic_font_adv.h index c35dd9390b..d69a30b321 100644 --- a/modules/text_server_adv/dynamic_font_adv.h +++ b/modules/text_server_adv/dynamic_font_adv.h @@ -33,6 +33,10 @@ #include "font_adv.h" +#include "modules/modules_enabled.gen.h" + +#ifdef MODULE_FREETYPE_ENABLED + #include <ft2build.h> #include FT_FREETYPE_H #include FT_TRUETYPE_TABLES_H @@ -74,14 +78,11 @@ private: uint32_t size : 16; uint32_t outline_size : 16; }; - uint32_t key; + uint32_t key = 0; }; bool operator<(CacheID right) const { return key < right.key; } - CacheID() { - key = 0; - } }; struct DataAtSize { @@ -91,10 +92,10 @@ private: int size = 0; float scale_color_font = 1.f; - float ascent = 0; - float descent = 0; - float underline_position = 0; - float underline_thickness = 0; + float ascent = 0.0; + float descent = 0.0; + float underline_position = 0.0; + float underline_thickness = 0.0; Vector<CharTexture> textures; HashMap<uint32_t, Character> glyph_map; @@ -188,4 +189,6 @@ public: virtual ~DynamicFontDataAdvanced() override; }; +#endif // MODULE_FREETYPE_ENABLED + #endif // DYNAMIC_FONT_ADV_H diff --git a/modules/text_server_adv/font_adv.h b/modules/text_server_adv/font_adv.h index 4bbd2dd4bf..2b6d977451 100644 --- a/modules/text_server_adv/font_adv.h +++ b/modules/text_server_adv/font_adv.h @@ -39,11 +39,18 @@ struct FontDataAdvanced { Map<String, bool> lang_support_overrides; Map<String, bool> script_support_overrides; bool valid = false; + int spacing_space = 0; + int spacing_glyph = 0; virtual void clear_cache() = 0; - virtual Error load_from_file(const String &p_filename, int p_base_size) = 0; - virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) = 0; + virtual Error load_from_file(const String &p_filename, int p_base_size) { return ERR_CANT_CREATE; }; + virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) { return ERR_CANT_CREATE; }; + virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) { return ERR_CANT_CREATE; }; + + virtual void bitmap_add_texture(const Ref<Texture> &p_texture) { ERR_FAIL_MSG("Not supported."); }; + virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { ERR_FAIL_MSG("Not supported."); }; + virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { ERR_FAIL_MSG("Not supported."); }; virtual float get_height(int p_size) const = 0; virtual float get_ascent(int p_size) const = 0; @@ -58,6 +65,18 @@ struct FontDataAdvanced { virtual float get_underline_position(int p_size) const = 0; virtual float get_underline_thickness(int p_size) const = 0; + virtual int get_spacing_space() const { return spacing_space; }; + virtual void set_spacing_space(int p_value) { + spacing_space = p_value; + clear_cache(); + }; + + virtual int get_spacing_glyph() const { return spacing_glyph; }; + virtual void set_spacing_glyph(int p_value) { + spacing_glyph = p_value; + clear_cache(); + }; + virtual void set_antialiased(bool p_antialiased) = 0; virtual bool get_antialiased() const = 0; diff --git a/modules/text_server_adv/script_iterator.h b/modules/text_server_adv/script_iterator.h index ad476f7c75..896a0e5c15 100644 --- a/modules/text_server_adv/script_iterator.h +++ b/modules/text_server_adv/script_iterator.h @@ -45,9 +45,9 @@ class ScriptIterator { public: struct ScriptRange { - int start; - int end; - hb_script_t script; + int start = 0; + int end = 0; + hb_script_t script = HB_SCRIPT_COMMON; }; Vector<ScriptRange> script_ranges; diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 8b05611089..2e3c2d1cab 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -529,10 +529,12 @@ RID TextServerAdvanced::create_font_system(const String &p_name, int p_base_size RID TextServerAdvanced::create_font_resource(const String &p_filename, int p_base_size) { _THREAD_SAFE_METHOD_ FontDataAdvanced *fd = nullptr; - if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") { - fd = memnew(DynamicFontDataAdvanced); - } else if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") { + if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") { fd = memnew(BitmapFontDataAdvanced); +#ifdef MODULE_FREETYPE_ENABLED + } else if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") { + fd = memnew(DynamicFontDataAdvanced); +#endif } else { return RID(); } @@ -549,10 +551,12 @@ RID TextServerAdvanced::create_font_resource(const String &p_filename, int p_bas RID TextServerAdvanced::create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size) { _THREAD_SAFE_METHOD_ FontDataAdvanced *fd = nullptr; - if (p_type == "ttf" || p_type == "otf" || p_type == "woff") { - fd = memnew(DynamicFontDataAdvanced); - } else if (p_type == "fnt" || p_type == "font") { + if (p_type == "fnt" || p_type == "font") { fd = memnew(BitmapFontDataAdvanced); +#ifdef MODULE_FREETYPE_ENABLED + } else if (p_type == "ttf" || p_type == "otf" || p_type == "woff") { + fd = memnew(DynamicFontDataAdvanced); +#endif } else { return RID(); } @@ -566,6 +570,39 @@ RID TextServerAdvanced::create_font_memory(const uint8_t *p_data, size_t p_size, return font_owner.make_rid(fd); } +RID TextServerAdvanced::create_font_bitmap(float p_height, float p_ascent, int p_base_size) { + _THREAD_SAFE_METHOD_ + FontDataAdvanced *fd = memnew(BitmapFontDataAdvanced); + Error err = fd->bitmap_new(p_height, p_ascent, p_base_size); + if (err != OK) { + memdelete(fd); + return RID(); + } + + return font_owner.make_rid(fd); +} + +void TextServerAdvanced::font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) { + _THREAD_SAFE_METHOD_ + FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->bitmap_add_texture(p_texture); +} + +void TextServerAdvanced::font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { + _THREAD_SAFE_METHOD_ + FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->bitmap_add_char(p_char, p_texture_idx, p_rect, p_align, p_advance); +} + +void TextServerAdvanced::font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) { + _THREAD_SAFE_METHOD_ + FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->bitmap_add_kerning_pair(p_A, p_B, p_kerning); +} + float TextServerAdvanced::font_get_height(RID p_font, int p_size) const { _THREAD_SAFE_METHOD_ const FontDataAdvanced *fd = font_owner.getornull(p_font); @@ -601,6 +638,34 @@ float TextServerAdvanced::font_get_underline_thickness(RID p_font, int p_size) c return fd->get_underline_thickness(p_size); } +int TextServerAdvanced::font_get_spacing_space(RID p_font) const { + _THREAD_SAFE_METHOD_ + const FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND_V(!fd, 0); + return fd->get_spacing_space(); +} + +void TextServerAdvanced::font_set_spacing_space(RID p_font, int p_value) { + _THREAD_SAFE_METHOD_ + FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->set_spacing_space(p_value); +} + +int TextServerAdvanced::font_get_spacing_glyph(RID p_font) const { + _THREAD_SAFE_METHOD_ + const FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND_V(!fd, 0); + return fd->get_spacing_glyph(); +} + +void TextServerAdvanced::font_set_spacing_glyph(RID p_font, int p_value) { + _THREAD_SAFE_METHOD_ + FontDataAdvanced *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->set_spacing_glyph(p_value); +} + void TextServerAdvanced::font_set_antialiased(RID p_font, bool p_antialiased) { _THREAD_SAFE_METHOD_ FontDataAdvanced *fd = font_owner.getornull(p_font); @@ -1602,11 +1667,18 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { HashMap<int, bool> breaks; UErrorCode err = U_ZERO_ERROR; - for (int i = 0; i < sd->spans.size(); i++) { - UBreakIterator *bi = ubrk_open(UBRK_LINE, sd->spans[i].language.ascii().get_data(), data + _convert_pos_inv(sd, sd->spans[i].start), _convert_pos_inv(sd, sd->spans[i].end - sd->spans[i].start), &err); + int i = 0; + while (i < sd->spans.size()) { + String language = sd->spans[i].language; + int r_start = sd->spans[i].start; + while (i + 1 < sd->spans.size() && language == sd->spans[i + 1].language) { + i++; + } + int r_end = sd->spans[i].end; + UBreakIterator *bi = ubrk_open(UBRK_LINE, language.ascii().get_data(), data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err); if (U_FAILURE(err)) { //No data loaded - use fallback. - for (int j = sd->spans[i].start; j < sd->spans[i].end; j++) { + for (int j = r_start; j < r_end; j++) { char32_t c = sd->text[j - sd->start]; if (is_whitespace(c)) { breaks[j] = false; @@ -1617,8 +1689,8 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { } } else { while (ubrk_next(bi) != UBRK_DONE) { - int pos = _convert_pos(sd, ubrk_current(bi)) + sd->spans[i].start - 1; - if (pos != sd->spans[i].end) { + int pos = _convert_pos(sd, ubrk_current(bi)) + r_start - 1; + if (pos != r_end) { if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_HARD) && (ubrk_getRuleStatus(bi) < UBRK_LINE_HARD_LIMIT)) { breaks[pos] = true; } else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) { @@ -1628,6 +1700,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { } } ubrk_close(bi); + i++; } sd->sort_valid = false; @@ -1636,7 +1709,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { const char32_t *ch = sd->text.ptr(); Glyph *sd_glyphs = sd->glyphs.ptrw(); - for (int i = 0; i < sd_size; i++) { + for (i = 0; i < sd_size; i++) { if (sd_glyphs[i].count > 0) { char32_t c = ch[sd_glyphs[i].start - sd->start]; if (c == 0xfffc) { @@ -2041,6 +2114,11 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star gl.x_off = Math::round(glyph_pos[i].x_offset / (64.0 / fd->get_font_scale(fs))); gl.y_off = -Math::round(glyph_pos[i].y_offset / (64.0 / fd->get_font_scale(fs))); } + if (fd->get_spacing_space() && is_whitespace(p_sd->text[glyph_info[i].cluster])) { + gl.advance += fd->get_spacing_space(); + } else { + gl.advance += fd->get_spacing_glyph(); + } if (p_sd->preserve_control) { last_cluster_valid = last_cluster_valid && ((glyph_info[i].codepoint != 0) || is_whitespace(p_sd->text[glyph_info[i].cluster]) || is_linebreak(p_sd->text[glyph_info[i].cluster])); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 89fae477f9..b53b5716e5 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -126,6 +126,11 @@ public: virtual RID create_font_system(const String &p_name, int p_base_size = 16) override; virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) override; virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) override; + virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) override; + + virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) override; + virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override; + virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) override; virtual float font_get_height(RID p_font, int p_size) const override; virtual float font_get_ascent(RID p_font, int p_size) const override; @@ -134,6 +139,12 @@ public: virtual float font_get_underline_position(RID p_font, int p_size) const override; virtual float font_get_underline_thickness(RID p_font, int p_size) const override; + virtual int font_get_spacing_space(RID p_font) const override; + virtual void font_set_spacing_space(RID p_font, int p_value) override; + + virtual int font_get_spacing_glyph(RID p_font) const override; + virtual void font_set_spacing_glyph(RID p_font, int p_value) override; + virtual void font_set_antialiased(RID p_font, bool p_antialiased) override; virtual bool font_get_antialiased(RID p_font) const override; diff --git a/modules/text_server_fb/bitmap_font_fb.cpp b/modules/text_server_fb/bitmap_font_fb.cpp index 5c691b7bbd..c58f8cbba1 100644 --- a/modules/text_server_fb/bitmap_font_fb.cpp +++ b/modules/text_server_fb/bitmap_font_fb.cpp @@ -148,7 +148,7 @@ Error BitmapFontDataFallback::load_from_file(const String &p_filename, int p_bas char_map[idx] = c; } else if (type == "kerning") { KerningPairKey kpk; - float k = 0; + float k = 0.0; if (keys.has("first")) { kpk.A = keys["first"].to_int(); } @@ -175,61 +175,58 @@ Error BitmapFontDataFallback::load_from_file(const String &p_filename, int p_bas return OK; } -Error BitmapFontDataFallback::load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) { - _THREAD_SAFE_METHOD_ - ERR_FAIL_COND_V(p_data == nullptr, ERR_CANT_CREATE); - ERR_FAIL_COND_V(p_size != sizeof(TextServer::BitmapFontData), ERR_CANT_CREATE); +Error BitmapFontDataFallback::bitmap_new(float p_height, float p_ascent, int p_base_size) { + height = p_height; + ascent = p_ascent; - const TextServer::BitmapFontData *data = (const TextServer::BitmapFontData *)p_data; + base_size = p_base_size; + if (base_size == 0) { + base_size = height; + } - if (RenderingServer::get_singleton() != nullptr) { - Ref<Image> image = memnew(Image(data->img)); - Ref<ImageTexture> tex = memnew(ImageTexture); - tex->create_from_image(image); + char_map.clear(); + textures.clear(); + kerning_map.clear(); - textures.push_back(tex); - } + valid = true; - for (int i = 0; i < data->charcount; i++) { - const int *c = &data->char_rects[i * 8]; - - Character chr; - chr.rect.position.x = c[1]; - chr.rect.position.y = c[2]; - chr.rect.size.x = c[3]; - chr.rect.size.y = c[4]; - if (c[7] < 0) { - chr.advance.x = c[3]; - } else { - chr.advance.x = c[7]; - } - chr.align = Vector2(c[6], c[5]); - char_map[c[0]] = chr; - } + return OK; +} - for (int i = 0; i < data->kerning_count; i++) { - KerningPairKey kpk; - kpk.A = data->kernings[i * 3 + 0]; - kpk.B = data->kernings[i * 3 + 1]; +void BitmapFontDataFallback::bitmap_add_texture(const Ref<Texture> &p_texture) { + ERR_FAIL_COND(!valid); + ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object."); - if (data->kernings[i * 3 + 2] == 0 && kerning_map.has(kpk)) { - kerning_map.erase(kpk); - } else { - kerning_map[kpk] = data->kernings[i * 3 + 2]; - } - } + textures.push_back(p_texture); +} - height = data->height; - ascent = data->ascent; +void BitmapFontDataFallback::bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { + ERR_FAIL_COND(!valid); - base_size = p_base_size; - if (base_size == 0) { - base_size = height; + Character chr; + chr.rect = p_rect; + chr.texture_idx = p_texture_idx; + if (p_advance < 0) { + chr.advance.x = chr.rect.size.x; + } else { + chr.advance.x = p_advance; } + chr.align = p_align; + char_map[p_char] = chr; +} - valid = true; +void BitmapFontDataFallback::bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { + ERR_FAIL_COND(!valid); - return OK; + KerningPairKey kpk; + kpk.A = p_A; + kpk.B = p_B; + + if (p_kerning == 0 && kerning_map.has(kpk)) { + kerning_map.erase(kpk); + } else { + kerning_map[kpk] = p_kerning; + } } float BitmapFontDataFallback::get_height(int p_size) const { @@ -321,7 +318,7 @@ Vector2 BitmapFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vecto ERR_FAIL_COND_V(c == nullptr, Vector2()); ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2()); if (c->texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += c->align * (float(p_size) / float(base_size)); cpos.y -= ascent * (float(p_size) / float(base_size)); diff --git a/modules/text_server_fb/bitmap_font_fb.h b/modules/text_server_fb/bitmap_font_fb.h index 33401b85fa..7cd7507ebc 100644 --- a/modules/text_server_fb/bitmap_font_fb.h +++ b/modules/text_server_fb/bitmap_font_fb.h @@ -70,7 +70,11 @@ public: virtual void clear_cache() override{}; virtual Error load_from_file(const String &p_filename, int p_base_size) override; - virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) override; + virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) override; + + virtual void bitmap_add_texture(const Ref<Texture> &p_texture) override; + virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override; + virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) override; virtual float get_height(int p_size) const override; virtual float get_ascent(int p_size) const override; diff --git a/modules/text_server_fb/config.py b/modules/text_server_fb/config.py index 491377a369..7a73080ae9 100644 --- a/modules/text_server_fb/config.py +++ b/modules/text_server_fb/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return env.module_check_dependencies("text_server_fb", ["freetype"]) + return True def configure(env): diff --git a/modules/text_server_fb/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp index 4eecba6ae8..66d36bc885 100644 --- a/modules/text_server_fb/dynamic_font_fb.cpp +++ b/modules/text_server_fb/dynamic_font_fb.cpp @@ -30,6 +30,8 @@ #include "dynamic_font_fb.h" +#ifdef MODULE_FREETYPE_ENABLED + #include FT_STROKER_H #include FT_ADVANCES_H @@ -124,8 +126,9 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size( fds->size = p_size; fds->ascent = (fds->face->size->metrics.ascender / 64.0) / oversampling * fds->scale_color_font; fds->descent = (-fds->face->size->metrics.descender / 64.0) / oversampling * fds->scale_color_font; - fds->underline_position = -fds->face->underline_position / 64.0 / oversampling * fds->scale_color_font; - fds->underline_thickness = fds->face->underline_thickness / 64.0 / oversampling * fds->scale_color_font; + fds->underline_position = (-FT_MulFix(fds->face->underline_position, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font; + fds->underline_thickness = (FT_MulFix(fds->face->underline_thickness, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font; + if (p_outline_size != 0) { size_cache_outline[id] = fds; } else { @@ -626,7 +629,7 @@ Vector2 DynamicFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vect ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; @@ -658,7 +661,7 @@ Vector2 DynamicFontDataFallback::draw_glyph_outline(RID p_canvas, int p_size, in ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; @@ -683,3 +686,5 @@ DynamicFontDataFallback::~DynamicFontDataFallback() { FT_Done_FreeType(library); } } + +#endif // MODULE_FREETYPE_ENABLED diff --git a/modules/text_server_fb/dynamic_font_fb.h b/modules/text_server_fb/dynamic_font_fb.h index f1cd758f2c..eb70f46666 100644 --- a/modules/text_server_fb/dynamic_font_fb.h +++ b/modules/text_server_fb/dynamic_font_fb.h @@ -33,6 +33,10 @@ #include "font_fb.h" +#include "modules/modules_enabled.gen.h" + +#ifdef MODULE_FREETYPE_ENABLED + #include <ft2build.h> #include FT_FREETYPE_H @@ -70,14 +74,11 @@ private: uint32_t size : 16; uint32_t outline_size : 16; }; - uint32_t key; + uint32_t key = 0; }; bool operator<(CacheID right) const { return key < right.key; } - CacheID() { - key = 0; - } }; struct DataAtSize { @@ -86,10 +87,10 @@ private: int size = 0; float scale_color_font = 1.f; - float ascent = 0; - float descent = 0; - float underline_position = 0; - float underline_thickness = 0; + float ascent = 0.0; + float descent = 0.0; + float underline_position = 0.0; + float underline_thickness = 0.0; Vector<CharTexture> textures; HashMap<char32_t, Character> char_map; @@ -166,4 +167,6 @@ public: virtual ~DynamicFontDataFallback() override; }; +#endif // MODULE_FREETYPE_ENABLED + #endif // DYNAMIC_FONT_FALLBACK_H diff --git a/modules/text_server_fb/font_fb.h b/modules/text_server_fb/font_fb.h index cc72919542..218f3df03a 100644 --- a/modules/text_server_fb/font_fb.h +++ b/modules/text_server_fb/font_fb.h @@ -37,11 +37,18 @@ struct FontDataFallback { Map<String, bool> lang_support_overrides; Map<String, bool> script_support_overrides; bool valid = false; + int spacing_space = 0; + int spacing_glyph = 0; virtual void clear_cache() = 0; - virtual Error load_from_file(const String &p_filename, int p_base_size) = 0; - virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) = 0; + virtual Error load_from_file(const String &p_filename, int p_base_size) { return ERR_CANT_CREATE; }; + virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) { return ERR_CANT_CREATE; }; + virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) { return ERR_CANT_CREATE; }; + + virtual void bitmap_add_texture(const Ref<Texture> &p_texture) { ERR_FAIL_MSG("Not supported."); }; + virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { ERR_FAIL_MSG("Not supported."); }; + virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { ERR_FAIL_MSG("Not supported."); }; virtual float get_height(int p_size) const = 0; virtual float get_ascent(int p_size) const = 0; @@ -50,6 +57,18 @@ struct FontDataFallback { virtual float get_underline_position(int p_size) const = 0; virtual float get_underline_thickness(int p_size) const = 0; + virtual int get_spacing_space() const { return spacing_space; }; + virtual void set_spacing_space(int p_value) { + spacing_space = p_value; + clear_cache(); + }; + + virtual int get_spacing_glyph() const { return spacing_glyph; }; + virtual void set_spacing_glyph(int p_value) { + spacing_glyph = p_value; + clear_cache(); + }; + virtual void set_antialiased(bool p_antialiased) = 0; virtual bool get_antialiased() const = 0; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index e60d269408..60ab14738a 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -107,10 +107,12 @@ RID TextServerFallback::create_font_system(const String &p_name, int p_base_size RID TextServerFallback::create_font_resource(const String &p_filename, int p_base_size) { _THREAD_SAFE_METHOD_ FontDataFallback *fd = nullptr; - if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") { - fd = memnew(DynamicFontDataFallback); - } else if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") { + if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") { fd = memnew(BitmapFontDataFallback); +#ifdef MODULE_FREETYPE_ENABLED + } else if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") { + fd = memnew(DynamicFontDataFallback); +#endif } else { return RID(); } @@ -127,10 +129,12 @@ RID TextServerFallback::create_font_resource(const String &p_filename, int p_bas RID TextServerFallback::create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size) { _THREAD_SAFE_METHOD_ FontDataFallback *fd = nullptr; - if (p_type == "ttf" || p_type == "otf" || p_type == "woff") { - fd = memnew(DynamicFontDataFallback); - } else if (p_type == "fnt" || p_type == "font") { + if (p_type == "fnt" || p_type == "font") { fd = memnew(BitmapFontDataFallback); +#ifdef MODULE_FREETYPE_ENABLED + } else if (p_type == "ttf" || p_type == "otf" || p_type == "woff") { + fd = memnew(DynamicFontDataFallback); +#endif } else { return RID(); } @@ -144,6 +148,39 @@ RID TextServerFallback::create_font_memory(const uint8_t *p_data, size_t p_size, return font_owner.make_rid(fd); } +RID TextServerFallback::create_font_bitmap(float p_height, float p_ascent, int p_base_size) { + _THREAD_SAFE_METHOD_ + FontDataFallback *fd = memnew(BitmapFontDataFallback); + Error err = fd->bitmap_new(p_height, p_ascent, p_base_size); + if (err != OK) { + memdelete(fd); + return RID(); + } + + return font_owner.make_rid(fd); +} + +void TextServerFallback::font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) { + _THREAD_SAFE_METHOD_ + FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->bitmap_add_texture(p_texture); +} + +void TextServerFallback::font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { + _THREAD_SAFE_METHOD_ + FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->bitmap_add_char(p_char, p_texture_idx, p_rect, p_align, p_advance); +} + +void TextServerFallback::font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) { + _THREAD_SAFE_METHOD_ + FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->bitmap_add_kerning_pair(p_A, p_B, p_kerning); +} + float TextServerFallback::font_get_height(RID p_font, int p_size) const { _THREAD_SAFE_METHOD_ const FontDataFallback *fd = font_owner.getornull(p_font); @@ -179,6 +216,34 @@ float TextServerFallback::font_get_underline_thickness(RID p_font, int p_size) c return fd->get_underline_thickness(p_size); } +int TextServerFallback::font_get_spacing_space(RID p_font) const { + _THREAD_SAFE_METHOD_ + const FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND_V(!fd, 0); + return fd->get_spacing_space(); +} + +void TextServerFallback::font_set_spacing_space(RID p_font, int p_value) { + _THREAD_SAFE_METHOD_ + FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->set_spacing_space(p_value); +} + +int TextServerFallback::font_get_spacing_glyph(RID p_font) const { + _THREAD_SAFE_METHOD_ + const FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND_V(!fd, 0); + return fd->get_spacing_glyph(); +} + +void TextServerFallback::font_set_spacing_glyph(RID p_font, int p_value) { + _THREAD_SAFE_METHOD_ + FontDataFallback *fd = font_owner.getornull(p_font); + ERR_FAIL_COND(!fd); + fd->set_spacing_glyph(p_value); +} + void TextServerFallback::font_set_antialiased(RID p_font, bool p_antialiased) { _THREAD_SAFE_METHOD_ FontDataFallback *fd = font_owner.getornull(p_font); @@ -1184,6 +1249,11 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { sd->descent = MAX(sd->descent, Math::round(fd->get_advance(gl.index, gl.font_size).x * 0.5)); } } + if (fd->get_spacing_space() && is_whitespace(sd->text[j])) { + gl.advance += fd->get_spacing_space(); + } else { + gl.advance += fd->get_spacing_glyph(); + } sd->upos = MAX(sd->upos, fd->get_underline_position(gl.font_size)); sd->uthk = MAX(sd->uthk, fd->get_underline_thickness(gl.font_size)); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index d142b320e4..b10369d172 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -81,6 +81,11 @@ public: virtual RID create_font_system(const String &p_name, int p_base_size = 16) override; virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) override; virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) override; + virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) override; + + virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) override; + virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override; + virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) override; virtual float font_get_height(RID p_font, int p_size) const override; virtual float font_get_ascent(RID p_font, int p_size) const override; @@ -89,6 +94,12 @@ public: virtual float font_get_underline_position(RID p_font, int p_size) const override; virtual float font_get_underline_thickness(RID p_font, int p_size) const override; + virtual int font_get_spacing_space(RID p_font) const override; + virtual void font_set_spacing_space(RID p_font, int p_value) override; + + virtual int font_get_spacing_glyph(RID p_font) const override; + virtual void font_set_spacing_glyph(RID p_font, int p_value) override; + virtual void font_set_antialiased(RID p_font, bool p_antialiased) override; virtual bool font_get_antialiased(RID p_font) const override; diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 2da9159228..ef53661557 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -56,6 +56,10 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t compressed_pos += 1; count = (c & 0x7f) + 1; + if (output_pos + count * p_pixel_size > output_pos) { + return ERR_PARSE_ERROR; + } + if (c & 0x80) { for (size_t i = 0; i < p_pixel_size; i++) { pixels_w[i] = p_compressed_buffer[compressed_pos]; @@ -79,7 +83,7 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t return OK; } -Error ImageLoaderTGA::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) { +Error ImageLoaderTGA::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_output_size) { #define TGA_PUT_PIXEL(r, g, b, a) \ int image_data_ofs = ((y * width) + x); \ image_data_w[image_data_ofs * 4 + 0] = r; \ @@ -130,6 +134,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff if (p_is_monochrome) { while (y != y_end) { while (x != x_end) { + if (i > p_output_size) { + return ERR_PARSE_ERROR; + } uint8_t shade = p_buffer[i]; TGA_PUT_PIXEL(shade, shade, shade, 0xff) @@ -143,6 +150,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } else { while (y != y_end) { while (x != x_end) { + if (i > p_output_size) { + return ERR_PARSE_ERROR; + } uint8_t index = p_buffer[i]; uint8_t r = 0x00; uint8_t g = 0x00; @@ -171,6 +181,10 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } else if (p_header.pixel_depth == 24) { while (y != y_end) { while (x != x_end) { + if (i + 2 > p_output_size) { + return ERR_PARSE_ERROR; + } + uint8_t r = p_buffer[i + 2]; uint8_t g = p_buffer[i + 1]; uint8_t b = p_buffer[i + 0]; @@ -186,6 +200,10 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } else if (p_header.pixel_depth == 32) { while (y != y_end) { while (x != x_end) { + if (i + 3 > p_output_size) { + return ERR_PARSE_ERROR; + } + uint8_t a = p_buffer[i + 3]; uint8_t r = p_buffer[i + 2]; uint8_t g = p_buffer[i + 1]; @@ -279,7 +297,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force const uint8_t *src_image_r = src_image.ptr(); const size_t pixel_size = tga_header.pixel_depth >> 3; - const size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size; + size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size; Vector<uint8_t> uncompressed_buffer; uncompressed_buffer.resize(buffer_size); @@ -297,11 +315,12 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force } } else { buffer = src_image_r; + buffer_size = src_image_len; }; if (err == OK) { const uint8_t *palette_r = palette.ptr(); - err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome); + err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome, buffer_size); } } diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index 249e33411e..cb2ce07edd 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -57,23 +57,23 @@ class ImageLoaderTGA : public ImageFormatLoader { }; struct tga_header_s { - uint8_t id_length; - uint8_t color_map_type; + uint8_t id_length = 0; + uint8_t color_map_type = 0; tga_type_e image_type; - uint16_t first_color_entry; - uint16_t color_map_length; - uint8_t color_map_depth; + uint16_t first_color_entry = 0; + uint16_t color_map_length = 0; + uint8_t color_map_depth = 0; - uint16_t x_origin; - uint16_t y_origin; - uint16_t image_width; - uint16_t image_height; - uint8_t pixel_depth; - uint8_t image_descriptor; + uint16_t x_origin = 0; + uint16_t y_origin = 0; + uint16_t image_width = 0; + uint16_t image_height = 0; + uint8_t pixel_depth = 0; + uint8_t image_descriptor = 0; }; static Error decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size); - 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); + 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_output_size); public: virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale); diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 243265769e..c5f6dc0d99 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -140,9 +140,7 @@ void VideoStreamPlaybackTheora::clear() { #ifdef THEORA_USE_THREAD_STREAMING thread_exit = true; thread_sem->post(); //just in case - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread.wait_to_finish(); ring_buffer.clear(); #endif @@ -181,7 +179,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { int read = file->get_buffer(read_buffer.ptr(), to_read); ring_buffer.write(read_buffer.ptr(), read); - thread = Thread::create(_streaming_thread, this); + thread.start(_streaming_thread, this); #endif @@ -556,7 +554,7 @@ void VideoStreamPlaybackTheora::play() { } playing = true; - delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms"); + delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms"); delay_compensation /= 1000.0; }; @@ -647,31 +645,13 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) { #endif VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() { - file = nullptr; - theora_p = 0; - vorbis_p = 0; - videobuf_ready = 0; - playing = false; - frames_pending = 0; - videobuf_time = 0; - paused = false; - - buffering = false; texture = Ref<ImageTexture>(memnew(ImageTexture)); - mix_callback = nullptr; - mix_udata = nullptr; - audio_track = 0; - delay_compensation = 0; - audio_frames_wrote = 0; #ifdef THEORA_USE_THREAD_STREAMING int rb_power = nearest_shift(RB_SIZE_KB * 1024); ring_buffer.resize(rb_power); read_buffer.resize(RB_SIZE_KB * 1024); thread_sem = Semaphore::create(); - thread = nullptr; - thread_exit = false; - thread_eof = false; #endif }; @@ -697,7 +677,7 @@ void VideoStreamTheora::_bind_methods() { //////////// -RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index d2036b5cb4..2685a8a013 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -36,6 +36,7 @@ #include "core/os/semaphore.h" #include "core/os/thread.h" #include "core/templates/ring_buffer.h" +#include "core/templates/safe_refcount.h" #include "scene/resources/video_stream.h" #include "servers/audio_server.h" @@ -52,12 +53,12 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { }; //Image frames[MAX_FRAMES]; - Image::Format format; + Image::Format format = Image::Format::FORMAT_L8; Vector<uint8_t> frame_data; - int frames_pending; - FileAccess *file; + int frames_pending = 0; + FileAccess *file = nullptr; String file_name; - int audio_frames_wrote; + int audio_frames_wrote = 0; Point2i size; int buffer_data(); @@ -65,8 +66,8 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { void video_write(); float get_time() const; - bool theora_eos; - bool vorbis_eos; + bool theora_eos = false; + bool vorbis_eos = false; ogg_sync_state oy; ogg_page og; @@ -74,33 +75,33 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { ogg_stream_state to; th_info ti; th_comment tc; - th_dec_ctx *td; + th_dec_ctx *td = nullptr; vorbis_info vi; vorbis_dsp_state vd; vorbis_block vb; vorbis_comment vc; th_pixel_fmt px_fmt; - double videobuf_time; - int pp_inc; + double videobuf_time = 0; + int pp_inc = 0; - int theora_p; - int vorbis_p; - int pp_level_max; - int pp_level; - int videobuf_ready; + int theora_p = 0; + int vorbis_p = 0; + int pp_level_max = 0; + int pp_level = 0; + int videobuf_ready = 0; - bool playing; - bool buffering; + bool playing = false; + bool buffering = false; - double last_update_time; - double time; - double delay_compensation; + double last_update_time = 0; + double time = 0; + double delay_compensation = 0; Ref<ImageTexture> texture; AudioMixCallback mix_callback; - void *mix_udata; - bool paused; + void *mix_udata = nullptr; + bool paused = false; #ifdef THEORA_USE_THREAD_STREAMING @@ -110,16 +111,16 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { RingBuffer<uint8_t> ring_buffer; Vector<uint8_t> read_buffer; - bool thread_eof; + bool thread_eof = false; Semaphore *thread_sem; - Thread *thread; - volatile bool thread_exit; + Thread thread; + SafeFlag thread_exit; static void _streaming_thread(void *ud); #endif - int audio_track; + int audio_track = 0; protected: void clear(); @@ -185,7 +186,7 @@ public: class ResourceFormatLoaderTheora : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp index 8c3be884bd..cff13251ce 100644 --- a/modules/upnp/upnp.cpp +++ b/modules/upnp/upnp.cpp @@ -393,9 +393,6 @@ void UPNP::_bind_methods() { } UPNP::UPNP() { - discover_multicast_if = ""; - discover_local_port = 0; - discover_ipv6 = false; } UPNP::~UPNP() { diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index 9dfa907476..a0cca96bc8 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -41,9 +41,9 @@ class UPNP : public Reference { GDCLASS(UPNP, Reference); private: - String discover_multicast_if; - int discover_local_port; - bool discover_ipv6; + String discover_multicast_if = ""; + int discover_local_port = 0; + bool discover_ipv6 = false; Vector<Ref<UPNPDevice>> devices; diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index 4004f1a04c..219ffd01d3 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -202,24 +202,20 @@ <constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc"> Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES]. </constant> - <constant name="COLORN" value="63" enum="BuiltinFunc"> - Return the [Color] with the given name and alpha ranging from 0 to 1. - [b]Note:[/b] Names are defined in [code]color_names.inc[/code]. - </constant> - <constant name="MATH_SMOOTHSTEP" value="64" enum="BuiltinFunc"> + <constant name="MATH_SMOOTHSTEP" value="63" enum="BuiltinFunc"> Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula: [codeblock] var t = clamp((weight - from) / (to - from), 0.0, 1.0) return t * t * (3.0 - 2.0 * t) [/codeblock] </constant> - <constant name="MATH_POSMOD" value="65" enum="BuiltinFunc"> + <constant name="MATH_POSMOD" value="64" enum="BuiltinFunc"> </constant> - <constant name="MATH_LERP_ANGLE" value="66" enum="BuiltinFunc"> + <constant name="MATH_LERP_ANGLE" value="65" enum="BuiltinFunc"> </constant> - <constant name="TEXT_ORD" value="67" enum="BuiltinFunc"> + <constant name="TEXT_ORD" value="66" enum="BuiltinFunc"> </constant> - <constant name="FUNC_MAX" value="68" enum="BuiltinFunc"> + <constant name="FUNC_MAX" value="67" enum="BuiltinFunc"> Represents the size of the [enum BuiltinFunc] enum. </constant> </constants> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index fe92f59179..2517b17168 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -137,7 +137,6 @@ Ref<VisualScript> VisualScriptNode::get_visual_script() const { } VisualScriptNode::VisualScriptNode() { - breakpoint = false; } //////////////// @@ -145,8 +144,6 @@ VisualScriptNode::VisualScriptNode() { ///////////////////// VisualScriptNodeInstance::VisualScriptNodeInstance() { - sequence_outputs = nullptr; - input_ports = nullptr; } VisualScriptNodeInstance::~VisualScriptNodeInstance() { @@ -2623,14 +2620,8 @@ void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) { } VisualScriptLanguage::VisualScriptLanguage() { - notification = "_notification"; - _step = "_step"; - _subcall = "_subcall"; singleton = this; - _debug_parse_err_node = -1; - _debug_parse_err_file = ""; - _debug_call_stack_pos = 0; int dmcs = GLOBAL_DEF("debug/settings/visual_script/max_call_stack", 1024); ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/visual_script/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/visual_script/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024 diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index bdb3c3a16b..72362e0ef4 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -49,7 +49,7 @@ class VisualScriptNode : public Resource { Ref<VisualScript> script_used; Array default_input_values; - bool breakpoint; + bool breakpoint = false; void _set_default_input_values(Array p_values); Array _get_default_input_values() const; @@ -90,13 +90,9 @@ public: virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) = 0; struct TypeGuess { - Variant::Type type; + Variant::Type type = Variant::NIL; StringName gdclass; Ref<Script> script; - - TypeGuess() { - type = Variant::NIL; - } }; virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const; @@ -114,19 +110,19 @@ class VisualScriptNodeInstance { INPUT_DEFAULT_VALUE_BIT = INPUT_SHIFT, // from unassigned input port, using default value (edited by user) }; - int id; - int sequence_index; - VisualScriptNodeInstance **sequence_outputs; - int sequence_output_count; + int id = 0; + int sequence_index = 0; + VisualScriptNodeInstance **sequence_outputs = nullptr; + int sequence_output_count = 0; Vector<VisualScriptNodeInstance *> dependencies; - int *input_ports; - int input_port_count; - int *output_ports; - int output_port_count; - int working_mem_idx; - int pass_idx; + int *input_ports = nullptr; + int input_port_count = 0; + int *output_ports = nullptr; + int output_port_count = 0; + int working_mem_idx = 0; + int pass_idx = 0; - VisualScriptNode *base; + VisualScriptNode *base = nullptr; public: enum StartMode { @@ -178,7 +174,7 @@ public: uint64_t from_output : 16; uint64_t to_node : 24; }; - uint64_t id; + uint64_t id = 0; }; bool operator<(const SequenceConnection &p_connection) const { @@ -194,7 +190,7 @@ public: uint64_t to_node : 24; uint64_t to_port : 8; }; - uint64_t id; + uint64_t id = 0; }; bool operator<(const DataConnection &p_connection) const { @@ -208,7 +204,7 @@ private: StringName base_type; struct Argument { String name; - Variant::Type type; + Variant::Type type = Variant::Type::NIL; }; struct NodeData { @@ -231,7 +227,7 @@ private: struct Variable { PropertyInfo info; Variant default_value; - bool _export; + bool _export = false; // Add getter & setter options here. }; @@ -388,26 +384,27 @@ public: }; class VisualScriptInstance : public ScriptInstance { - Object *owner; + Object *owner = nullptr; Ref<VisualScript> script; Map<StringName, Variant> variables; // Using variable path, not script. Map<int, VisualScriptNodeInstance *> instances; struct Function { - int node; - int max_stack; - int trash_pos; - int flow_stack_size; - int pass_stack_size; - int node_count; - int argument_count; + int node = 0; + int max_stack = 0; + int trash_pos = 0; + int flow_stack_size = 0; + int pass_stack_size = 0; + int node_count = 0; + int argument_count = 0; }; Map<StringName, Function> functions; Vector<Variant> default_values; - int max_input_args, max_output_args; + int max_input_args = 0; + int max_output_args = 0; StringName source; @@ -479,14 +476,14 @@ class VisualScriptFunctionState : public Reference { ObjectID instance_id; ObjectID script_id; - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; StringName function; Vector<uint8_t> stack; - int working_mem_index; - int variant_stack_size; - VisualScriptNodeInstance *node; - int flow_stack_pos; - int pass; + int working_mem_index = 0; + int variant_stack_size = 0; + VisualScriptNodeInstance *node = nullptr; + int flow_stack_pos = 0; + int pass = 0; Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); @@ -507,25 +504,25 @@ class VisualScriptLanguage : public ScriptLanguage { Map<String, VisualScriptNodeRegisterFunc> register_funcs; struct CallLevel { - Variant *stack; - Variant **work_mem; - const StringName *function; - VisualScriptInstance *instance; - int *current_id; + Variant *stack = nullptr; + Variant **work_mem = nullptr; + const StringName *function = nullptr; + VisualScriptInstance *instance = nullptr; + int *current_id = nullptr; }; - int _debug_parse_err_node; - String _debug_parse_err_file; + int _debug_parse_err_node = -1; + String _debug_parse_err_file = ""; String _debug_error; - int _debug_call_stack_pos; + int _debug_call_stack_pos = 0; int _debug_max_call_stack; CallLevel *_call_stack; public: - StringName notification; + StringName notification = "_notification"; StringName _get_output_port_unsequenced; - StringName _step; - StringName _subcall; + StringName _step = "_step"; + StringName _subcall = "_subcall"; static VisualScriptLanguage *singleton; diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 2558c1d7ec..7ca14fbca8 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -101,7 +101,6 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "str2var", "var2bytes", "bytes2var", - "color_named", "smoothstep", "posmod", "lerp_angle", @@ -200,7 +199,6 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { case LOGIC_MAX: case LOGIC_MIN: case TYPE_CONVERT: - case COLORN: return 2; case MATH_LERP: case MATH_LERP_ANGLE: @@ -476,13 +474,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const return PropertyInfo(Variant::BOOL, "allow_objects"); } } break; - case COLORN: { - if (p_idx == 0) { - return PropertyInfo(Variant::STRING, "name"); - } else { - return PropertyInfo(Variant::FLOAT, "alpha"); - } - } break; case FUNC_MAX: { } } @@ -635,9 +626,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons t = Variant::BOOL; } } break; - case COLORN: { - t = Variant::COLOR; - } break; case FUNC_MAX: { } } @@ -659,7 +647,7 @@ String VisualScriptBuiltinFunc::get_caption() const { void VisualScriptBuiltinFunc::set_func(BuiltinFunc p_which) { ERR_FAIL_INDEX(p_which, FUNC_MAX); func = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1176,15 +1164,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in *r_return = ret; } break; - case VisualScriptBuiltinFunc::COLORN: { - VALIDATE_ARG_NUM(1); - - Color color = Color::named(*p_inputs[0]); - color.a = *p_inputs[1]; - - *r_return = String(color); - - } break; default: { } } @@ -1292,7 +1271,6 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(STR_TO_VAR); BIND_ENUM_CONSTANT(VAR_TO_BYTES); BIND_ENUM_CONSTANT(BYTES_TO_VAR); - BIND_ENUM_CONSTANT(COLORN); BIND_ENUM_CONSTANT(MATH_SMOOTHSTEP); BIND_ENUM_CONSTANT(MATH_POSMOD); BIND_ENUM_CONSTANT(MATH_LERP_ANGLE); @@ -1388,5 +1366,4 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/str2var", create_builtin_func_node<VisualScriptBuiltinFunc::STR_TO_VAR>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/var2bytes", create_builtin_func_node<VisualScriptBuiltinFunc::VAR_TO_BYTES>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/bytes2var", create_builtin_func_node<VisualScriptBuiltinFunc::BYTES_TO_VAR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/color_named", create_builtin_func_node<VisualScriptBuiltinFunc::COLORN>); } diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h index eaa2ef41e2..1fafaf1d98 100644 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ b/modules/visual_script/visual_script_builtin_funcs.h @@ -101,7 +101,6 @@ public: STR_TO_VAR, VAR_TO_BYTES, BYTES_TO_VAR, - COLORN, MATH_SMOOTHSTEP, MATH_POSMOD, MATH_LERP_ANGLE, diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 1e82259e59..fcd55b3049 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -61,7 +61,7 @@ protected: } void _sig_changed() { - _change_notify(); + notify_property_list_changed(); emit_signal("changed"); } @@ -172,7 +172,7 @@ protected: public: void edit(const StringName &p_sig) { sig = p_sig; - _change_notify(); + notify_property_list_changed(); } VisualScriptEditorSignalEdit() { undo_redo = nullptr; } @@ -195,11 +195,10 @@ protected: } void _var_changed() { - _change_notify(); + notify_property_list_changed(); emit_signal("changed"); } void _var_value_changed() { - _change_notify("value"); // So the whole tree is not redrawn, makes editing smoother in general. emit_signal("changed"); } @@ -331,7 +330,7 @@ protected: public: void edit(const StringName &p_var) { var = p_var; - _change_notify(); + notify_property_list_changed(); } VisualScriptEditorVariableEdit() { undo_redo = nullptr; } @@ -981,6 +980,10 @@ void VisualScriptEditor::_update_graph(int p_only_id) { } _update_graph_connections(); + + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); + // Use default_func instead of default_func for now I think that should be good stop gap solution to ensure not breaking anything. graph->call_deferred("set_scroll_ofs", script->get_scroll() * EDSCALE); updating_graph = false; @@ -3685,16 +3688,23 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_ return; } + Vector2 new_size = p_new_size; + if (graph->is_using_snap()) { + Vector2 snap = Vector2(graph->get_snap(), graph->get_snap()); + Vector2 min_size = (gn->get_minimum_size() + (snap * 0.5)).snapped(snap); + new_size = new_size.snapped(snap).max(min_size); + } + updating_graph = true; graph->set_block_minimum_size_adjust(true); //faster resize undo_redo->create_action(TTR("Resize Comment"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(vsc.ptr(), "set_size", p_new_size / EDSCALE); + undo_redo->add_do_method(vsc.ptr(), "set_size", new_size / EDSCALE); undo_redo->add_undo_method(vsc.ptr(), "set_size", vsc->get_size()); undo_redo->commit_action(); - gn->set_custom_minimum_size(p_new_size); + gn->set_custom_minimum_size(new_size); gn->set_size(Size2(1, 1)); graph->set_block_minimum_size_adjust(false); updating_graph = false; @@ -4264,13 +4274,13 @@ VisualScriptEditor::VisualScriptEditor() { edit_menu->set_shortcut_context(this); edit_menu->set_text(TTR("Edit")); edit_menu->set_switch_on_hover(true); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/delete_selected"), EDIT_DELETE_NODES); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_graph_delete"), EDIT_DELETE_NODES); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/toggle_breakpoint"), EDIT_TOGGLE_BREAKPOINT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/find_node_type"), EDIT_FIND_NODE_TYPE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/copy_nodes"), EDIT_COPY_NODES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/cut_nodes"), EDIT_CUT_NODES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/paste_nodes"), EDIT_PASTE_NODES); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY_NODES); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT_NODES); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE_NODES); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/create_function"), EDIT_CREATE_FUNCTION); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/refresh_nodes"), REFRESH_GRAPH); @@ -4326,6 +4336,8 @@ VisualScriptEditor::VisualScriptEditor() { graph->connect("duplicate_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_duplicate)); graph->connect("gui_input", callable_mp(this, &VisualScriptEditor::_graph_gui_input)); graph->set_drag_forwarding(this); + float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + graph->set_minimap_opacity(graph_minimap_opacity); graph->hide(); graph->connect("scroll_offset_changed", callable_mp(this, &VisualScriptEditor::_graph_ofs_changed)); @@ -4508,12 +4520,8 @@ void VisualScriptEditor::free_clipboard() { static void register_editor_callback() { ScriptEditor::register_create_script_editor_function(create_editor); - ED_SHORTCUT("visual_script_editor/delete_selected", TTR("Delete Selected"), KEY_DELETE); ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9); ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KEY_MASK_CMD + KEY_F); - ED_SHORTCUT("visual_script_editor/copy_nodes", TTR("Copy Nodes"), KEY_MASK_CMD + KEY_C); - ED_SHORTCUT("visual_script_editor/cut_nodes", TTR("Cut Nodes"), KEY_MASK_CMD + KEY_X); - ED_SHORTCUT("visual_script_editor/paste_nodes", TTR("Paste Nodes"), KEY_MASK_CMD + KEY_V); ED_SHORTCUT("visual_script_editor/create_function", TTR("Make Function"), KEY_MASK_CMD + KEY_G); ED_SHORTCUT("visual_script_editor/refresh_nodes", TTR("Refresh Graph"), KEY_MASK_CMD + KEY_R); ED_SHORTCUT("visual_script_editor/edit_member", TTR("Edit Member"), KEY_MASK_CMD + KEY_E); diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 9596fda95c..f673cbb06d 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -63,7 +63,7 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val } expression_dirty = true; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } @@ -1506,13 +1506,20 @@ VisualScriptNodeInstance *VisualScriptExpression::instance(VisualScriptInstance return instance; } +void VisualScriptExpression::reset_state() { + if (nodes) { + memdelete(nodes); + nodes = nullptr; + root = nullptr; + } + + error_str = String(); + error_set = false; + str_ofs = 0; + inputs.clear(); +} + VisualScriptExpression::VisualScriptExpression() { - output_type = Variant::NIL; - expression_dirty = true; - error_set = true; - root = nullptr; - nodes = nullptr; - sequenced = false; } VisualScriptExpression::~VisualScriptExpression() { diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h index 7fe665769d..c35075ea53 100644 --- a/modules/visual_script/visual_script_expression.h +++ b/modules/visual_script/visual_script_expression.h @@ -39,20 +39,18 @@ class VisualScriptExpression : public VisualScriptNode { friend class VisualScriptNodeInstanceExpression; struct Input { - Variant::Type type; + Variant::Type type = Variant::NIL; String name; - - Input() { type = Variant::NIL; } }; Vector<Input> inputs; - Variant::Type output_type; + Variant::Type output_type = Variant::NIL; String expression; - bool sequenced; - int str_ofs; - bool expression_dirty; + bool sequenced = false; + int str_ofs = 0; + bool expression_dirty = true; bool _compile_expression(); @@ -114,7 +112,7 @@ class VisualScriptExpression : public VisualScriptNode { Error _get_token(Token &r_token); String error_str; - bool error_set; + bool error_set = true; struct ENode { enum Type { @@ -131,11 +129,10 @@ class VisualScriptExpression : public VisualScriptNode { TYPE_CALL }; - ENode *next; + ENode *next = nullptr; - Type type; + Type type = Type::TYPE_SELF; - ENode() { next = nullptr; } virtual ~ENode() { if (next) { memdelete(next); @@ -144,17 +141,17 @@ class VisualScriptExpression : public VisualScriptNode { }; struct Expression { - bool is_op; + bool is_op = false; union { Variant::Operator op; - ENode *node; + ENode *node = nullptr; }; }; ENode *_parse_expression(); struct InputNode : public ENode { - int index; + int index = 0; InputNode() { type = TYPE_INPUT; } @@ -168,9 +165,9 @@ class VisualScriptExpression : public VisualScriptNode { }; struct OperatorNode : public ENode { - Variant::Operator op; + Variant::Operator op = Variant::Operator::OP_ADD; - ENode *nodes[2]; + ENode *nodes[2] = { nullptr, nullptr }; OperatorNode() { type = TYPE_OPERATOR; @@ -184,8 +181,8 @@ class VisualScriptExpression : public VisualScriptNode { }; struct IndexNode : public ENode { - ENode *base; - ENode *index; + ENode *base = nullptr; + ENode *index = nullptr; IndexNode() { type = TYPE_INDEX; @@ -193,7 +190,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct NamedIndexNode : public ENode { - ENode *base; + ENode *base = nullptr; StringName name; NamedIndexNode() { @@ -202,7 +199,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct ConstructorNode : public ENode { - Variant::Type data_type; + Variant::Type data_type = Variant::Type::NIL; Vector<ENode *> arguments; ConstructorNode() { @@ -211,7 +208,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct CallNode : public ENode { - ENode *base; + ENode *base = nullptr; StringName method; Vector<ENode *> arguments; @@ -235,7 +232,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct BuiltinFuncNode : public ENode { - VisualScriptBuiltinFunc::BuiltinFunc func; + VisualScriptBuiltinFunc::BuiltinFunc func = VisualScriptBuiltinFunc::BuiltinFunc::BYTES_TO_VAR; Vector<ENode *> arguments; BuiltinFuncNode() { type = TYPE_BUILTIN_FUNC; @@ -250,8 +247,8 @@ class VisualScriptExpression : public VisualScriptNode { return node; } - ENode *root; - ENode *nodes; + ENode *root = nullptr; + ENode *nodes = nullptr; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -259,6 +256,8 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; public: + virtual void reset_state() override; + virtual int get_output_sequence_port_count() const override; virtual bool has_input_sequence_port() const override; diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 0049e254c4..e2a8323509 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -628,7 +628,7 @@ VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_i bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) { if (String(p_name) == "case_count") { case_values.resize(p_value); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); return true; } @@ -638,7 +638,7 @@ bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) ERR_FAIL_INDEX_V(idx, case_values.size(), false); case_values.write[idx].type = Variant::Type(int(p_value)); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); return true; @@ -677,6 +677,10 @@ void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const { } } +void VisualScriptSwitch::reset_state() { + case_values.clear(); +} + void VisualScriptSwitch::_bind_methods() { } @@ -733,7 +737,7 @@ void VisualScriptTypeCast::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -747,7 +751,7 @@ void VisualScriptTypeCast::set_base_script(const String &p_path) { } script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h index 46a72bb92d..d9c4dedafd 100644 --- a/modules/visual_script/visual_script_flow_control.h +++ b/modules/visual_script/visual_script_flow_control.h @@ -202,6 +202,8 @@ protected: static void _bind_methods(); public: + virtual void reset_state() override; + virtual int get_output_sequence_port_count() const override; virtual bool has_input_sequence_port() const override; diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index d016b938de..b5aacb0506 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -281,7 +281,7 @@ void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) { } basic_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -295,7 +295,7 @@ void VisualScriptFunctionCall::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -309,7 +309,7 @@ void VisualScriptFunctionCall::set_base_script(const String &p_path) { } base_script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -328,7 +328,7 @@ void VisualScriptFunctionCall::set_singleton(const StringName &p_type) { base_type = obj->get_class(); } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -425,7 +425,7 @@ void VisualScriptFunctionCall::set_function(const StringName &p_type) { _update_method_cache(); } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -439,7 +439,7 @@ void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) { } base_path = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -453,7 +453,7 @@ void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) { } call_mode = p_mode; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -476,7 +476,7 @@ void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCa } rpc_call_mode = p_mode; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const { @@ -1067,7 +1067,7 @@ void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) { } basic_type = p_type; - _change_notify(); + notify_property_list_changed(); _update_base_type(); ports_changed_notify(); } @@ -1082,7 +1082,7 @@ void VisualScriptPropertySet::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1096,7 +1096,7 @@ void VisualScriptPropertySet::set_base_script(const String &p_path) { } base_script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1191,7 +1191,7 @@ void VisualScriptPropertySet::set_property(const StringName &p_type) { property = p_type; index = StringName(); _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1206,7 +1206,7 @@ void VisualScriptPropertySet::set_base_path(const NodePath &p_type) { base_path = p_type; _update_base_type(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1221,7 +1221,7 @@ void VisualScriptPropertySet::set_call_mode(CallMode p_mode) { call_mode = p_mode; _update_base_type(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1243,7 +1243,7 @@ void VisualScriptPropertySet::set_index(const StringName &p_type) { } index = p_type; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1259,7 +1259,7 @@ void VisualScriptPropertySet::set_assign_op(AssignOp p_op) { assign_op = p_op; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1760,7 +1760,7 @@ void VisualScriptPropertyGet::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1774,7 +1774,7 @@ void VisualScriptPropertyGet::set_base_script(const String &p_path) { } base_script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1871,7 +1871,7 @@ void VisualScriptPropertyGet::set_property(const StringName &p_type) { property = p_type; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1885,7 +1885,7 @@ void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) { } base_path = p_type; - _change_notify(); + notify_property_list_changed(); _update_base_type(); ports_changed_notify(); } @@ -1900,7 +1900,7 @@ void VisualScriptPropertyGet::set_call_mode(CallMode p_mode) { } call_mode = p_mode; - _change_notify(); + notify_property_list_changed(); _update_base_type(); ports_changed_notify(); } @@ -1915,7 +1915,7 @@ void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) { } basic_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1937,7 +1937,7 @@ void VisualScriptPropertyGet::set_index(const StringName &p_type) { } index = p_type; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2261,7 +2261,7 @@ void VisualScriptEmitSignal::set_signal(const StringName &p_type) { name = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index ae2b548f21..fed6637acb 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -57,7 +57,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value arguments.write[i].type = Variant::NIL; } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } if (String(p_name).begins_with("argument_")) { @@ -303,6 +303,14 @@ VisualScriptNodeInstance *VisualScriptFunction::instance(VisualScriptInstance *p return instance; } +void VisualScriptFunction::reset_state() { + arguments.clear(); + stack_size = 256; + stack_less = false; + sequenced = true; + rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; +} + VisualScriptFunction::VisualScriptFunction() { stack_size = 256; stack_less = false; @@ -312,7 +320,7 @@ VisualScriptFunction::VisualScriptFunction() { void VisualScriptFunction::set_stack_less(bool p_enable) { stack_less = p_enable; - _change_notify(); + notify_property_list_changed(); } bool VisualScriptFunction::is_stack_less() const { @@ -421,7 +429,7 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) { inputports.write[i].type = Variant::NIL; } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } if (String(p_name).begins_with("input_") && is_input_port_editable()) { @@ -457,7 +465,7 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) { outputports.write[i].type = Variant::NIL; } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } if (String(p_name).begins_with("output_") && is_output_port_editable()) { @@ -578,7 +586,7 @@ void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String & } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) { @@ -590,7 +598,7 @@ void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type inputports.write[p_idx].type = p_type; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) { @@ -602,7 +610,7 @@ void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name inputports.write[p_idx].name = p_name; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::remove_input_data_port(int p_argidx) { @@ -615,7 +623,7 @@ void VisualScriptLists::remove_input_data_port(int p_argidx) { inputports.remove(p_argidx); ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } // output data port interaction @@ -634,7 +642,7 @@ void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) { @@ -646,7 +654,7 @@ void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_typ outputports.write[p_idx].type = p_type; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) { @@ -658,7 +666,7 @@ void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_nam outputports.write[p_idx].name = p_name; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::remove_output_data_port(int p_argidx) { @@ -671,7 +679,7 @@ void VisualScriptLists::remove_output_data_port(int p_argidx) { outputports.remove(p_argidx); ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } // sequences @@ -687,6 +695,13 @@ bool VisualScriptLists::is_sequenced() const { return sequenced; } +void VisualScriptLists::reset_state() { + inputports.clear(); + outputports.clear(); + sequenced = false; + flags = 0; +} + VisualScriptLists::VisualScriptLists() { // initialize sequenced = false; @@ -1433,7 +1448,7 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) { Callable::CallError ce; Variant::construct(type, value, nullptr, 0, ce); ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } Variant::Type VisualScriptConstant::get_constant_type() const { @@ -1764,7 +1779,7 @@ String VisualScriptGlobalConstant::get_caption() const { void VisualScriptGlobalConstant::set_global_constant(int p_which) { index = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1850,7 +1865,7 @@ String VisualScriptClassConstant::get_caption() const { void VisualScriptClassConstant::set_class_constant(const StringName &p_which) { name = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1876,7 +1891,7 @@ void VisualScriptClassConstant::set_base_type(const StringName &p_which) { } else { name = ""; } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1983,7 +1998,7 @@ String VisualScriptBasicTypeConstant::get_text() const { void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) { name = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2010,7 +2025,7 @@ void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { } else { name = ""; } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2140,7 +2155,7 @@ String VisualScriptMathConstant::get_caption() const { void VisualScriptMathConstant::set_math_constant(MathConstant p_which) { constant = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2233,7 +2248,7 @@ String VisualScriptEngineSingleton::get_caption() const { void VisualScriptEngineSingleton::set_singleton(const String &p_string) { singleton = p_string; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2342,7 +2357,7 @@ String VisualScriptSceneNode::get_caption() const { void VisualScriptSceneNode::set_node_path(const NodePath &p_path) { path = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2620,7 +2635,7 @@ String VisualScriptResourcePath::get_caption() const { void VisualScriptResourcePath::set_resource_path(const String &p_path) { path = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -3748,7 +3763,7 @@ void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) { type = p_type; _update_elements(); ports_changed_notify(); - _change_notify(); //to make input appear/disappear + notify_property_list_changed(); //to make input appear/disappear } Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const { diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index ae5e04d096..7392443e4e 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -99,6 +99,8 @@ public: virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) override; + virtual void reset_state() override; + VisualScriptFunction(); }; @@ -134,6 +136,8 @@ protected: static void _bind_methods(); public: + virtual void reset_state() override; + virtual bool is_output_port_editable() const; virtual bool is_output_port_name_editable() const; virtual bool is_output_port_type_editable() const; diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index 6c9af4e600..25fabd7b87 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -152,7 +152,7 @@ void VisualScriptYield::set_yield_mode(YieldMode p_mode) { } yield_mode = p_mode; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } VisualScriptYield::YieldMode VisualScriptYield::get_yield_mode() { @@ -359,7 +359,7 @@ void VisualScriptYieldSignal::set_base_type(const StringName &p_type) { base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -374,7 +374,7 @@ void VisualScriptYieldSignal::set_signal(const StringName &p_type) { signal = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -389,7 +389,7 @@ void VisualScriptYieldSignal::set_base_path(const NodePath &p_type) { base_path = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -404,7 +404,7 @@ void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) { call_mode = p_mode; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 5d8245c64c..101001cba0 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -156,7 +156,7 @@ void VideoStreamPlaybackWebm::stop() { void VideoStreamPlaybackWebm::play() { stop(); - delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms"); + delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms"); delay_compensation /= 1000.0; playing = true; @@ -429,7 +429,7 @@ void VideoStreamWebm::set_audio_track(int p_track) { //////////// -RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index cb3cf58850..60e02ab38b 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -126,7 +126,7 @@ public: class ResourceFormatLoaderWebm : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp index 9f2b084cb1..dfbec80c86 100644 --- a/modules/webrtc/webrtc_data_channel_js.cpp +++ b/modules/webrtc/webrtc_data_channel_js.cpp @@ -182,16 +182,9 @@ bool WebRTCDataChannelJS::is_negotiated() const { } WebRTCDataChannelJS::WebRTCDataChannelJS() { - queue_count = 0; - _was_string = false; - _write_mode = WRITE_MODE_BINARY; - _js_id = 0; } WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) { - queue_count = 0; - _was_string = false; - _write_mode = WRITE_MODE_BINARY; _js_id = js_id; godot_js_rtc_datachannel_connect(js_id, this, &_on_open, &_on_message, &_on_error, &_on_close); diff --git a/modules/webrtc/webrtc_data_channel_js.h b/modules/webrtc/webrtc_data_channel_js.h index 8c56b62303..db58ebccff 100644 --- a/modules/webrtc/webrtc_data_channel_js.h +++ b/modules/webrtc/webrtc_data_channel_js.h @@ -42,16 +42,16 @@ private: String _label; String _protocol; - bool _was_string; - WriteMode _write_mode; + bool _was_string = false; + WriteMode _write_mode = WRITE_MODE_BINARY; enum { PACKET_BUFFER_SIZE = 65536 - 5 // 4 bytes for the size, 1 for for type }; - int _js_id; + int _js_id = 0; RingBuffer<uint8_t> in_buffer; - int queue_count; + int queue_count = 0; uint8_t packet_buffer[PACKET_BUFFER_SIZE]; static void _on_open(void *p_obj); diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index aec01a1eea..25b6d6ef0e 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -140,11 +140,7 @@ Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffe } EMWSClient::EMWSClient() { - _in_buf_size = DEF_BUF_SHIFT; - _in_pkt_size = DEF_PKT_SHIFT; - _is_connecting = false; _peer = Ref<EMWSPeer>(memnew(EMWSPeer)); - _js_id = 0; } EMWSClient::~EMWSClient() { diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index fdf7a231d2..2ab7dc83d0 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -41,10 +41,10 @@ class EMWSClient : public WebSocketClient { GDCIIMPL(EMWSClient, WebSocketClient); private: - int _js_id; - bool _is_connecting; - int _in_buf_size; - int _in_pkt_size; + int _js_id = 0; + bool _is_connecting = false; + int _in_buf_size = DEF_BUF_SHIFT; + int _in_pkt_size = DEF_PKT_SHIFT; static void _esws_on_connect(void *obj, char *proto); static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string); diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 496c1edc04..5e75e10d68 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -106,8 +106,6 @@ void EMWSPeer::set_no_delay(bool p_enabled) { } EMWSPeer::EMWSPeer() { - peer_sock = -1; - write_mode = WRITE_MODE_BINARY; close(); }; diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 07f61b62a0..abe5bf2bdb 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -56,12 +56,12 @@ class EMWSPeer : public WebSocketPeer { GDCIIMPL(EMWSPeer, WebSocketPeer); private: - int peer_sock; - WriteMode write_mode; + int peer_sock = -1; + WriteMode write_mode = WRITE_MODE_BINARY; Vector<uint8_t> _packet_buffer; PacketBuffer<uint8_t> _in_buffer; - uint8_t _is_string; + uint8_t _is_string = 0; public: Error read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string); diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp index eb0252e6d1..425013f811 100644 --- a/modules/websocket/websocket_client.cpp +++ b/modules/websocket/websocket_client.cpp @@ -33,7 +33,6 @@ GDCINULL(WebSocketClient); WebSocketClient::WebSocketClient() { - verify_ssl = true; } WebSocketClient::~WebSocketClient() { diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 78b77b89cd..0225c9b3d3 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -42,7 +42,7 @@ class WebSocketClient : public WebSocketMultiplayerPeer { protected: Ref<WebSocketPeer> _peer; - bool verify_ssl; + bool verify_ssl = true; Ref<X509Certificate> ssl_cert; static void _bind_methods(); diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index f94642475c..011cb86535 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -33,15 +33,6 @@ #include "core/os/os.h" WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() { - _is_multiplayer = false; - _peer_id = 0; - _target_peer = 0; - _refusing = false; - - _current_packet.source = 0; - _current_packet.destination = 0; - _current_packet.size = 0; - _current_packet.data = nullptr; } WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() { diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index e593163b7c..48a6607d89 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -55,20 +55,20 @@ protected: }; struct Packet { - int source; - int destination; - uint8_t *data; - uint32_t size; + int source = 0; + int destination = 0; + uint8_t *data = nullptr; + uint32_t size = 0; }; List<Packet> _incoming_packets; Map<int, Ref<WebSocketPeer>> _peer_map; Packet _current_packet; - bool _is_multiplayer; - int _target_peer; - int _peer_id; - int _refusing; + bool _is_multiplayer = false; + int _target_peer = 0; + int _peer_id = 0; + int _refusing = false; static void _bind_methods(); diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 3e2f48e9b3..a075ae3982 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -337,11 +337,6 @@ Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer } WSLClient::WSLClient() { - _in_buf_size = DEF_BUF_SHIFT; - _in_pkt_size = DEF_PKT_SHIFT; - _out_buf_size = DEF_BUF_SHIFT; - _out_pkt_size = DEF_PKT_SHIFT; - _peer.instance(); _tcp.instance(); disconnect_from_host(); diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 8712b57f2c..e7c91ed333 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -44,27 +44,27 @@ class WSLClient : public WebSocketClient { GDCIIMPL(WSLClient, WebSocketClient); private: - int _in_buf_size; - int _in_pkt_size; - int _out_buf_size; - int _out_pkt_size; + int _in_buf_size = DEF_BUF_SHIFT; + int _in_pkt_size = DEF_PKT_SHIFT; + int _out_buf_size = DEF_BUF_SHIFT; + int _out_pkt_size = DEF_PKT_SHIFT; Ref<WSLPeer> _peer; Ref<StreamPeerTCP> _tcp; Ref<StreamPeer> _connection; CharString _request; - int _requested; + int _requested = 0; uint8_t _resp_buf[WSL_MAX_HEADER_SIZE]; - int _resp_pos; + int _resp_pos = 0; String _response; String _key; String _host; Vector<String> _protocols; - bool _use_ssl; + bool _use_ssl = false; void _do_handshake(); bool _verify_headers(String &r_protocol); diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 9d016e1139..dbbf86d0da 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -329,10 +329,6 @@ void WSLPeer::invalidate() { } WSLPeer::WSLPeer() { - _data = nullptr; - _is_string = 0; - close_code = -1; - write_mode = WRITE_MODE_BINARY; } WSLPeer::~WSLPeer() { diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index 01efa4b21e..5e6a7e8554 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -48,29 +48,17 @@ class WSLPeer : public WebSocketPeer { public: struct PeerData { - bool polling; - bool destroy; - bool valid; - bool is_server; - bool closing; - void *obj; - void *peer; + bool polling = false; + bool destroy = false; + bool valid = false; + bool is_server = false; + bool closing = false; + void *obj = nullptr; + void *peer = nullptr; Ref<StreamPeer> conn; Ref<StreamPeerTCP> tcp; - int id; - wslay_event_context_ptr ctx; - - PeerData() { - polling = false; - destroy = false; - valid = false; - is_server = false; - id = 1; - ctx = nullptr; - obj = nullptr; - closing = false; - peer = nullptr; - } + int id = 1; + wslay_event_context_ptr ctx = nullptr; }; static String compute_key_response(String p_key); @@ -80,17 +68,17 @@ private: static bool _wsl_poll(struct PeerData *p_data); static void _wsl_destroy(struct PeerData **p_data); - struct PeerData *_data; - uint8_t _is_string; + struct PeerData *_data = nullptr; + uint8_t _is_string = 0; // Our packet info is just a boolean (is_string), using uint8_t for it. PacketBuffer<uint8_t> _in_buffer; Vector<uint8_t> _packet_buffer; - WriteMode write_mode; + WriteMode write_mode = WRITE_MODE_BINARY; public: - int close_code; + int close_code = -1; String close_reason; void poll(); // Used by client and server. diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 9df076bf3f..437eb2061b 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -34,15 +34,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" -WSLServer::PendingPeer::PendingPeer() { - use_ssl = false; - time = 0; - has_request = false; - response_sent = 0; - req_pos = 0; - memset(req_buf, 0, sizeof(req_buf)); -} - bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) { Vector<String> psa = String((char *)req_buf).split("\r\n"); int len = psa.size(); @@ -310,10 +301,6 @@ Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer } WSLServer::WSLServer() { - _in_buf_size = DEF_BUF_SHIFT; - _in_pkt_size = DEF_PKT_SHIFT; - _out_buf_size = DEF_BUF_SHIFT; - _out_pkt_size = DEF_PKT_SHIFT; _server.instance(); } diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 8b2d4d3a04..75669e12ee 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -53,26 +53,24 @@ private: public: Ref<StreamPeerTCP> tcp; Ref<StreamPeer> connection; - bool use_ssl; + bool use_ssl = false; - int time; - uint8_t req_buf[WSL_MAX_HEADER_SIZE]; - int req_pos; + int time = 0; + uint8_t req_buf[WSL_MAX_HEADER_SIZE] = {}; + int req_pos = 0; String key; String protocol; - bool has_request; + bool has_request = false; CharString response; - int response_sent; - - PendingPeer(); + int response_sent = 0; Error do_handshake(const Vector<String> p_protocols); }; - int _in_buf_size; - int _in_pkt_size; - int _out_buf_size; - int _out_pkt_size; + int _in_buf_size = DEF_BUF_SHIFT; + int _in_pkt_size = DEF_PKT_SHIFT; + int _out_buf_size = DEF_BUF_SHIFT; + int _out_pkt_size = DEF_PKT_SHIFT; List<Ref<PendingPeer>> _pending; Ref<TCP_Server> _server; diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml index bddffd910e..2407d44496 100644 --- a/modules/webxr/doc_classes/WebXRInterface.xml +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -10,75 +10,79 @@ Since WebXR is based on Javascript, it makes extensive use of callbacks, which means that [WebXRInterface] is forced to use signals, where other AR/VR interfaces would instead use functions that return a result immediately. This makes [WebXRInterface] quite a bit more complicated to intialize than other AR/VR interfaces. Here's the minimum code required to start an immersive VR session: [codeblock] - var webxr_interface - var vr_supported = false + extends Node3D - func _ready(): - # We assume this node has a canvas layer with a button on it as a child. - # This button is for the user to consent to entering immersive VR mode. - $CanvasLayer/Button.connect("pressed", self, "_on_Button_pressed") + var webxr_interface + var vr_supported = false - webxr_interface = XRServer.find_interface("WebXR") - if webxr_interface: - # WebXR uses a lot of asynchronous callbacks, so we connect to various - # signals in order to receive them. - webxr_interface.connect("session_supported", self, "_webxr_session_supported") - webxr_interface.connect("session_started", self, "_webxr_session_started") - webxr_interface.connect("session_ended", self, "_webxr_session_ended") - webxr_interface.connect("session_failed", self, "_webxr_session_failed") + func _ready(): + # We assume this node has a button as a child. + # This button is for the user to consent to entering immersive VR mode. + $Button.connect("pressed", self, "_on_Button_pressed") - # This returns immediately - our _webxr_session_supported() method - # (which we connected to the "session_supported" signal above) will - # be called sometime later to let us know if it's supported or not. - webxr_interface.is_session_supported("immersive-vr") + webxr_interface = XRServer.find_interface("WebXR") + if webxr_interface: + # WebXR uses a lot of asynchronous callbacks, so we connect to various + # signals in order to receive them. + webxr_interface.connect("session_supported", self, "_webxr_session_supported") + webxr_interface.connect("session_started", self, "_webxr_session_started") + webxr_interface.connect("session_ended", self, "_webxr_session_ended") + webxr_interface.connect("session_failed", self, "_webxr_session_failed") - func _webxr_session_supported(session_mode, supported): - if session_mode == 'immersive-vr': - vr_supported = supported + # This returns immediately - our _webxr_session_supported() method + # (which we connected to the "session_supported" signal above) will + # be called sometime later to let us know if it's supported or not. + webxr_interface.is_session_supported("immersive-vr") - func _on_Button_pressed(): - if not vr_supported: - OS.alert("Your browser doesn't support VR") - return + func _webxr_session_supported(session_mode, supported): + if session_mode == 'immersive-vr': + vr_supported = supported - # We want an immersive VR session, as opposed to AR ('immersive-ar') or a - # simple 3DoF viewer ('viewer'). - webxr_interface.session_mode = 'immersive-vr' - # 'bounded-floor' is room scale, 'local-floor' is a standing or sitting - # experience (it puts you 1.6m above the ground if you have 3DoF headset), - # whereas as 'local' puts you down at the XROrigin. - # This list means it'll first try to request 'bounded-floor', then - # fallback on 'local-floor' and ultimately 'local', if nothing else is - # supported. - webxr_interface.requested_reference_space_types = 'bounded-floor, local-floor, local' - # In order to use 'local-floor' or 'bounded-floor' we must also - # mark the features as required or optional. - webxr_interface.required_features = 'local-floor' - webxr_interface.optional_features = 'bounded-floor' + func _on_Button_pressed(): + if not vr_supported: + OS.alert("Your browser doesn't support VR") + return - # This will return false if we're unable to even request the session, - # however, it can still fail asynchronously later in the process, so we - # only know if it's really succeeded or failed when our - # _webxr_session_started() or _webxr_session_failed() methods are called. - if not webxr_interface.initialize(): - OS.alert("Failed to initialize") - return + # We want an immersive VR session, as opposed to AR ('immersive-ar') or a + # simple 3DoF viewer ('viewer'). + webxr_interface.session_mode = 'immersive-vr' + # 'bounded-floor' is room scale, 'local-floor' is a standing or sitting + # experience (it puts you 1.6m above the ground if you have 3DoF headset), + # whereas as 'local' puts you down at the XROrigin. + # This list means it'll first try to request 'bounded-floor', then + # fallback on 'local-floor' and ultimately 'local', if nothing else is + # supported. + webxr_interface.requested_reference_space_types = 'bounded-floor, local-floor, local' + # In order to use 'local-floor' or 'bounded-floor' we must also + # mark the features as required or optional. + webxr_interface.required_features = 'local-floor' + webxr_interface.optional_features = 'bounded-floor' - func _webxr_session_started(): - # This tells Godot to start rendering to the headset. - get_viewport().xr = true - # This will be the reference space type you ultimately got, out of the - # types that you requested above. This is useful if you want the game to - # work a little differently in 'bounded-floor' versus 'local-floor'. - print ("Reference space type: " + webxr_interface.reference_space_type) + # This will return false if we're unable to even request the session, + # however, it can still fail asynchronously later in the process, so we + # only know if it's really succeeded or failed when our + # _webxr_session_started() or _webxr_session_failed() methods are called. + if not webxr_interface.initialize(): + OS.alert("Failed to initialize") + return - func _webxr_session_ended(): - # If the user exits immersive mode, then we tell Godot to render to the web - # page again. - get_viewport().xr = false + func _webxr_session_started(): + $Button.visible = false + # This tells Godot to start rendering to the headset. + get_viewport().xr = true + # This will be the reference space type you ultimately got, out of the + # types that you requested above. This is useful if you want the game to + # work a little differently in 'bounded-floor' versus 'local-floor'. + print ("Reference space type: " + webxr_interface.reference_space_type) - func _webxr_session_failed(message): - OS.alert("Failed to initialize: " + message) + func _webxr_session_ended(): + $Button.visible = true + # If the user exits immersive mode, then we tell Godot to render to the web + # page again. + get_viewport().xr = false + + func _webxr_session_failed(message): + OS.alert("Failed to initialize: " + message) [/codeblock] There are several ways to handle "controller" input: - Using [XRController3D] nodes and their [signal XRController3D.button_pressed] and [signal XRController3D.button_released] signals. This is how controllers are typically handled in AR/VR apps in Godot, however, this will only work with advanced VR controllers like the Oculus Touch or Index controllers, for example. The buttons codes are defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url]. diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h index 5e50ffde28..41a690f473 100644 --- a/modules/webxr/godot_webxr.h +++ b/modules/webxr/godot_webxr.h @@ -61,6 +61,7 @@ extern void godot_webxr_initialize( GodotWebXRSimpleEventCallback p_on_simple_event); extern void godot_webxr_uninitialize(); +extern int godot_webxr_get_view_count(); extern int *godot_webxr_get_render_targetsize(); extern float *godot_webxr_get_transform_for_eye(int p_eye); extern float *godot_webxr_get_projection_for_eye(int p_eye); diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js index 447045ed27..8e9ef8a73c 100644 --- a/modules/webxr/native/library_godot_webxr.js +++ b/modules/webxr/native/library_godot_webxr.js @@ -380,6 +380,11 @@ const GodotWebXR = { gl.deleteTexture(texture); } GodotWebXR.textures[i] = null; + + const texture_id = GodotWebXR.texture_ids[i]; + if (texture_id !== null) { + GL.textures[texture_id] = null; + } GodotWebXR.texture_ids[i] = null; } @@ -394,6 +399,15 @@ const GodotWebXR = { GodotWebXR.pauseResumeMainLoop(); }, + godot_webxr_get_view_count__proxy: 'sync', + godot_webxr_get_view_count__sig: 'i', + godot_webxr_get_view_count: function () { + if (!GodotWebXR.session || !GodotWebXR.pose) { + return 0; + } + return GodotWebXR.pose.views.length; + }, + godot_webxr_get_render_targetsize__proxy: 'sync', godot_webxr_get_render_targetsize__sig: 'i', godot_webxr_get_render_targetsize: function () { @@ -451,7 +465,7 @@ const GodotWebXR = { godot_webxr_get_external_texture_for_eye__proxy: 'sync', godot_webxr_get_external_texture_for_eye__sig: 'ii', godot_webxr_get_external_texture_for_eye: function (p_eye) { - if (!GodotWebXR.session || !GodotWebXR.pose) { + if (!GodotWebXR.session) { return 0; } @@ -460,6 +474,13 @@ const GodotWebXR = { return GodotWebXR.texture_ids[view_index]; } + // Check pose separately and after returning the cached texture id, + // because we won't get a pose in some cases if we lose tracking, and + // we don't want to return 0 just because tracking was lost. + if (!GodotWebXR.pose) { + return 0; + } + const glLayer = GodotWebXR.session.renderState.baseLayer; const view = GodotWebXR.pose.views[view_index]; const viewport = glLayer.getViewport(view); @@ -601,7 +622,13 @@ const GodotWebXR = { const buf = GodotRuntime.malloc((axes_count + 1) * 4); GodotRuntime.setHeapValue(buf, axes_count, 'i32'); for (let i = 0; i < axes_count; i++) { - GodotRuntime.setHeapValue(buf + 4 + (i * 4), controller.gamepad.axes[i], 'float'); + let value = controller.gamepad.axes[i]; + if (i === 1 || i === 3) { + // Invert the Y-axis on thumbsticks and trackpads, in order to + // match OpenXR and other XR platform SDKs. + value *= -1.0; + } + GodotRuntime.setHeapValue(buf + 4 + (i * 4), value, 'float'); } return buf; }, diff --git a/modules/webxr/native/webxr.externs.js b/modules/webxr/native/webxr.externs.js index 03dc05bc83..9ea105aa93 100644 --- a/modules/webxr/native/webxr.externs.js +++ b/modules/webxr/native/webxr.externs.js @@ -33,7 +33,7 @@ XR.prototype.ondevicechanged; * * @return {!Promise<boolean>} */ -XR.prototype.isSessionSupported = function(mode) {} +XR.prototype.isSessionSupported = function(mode) {}; /** * @param {string} mode @@ -41,7 +41,7 @@ XR.prototype.isSessionSupported = function(mode) {} * * @return {!Promise<XRSession>} */ -XR.prototype.requestSession = function(mode, options) {} +XR.prototype.requestSession = function(mode, options) {}; /** * @constructor diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index 72dc4790ac..74789fc98e 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -78,6 +78,8 @@ void _emwebxr_on_session_failed(char *p_message) { Ref<XRInterface> interface = xr_server->find_interface("WebXR"); ERR_FAIL_COND(interface.is_null()); + interface->uninitialize(); + String message = String(p_message); interface->emit_signal("session_failed", message); } @@ -197,12 +199,11 @@ StringName WebXRInterfaceJS::get_name() const { }; int WebXRInterfaceJS::get_capabilities() const { - return XRInterface::XR_STEREO; + return XRInterface::XR_STEREO | XRInterface::XR_MONO; }; bool WebXRInterfaceJS::is_stereo() { - // @todo WebXR can be mono! So, how do we know? Count the views in the frame? - return true; + return godot_webxr_get_view_count() == 2; }; bool WebXRInterfaceJS::is_initialized() const { @@ -225,6 +226,12 @@ bool WebXRInterfaceJS::initialize() { // make this our primary interface xr_server->set_primary_interface(this); + // Clear render_targetsize to make sure it gets reset to the new size. + // Clearing in uninitialize() doesn't work because a frame can still be + // rendered after it's called, which will fill render_targetsize again. + render_targetsize.width = 0; + render_targetsize.height = 0; + initialized = true; godot_webxr_initialize( @@ -278,22 +285,24 @@ Transform WebXRInterfaceJS::_js_matrix_to_transform(float *p_js_matrix) { } Size2 WebXRInterfaceJS::get_render_targetsize() { - Size2 target_size; + if (render_targetsize.width != 0 && render_targetsize.height != 0) { + return render_targetsize; + } int *js_size = godot_webxr_get_render_targetsize(); if (!initialized || js_size == nullptr) { - // As a default, use half the window size. - target_size = DisplayServer::get_singleton()->window_get_size(); - target_size.width /= 2.0; - return target_size; + // As a temporary default (until WebXR is fully initialized), use half the window size. + Size2 temp = DisplayServer::get_singleton()->window_get_size(); + temp.width /= 2.0; + return temp; } - target_size.width = js_size[0]; - target_size.height = js_size[1]; + render_targetsize.width = js_size[0]; + render_targetsize.height = js_size[1]; free(js_size); - return target_size; + return render_targetsize; }; Transform WebXRInterfaceJS::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { @@ -375,11 +384,11 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) { if (godot_webxr_is_controller_connected(p_controller_id)) { if (tracker == nullptr) { tracker = memnew(XRPositionalTracker); - tracker->set_type(XRServer::TRACKER_CONTROLLER); + tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); // Controller id's 0 and 1 are always the left and right hands. if (p_controller_id < 2) { - tracker->set_name(p_controller_id == 0 ? "Left" : "Right"); - tracker->set_hand(p_controller_id == 0 ? XRPositionalTracker::TRACKER_LEFT_HAND : XRPositionalTracker::TRACKER_RIGHT_HAND); + tracker->set_tracker_name(p_controller_id == 0 ? "Left" : "Right"); + tracker->set_tracker_hand(p_controller_id == 0 ? XRPositionalTracker::TRACKER_HAND_LEFT : XRPositionalTracker::TRACKER_HAND_RIGHT); } // Use the ids we're giving to our "virtual" gamepads. tracker->set_joy_id(p_controller_id + 100); diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index 93da9a6d12..49299b252f 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -47,7 +47,6 @@ class WebXRInterfaceJS : public WebXRInterface { private: bool initialized; - // @todo Should these really use enums instead of strings? String session_mode; String required_features; String optional_features; @@ -55,6 +54,7 @@ private: String reference_space_type; bool controllers_state[2]; + Size2 render_targetsize; Transform _js_matrix_to_transform(float *p_js_matrix); void _update_tracker(int p_controller_id); diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 9f6e7efb27..fb4df10904 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -154,6 +154,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver float h = *r_size_hint_y; if (w == 0 || h == 0) { + xatlas::Destroy(atlas); return false; //could not bake because there is no area } @@ -163,8 +164,8 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver *r_uvs = (float *)malloc(sizeof(float) * output.vertexCount * 2); *r_indices = (int *)malloc(sizeof(int) * output.indexCount); - float max_x = 0; - float max_y = 0; + float max_x = 0.0; + float max_y = 0.0; for (uint32_t i = 0; i < output.vertexCount; i++) { (*r_vertices)[i] = output.vertexArray[i].xref; (*r_uvs)[i * 2 + 0] = output.vertexArray[i].uv[0] / w; diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h index 49c0104e67..965eaabf81 100644 --- a/platform/android/api/jni_singleton.h +++ b/platform/android/api/jni_singleton.h @@ -83,7 +83,7 @@ public: v = (jvalue *)alloca(sizeof(jvalue) * p_argcount); } - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); int res = env->PushLocalFrame(16); diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index 825132ac8c..3a2ccac481 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -72,10 +72,10 @@ Error AudioDriverAndroid::init() { // __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device"); - JNIEnv *env = ThreadAndroid::get_env(); - int mix_rate = GLOBAL_GET("audio/mix_rate"); + JNIEnv *env = get_jni_env(); + int mix_rate = GLOBAL_GET("audio/driver/mix_rate"); - int latency = GLOBAL_GET("audio/output_latency"); + int latency = GLOBAL_GET("audio/driver/output_latency"); unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000); print_verbose("Audio buffer size: " + itos(buffer_size)); @@ -98,7 +98,7 @@ void AudioDriverAndroid::start() { } void AudioDriverAndroid::setup(jobject p_io) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); io = p_io; jclass c = env->GetObjectClass(io); @@ -162,7 +162,7 @@ void AudioDriverAndroid::unlock() { } void AudioDriverAndroid::finish() { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(io, _quit); if (audioBuffer) { @@ -175,7 +175,7 @@ void AudioDriverAndroid::finish() { } void AudioDriverAndroid::set_pause(bool p_pause) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(io, _pause, p_pause); } diff --git a/platform/android/detect.py b/platform/android/detect.py index 650606ff8b..5f0fcc9b77 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -13,7 +13,7 @@ def get_name(): def can_build(): - return "ANDROID_NDK_ROOT" in os.environ + return ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ) def get_platform(platform): @@ -24,13 +24,33 @@ def get_opts(): from SCons.Variables import BoolVariable, EnumVariable return [ - ("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)), + ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()), + ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()), ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"), EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")), BoolVariable("android_neon", "Enable NEON support (armv7 only)", True), ] +# Return the ANDROID_SDK_ROOT environment variable. +# While ANDROID_HOME has been deprecated, it's used as a fallback for backward +# compatibility purposes. +def get_android_sdk_root(): + if "ANDROID_SDK_ROOT" in os.environ: + return os.environ.get("ANDROID_SDK_ROOT", 0) + else: + return os.environ.get("ANDROID_HOME", 0) + + +# Return the ANDROID_NDK_ROOT environment variable. +# We generate one for this build using the ANDROID_SDK_ROOT env +# variable and the project ndk version. +# If the env variable is already defined, we override it with +# our own to match what the project expects. +def get_android_ndk_root(): + return get_android_sdk_root() + "/ndk/" + get_project_ndk_version() + + def get_flags(): return [ ("tools", False), @@ -47,7 +67,31 @@ def create(env): return env.Clone(tools=tools) +# Check if ANDROID_NDK_ROOT is valid. +# If not, install the ndk using ANDROID_SDK_ROOT and sdkmanager. +def install_ndk_if_needed(env): + print("Checking for Android NDK...") + env_ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"]) + if env_ndk_version is None: + # Reinstall the ndk and update ANDROID_NDK_ROOT. + print("Installing Android NDK...") + if env["ANDROID_SDK_ROOT"] is None: + raise Exception("Invalid ANDROID_SDK_ROOT environment variable.") + + import subprocess + + extension = ".bat" if os.name == "nt" else "" + sdkmanager_path = env["ANDROID_SDK_ROOT"] + "/cmdline-tools/latest/bin/sdkmanager" + extension + ndk_download_args = "ndk;" + get_project_ndk_version() + subprocess.check_call([sdkmanager_path, ndk_download_args]) + + env["ANDROID_NDK_ROOT"] = env["ANDROID_SDK_ROOT"] + "/ndk/" + get_project_ndk_version() + print("ANDROID_NDK_ROOT: " + env["ANDROID_NDK_ROOT"]) + + def configure(env): + install_ndk_if_needed(env) + # Workaround for MinGW. See: # http://www.scons.org/wiki/LongCmdLinesOnWin32 if os.name == "nt": @@ -270,7 +314,7 @@ def configure(env): # Link flags - ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"]) + ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"]) if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"): env.Append(LINKFLAGS=["-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"]) else: @@ -323,8 +367,14 @@ def configure(env): env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"]) +# Return the project NDK version. +# This is kept in sync with the value in 'platform/android/java/app/config.gradle'. +def get_project_ndk_version(): + return "21.4.7075529" + + # Return NDK version string in source.properties (adapted from the Chromium project). -def get_ndk_version(path): +def get_env_ndk_version(path): if path is None: return None prop_file_path = os.path.join(path, "source.properties") diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 78685991a8..f8ac29c738 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -47,7 +47,7 @@ DirAccess *DirAccessJAndroid::create_fs() { Error DirAccessJAndroid::list_dir_begin() { list_dir_end(); - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring js = env->NewStringUTF(current_dir.utf8().get_data()); int res = env->CallIntMethod(io, _dir_open, js); @@ -62,7 +62,7 @@ Error DirAccessJAndroid::list_dir_begin() { String DirAccessJAndroid::get_next() { ERR_FAIL_COND_V(id == 0, ""); - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring str = (jstring)env->CallObjectMethod(io, _dir_next, id); if (!str) return ""; @@ -73,7 +73,7 @@ String DirAccessJAndroid::get_next() { } bool DirAccessJAndroid::current_is_dir() const { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallBooleanMethod(io, _dir_is_dir, id); } @@ -86,7 +86,7 @@ void DirAccessJAndroid::list_dir_end() { if (id == 0) return; - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(io, _dir_close, id); id = 0; } @@ -100,7 +100,7 @@ String DirAccessJAndroid::get_drive(int p_drive) { } Error DirAccessJAndroid::change_dir(String p_dir) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == "")) return OK; @@ -154,7 +154,7 @@ bool DirAccessJAndroid::file_exists(String p_file) { } bool DirAccessJAndroid::dir_exists(String p_dir) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); String sd; @@ -207,7 +207,7 @@ size_t DirAccessJAndroid::get_space_left() { } void DirAccessJAndroid::setup(jobject p_io) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); io = p_io; jclass c = env->GetObjectClass(io); diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 08ee410a96..326e513261 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -37,6 +37,7 @@ #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" +#include "core/templates/safe_refcount.h" #include "core/version.h" #include "drivers/png/png_driver_common.h" #include "editor/editor_export.h" @@ -202,6 +203,19 @@ static const char *android_perms[] = { static const char *SPLASH_IMAGE_EXPORT_PATH = "res/drawable/splash.png"; static const char *SPLASH_BG_COLOR_PATH = "res/drawable/splash_bg_color.png"; +static const char *SPLASH_CONFIG_PATH = "res://android/build/res/drawable/splash_drawable.xml"; + +const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:drawable="@drawable/splash_bg_color" /> + <item> + <bitmap + android:gravity="%s" + android:filter="%s" + android:src="@drawable/splash" /> + </item> +</layer-list> +)SPLASH"; struct LauncherIcon { const char *export_path; @@ -261,41 +275,41 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { EditorProgress *ep = nullptr; }; - Vector<PluginConfig> plugins; + Vector<PluginConfigAndroid> plugins; String last_plugin_names; uint64_t last_custom_build_time = 0; - volatile bool plugins_changed; + SafeFlag plugins_changed; Mutex plugins_lock; Vector<Device> devices; - volatile bool devices_changed; + SafeFlag devices_changed; Mutex device_lock; - Thread *check_for_changes_thread; - volatile bool quit_request; + Thread check_for_changes_thread; + SafeFlag quit_request; static void _check_for_changes_poll_thread(void *ud) { EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud; - while (!ea->quit_request) { + while (!ea->quit_request.is_set()) { // Check for plugins updates { // Nothing to do if we already know the plugins have changed. - if (!ea->plugins_changed) { - Vector<PluginConfig> loaded_plugins = get_plugins(); + if (!ea->plugins_changed.is_set()) { + Vector<PluginConfigAndroid> loaded_plugins = get_plugins(); MutexLock lock(ea->plugins_lock); if (ea->plugins.size() != loaded_plugins.size()) { - ea->plugins_changed = true; + ea->plugins_changed.set(); } else { for (int i = 0; i < ea->plugins.size(); i++) { if (ea->plugins[i].name != loaded_plugins[i].name) { - ea->plugins_changed = true; + ea->plugins_changed.set(); break; } } } - if (ea->plugins_changed) { + if (ea->plugins_changed.is_set()) { ea->plugins = loaded_plugins; } } @@ -308,7 +322,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { List<String> args; args.push_back("devices"); int ec; - OS::get_singleton()->execute(adb, args, true, nullptr, &devices, &ec); + OS::get_singleton()->execute(adb, args, &devices, &ec); Vector<String> ds = devices.split("\n"); Vector<String> ldevices; @@ -361,7 +375,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int ec2; String dp; - OS::get_singleton()->execute(adb, args, true, nullptr, &dp, &ec2); + OS::get_singleton()->execute(adb, args, &dp, &ec2); Vector<String> props = dp.split("\n"); String vendor; @@ -409,7 +423,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } ea->devices = ndevices; - ea->devices_changed = true; + ea->devices_changed.set(); } } @@ -418,7 +432,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { uint64_t time = OS::get_singleton()->get_ticks_usec(); while (OS::get_singleton()->get_ticks_usec() - time < wait) { OS::get_singleton()->delay_usec(1000 * sleep); - if (ea->quit_request) { + if (ea->quit_request.is_set()) { break; } } @@ -432,7 +446,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { List<String> args; args.push_back("kill-server"); - OS::get_singleton()->execute(adb, args, true); + OS::get_singleton()->execute(adb, args); }; } @@ -629,7 +643,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { continue; } - if (file.ends_with(PLUGIN_CONFIG_EXT)) { + if (file.ends_with(PluginConfigAndroid::PLUGIN_CONFIG_EXT)) { dir_files.push_back(file); } } @@ -639,8 +653,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { return dir_files; } - static Vector<PluginConfig> get_plugins() { - Vector<PluginConfig> loaded_plugins; + static Vector<PluginConfigAndroid> get_plugins() { + Vector<PluginConfigAndroid> loaded_plugins; String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/plugins"); @@ -653,7 +667,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { if (!plugins_filenames.is_empty()) { Ref<ConfigFile> config_file = memnew(ConfigFile); for (int i = 0; i < plugins_filenames.size(); i++) { - PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i])); + PluginConfigAndroid config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i])); if (config.valid_config) { loaded_plugins.push_back(config); } else { @@ -666,11 +680,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { return loaded_plugins; } - static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) { - Vector<PluginConfig> enabled_plugins; - Vector<PluginConfig> all_plugins = get_plugins(); + static Vector<PluginConfigAndroid> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) { + Vector<PluginConfigAndroid> enabled_plugins; + Vector<PluginConfigAndroid> all_plugins = get_plugins(); for (int i = 0; i < all_plugins.size(); i++) { - PluginConfig plugin = all_plugins[i]; + PluginConfigAndroid plugin = all_plugins[i]; bool enabled = p_presets->get("plugins/" + plugin.name); if (enabled) { enabled_plugins.push_back(plugin); @@ -775,6 +789,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) { + print_verbose("Building temporary manifest.."); String manifest_text = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" @@ -791,10 +806,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { manifest_text += _get_xr_features_tag(p_preset); manifest_text += _get_instrumentation_tag(p_preset); - String plugins_names = get_plugins_names(get_enabled_plugins(p_preset)); - manifest_text += _get_application_tag(p_preset, plugins_names); + manifest_text += _get_application_tag(p_preset); manifest_text += "</manifest>\n"; String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release")); + + print_verbose("Storing manifest into " + manifest_path + ": " + "\n" + manifest_text); store_string_at_path(manifest_path, manifest_text); } @@ -839,8 +855,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int xr_mode_index = p_preset->get("xr_features/xr_mode"); bool focus_awareness = p_preset->get("xr_features/focus_awareness"); - String plugins_names = get_plugins_names(get_enabled_plugins(p_preset)); - Vector<String> perms; // Write permissions into the perms variable. _get_permissions(p_preset, p_give_internet, perms); @@ -978,11 +992,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { encode_uint32(xr_mode_index == /* XRMode.OVR */ 1 && focus_awareness ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); } - if (tname == "meta-data" && attrname == "value" && value == "plugins_value" && !plugins_names.is_empty()) { - // Update the meta-data 'android:value' attribute with the list of enabled plugins. - string_table.write[attr_value] = plugins_names; - } - is_focus_aware_metadata = tname == "meta-data" && attrname == "name" && value == "com.oculus.vr.focusaware"; iofs += 20; } @@ -1470,20 +1479,26 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } } - void load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) { - // TODO: Figure out how to handle remaining boot splash parameters (e.g: fullsize, filter) + String load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) { + bool scale_splash = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize"); + bool apply_filter = ProjectSettings::get_singleton()->get("application/boot_splash/use_filter"); String project_splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); if (!project_splash_path.is_empty()) { splash_image.instance(); + print_verbose("Loading splash image: " + project_splash_path); const Error err = ImageLoader::load_image(project_splash_path, splash_image); if (err) { + if (OS::get_singleton()->is_stdout_verbose()) { + print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")"); + } splash_image.unref(); } } if (splash_image.is_null()) { // Use the default + print_verbose("Using default splash image."); splash_image = Ref<Image>(memnew(Image(boot_splash_png))); } @@ -1494,9 +1509,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { bg_color = boot_splash_bg_color; } + print_verbose("Creating splash background color image."); splash_bg_color_image.instance(); splash_bg_color_image->create(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format()); splash_bg_color_image->fill(bg_color); + + String gravity = scale_splash ? "fill" : "center"; + String processed_splash_config_xml = vformat(SPLASH_CONFIG_XML_CONTENT, gravity, bool_to_string(apply_filter)); + return processed_splash_config_xml; } void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) { @@ -1508,19 +1528,24 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { // Regular icon: user selection -> project icon -> default. String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges(); + print_verbose("Loading regular icon from " + path); if (path.is_empty() || ImageLoader::load_image(path, icon) != OK) { + print_verbose("- falling back to project icon: " + project_icon_path); ImageLoader::load_image(project_icon_path, icon); } // Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default). path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges(); + print_verbose("Loading adaptive foreground icon from " + path); if (path.is_empty() || ImageLoader::load_image(path, foreground) != OK) { + print_verbose("- falling back to using the regular icon"); foreground = icon; } // Adaptive background: user selection -> default. path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges(); if (!path.is_empty()) { + print_verbose("Loading adaptive background icon from " + path); ImageLoader::load_image(path, background); } } @@ -1535,13 +1560,21 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, + const String &processed_splash_config_xml, const Ref<Image> &splash_image, const Ref<Image> &splash_bg_color_image, const Ref<Image> &main_image, const Ref<Image> &foreground, const Ref<Image> &background) { + // Store the splash configuration + if (!processed_splash_config_xml.is_empty()) { + print_verbose("Storing processed splash configuration: " + String("\n") + processed_splash_config_xml); + store_string_at_path(SPLASH_CONFIG_PATH, processed_splash_config_xml); + } + // Store the splash image if (splash_image.is_valid() && !splash_image->is_empty()) { + print_verbose("Storing splash image in " + String(SPLASH_IMAGE_EXPORT_PATH)); Vector<uint8_t> data; _load_image_data(splash_image, data); store_image(SPLASH_IMAGE_EXPORT_PATH, data); @@ -1549,6 +1582,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { // Store the splash bg color image if (splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) { + print_verbose("Storing splash background image in " + String(SPLASH_BG_COLOR_PATH)); Vector<uint8_t> data; _load_image_data(splash_bg_color_image, data); store_image(SPLASH_BG_COLOR_PATH, data); @@ -1559,12 +1593,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { for (int i = 0; i < icon_densities_count; ++i) { if (main_image.is_valid() && !main_image->is_empty()) { + print_verbose("Processing launcher icon for dimension " + itos(launcher_icons[i].dimensions) + " into " + launcher_icons[i].export_path); Vector<uint8_t> data; _process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data); store_image(launcher_icons[i], data); } if (foreground.is_valid() && !foreground->is_empty()) { + print_verbose("Processing launcher adaptive icon foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path); Vector<uint8_t> data; _process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground, launcher_adaptive_icon_foregrounds[i].dimensions, data); @@ -1572,6 +1608,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } if (background.is_valid() && !background->is_empty()) { + print_verbose("Processing launcher adaptive icon background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path); Vector<uint8_t> data; _process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background, launcher_adaptive_icon_backgrounds[i].dimensions, data); @@ -1597,7 +1634,7 @@ public: public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override { - String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); + String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); if (driver == "GLES2") { r_features->push_back("etc"); } @@ -1618,12 +1655,12 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK)); - Vector<PluginConfig> plugins_configs = get_plugins(); + Vector<PluginConfigAndroid> plugins_configs = get_plugins(); for (int i = 0; i < plugins_configs.size(); i++) { print_verbose("Found Android plugin " + plugins_configs[i].name); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + plugins_configs[i].name), false)); } - plugins_changed = false; + plugins_changed.clear(); Vector<String> abis = get_abis(); for (int i = 0; i < abis.size(); ++i) { @@ -1693,19 +1730,19 @@ public: } virtual bool should_update_export_options() override { - bool export_options_changed = plugins_changed; + bool export_options_changed = plugins_changed.is_set(); if (export_options_changed) { // don't clear unless we're reporting true, to avoid race - plugins_changed = false; + plugins_changed.clear(); } return export_options_changed; } virtual bool poll_export() override { - bool dc = devices_changed; + bool dc = devices_changed.is_set(); if (dc) { // don't clear unless we're reporting true, to avoid race - devices_changed = false; + devices_changed.clear(); } return dc; } @@ -1800,7 +1837,7 @@ public: args.push_back("uninstall"); args.push_back(get_package_name(package_name)); - err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv); + err = OS::get_singleton()->execute(adb, args, nullptr, &rv); } print_line("Installing to device (please wait...): " + devices[p_device].name); @@ -1815,7 +1852,7 @@ public: args.push_back("-r"); args.push_back(tmp_export_path); - err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv); + err = OS::get_singleton()->execute(adb, args, nullptr, &rv); if (err || rv != 0) { EditorNode::add_io_error("Could not install to device."); CLEANUP_AND_RETURN(ERR_CANT_CREATE); @@ -1832,7 +1869,7 @@ public: args.push_back(devices[p_device].id); args.push_back("reverse"); args.push_back("--remove-all"); - OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv); + OS::get_singleton()->execute(adb, args, nullptr, &rv); if (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) { int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port"); @@ -1843,7 +1880,7 @@ public: args.push_back("tcp:" + itos(dbg_port)); args.push_back("tcp:" + itos(dbg_port)); - OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv); + OS::get_singleton()->execute(adb, args, nullptr, &rv); print_line("Reverse result: " + itos(rv)); } @@ -1857,7 +1894,7 @@ public: args.push_back("tcp:" + itos(fs_port)); args.push_back("tcp:" + itos(fs_port)); - err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv); + err = OS::get_singleton()->execute(adb, args, nullptr, &rv); print_line("Reverse result2: " + itos(rv)); } } else { @@ -1885,7 +1922,7 @@ public: args.push_back("-n"); args.push_back(get_package_name(package_name) + "/com.godot.game.GodotApp"); - err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv); + err = OS::get_singleton()->execute(adb, args, nullptr, &rv); if (err || rv != 0) { EditorNode::add_io_error("Could not execute on device."); CLEANUP_AND_RETURN(ERR_CANT_CREATE); @@ -1958,6 +1995,7 @@ public: String template_err; bool dvalid = false; bool rvalid = false; + bool has_export_templates = false; if (p_preset->get("custom_template/debug") != "") { dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); @@ -1965,7 +2003,7 @@ public: template_err += TTR("Custom debug template not found.") + "\n"; } } else { - dvalid = exists_export_template("android_debug.apk", &template_err); + has_export_templates |= exists_export_template("android_debug.apk", &template_err); } if (p_preset->get("custom_template/release") != "") { @@ -1974,22 +2012,24 @@ public: template_err += TTR("Custom release template not found.") + "\n"; } } else { - rvalid = exists_export_template("android_release.apk", &template_err); + has_export_templates |= exists_export_template("android_release.apk", &template_err); } - valid = dvalid || rvalid; + r_missing_templates = !has_export_templates; + valid = dvalid || rvalid || has_export_templates; if (!valid) { err += template_err; } } else { - valid = exists_export_template("android_source.zip", &err); + r_missing_templates = !exists_export_template("android_source.zip", &err); - if (!FileAccess::exists("res://android/build/build.gradle")) { + bool installed_android_build_template = FileAccess::exists("res://android/build/build.gradle"); + if (!installed_android_build_template) { err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n"; - valid = false; } + + valid = installed_android_build_template && !r_missing_templates; } - r_missing_templates = !valid; // Validate the rest of the configuration. @@ -2131,7 +2171,7 @@ public: return list; } - inline bool is_clean_build_required(Vector<PluginConfig> enabled_plugins) { + inline bool is_clean_build_required(Vector<PluginConfigAndroid> enabled_plugins) { String plugin_names = get_plugins_names(enabled_plugins); bool first_build = last_custom_build_time == 0; bool have_plugins_changed = false; @@ -2239,6 +2279,7 @@ public: String release_password = p_preset->get("keystore/release_password"); String apksigner = get_apksigner_path(); + print_verbose("Starting signing of the " + export_label + " binary using " + apksigner); if (!FileAccess::exists(apksigner)) { EditorNode::add_io_error("'apksigner' could not be found.\nPlease check the command is available in the Android SDK build-tools directory.\nThe resulting " + export_label + " is unsigned."); return OK; @@ -2287,8 +2328,12 @@ public: args.push_back("--ks-key-alias"); args.push_back(user); args.push_back(export_path); + if (p_debug) { + // We only print verbose logs for debug builds to avoid leaking release keystore credentials. + print_verbose("Signing debug binary using: " + String("\n") + apksigner + " " + join_list(args, String(" "))); + } int retval; - OS::get_singleton()->execute(apksigner, args, true, NULL, NULL, &retval); + OS::get_singleton()->execute(apksigner, args, nullptr, &retval); if (retval) { EditorNode::add_io_error("'apksigner' returned with error #" + itos(retval)); return ERR_CANT_CREATE; @@ -2302,24 +2347,41 @@ public: args.push_back("verify"); args.push_back("--verbose"); args.push_back(export_path); + if (p_debug) { + print_verbose("Verifying signed build using: " + String("\n") + apksigner + " " + join_list(args, String(" "))); + } - OS::get_singleton()->execute(apksigner, args, true, NULL, NULL, &retval); + OS::get_singleton()->execute(apksigner, args, nullptr, &retval); if (retval) { EditorNode::add_io_error("'apksigner' verification of " + export_label + " failed."); return ERR_CANT_CREATE; } + + print_verbose("Successfully completed signing build."); return OK; } void _clear_assets_directory() { DirAccessRef da_res = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (da_res->dir_exists("res://android/build/assets")) { + print_verbose("Clearing assets directory.."); DirAccessRef da_assets = DirAccess::open("res://android/build/assets"); da_assets->erase_contents_recursive(); da_res->remove("res://android/build/assets"); } } + String join_list(List<String> parts, const String &separator) const { + String ret; + for (int i = 0; i < parts.size(); ++i) { + if (i > 0) { + ret += separator; + } + ret += parts[i]; + } + return ret; + } + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override { int export_format = int(p_preset->get("custom_template/export_format")); bool should_sign = p_preset->get("package/signed"); @@ -2339,9 +2401,21 @@ public: bool apk_expansion = p_preset->get("apk_expansion/enable"); Vector<String> enabled_abis = get_enabled_abis(p_preset); + print_verbose("Exporting for Android..."); + print_verbose("- debug build: " + bool_to_string(p_debug)); + print_verbose("- export path: " + p_path); + print_verbose("- export format: " + itos(export_format)); + print_verbose("- sign build: " + bool_to_string(should_sign)); + print_verbose("- custom build enabled: " + bool_to_string(use_custom_build)); + print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion)); + print_verbose("- enabled abis: " + String(",").join(enabled_abis)); + print_verbose("- export filter: " + itos(p_preset->get_export_filter())); + print_verbose("- include filter: " + p_preset->get_include_filter()); + print_verbose("- exclude filter: " + p_preset->get_exclude_filter()); + Ref<Image> splash_image; Ref<Image> splash_bg_color_image; - load_splash_refs(splash_image, splash_bg_color_image); + String processed_splash_config_xml = load_splash_refs(splash_image, splash_bg_color_image); Ref<Image> main_image; Ref<Image> foreground; @@ -2374,14 +2448,17 @@ public: } if (use_custom_build) { + print_verbose("Starting custom build.."); //test that installed build version is alright { + print_verbose("Checking build version.."); FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::READ); if (!f) { EditorNode::get_singleton()->show_warning(TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu.")); return ERR_UNCONFIGURED; } String version = f->get_line().strip_edges(); + print_verbose("- build version: " + version); f->close(); if (version != VERSION_FULL_CONFIG) { EditorNode::get_singleton()->show_warning(vformat(TTR("Android build version mismatch:\n Template installed: %s\n Godot Version: %s\nPlease reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG)); @@ -2389,7 +2466,8 @@ public: } } String sdk_path = EDITOR_GET("export/android/android_sdk_path"); - ERR_FAIL_COND_V_MSG(sdk_path == "", ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'."); + ERR_FAIL_COND_V_MSG(sdk_path.is_empty(), ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'."); + print_verbose("Android sdk path: " + sdk_path); // TODO: should we use "package/name" or "application/config/name"? String project_name = get_project_name(p_preset->get("package/name")); @@ -2398,27 +2476,31 @@ public: EditorNode::add_io_error("Unable to overwrite res://android/build/res/*.xml files with project name"); } // Copies the project icon files into the appropriate Gradle project directory. - _copy_icons_to_gradle_project(p_preset, splash_image, splash_bg_color_image, main_image, foreground, background); + _copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background); // Write an AndroidManifest.xml file into the Gradle project directory. _write_tmp_manifest(p_preset, p_give_internet, p_debug); //stores all the project files inside the Gradle project directory. Also includes all ABIs _clear_assets_directory(); if (!apk_expansion) { + print_verbose("Exporting project files.."); err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, NULL, ignore_so_file); if (err != OK) { EditorNode::add_io_error("Could not export project files to gradle project\n"); return err; } } else { + print_verbose("Saving apk expansion file.."); err = save_apk_expansion_file(p_preset, p_path); if (err != OK) { EditorNode::add_io_error("Could not write expansion package file!"); return err; } } + print_verbose("Storing command line flags.."); store_file_at_path("res://android/build/assets/_cl_", command_line_flags); + print_verbose("Updating ANDROID_HOME environment to " + sdk_path); OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required String build_command; @@ -2438,9 +2520,9 @@ public: String sign_flag = should_sign ? "true" : "false"; String zipalign_flag = "true"; - Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset); - String local_plugins_binaries = get_plugins_binaries(BINARY_TYPE_LOCAL, enabled_plugins); - String remote_plugins_binaries = get_plugins_binaries(BINARY_TYPE_REMOTE, enabled_plugins); + Vector<PluginConfigAndroid> enabled_plugins = get_enabled_plugins(p_preset); + String local_plugins_binaries = get_plugins_binaries(PluginConfigAndroid::BINARY_TYPE_LOCAL, enabled_plugins); + String remote_plugins_binaries = get_plugins_binaries(PluginConfigAndroid::BINARY_TYPE_REMOTE, enabled_plugins); String custom_maven_repos = get_plugins_custom_maven_repos(enabled_plugins); bool clean_build_required = is_clean_build_required(enabled_plugins); @@ -2458,6 +2540,8 @@ public: cmdline.push_back(apk_build_command); } + cmdline.push_back("-p"); // argument to specify the start directory. + cmdline.push_back(build_path); // start directory. cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name. cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code. cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name. @@ -2467,6 +2551,14 @@ public: cmdline.push_back("-Pplugins_maven_repos=" + custom_maven_repos); // argument to specify the list of custom maven repos for the plugins dependencies. cmdline.push_back("-Pperform_zipalign=" + zipalign_flag); // argument to specify whether the build should be zipaligned. cmdline.push_back("-Pperform_signing=" + sign_flag); // argument to specify whether the build should be signed. + cmdline.push_back("-Pgodot_editor_version=" + String(VERSION_FULL_CONFIG)); + + // NOTE: The release keystore is not included in the verbose logging + // to avoid accidentally leaking sensitive information when sharing verbose logs for troubleshooting. + // Any non-sensitive additions to the command line arguments must be done above this section. + // Sensitive additions must be done below the logging statement. + print_verbose("Build Android project using gradle command: " + String("\n") + build_command + " " + join_list(cmdline, String(" "))); + if (should_sign && !p_debug) { // Pass the release keystore info as well String release_keystore = p_preset->get("keystore/release"); @@ -2481,8 +2573,6 @@ public: cmdline.push_back("-Prelease_keystore_alias=" + release_username); // argument to specify the release keystore alias. cmdline.push_back("-Prelease_keystore_password=" + release_password); // argument to specity the release keystore password. } - cmdline.push_back("-p"); // argument to specify the start directory. - cmdline.push_back(build_path); // start directory. int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Building Android Project (gradle)"), build_command, cmdline); if (result != 0) { @@ -2513,15 +2603,18 @@ public: copy_args.push_back("-Pexport_path=file:" + export_path); copy_args.push_back("-Pexport_filename=" + export_filename); + print_verbose("Copying Android binary using gradle command: " + String("\n") + build_command + " " + join_list(copy_args, String(" "))); int copy_result = EditorNode::get_singleton()->execute_and_show_output(TTR("Moving output"), build_command, copy_args); if (copy_result != 0) { EditorNode::get_singleton()->show_warning(TTR("Unable to copy and rename export file, check gradle project directory for outputs.")); return ERR_CANT_CREATE; } + print_verbose("Successfully completed Android custom build."); return OK; } // This is the start of the Legacy build system + print_verbose("Starting legacy build system.."); if (p_debug) src_apk = p_preset->get("custom_template/debug"); else @@ -2845,16 +2938,14 @@ public: run_icon.instance(); run_icon->create_from_image(img); - devices_changed = true; - plugins_changed = true; - quit_request = false; - check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this); + devices_changed.set(); + plugins_changed.set(); + check_for_changes_thread.start(_check_for_changes_poll_thread, this); } ~EditorExportPlatformAndroid() { - quit_request = true; - Thread::wait_to_finish(check_for_changes_thread); - memdelete(check_for_changes_thread); + quit_request.set(); + check_for_changes_thread.wait_to_finish(); } }; diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index fc54b65d26..097a2391ee 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -146,6 +146,9 @@ Error store_string_at_path(const String &p_path, const String &p_data) { String dir = p_path.get_base_dir(); Error err = create_directory(dir); if (err != OK) { + if (OS::get_singleton()->is_stdout_verbose()) { + print_error("Unable to write data into " + p_path); + } return err; } FileAccess *fa = FileAccess::open(p_path, FileAccess::WRITE); @@ -162,12 +165,14 @@ Error store_string_at_path(const String &p_path, const String &p_data) { // This method will be called ONLY when custom build is enabled. Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { String dst_path = p_path.replace_first("res://", "res://android/build/assets/"); + print_verbose("Saving project files from " + p_path + " into " + dst_path); Error err = store_file_at_path(dst_path, p_data); return err; } // Creates strings.xml files inside the gradle project for different locales. Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset, const String &project_name) { + print_verbose("Creating strings resources for supported locales for project " + project_name); // Stores the string into the default values directory. String processed_default_xml_string = vformat(godot_project_name_xml_string, project_name.xml_escape(true)); store_string_at_path("res://android/build/res/values/godot_project_name_string.xml", processed_default_xml_string); @@ -175,6 +180,9 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset // Searches the Gradle project res/ directory to find all supported locales DirAccessRef da = DirAccess::open("res://android/build/res"); if (!da) { + if (OS::get_singleton()->is_stdout_verbose()) { + print_error("Unable to open Android resources directory."); + } return ERR_CANT_OPEN; } da->list_dir_begin(); @@ -193,6 +201,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset if (ProjectSettings::get_singleton()->has_setting(property_name)) { String locale_project_name = ProjectSettings::get_singleton()->get(property_name); String processed_xml_string = vformat(godot_project_name_xml_string, locale_project_name.xml_escape(true)); + print_verbose("Storing project name for locale " + locale + " under " + locale_directory); store_string_at_path(locale_directory, processed_xml_string); } else { // TODO: Once the legacy build system is deprecated we don't need to have xml files for this else branch @@ -208,8 +217,8 @@ String bool_to_string(bool v) { } String _get_gles_tag() { - bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES3" && - !ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2"); + bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES3" && + !ProjectSettings::get_singleton()->get("rendering/driver/fallback_to_gles2"); return min_gles3 ? " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n" : ""; } @@ -260,14 +269,6 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) { return manifest_instrumentation_text; } -String _get_plugins_tag(const String &plugins_names) { - if (!plugins_names.is_empty()) { - return vformat(" <meta-data tools:node=\"replace\" android:name=\"plugins\" android:value=\"%s\" />\n", plugins_names); - } else { - return " <meta-data tools:node=\"remove\" android:name=\"plugins\" />\n"; - } -} - String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; String orientation = _get_android_orientation_label(_get_screen_orientation()); @@ -286,7 +287,7 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { return manifest_activity_text; } -String _get_application_tag(const Ref<EditorExportPreset> &p_preset, const String &plugins_names) { +String _get_application_tag(const Ref<EditorExportPreset> &p_preset) { bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; String manifest_application_text = " <application android:label=\"@string/godot_project_name_string\"\n" @@ -294,7 +295,6 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, const Strin " android:icon=\"@mipmap/icon\">\n\n" " <meta-data tools:node=\"remove\" android:name=\"xr_mode_metadata_name\" />\n"; - manifest_application_text += _get_plugins_tag(plugins_names); if (uses_xr) { manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n"; } diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index e94681659c..948fa8c00b 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -22,6 +22,11 @@ tools:ignore="GoogleAppIndexingWarning" android:icon="@mipmap/icon" > + <!-- Records the version of the Godot editor used for building --> + <meta-data + android:name="org.godotengine.editor.version" + android:value="${godotEditorVersion}" /> + <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> <!-- Do these changes in the export preset. Adding new ones is fine. --> @@ -30,11 +35,6 @@ android:name="xr_mode_metadata_name" android:value="xr_mode_metadata_value" /> - <!-- Metadata populated at export time and used by Godot to figure out which plugins must be enabled. --> - <meta-data - android:name="plugins" - android:value="plugins_value"/> - <activity android:name=".GodotApp" android:label="@string/godot_project_name_string" diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 53d11fda5b..934c4bf441 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -85,6 +85,8 @@ android { abiFilters export_abi_list } + manifestPlaceholders = [godotEditorVersion: getGodotEditorVersion()] + // Feel free to modify the application id to your own. applicationId getExportPackageName() versionCode getExportVersionCode() @@ -98,6 +100,8 @@ android { disable 'MissingTranslation', 'UnusedResources' } + ndkVersion versions.ndkVersion + packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 80cf6f7ede..585e517631 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,5 +1,5 @@ ext.versions = [ - androidGradlePlugin: '4.1.0', + androidGradlePlugin: '4.0.1', compileSdk : 29, minSdk : 18, targetSdk : 29, @@ -7,7 +7,8 @@ ext.versions = [ supportCoreUtils : '1.0.0', kotlinVersion : '1.4.10', v4Support : '1.0.0', - javaVersion : 1.8 + javaVersion : 1.8, + ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated. ] @@ -49,7 +50,56 @@ ext.getExportVersionName = { -> return versionName } -final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|" +ext.getGodotEditorVersion = { -> + String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : "" + if (editorVersion == null || editorVersion.isEmpty()) { + // Try the library version first + editorVersion = getGodotLibraryVersion() + + if (editorVersion.isEmpty()) { + // Fallback value. + editorVersion = "custom_build" + } + } + return editorVersion +} + +ext.getGodotLibraryVersion = { -> + // Attempt to read the version from the `version.py` file. + String libraryVersion = "" + + File versionFile = new File("../../../version.py") + if (versionFile.isFile()) { + List<String> requiredKeys = ["major", "minor", "patch", "status", "module_config"] + def map = [:] + + List<String> lines = versionFile.readLines() + for (String line in lines) { + String[] keyValue = line.split("=") + String key = keyValue[0].trim() + String value = keyValue[1].trim().replaceAll("\"", "") + + if (requiredKeys.contains(key)) { + if (!value.isEmpty()) { + map[key] = value + } + requiredKeys.remove(key) + } + } + + if (requiredKeys.empty) { + libraryVersion = map.values().join(".") + } + } + + if (libraryVersion.isEmpty()) { + // Fallback value in case we're unable to read the file. + libraryVersion = "custom_build" + } + return libraryVersion +} + +final String VALUE_SEPARATOR_REGEX = "\\|" // get the list of ABIs the project should be exported to ext.getExportEnabledABIs = { -> @@ -58,7 +108,7 @@ ext.getExportEnabledABIs = { -> enabledABIs = "armeabi-v7a|arm64-v8a|x86|x86_64|" } Set<String> exportAbiFilter = []; - for (String abi_name : enabledABIs.split(PLUGIN_VALUE_SEPARATOR_REGEX)) { + for (String abi_name : enabledABIs.split(VALUE_SEPARATOR_REGEX)) { if (!abi_name.trim().isEmpty()){ exportAbiFilter.add(abi_name); } @@ -93,7 +143,7 @@ ext.getGodotPluginsMavenRepos = { -> if (project.hasProperty("plugins_maven_repos")) { String mavenReposProperty = project.property("plugins_maven_repos") if (mavenReposProperty != null && !mavenReposProperty.trim().isEmpty()) { - for (String mavenRepoUrl : mavenReposProperty.split(PLUGIN_VALUE_SEPARATOR_REGEX)) { + for (String mavenRepoUrl : mavenReposProperty.split(VALUE_SEPARATOR_REGEX)) { mavenRepos += mavenRepoUrl.trim() } } @@ -113,7 +163,7 @@ ext.getGodotPluginsRemoteBinaries = { -> if (project.hasProperty("plugins_remote_binaries")) { String remoteDepsList = project.property("plugins_remote_binaries") if (remoteDepsList != null && !remoteDepsList.trim().isEmpty()) { - for (String dep: remoteDepsList.split(PLUGIN_VALUE_SEPARATOR_REGEX)) { + for (String dep: remoteDepsList.split(VALUE_SEPARATOR_REGEX)) { remoteDeps += dep.trim() } } @@ -132,7 +182,7 @@ ext.getGodotPluginsLocalBinaries = { -> if (project.hasProperty("plugins_local_binaries")) { String pluginsList = project.property("plugins_local_binaries") if (pluginsList != null && !pluginsList.trim().isEmpty()) { - for (String plugin : pluginsList.split(PLUGIN_VALUE_SEPARATOR_REGEX)) { + for (String plugin : pluginsList.split(VALUE_SEPARATOR_REGEX)) { binDeps += plugin.trim() } } diff --git a/platform/android/java/app/res/drawable/splash_drawable.xml b/platform/android/java/app/res/drawable/splash_drawable.xml index 2794a40817..30627b998c 100644 --- a/platform/android/java/app/res/drawable/splash_drawable.xml +++ b/platform/android/java/app/res/drawable/splash_drawable.xml @@ -6,7 +6,7 @@ <item> <bitmap android:gravity="center" + android:filter="false" android:src="@drawable/splash" /> </item> - </layer-list> diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index 73c136ed0e..ec02b0fc7a 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -165,12 +165,6 @@ task cleanGodotTemplates(type: Delete) { // Delete the library generated AAR files delete("lib/build/outputs/aar") - // Delete the godotpayment libs directory contents - delete("plugins/godotpayment/libs") - - // Delete the generated godotpayment aar - delete("plugins/godotpayment/build/outputs/aar") - // Delete the app libs directory contents delete("app/libs") diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index fa39bc0f1d..3034794d69 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -6,6 +6,11 @@ <application> + <!-- Records the version of the Godot library --> + <meta-data + android:name="org.godotengine.library.version" + android:value="${godotLibraryVersion}" /> + <service android:name=".GodotDownloaderService" /> </application> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 89ce3d15e6..6fc9a11a08 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -13,9 +13,13 @@ android { compileSdkVersion versions.compileSdk buildToolsVersion versions.buildTools + ndkVersion versions.ndkVersion + defaultConfig { minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk + + manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersion()] } compileOptions { @@ -68,7 +72,7 @@ android { File sconsExecutableFile = null def sconsName = "scons" def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows() - ? [".bat", ".exe"] + ? [".bat", ".cmd", ".ps1", ".exe"] : [""]) logger.lifecycle("Looking for $sconsName executable path") for (ext in sconsExts) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 7d396b402e..0891904dff 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -464,7 +464,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + final Activity activity = getActivity(); Window window = activity.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); @@ -572,24 +574,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { // This is where you do set up to display the download - // progress (next step) + // progress (next step in onCreateView) mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, GodotDownloaderService.class); - View downloadingExpansionView = - inflater.inflate(R.layout.downloading_expansion, container, false); - mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar); - mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText); - mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction); - mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage); - mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed); - mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining); - mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard); - mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular); - mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton); - mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton); - - return downloadingExpansionView; + return; } } catch (NameNotFoundException e) { // TODO Auto-generated catch block @@ -600,6 +589,27 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC mCurrentIntent = activity.getIntent(); initializeGodot(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { + if (mDownloaderClientStub != null) { + View downloadingExpansionView = + inflater.inflate(R.layout.downloading_expansion, container, false); + mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar); + mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText); + mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction); + mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage); + mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed); + mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining); + mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard); + mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular); + mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton); + mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton); + + return downloadingExpansionView; + } + return containerLayout; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index b536733201..63c91561ff 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -188,15 +188,15 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView if (GLUtils.use_32) { setEGLConfigChooser(translucent ? - new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, + new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, new RegularConfigChooser(8, 8, 8, 8, 16, stencil)) : - new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, + new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, new RegularConfigChooser(5, 6, 5, 0, 16, stencil))); } else { setEGLConfigChooser(translucent ? - new RegularConfigChooser(8, 8, 8, 8, 16, stencil) : - new RegularConfigChooser(5, 6, 5, 0, 16, stencil)); + new RegularConfigChooser(8, 8, 8, 8, 16, stencil) : + new RegularConfigChooser(5, 6, 5, 0, 16, stencil)); } break; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index 3368363ce7..435b8b325f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -38,6 +38,8 @@ import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; import android.os.Build; import android.util.Log; +import android.util.SparseArray; +import android.util.SparseIntArray; import android.view.InputDevice; import android.view.InputDevice.MotionRange; import android.view.KeyEvent; @@ -46,17 +48,24 @@ import android.view.MotionEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; /** * Handles input related events for the {@link GodotRenderView} view. */ public class GodotInputHandler implements InputDeviceListener { - private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>(); - private final GodotRenderView mRenderView; private final InputManagerCompat mInputManager; + private final String tag = this.getClass().getSimpleName(); + + private final SparseIntArray mJoystickIds = new SparseIntArray(4); + private final SparseArray<Joystick> mJoysticksDevices = new SparseArray<Joystick>(4); + public GodotInputHandler(GodotRenderView godotView) { mRenderView = godotView; mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext()); @@ -82,19 +91,20 @@ public class GodotInputHandler implements InputDeviceListener { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { return false; - }; + } int source = event.getSource(); if (isKeyEvent_GameDevice(source)) { - final int button = getGodotButton(keyCode); - final int device_id = findJoystickDevice(event.getDeviceId()); - // Check if the device exists - if (device_id > -1) { + final int deviceId = event.getDeviceId(); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + final int button = getGodotButton(keyCode); + final int godotJoyId = mJoystickIds.get(deviceId); + queueEvent(new Runnable() { @Override public void run() { - GodotLib.joybutton(device_id, button, false); + GodotLib.joybutton(godotJoyId, button, false); } }); } @@ -107,7 +117,7 @@ public class GodotInputHandler implements InputDeviceListener { GodotLib.key(keyCode, scanCode, chr, false); } }); - }; + } return true; } @@ -122,24 +132,25 @@ public class GodotInputHandler implements InputDeviceListener { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { return false; - }; + } int source = event.getSource(); //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); + final int deviceId = event.getDeviceId(); + // Check if source is a game device and that the device is a registered gamepad if (isKeyEvent_GameDevice(source)) { if (event.getRepeatCount() > 0) // ignore key echo return true; - final int button = getGodotButton(keyCode); - final int device_id = findJoystickDevice(event.getDeviceId()); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + final int button = getGodotButton(keyCode); + final int godotJoyId = mJoystickIds.get(deviceId); - // Check if the device exists - if (device_id > -1) { queueEvent(new Runnable() { @Override public void run() { - GodotLib.joybutton(device_id, button, true); + GodotLib.joybutton(godotJoyId, button, true); } }); } @@ -152,7 +163,7 @@ public class GodotInputHandler implements InputDeviceListener { GodotLib.key(keyCode, scanCode, chr, true); } }); - }; + } return true; } @@ -203,38 +214,52 @@ public class GodotInputHandler implements InputDeviceListener { } public boolean onGenericMotionEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - final int device_id = findJoystickDevice(event.getDeviceId()); - + if (event.isFromSource(InputDevice.SOURCE_JOYSTICK) && event.getAction() == MotionEvent.ACTION_MOVE) { // Check if the device exists - if (device_id > -1) { - Joystick joy = mJoysticksDevices.get(device_id); - - for (int i = 0; i < joy.axes.size(); i++) { - InputDevice.MotionRange range = joy.axes.get(i); - final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f; - final int idx = i; - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyaxis(device_id, idx, value); - } - }); + final int deviceId = event.getDeviceId(); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + final int godotJoyId = mJoystickIds.get(deviceId); + Joystick joystick = mJoysticksDevices.get(deviceId); + + for (int i = 0; i < joystick.axes.size(); i++) { + final int axis = joystick.axes.get(i); + final float value = event.getAxisValue(axis); + /** + * As all axes are polled for each event, only fire an axis event if the value has actually changed. + * Prevents flooding Godot with repeated events. + */ + if (joystick.axesValues.indexOfKey(axis) < 0 || (float)joystick.axesValues.get(axis) != value) { + // save value to prevent repeats + joystick.axesValues.put(axis, value); + final int godotAxisIdx = i; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyaxis(godotJoyId, godotAxisIdx, value); + //Log.i(tag, "GodotLib.joyaxis("+godotJoyId+", "+godotAxisIdx+", "+value+");"); + } + }); + } } - for (int i = 0; i < joy.hats.size(); i += 2) { - final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); - final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis())); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyhat(device_id, hatX, hatY); - } - }); + if (joystick.hasAxisHat) { + final int hatX = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_X)); + final int hatY = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_Y)); + if (joystick.hatX != hatX || joystick.hatY != hatY) { + joystick.hatX = hatX; + joystick.hatY = hatY; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyhat(godotJoyId, hatX, hatY); + //Log.i(tag, "GodotLib.joyhat("+godotJoyId+", "+hatX+", "+hatY+");"); + } + }); + } } return true; } - } else if ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) { + } else if (event.isFromSource(InputDevice.SOURCE_STYLUS)) { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); @@ -245,6 +270,7 @@ public class GodotInputHandler implements InputDeviceListener { } }); return true; + } else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return handleMouseEvent(event); @@ -266,67 +292,98 @@ public class GodotInputHandler implements InputDeviceListener { } } + private int assignJoystickIdNumber(int deviceId) { + int godotJoyId = 0; + while (mJoystickIds.indexOfValue(godotJoyId) >= 0) { + godotJoyId++; + } + mJoystickIds.put(deviceId, godotJoyId); + return godotJoyId; + } + @Override public void onInputDeviceAdded(int deviceId) { - int id = findJoystickDevice(deviceId); - // Check if the device has not been already added - if (id < 0) { - InputDevice device = mInputManager.getInputDevice(deviceId); - //device can be null if deviceId is not found - if (device != null) { - int sources = device.getSources(); - if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || - ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) { - id = mJoysticksDevices.size(); - - Joystick joy = new Joystick(); - joy.device_id = deviceId; - joy.name = device.getName(); - joy.axes = new ArrayList<InputDevice.MotionRange>(); - joy.hats = new ArrayList<InputDevice.MotionRange>(); - - List<InputDevice.MotionRange> ranges = device.getMotionRanges(); - Collections.sort(ranges, new RangeComparator()); - - for (InputDevice.MotionRange range : ranges) { - if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) { - joy.hats.add(range); - } else { - joy.axes.add(range); - } - } - mJoysticksDevices.add(joy); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + return; + } + + InputDevice device = mInputManager.getInputDevice(deviceId); + //device can be null if deviceId is not found + if (device == null) { + return; + } + + int sources = device.getSources(); + + // Device may not be a joystick or gamepad + if ((sources & InputDevice.SOURCE_GAMEPAD) != InputDevice.SOURCE_GAMEPAD && + (sources & InputDevice.SOURCE_JOYSTICK) != InputDevice.SOURCE_JOYSTICK) { + return; + } + + // Assign first available number. Re-use numbers where possible. + final int id = assignJoystickIdNumber(deviceId); + + final Joystick joystick = new Joystick(); + joystick.device_id = deviceId; + joystick.name = device.getName(); + + //Helps with creating new joypad mappings. + Log.i(tag, "=== New Input Device: " + joystick.name); - final int device_id = id; - final String name = joy.name; - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyconnectionchanged(device_id, true, name); - } - }); + Set<Integer> already = new HashSet<Integer>(); + for (InputDevice.MotionRange range : device.getMotionRanges()) { + boolean isJoystick = range.isFromSource(InputDevice.SOURCE_JOYSTICK); + boolean isGamepad = range.isFromSource(InputDevice.SOURCE_GAMEPAD); + //Log.i(tag, "axis: "+range.getAxis()+ ", isJoystick: "+isJoystick+", isGamepad: "+isGamepad); + if (!isJoystick && !isGamepad) { + continue; + } + final int axis = range.getAxis(); + if (axis == MotionEvent.AXIS_HAT_X || axis == MotionEvent.AXIS_HAT_Y) { + joystick.hasAxisHat = true; + } else { + if (!already.contains(axis)) { + already.add(axis); + joystick.axes.add(axis); + } else { + Log.w(tag, " - DUPLICATE AXIS VALUE IN LIST: " + axis); } } } + Collections.sort(joystick.axes); + for (int idx = 0; idx < joystick.axes.size(); idx++) { + //Helps with creating new joypad mappings. + Log.i(tag, " - Mapping Android axis " + joystick.axes.get(idx) + " to Godot axis " + idx); + } + mJoysticksDevices.put(deviceId, joystick); + + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, true, joystick.name); + } + }); } @Override public void onInputDeviceRemoved(int deviceId) { - final int device_id = findJoystickDevice(deviceId); - - // Check if the evice has not been already removed - if (device_id > -1) { - mJoysticksDevices.remove(device_id); - - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyconnectionchanged(device_id, false, ""); - } - }); + // Check if the device has not been already removed + if (mJoystickIds.indexOfKey(deviceId) < 0) { + return; } + final int godotJoyId = mJoystickIds.get(deviceId); + mJoystickIds.delete(deviceId); + mJoysticksDevices.delete(deviceId); + + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(godotJoyId, false, ""); + } + }); } @Override @@ -407,16 +464,6 @@ public class GodotInputHandler implements InputDeviceListener { return button; } - private int findJoystickDevice(int device_id) { - for (int i = 0; i < mJoysticksDevices.size(); i++) { - if (mJoysticksDevices.get(i).device_id == device_id) { - return i; - } - } - - return -1; - } - private boolean handleMouseEvent(final MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_HOVER_ENTER: diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java index 82bd45ee3f..4b7318c718 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java @@ -30,9 +30,10 @@ package org.godotengine.godot.input; -import android.view.InputDevice.MotionRange; +import android.util.SparseArray; import java.util.ArrayList; +import java.util.List; /** * POJO class to represent a Joystick input device. @@ -40,6 +41,12 @@ import java.util.ArrayList; class Joystick { int device_id; String name; - ArrayList<MotionRange> axes; - ArrayList<MotionRange> hats; + List<Integer> axes = new ArrayList<Integer>(); + protected boolean hasAxisHat = false; + /* + * Keep track of values so we can prevent flooding the engine with useless events. + */ + protected final SparseArray axesValues = new SparseArray<Float>(4); + protected int hatX; + protected int hatY; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java index a22b80761d..993f0e9127 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java @@ -46,7 +46,9 @@ import androidx.annotation.Nullable; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -107,14 +109,47 @@ public abstract class GodotPlugin { * This method is invoked on the render thread. */ public final void onRegisterPluginWithGodotNative() { - nativeRegisterSingleton(getPluginName()); + registeredSignals.putAll(registerPluginWithGodotNative(this, new GodotPluginInfoProvider() { + @NonNull + @Override + public String getPluginName() { + return GodotPlugin.this.getPluginName(); + } + + @NonNull + @Override + public List<String> getPluginMethods() { + return GodotPlugin.this.getPluginMethods(); + } + + @NonNull + @Override + public Set<SignalInfo> getPluginSignals() { + return GodotPlugin.this.getPluginSignals(); + } + + @NonNull + @Override + public Set<String> getPluginGDNativeLibrariesPaths() { + return GodotPlugin.this.getPluginGDNativeLibrariesPaths(); + } + })); + } - Class clazz = getClass(); + /** + * Register the plugin with Godot native code. + * + * This method must be invoked on the render thread. + */ + public static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject, GodotPluginInfoProvider pluginInfoProvider) { + nativeRegisterSingleton(pluginInfoProvider.getPluginName(), pluginObject); + + Class clazz = pluginObject.getClass(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { boolean found = false; - for (String s : getPluginMethods()) { + for (String s : pluginInfoProvider.getPluginMethods()) { if (s.equals(method.getName())) { found = true; break; @@ -123,7 +158,7 @@ public abstract class GodotPlugin { if (!found) continue; - List<String> ptr = new ArrayList<String>(); + List<String> ptr = new ArrayList<>(); Class[] paramTypes = method.getParameterTypes(); for (Class c : paramTypes) { @@ -133,26 +168,29 @@ public abstract class GodotPlugin { String[] pt = new String[ptr.size()]; ptr.toArray(pt); - nativeRegisterMethod(getPluginName(), method.getName(), method.getReturnType().getName(), pt); + nativeRegisterMethod(pluginInfoProvider.getPluginName(), method.getName(), method.getReturnType().getName(), pt); } // Register the signals for this plugin. - for (SignalInfo signalInfo : getPluginSignals()) { + Map<String, SignalInfo> registeredSignals = new HashMap<>(); + for (SignalInfo signalInfo : pluginInfoProvider.getPluginSignals()) { String signalName = signalInfo.getName(); - nativeRegisterSignal(getPluginName(), signalName, signalInfo.getParamTypesNames()); + nativeRegisterSignal(pluginInfoProvider.getPluginName(), signalName, signalInfo.getParamTypesNames()); registeredSignals.put(signalName, signalInfo); } // Get the list of gdnative libraries to register. - Set<String> gdnativeLibrariesPaths = getPluginGDNativeLibrariesPaths(); + Set<String> gdnativeLibrariesPaths = pluginInfoProvider.getPluginGDNativeLibrariesPaths(); if (!gdnativeLibrariesPaths.isEmpty()) { nativeRegisterGDNativeLibraries(gdnativeLibrariesPaths.toArray(new String[0])); } + + return registeredSignals; } /** * Invoked once during the Godot Android initialization process after creation of the - * {@link org.godotengine.godot.GodotView} view. + * {@link org.godotengine.godot.GodotRenderView} view. * <p> * The plugin can return a non-null {@link View} layout in order to add it to the Godot view * hierarchy. @@ -290,8 +328,8 @@ public abstract class GodotPlugin { /** * Emit a registered Godot signal. - * @param signalName - * @param signalArgs + * @param signalName Name of the signal to emit. It will be validated against the set of registered signals. + * @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the {@link SignalInfo} matching the registered signalName parameter. */ protected void emitSignal(final String signalName, final Object... signalArgs) { try { @@ -301,6 +339,27 @@ public abstract class GodotPlugin { throw new IllegalArgumentException( "Signal " + signalName + " is not registered for this plugin."); } + emitSignal(getGodot(), getPluginName(), signalInfo, signalArgs); + } catch (IllegalArgumentException exception) { + Log.w(TAG, exception.getMessage()); + if (BuildConfig.DEBUG) { + throw exception; + } + } + } + + /** + * Emit a Godot signal. + * @param godot + * @param pluginName Name of the Godot plugin the signal will be emitted from. The plugin must already be registered with the Godot engine. + * @param signalInfo Information about the signal to emit. + * @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the given {@link SignalInfo} parameter. + */ + public static void emitSignal(Godot godot, String pluginName, SignalInfo signalInfo, final Object... signalArgs) { + try { + if (signalInfo == null) { + throw new IllegalArgumentException("Signal must be non null."); + } // Validate the arguments count. Class<?>[] signalParamTypes = signalInfo.getParamTypes(); @@ -317,12 +376,8 @@ public abstract class GodotPlugin { } } - runOnRenderThread(new Runnable() { - @Override - public void run() { - nativeEmitSignal(getPluginName(), signalName, signalArgs); - } - }); + godot.runOnRenderThread(() -> nativeEmitSignal(pluginName, signalInfo.getName(), signalArgs)); + } catch (IllegalArgumentException exception) { Log.w(TAG, exception.getMessage()); if (BuildConfig.DEBUG) { @@ -335,7 +390,7 @@ public abstract class GodotPlugin { * Used to setup a {@link GodotPlugin} instance. * @param p_name Name of the instance. */ - private native void nativeRegisterSingleton(String p_name); + private static native void nativeRegisterSingleton(String p_name, Object object); /** * Used to complete registration of the {@link GodotPlugin} instance's methods. @@ -344,13 +399,13 @@ public abstract class GodotPlugin { * @param p_ret Return type of the registered method * @param p_params Method parameters types */ - private native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params); + private static native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params); /** * Used to register gdnative libraries bundled by the plugin. * @param gdnlibPaths Paths to the libraries relative to the 'assets' directory. */ - private native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths); + private static native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths); /** * Used to complete registration of the {@link GodotPlugin} instance's methods. @@ -358,7 +413,7 @@ public abstract class GodotPlugin { * @param signalName Name of the signal to register * @param signalParamTypes Signal parameters types */ - private native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes); + private static native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes); /** * Used to emit signal by {@link GodotPlugin} instance. @@ -366,5 +421,5 @@ public abstract class GodotPlugin { * @param signalName Name of the signal to emit * @param signalParams Signal parameters */ - private native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams); + private static native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams); } diff --git a/modules/arkit/arkit_session_delegate.h b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java index f227d50b35..c3084b036e 100644 --- a/modules/arkit/arkit_session_delegate.h +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arkit_session_delegate.h */ +/* GodotPluginInfoProvider.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,23 +28,40 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARKIT_SESSION_DELEGATE_H -#define ARKIT_SESSION_DELEGATE_H +package org.godotengine.godot.plugin; -#import <ARKit/ARKit.h> -#import <UIKit/UIKit.h> +import androidx.annotation.NonNull; -class ARKitInterface; +import java.util.List; +import java.util.Set; -@interface ARKitSessionDelegate : NSObject <ARSessionDelegate> { - ARKitInterface *arkit_interface; -} +/** + * Provides the set of information expected from a Godot plugin. + */ +public interface GodotPluginInfoProvider { + /** + * Returns the name of the plugin. + */ + @NonNull + String getPluginName(); -@property(nonatomic) ARKitInterface *arkit_interface; + /** + * Returns the list of methods to be exposed to Godot. + */ + @NonNull + List<String> getPluginMethods(); -- (void)session:(ARSession *)session didAddAnchors:(NSArray<ARAnchor *> *)anchors API_AVAILABLE(ios(11.0)); -- (void)session:(ARSession *)session didRemoveAnchors:(NSArray<ARAnchor *> *)anchors API_AVAILABLE(ios(11.0)); -- (void)session:(ARSession *)session didUpdateAnchors:(NSArray<ARAnchor *> *)anchors API_AVAILABLE(ios(11.0)); -@end + /** + * Returns the list of signals to be exposed to Godot. + */ + @NonNull + Set<SignalInfo> getPluginSignals(); -#endif /* !ARKIT_SESSION_DELEGATE_H */ + /** + * Returns the paths for the plugin's gdnative libraries (if any). + * + * The paths must be relative to the 'assets' directory and point to a '*.gdnlib' file. + */ + @NonNull + Set<String> getPluginGDNativeLibrariesPaths(); +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java index 99811f72ed..5b41205253 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java @@ -44,8 +44,6 @@ import androidx.annotation.Nullable; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Collection; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** @@ -56,13 +54,6 @@ public final class GodotPluginRegistry { private static final String GODOT_PLUGIN_V1_NAME_PREFIX = "org.godotengine.plugin.v1."; - /** - * Name for the metadata containing the list of Godot plugins to enable. - */ - private static final String GODOT_ENABLED_PLUGINS_LABEL = "plugins"; - - private static final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|"; - private static GodotPluginRegistry instance; private final ConcurrentHashMap<String, GodotPlugin> registry; @@ -132,37 +123,11 @@ public final class GodotPluginRegistry { return; } - // When using the Godot editor for building and exporting the apk, this is used to check - // which plugins to enable. - // When using a custom process to generate the apk, the metadata is not needed since - // it's assumed that the developer is aware of the dependencies included in the apk. - final Set<String> enabledPluginsSet; - if (metaData.containsKey(GODOT_ENABLED_PLUGINS_LABEL)) { - String enabledPlugins = metaData.getString(GODOT_ENABLED_PLUGINS_LABEL, ""); - String[] enabledPluginsList = enabledPlugins.split(PLUGIN_VALUE_SEPARATOR_REGEX); - if (enabledPluginsList.length == 0) { - // No plugins to enable. Aborting early. - return; - } - - enabledPluginsSet = new HashSet<>(); - for (String enabledPlugin : enabledPluginsList) { - enabledPluginsSet.add(enabledPlugin.trim()); - } - } else { - enabledPluginsSet = null; - } - int godotPluginV1NamePrefixLength = GODOT_PLUGIN_V1_NAME_PREFIX.length(); for (String metaDataName : metaData.keySet()) { // Parse the meta-data looking for entry with the Godot plugin name prefix. if (metaDataName.startsWith(GODOT_PLUGIN_V1_NAME_PREFIX)) { String pluginName = metaDataName.substring(godotPluginV1NamePrefixLength).trim(); - if (enabledPluginsSet != null && !enabledPluginsSet.contains(pluginName)) { - Log.w(TAG, "Plugin " + pluginName + " is listed in the dependencies but is not enabled."); - continue; - } - Log.i(TAG, "Initializing Godot plugin " + pluginName); // Retrieve the plugin class full name. @@ -177,8 +142,7 @@ public final class GodotPluginRegistry { .getConstructor(Godot.class); GodotPlugin pluginHandle = pluginConstructor.newInstance(godot); - // Load the plugin initializer into the registry using the plugin name - // as key. + // Load the plugin initializer into the registry using the plugin name as key. if (!pluginName.equals(pluginHandle.getPluginName())) { Log.w(TAG, "Meta-data plugin name does not match the value returned by the plugin handle: " + pluginName + " =/= " + pluginHandle.getPluginName()); diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle index 65b7bb9dc9..66077060ea 100644 --- a/platform/android/java/nativeSrcsConfigs/build.gradle +++ b/platform/android/java/nativeSrcsConfigs/build.gradle @@ -31,6 +31,8 @@ android { } } + ndkVersion versions.ndkVersion + externalNativeBuild { cmake { path "CMakeLists.txt" diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 2b5ca530da..ab03599dc3 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -37,7 +37,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (!M) return false; - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); MethodInfo *method = nullptr; for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) { @@ -964,7 +964,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { if (class_cache.has(p_class)) return class_cache[p_class]; - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jclass bclass = env->FindClass(p_class.utf8().get_data()); ERR_FAIL_COND_V(!bclass, Ref<JavaClass>()); @@ -1148,7 +1148,7 @@ JavaClassWrapper *JavaClassWrapper::singleton = nullptr; JavaClassWrapper::JavaClassWrapper(jobject p_activity) { singleton = this; - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jclass activityClass = env->FindClass("android/app/Activity"); jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;"); diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index 8f8275826d..41201db32b 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -34,7 +34,7 @@ // JNIEnv is only valid within the thread it belongs to, in a multi threading environment // we can't cache it. // For GodotIO we call all access methods from our thread and we thus get a valid JNIEnv -// from ThreadAndroid. +// from get_jni_env(). GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance) { godot_io_instance = p_env->NewGlobalRef(p_godot_io_instance); @@ -72,7 +72,7 @@ jobject GodotIOJavaWrapper::get_instance() { Error GodotIOJavaWrapper::open_uri(const String &p_uri) { if (_open_URI) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring jStr = env->NewStringUTF(p_uri.utf8().get_data()); return env->CallIntMethod(godot_io_instance, _open_URI, jStr) ? ERR_CANT_OPEN : OK; } else { @@ -82,7 +82,7 @@ Error GodotIOJavaWrapper::open_uri(const String &p_uri) { String GodotIOJavaWrapper::get_user_data_dir() { if (_get_data_dir) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_data_dir); return jstring_to_string(s, env); } else { @@ -92,7 +92,7 @@ String GodotIOJavaWrapper::get_user_data_dir() { String GodotIOJavaWrapper::get_locale() { if (_get_locale) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_locale); return jstring_to_string(s, env); } else { @@ -102,7 +102,7 @@ String GodotIOJavaWrapper::get_locale() { String GodotIOJavaWrapper::get_model() { if (_get_model) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_model); return jstring_to_string(s, env); } else { @@ -112,7 +112,7 @@ String GodotIOJavaWrapper::get_model() { int GodotIOJavaWrapper::get_screen_dpi() { if (_get_screen_DPI) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallIntMethod(godot_io_instance, _get_screen_DPI); } else { return 160; @@ -121,7 +121,7 @@ int GodotIOJavaWrapper::get_screen_dpi() { void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) { if (_screen_get_usable_rect) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _screen_get_usable_rect); ERR_FAIL_COND(env->GetArrayLength(returnArray) != 4); jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE); @@ -134,7 +134,7 @@ void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) { String GodotIOJavaWrapper::get_unique_id() { if (_get_unique_id) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_unique_id); return jstring_to_string(s, env); } else { @@ -148,7 +148,7 @@ bool GodotIOJavaWrapper::has_vk() { void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { if (_show_keyboard) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring jStr = env->NewStringUTF(p_existing.utf8().get_data()); env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); } @@ -156,21 +156,21 @@ void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int void GodotIOJavaWrapper::hide_vk() { if (_hide_keyboard) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(godot_io_instance, _hide_keyboard); } } void GodotIOJavaWrapper::set_screen_orientation(int p_orient) { if (_set_screen_orientation) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(godot_io_instance, _set_screen_orientation, p_orient); } } int GodotIOJavaWrapper::get_screen_orientation() { if (_get_screen_orientation) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallIntMethod(godot_io_instance, _get_screen_orientation); } else { return 0; @@ -179,7 +179,7 @@ int GodotIOJavaWrapper::get_screen_orientation() { String GodotIOJavaWrapper::get_system_dir(int p_dir) { if (_get_system_dir) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir); return jstring_to_string(s, env); } else { @@ -187,14 +187,14 @@ String GodotIOJavaWrapper::get_system_dir(int p_dir) { } } -// volatile because it can be changed from non-main thread and we need to +// SafeNumeric because it can be changed from non-main thread and we need to // ensure the change is immediately visible to other threads. -static volatile int virtual_keyboard_height; +static SafeNumeric<int> virtual_keyboard_height; int GodotIOJavaWrapper::get_vk_height() { - return virtual_keyboard_height; + return virtual_keyboard_height.get(); } void GodotIOJavaWrapper::set_vk_height(int p_height) { - virtual_keyboard_height = p_height; + virtual_keyboard_height.set(p_height); } diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index e3a4ce63ef..bb22162879 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -87,7 +87,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en godot_java = new GodotJavaWrapper(env, activity, godot_instance); godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env)); - ThreadAndroid::make_default(jvm); + init_thread_jandroid(jvm, env); jobject amgr = env->NewGlobalRef(p_asset_manager); @@ -119,7 +119,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) { - ThreadAndroid::setup_thread(); + setup_android_thread(); const char **cmdline = nullptr; jstring *j_cmdline = nullptr; @@ -206,7 +206,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl return; if (step == 0) { - // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id, + // Since Godot is initialized on the UI thread, main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop Main::setup2(Thread::get_caller_id()); ++step; @@ -382,7 +382,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jclass clazz) { - ThreadAndroid::setup_thread(); + setup_android_thread(); AudioDriverAndroid::thread_func(env); } diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp index cb26c7b8c5..5b638300ef 100644 --- a/platform/android/java_godot_view_wrapper.cpp +++ b/platform/android/java_godot_view_wrapper.cpp @@ -33,7 +33,7 @@ #include "thread_jandroid.h" GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); _godot_view = env->NewGlobalRef(godot_view); @@ -47,20 +47,20 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) { void GodotJavaViewWrapper::request_pointer_capture() { if (_request_pointer_capture != 0) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(_godot_view, _request_pointer_capture); } } void GodotJavaViewWrapper::release_pointer_capture() { if (_request_pointer_capture != 0) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(_godot_view, _release_pointer_capture); } } GodotJavaViewWrapper::~GodotJavaViewWrapper() { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->DeleteGlobalRef(_godot_view); env->DeleteGlobalRef(_cls); } diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp index c4e7f272d3..759980373a 100644 --- a/platform/android/java_godot_wrapper.cpp +++ b/platform/android/java_godot_wrapper.cpp @@ -33,7 +33,7 @@ // JNIEnv is only valid within the thread it belongs to, in a multi threading environment // we can't cache it. // For Godot we call most access methods from our thread and we thus get a valid JNIEnv -// from ThreadAndroid. For one or two we expect to pass the environment +// from get_jni_env(). For one or two we expect to pass the environment // TODO we could probably create a base class for this... @@ -91,7 +91,7 @@ jobject GodotJavaWrapper::get_activity() { jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) { if (godot_class) { if (p_env == nullptr) - p_env = ThreadAndroid::get_env(); + p_env = get_jni_env(); jfieldID fid = p_env->GetStaticFieldID(godot_class, p_name, p_class); return p_env->GetStaticObjectField(godot_class, fid); @@ -102,7 +102,7 @@ jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_cl jobject GodotJavaWrapper::get_class_loader() { if (_get_class_loader) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallObjectMethod(activity, _get_class_loader); } else { return nullptr; @@ -113,7 +113,7 @@ GodotJavaViewWrapper *GodotJavaWrapper::get_godot_view() { if (_godot_view != nullptr) { return _godot_view; } - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jmethodID godot_view_getter = env->GetMethodID(godot_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;"); _godot_view = new GodotJavaViewWrapper(env->CallObjectMethod(godot_instance, godot_view_getter)); return _godot_view; @@ -122,7 +122,7 @@ GodotJavaViewWrapper *GodotJavaWrapper::get_godot_view() { void GodotJavaWrapper::on_video_init(JNIEnv *p_env) { if (_on_video_init) if (p_env == nullptr) - p_env = ThreadAndroid::get_env(); + p_env = get_jni_env(); p_env->CallVoidMethod(godot_instance, _on_video_init); } @@ -130,7 +130,7 @@ void GodotJavaWrapper::on_video_init(JNIEnv *p_env) { void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) { if (_on_godot_main_loop_started) { if (p_env == nullptr) { - p_env = ThreadAndroid::get_env(); + p_env = get_jni_env(); } } p_env->CallVoidMethod(godot_instance, _on_godot_main_loop_started); @@ -139,7 +139,7 @@ void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) { void GodotJavaWrapper::restart(JNIEnv *p_env) { if (_restart) if (p_env == nullptr) - p_env = ThreadAndroid::get_env(); + p_env = get_jni_env(); p_env->CallVoidMethod(godot_instance, _restart); } @@ -147,21 +147,21 @@ void GodotJavaWrapper::restart(JNIEnv *p_env) { void GodotJavaWrapper::force_quit(JNIEnv *p_env) { if (_finish) if (p_env == nullptr) - p_env = ThreadAndroid::get_env(); + p_env = get_jni_env(); p_env->CallVoidMethod(godot_instance, _finish); } void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) { if (_set_keep_screen_on) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(godot_instance, _set_keep_screen_on, p_enabled); } } void GodotJavaWrapper::alert(const String &p_message, const String &p_title) { if (_alert) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data()); jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data()); env->CallVoidMethod(godot_instance, _alert, jStrMessage, jStrTitle); @@ -169,7 +169,7 @@ void GodotJavaWrapper::alert(const String &p_message, const String &p_title) { } int GodotJavaWrapper::get_gles_version_code() { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); if (_get_GLES_version_code) { return env->CallIntMethod(godot_instance, _get_GLES_version_code); } @@ -183,7 +183,7 @@ bool GodotJavaWrapper::has_get_clipboard() { String GodotJavaWrapper::get_clipboard() { if (_get_clipboard) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_clipboard); return jstring_to_string(s, env); } else { @@ -193,7 +193,7 @@ String GodotJavaWrapper::get_clipboard() { String GodotJavaWrapper::get_input_fallback_mapping() { if (_get_input_fallback_mapping) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_instance, _get_input_fallback_mapping); return jstring_to_string(fallback_mapping, env); } else { @@ -207,7 +207,7 @@ bool GodotJavaWrapper::has_set_clipboard() { void GodotJavaWrapper::set_clipboard(const String &p_text) { if (_set_clipboard) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring jStr = env->NewStringUTF(p_text.utf8().get_data()); env->CallVoidMethod(godot_instance, _set_clipboard, jStr); } @@ -215,7 +215,7 @@ void GodotJavaWrapper::set_clipboard(const String &p_text) { bool GodotJavaWrapper::request_permission(const String &p_name) { if (_request_permission) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jstring jStrName = env->NewStringUTF(p_name.utf8().get_data()); return env->CallBooleanMethod(godot_instance, _request_permission, jStrName); } else { @@ -225,7 +225,7 @@ bool GodotJavaWrapper::request_permission(const String &p_name) { bool GodotJavaWrapper::request_permissions() { if (_request_permissions) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallBooleanMethod(godot_instance, _request_permissions); } else { return false; @@ -235,7 +235,7 @@ bool GodotJavaWrapper::request_permissions() { Vector<String> GodotJavaWrapper::get_granted_permissions() const { Vector<String> permissions_list; if (_get_granted_permissions) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); jobject permissions_object = env->CallObjectMethod(godot_instance, _get_granted_permissions); jobjectArray *arr = reinterpret_cast<jobjectArray *>(&permissions_object); @@ -253,14 +253,14 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const { void GodotJavaWrapper::init_input_devices() { if (_init_input_devices) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(godot_instance, _init_input_devices); } } jobject GodotJavaWrapper::get_surface() { if (_get_surface) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallObjectMethod(godot_instance, _get_surface); } else { return nullptr; @@ -269,7 +269,7 @@ jobject GodotJavaWrapper::get_surface() { bool GodotJavaWrapper::is_activity_resumed() { if (_is_activity_resumed) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); return env->CallBooleanMethod(godot_instance, _is_activity_resumed); } else { return false; @@ -278,7 +278,7 @@ bool GodotJavaWrapper::is_activity_resumed() { void GodotJavaWrapper::vibrate(int p_duration_ms) { if (_vibrate) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms); } } diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp index ba7b3d3775..ddc2368793 100644 --- a/platform/android/net_socket_android.cpp +++ b/platform/android/net_socket_android.cpp @@ -38,7 +38,7 @@ jmethodID NetSocketAndroid::_multicast_lock_acquire = 0; jmethodID NetSocketAndroid::_multicast_lock_release = 0; void NetSocketAndroid::setup(jobject p_net_utils) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); net_utils = env->NewGlobalRef(p_net_utils); @@ -51,14 +51,14 @@ void NetSocketAndroid::setup(jobject p_net_utils) { void NetSocketAndroid::multicast_lock_acquire() { if (_multicast_lock_acquire) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(net_utils, _multicast_lock_acquire); } } void NetSocketAndroid::multicast_lock_release() { if (_multicast_lock_release) { - JNIEnv *env = ThreadAndroid::get_env(); + JNIEnv *env = get_jni_env(); env->CallVoidMethod(net_utils, _multicast_lock_release); } } diff --git a/platform/android/plugin/godot_plugin_config.h b/platform/android/plugin/godot_plugin_config.h index 611053ccba..173ac115a2 100644 --- a/platform/android/plugin/godot_plugin_config.h +++ b/platform/android/plugin/godot_plugin_config.h @@ -35,23 +35,6 @@ #include "core/io/config_file.h" #include "core/string/ustring.h" -static const char *PLUGIN_CONFIG_EXT = ".gdap"; - -static const char *CONFIG_SECTION = "config"; -static const char *CONFIG_NAME_KEY = "name"; -static const char *CONFIG_BINARY_TYPE_KEY = "binary_type"; -static const char *CONFIG_BINARY_KEY = "binary"; - -static const char *DEPENDENCIES_SECTION = "dependencies"; -static const char *DEPENDENCIES_LOCAL_KEY = "local"; -static const char *DEPENDENCIES_REMOTE_KEY = "remote"; -static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos"; - -static const char *BINARY_TYPE_LOCAL = "local"; -static const char *BINARY_TYPE_REMOTE = "remote"; - -static const char *PLUGIN_VALUE_SEPARATOR = "|"; - /* The `config` section and fields are required and defined as follow: - **name**: name of the plugin @@ -67,7 +50,24 @@ The `dependencies` section and fields are optional and defined as follow: See https://github.com/godotengine/godot/issues/38157#issuecomment-618773871 */ -struct PluginConfig { +struct PluginConfigAndroid { + inline static const char *PLUGIN_CONFIG_EXT = ".gdap"; + + inline static const char *CONFIG_SECTION = "config"; + inline static const char *CONFIG_NAME_KEY = "name"; + inline static const char *CONFIG_BINARY_TYPE_KEY = "binary_type"; + inline static const char *CONFIG_BINARY_KEY = "binary"; + + inline static const char *DEPENDENCIES_SECTION = "dependencies"; + inline static const char *DEPENDENCIES_LOCAL_KEY = "local"; + inline static const char *DEPENDENCIES_REMOTE_KEY = "remote"; + inline static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos"; + + inline static const char *BINARY_TYPE_LOCAL = "local"; + inline static const char *BINARY_TYPE_REMOTE = "remote"; + + inline static const char *PLUGIN_VALUE_SEPARATOR = "|"; + // Set to true when the config file is properly loaded. bool valid_config = false; // Unix timestamp of last change to this plugin. @@ -88,7 +88,7 @@ struct PluginConfig { * Set of prebuilt plugins. * Currently unused, this is just for future reference: */ -// static const PluginConfig MY_PREBUILT_PLUGIN = { +// static const PluginConfigAndroid MY_PREBUILT_PLUGIN = { // /*.valid_config =*/true, // /*.last_updated =*/0, // /*.name =*/"GodotPayment", @@ -112,9 +112,9 @@ static inline String resolve_local_dependency_path(String plugin_config_dir, Str return absolute_path; } -static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin, String plugin_config_dir) { - PluginConfig resolved = prebuilt_plugin; - resolved.binary = resolved.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary; +static inline PluginConfigAndroid resolve_prebuilt_plugin(PluginConfigAndroid prebuilt_plugin, String plugin_config_dir) { + PluginConfigAndroid resolved = prebuilt_plugin; + resolved.binary = resolved.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary; if (!prebuilt_plugin.local_dependencies.is_empty()) { resolved.local_dependencies.clear(); for (int i = 0; i < prebuilt_plugin.local_dependencies.size(); i++) { @@ -124,21 +124,22 @@ static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin, return resolved; } -static inline Vector<PluginConfig> get_prebuilt_plugins(String plugins_base_dir) { - Vector<PluginConfig> prebuilt_plugins; +static inline Vector<PluginConfigAndroid> get_prebuilt_plugins(String plugins_base_dir) { + Vector<PluginConfigAndroid> prebuilt_plugins; // prebuilt_plugins.push_back(resolve_prebuilt_plugin(MY_PREBUILT_PLUGIN, plugins_base_dir)); return prebuilt_plugins; } -static inline bool is_plugin_config_valid(PluginConfig plugin_config) { +static inline bool is_plugin_config_valid(PluginConfigAndroid plugin_config) { bool valid_name = !plugin_config.name.is_empty(); - bool valid_binary_type = plugin_config.binary_type == BINARY_TYPE_LOCAL || - plugin_config.binary_type == BINARY_TYPE_REMOTE; + bool valid_binary_type = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL || + plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE; bool valid_binary = false; if (valid_binary_type) { valid_binary = !plugin_config.binary.is_empty() && - (plugin_config.binary_type == BINARY_TYPE_REMOTE || + (plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE || + FileAccess::exists(plugin_config.binary)); } @@ -154,7 +155,7 @@ static inline bool is_plugin_config_valid(PluginConfig plugin_config) { return valid_name && valid_binary && valid_binary_type && valid_local_dependencies; } -static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) { +static inline uint64_t get_plugin_modification_time(const PluginConfigAndroid &plugin_config, const String &config_path) { uint64_t last_updated = FileAccess::get_modified_time(config_path); last_updated = MAX(last_updated, FileAccess::get_modified_time(plugin_config.binary)); @@ -166,30 +167,30 @@ static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_c return last_updated; } -static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) { - PluginConfig plugin_config = {}; +static inline PluginConfigAndroid load_plugin_config(Ref<ConfigFile> config_file, const String &path) { + PluginConfigAndroid plugin_config = {}; if (config_file.is_valid()) { Error err = config_file->load(path); if (err == OK) { String config_base_dir = path.get_base_dir(); - plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String()); - plugin_config.binary_type = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_TYPE_KEY, String()); + plugin_config.name = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_NAME_KEY, String()); + plugin_config.binary_type = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_BINARY_TYPE_KEY, String()); - String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String()); - plugin_config.binary = plugin_config.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path; + String binary_path = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_BINARY_KEY, String()); + plugin_config.binary = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path; - if (config_file->has_section(DEPENDENCIES_SECTION)) { - Vector<String> local_dependencies_paths = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LOCAL_KEY, Vector<String>()); + if (config_file->has_section(PluginConfigAndroid::DEPENDENCIES_SECTION)) { + Vector<String> local_dependencies_paths = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_LOCAL_KEY, Vector<String>()); if (!local_dependencies_paths.is_empty()) { for (int i = 0; i < local_dependencies_paths.size(); i++) { plugin_config.local_dependencies.push_back(resolve_local_dependency_path(config_base_dir, local_dependencies_paths[i])); } } - plugin_config.remote_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_REMOTE_KEY, Vector<String>()); - plugin_config.custom_maven_repos = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>()); + plugin_config.remote_dependencies = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_REMOTE_KEY, Vector<String>()); + plugin_config.custom_maven_repos = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>()); } plugin_config.valid_config = is_plugin_config_valid(plugin_config); @@ -200,12 +201,12 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const return plugin_config; } -static inline String get_plugins_binaries(String binary_type, Vector<PluginConfig> plugins_configs) { +static inline String get_plugins_binaries(String binary_type, Vector<PluginConfigAndroid> plugins_configs) { String plugins_binaries; if (!plugins_configs.is_empty()) { Vector<String> binaries; for (int i = 0; i < plugins_configs.size(); i++) { - PluginConfig config = plugins_configs[i]; + PluginConfigAndroid config = plugins_configs[i]; if (!config.valid_config) { continue; } @@ -214,27 +215,27 @@ static inline String get_plugins_binaries(String binary_type, Vector<PluginConfi binaries.push_back(config.binary); } - if (binary_type == BINARY_TYPE_LOCAL) { + if (binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL) { binaries.append_array(config.local_dependencies); } - if (binary_type == BINARY_TYPE_REMOTE) { + if (binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE) { binaries.append_array(config.remote_dependencies); } } - plugins_binaries = String(PLUGIN_VALUE_SEPARATOR).join(binaries); + plugins_binaries = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(binaries); } return plugins_binaries; } -static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins_configs) { +static inline String get_plugins_custom_maven_repos(Vector<PluginConfigAndroid> plugins_configs) { String custom_maven_repos; if (!plugins_configs.is_empty()) { Vector<String> repos_urls; for (int i = 0; i < plugins_configs.size(); i++) { - PluginConfig config = plugins_configs[i]; + PluginConfigAndroid config = plugins_configs[i]; if (!config.valid_config) { continue; } @@ -242,24 +243,24 @@ static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins repos_urls.append_array(config.custom_maven_repos); } - custom_maven_repos = String(PLUGIN_VALUE_SEPARATOR).join(repos_urls); + custom_maven_repos = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(repos_urls); } return custom_maven_repos; } -static inline String get_plugins_names(Vector<PluginConfig> plugins_configs) { +static inline String get_plugins_names(Vector<PluginConfigAndroid> plugins_configs) { String plugins_names; if (!plugins_configs.is_empty()) { Vector<String> names; for (int i = 0; i < plugins_configs.size(); i++) { - PluginConfig config = plugins_configs[i]; + PluginConfigAndroid config = plugins_configs[i]; if (!config.valid_config) { continue; } names.push_back(config.name); } - plugins_names = String(PLUGIN_VALUE_SEPARATOR).join(names); + plugins_names = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(names); } return plugins_names; diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp index f602e99e61..ba3e9fa20f 100644 --- a/platform/android/plugin/godot_plugin_jni.cpp +++ b/platform/android/plugin/godot_plugin_jni.cpp @@ -41,7 +41,7 @@ static HashMap<String, JNISingleton *> jni_singletons; extern "C" { -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) { String singname = jstring_to_string(name, env); JNISingleton *s = (JNISingleton *)ClassDB::instance("JNISingleton"); s->set_instance(env->NewGlobalRef(obj)); @@ -51,7 +51,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis ProjectSettings::get_singleton()->set(singname, s); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args) { String singname = jstring_to_string(sname, env); ERR_FAIL_COND(!jni_singletons.has(singname)); @@ -83,7 +83,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis s->add_method(mname, mid, types, get_jni_type(retval)); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) { String singleton_name = jstring_to_string(j_plugin_name, env); ERR_FAIL_COND(!jni_singletons.has(singleton_name)); @@ -104,7 +104,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis singleton->add_signal(signal_name, types); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) { String singleton_name = jstring_to_string(j_plugin_name, env); ERR_FAIL_COND(!jni_singletons.has(singleton_name)); @@ -129,7 +129,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS singleton->emit_signal(signal_name, args, count); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths) { int gdnlib_count = env->GetArrayLength(gdnlib_paths); if (gdnlib_count == 0) { return; diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h index 8a08ec3709..b87f922e03 100644 --- a/platform/android/plugin/godot_plugin_jni.h +++ b/platform/android/plugin/godot_plugin_jni.h @@ -35,11 +35,11 @@ #include <jni.h> extern "C" { -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name); -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args); -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types); -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params); -JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths); } #endif // GODOT_PLUGIN_JNI_H diff --git a/platform/android/string_android.h b/platform/android/string_android.h index 25c6f749d4..3721315d3f 100644 --- a/platform/android/string_android.h +++ b/platform/android/string_android.h @@ -37,14 +37,14 @@ /** * Converts JNI jstring to Godot String. * @param source Source JNI string. If null an empty string is returned. - * @param env JNI environment instance. If null obtained by ThreadAndroid::get_env(). + * @param env JNI environment instance. If null obtained by get_jni_env(). * @return Godot string instance. */ static inline String jstring_to_string(jstring source, JNIEnv *env = nullptr) { String result; if (source) { if (!env) { - env = ThreadAndroid::get_env(); + env = get_jni_env(); } const char *const source_utf8 = env->GetStringUTFChars(source, nullptr); if (source_utf8) { diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index cb3527067f..afcc7294f2 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -30,116 +30,29 @@ #include "thread_jandroid.h" -#include "core/object/script_language.h" -#include "core/os/memory.h" -#include "core/templates/safe_refcount.h" +#include "core/os/thread.h" -static void _thread_id_key_destr_callback(void *p_value) { - memdelete(static_cast<Thread::ID *>(p_value)); -} - -static pthread_key_t _create_thread_id_key() { - pthread_key_t key; - pthread_key_create(&key, &_thread_id_key_destr_callback); - return key; -} - -pthread_key_t ThreadAndroid::thread_id_key = _create_thread_id_key(); -Thread::ID ThreadAndroid::next_thread_id = 0; - -Thread::ID ThreadAndroid::get_id() const { - return id; -} - -Thread *ThreadAndroid::create_thread_jandroid() { - return memnew(ThreadAndroid); -} - -void *ThreadAndroid::thread_callback(void *userdata) { - ThreadAndroid *t = reinterpret_cast<ThreadAndroid *>(userdata); - setup_thread(); - ScriptServer::thread_enter(); //scripts may need to attach a stack - t->id = atomic_increment(&next_thread_id); - pthread_setspecific(thread_id_key, (void *)memnew(ID(t->id))); - t->callback(t->user); - ScriptServer::thread_exit(); - return nullptr; -} - -Thread *ThreadAndroid::create_func_jandroid(ThreadCreateCallback p_callback, void *p_user, const Settings &) { - ThreadAndroid *tr = memnew(ThreadAndroid); - tr->callback = p_callback; - tr->user = p_user; - pthread_attr_init(&tr->pthread_attr); - pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE); - - pthread_create(&tr->pthread, &tr->pthread_attr, thread_callback, tr); - - return tr; -} +static JavaVM *java_vm = nullptr; +static thread_local JNIEnv *env = nullptr; -Thread::ID ThreadAndroid::get_thread_id_func_jandroid() { - void *value = pthread_getspecific(thread_id_key); - - if (value) - return *static_cast<ID *>(value); - - ID new_id = atomic_increment(&next_thread_id); - pthread_setspecific(thread_id_key, (void *)memnew(ID(new_id))); - return new_id; -} - -void ThreadAndroid::wait_to_finish_func_jandroid(Thread *p_thread) { - ThreadAndroid *tp = static_cast<ThreadAndroid *>(p_thread); - ERR_FAIL_COND(!tp); - ERR_FAIL_COND(tp->pthread == 0); - - pthread_join(tp->pthread, nullptr); - tp->pthread = 0; -} - -void ThreadAndroid::_thread_destroyed(void *value) { - /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */ - JNIEnv *env = (JNIEnv *)value; - if (env != nullptr) { - java_vm->DetachCurrentThread(); - pthread_setspecific(jvm_key, nullptr); - } -} - -pthread_key_t ThreadAndroid::jvm_key; -JavaVM *ThreadAndroid::java_vm = nullptr; - -void ThreadAndroid::setup_thread() { - if (pthread_getspecific(jvm_key)) - return; //already setup - JNIEnv *env; +static void init_thread() { java_vm->AttachCurrentThread(&env, nullptr); - pthread_setspecific(jvm_key, (void *)env); } -void ThreadAndroid::make_default(JavaVM *p_java_vm) { - java_vm = p_java_vm; - create_func = create_func_jandroid; - get_thread_id_func = get_thread_id_func_jandroid; - wait_to_finish_func = wait_to_finish_func_jandroid; - pthread_key_create(&jvm_key, _thread_destroyed); - setup_thread(); +static void term_thread() { + java_vm->DetachCurrentThread(); } -JNIEnv *ThreadAndroid::get_env() { - if (!pthread_getspecific(jvm_key)) { - setup_thread(); - } - - JNIEnv *env = nullptr; - java_vm->AttachCurrentThread(&env, nullptr); - return env; +void init_thread_jandroid(JavaVM *p_jvm, JNIEnv *p_env) { + java_vm = p_jvm; + env = p_env; + Thread::_set_platform_funcs(nullptr, nullptr, &init_thread, &term_thread); } -ThreadAndroid::ThreadAndroid() { - pthread = 0; +void setup_android_thread() { + init_thread(); } -ThreadAndroid::~ThreadAndroid() { +JNIEnv *get_jni_env() { + return env; } diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h index c37e2d740e..ff13ae911f 100644 --- a/platform/android/thread_jandroid.h +++ b/platform/android/thread_jandroid.h @@ -28,46 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef THREAD_POSIX_H -#define THREAD_POSIX_H +#ifndef THREAD_JANDROID_H +#define THREAD_JANDROID_H -#include "core/os/thread.h" #include <jni.h> -#include <pthread.h> -#include <sys/types.h> -class ThreadAndroid : public Thread { - static pthread_key_t thread_id_key; - static ID next_thread_id; +void init_thread_jandroid(JavaVM *p_jvm, JNIEnv *p_env); - pthread_t pthread; - pthread_attr_t pthread_attr; - ThreadCreateCallback callback; - void *user; - ID id; - - static Thread *create_thread_jandroid(); - - static void *thread_callback(void *userdata); - - static Thread *create_func_jandroid(ThreadCreateCallback p_callback, void *, const Settings &); - static ID get_thread_id_func_jandroid(); - static void wait_to_finish_func_jandroid(Thread *p_thread); - - static void _thread_destroyed(void *value); - ThreadAndroid(); - - static pthread_key_t jvm_key; - static JavaVM *java_vm; - -public: - virtual ID get_id() const; - - static void make_default(JavaVM *p_java_vm); - static void setup_thread(); - static JNIEnv *get_env(); - - ~ThreadAndroid(); -}; +void setup_android_thread(); +JNIEnv *get_jni_env(); #endif diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index ad4af9ba6a..17796beb6f 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -34,6 +34,7 @@ def get_opts(): " validation layers)", False, ), + BoolVariable("ios_simulator", "Build for iOS Simulator", False), BoolVariable("ios_exceptions", "Enable exceptions", False), ("ios_triple", "Triple for ios toolchain", ""), ] @@ -107,8 +108,17 @@ def configure(env): ## Compile flags - if env["arch"] == "x86" or env["arch"] == "x86_64": + if env["ios_simulator"]: detect_darwin_sdk_path("iphonesimulator", env) + env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"]) + env.Append(LINKFLAGS=["-mios-simulator-version-min=13.0"]) + env.extra_suffix = ".simulator" + env.extra_suffix + else: + detect_darwin_sdk_path("iphone", env) + env.Append(CCFLAGS=["-miphoneos-version-min=11.0"]) + env.Append(LINKFLAGS=["-miphoneos-version-min=11.0"]) + + if env["arch"] == "x86" or env["arch"] == "x86_64": env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9" arch_flag = "i386" if env["arch"] == "x86" else env["arch"] env.Append( @@ -116,11 +126,10 @@ def configure(env): "-fobjc-arc -arch " + arch_flag + " -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks" - " -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=13.0" + " -fasm-blocks -isysroot $IPHONESDK" ).split() ) elif env["arch"] == "arm": - detect_darwin_sdk_path("iphone", env) env.Append( CCFLAGS=( "-fobjc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing" @@ -128,16 +137,15 @@ def configure(env): " -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb" ' "-DIBOutlet=__attribute__((iboutlet))"' ' "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))"' - ' "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=11.0 -MMD -MT dependencies'.split() + ' "-DIBAction=void)__attribute__((ibaction)" -MMD -MT dependencies'.split() ) ) elif env["arch"] == "arm64": - detect_darwin_sdk_path("iphone", env) env.Append( CCFLAGS=( "-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing" " -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits" - " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=11.0" + " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies" " -isysroot $IPHONESDK".split() ) ) @@ -162,7 +170,6 @@ def configure(env): LINKFLAGS=[ "-arch", arch_flag, - "-mios-simulator-version-min=13.0", "-isysroot", "$IPHONESDK", "-Xlinker", @@ -173,46 +180,14 @@ def configure(env): ] ) elif env["arch"] == "arm": - env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip", "-miphoneos-version-min=11.0"]) + env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip"]) if env["arch"] == "arm64": - env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip", "-miphoneos-version-min=11.0"]) + env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip"]) env.Append( LINKFLAGS=[ "-isysroot", "$IPHONESDK", - "-framework", - "AudioToolbox", - "-framework", - "AVFoundation", - "-framework", - "CoreAudio", - "-framework", - "CoreGraphics", - "-framework", - "CoreMedia", - "-framework", - "CoreVideo", - "-framework", - "CoreMotion", - "-framework", - "Foundation", - "-framework", - "GameController", - "-framework", - "MediaPlayer", - "-framework", - "Metal", - "-framework", - "QuartzCore", - "-framework", - "Security", - "-framework", - "SystemConfiguration", - "-framework", - "UIKit", - "-framework", - "ARKit", ] ) diff --git a/platform/iphone/display_layer.mm b/platform/iphone/display_layer.mm index fb57db4518..b8df81b89a 100644 --- a/platform/iphone/display_layer.mm +++ b/platform/iphone/display_layer.mm @@ -89,7 +89,7 @@ // FIXME: Add Vulkan support via MoltenVK. Add fallback code back? // Create GL ES 2 context - if (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES2") { + if (GLOBAL_GET("rendering/driver/driver_name") == "GLES2") { context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; NSLog(@"Setting up an OpenGL ES 2.0 context."); if (!context) { diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 3253112bf3..c585c2afbe 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -37,6 +37,7 @@ #include "core/io/zip_io.h" #include "core/os/file_access.h" #include "core/os/os.h" +#include "core/templates/safe_refcount.h" #include "core/version.h" #include "editor/editor_export.h" #include "editor/editor_node.h" @@ -56,11 +57,11 @@ class EditorExportPlatformIOS : public EditorExportPlatform { Ref<ImageTexture> logo; // Plugins - volatile bool plugins_changed; - Thread *check_for_changes_thread; - volatile bool quit_request; + SafeFlag plugins_changed; + Thread check_for_changes_thread; + SafeFlag quit_request; Mutex plugins_lock; - Vector<PluginConfig> plugins; + Vector<PluginConfigIOS> plugins; typedef Error (*FileHandler)(String p_file, void *p_userdata); static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata); @@ -141,19 +142,19 @@ class EditorExportPlatformIOS : public EditorExportPlatform { static void _check_for_changes_poll_thread(void *ud) { EditorExportPlatformIOS *ea = (EditorExportPlatformIOS *)ud; - while (!ea->quit_request) { + while (!ea->quit_request.is_set()) { // Nothing to do if we already know the plugins have changed. - if (!ea->plugins_changed) { + if (!ea->plugins_changed.is_set()) { MutexLock lock(ea->plugins_lock); - Vector<PluginConfig> loaded_plugins = get_plugins(); + Vector<PluginConfigIOS> loaded_plugins = get_plugins(); if (ea->plugins.size() != loaded_plugins.size()) { - ea->plugins_changed = true; + ea->plugins_changed.set(); } else { for (int i = 0; i < ea->plugins.size(); i++) { if (ea->plugins[i].name != loaded_plugins[i].name || ea->plugins[i].last_updated != loaded_plugins[i].last_updated) { - ea->plugins_changed = true; + ea->plugins_changed.set(); break; } } @@ -165,7 +166,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { while (OS::get_singleton()->get_ticks_usec() - time < wait) { OS::get_singleton()->delay_usec(300000); - if (ea->quit_request) { + if (ea->quit_request.is_set()) { break; } } @@ -182,10 +183,10 @@ public: virtual Ref<Texture2D> get_logo() const override { return logo; } virtual bool should_update_export_options() override { - bool export_options_changed = plugins_changed; + bool export_options_changed = plugins_changed.is_set(); if (export_options_changed) { // don't clear unless we're reporting true, to avoid race - plugins_changed = false; + plugins_changed.clear(); } return export_options_changed; } @@ -241,7 +242,7 @@ public: continue; } - if (file.ends_with(PLUGIN_CONFIG_EXT)) { + if (file.ends_with(PluginConfigIOS::PLUGIN_CONFIG_EXT)) { dir_files.push_back(file); } } @@ -251,8 +252,8 @@ public: return dir_files; } - static Vector<PluginConfig> get_plugins() { - Vector<PluginConfig> loaded_plugins; + static Vector<PluginConfigIOS> get_plugins() { + Vector<PluginConfigIOS> loaded_plugins; String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("ios/plugins"); @@ -262,7 +263,7 @@ public: if (!plugins_filenames.is_empty()) { Ref<ConfigFile> config_file = memnew(ConfigFile); for (int i = 0; i < plugins_filenames.size(); i++) { - PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i])); + PluginConfigIOS config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i])); if (config.valid_config) { loaded_plugins.push_back(config); } else { @@ -275,11 +276,11 @@ public: return loaded_plugins; } - static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) { - Vector<PluginConfig> enabled_plugins; - Vector<PluginConfig> all_plugins = get_plugins(); + static Vector<PluginConfigIOS> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) { + Vector<PluginConfigIOS> enabled_plugins; + Vector<PluginConfigIOS> all_plugins = get_plugins(); for (int i = 0; i < all_plugins.size(); i++) { - PluginConfig plugin = all_plugins[i]; + PluginConfigIOS plugin = all_plugins[i]; bool enabled = p_presets->get("plugins/" + plugin.name); if (enabled) { enabled_plugins.push_back(plugin); @@ -291,7 +292,7 @@ public: }; void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); + String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); r_features->push_back("pvrtc"); if (driver == "Vulkan") { // FIXME: Review if this is correct. @@ -360,11 +361,11 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); - Vector<PluginConfig> found_plugins = get_plugins(); + Vector<PluginConfigIOS> found_plugins = get_plugins(); for (int i = 0; i < found_plugins.size(); i++) { r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false)); } - plugins_changed = false; + plugins_changed.clear(); plugins = found_plugins; r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false)); @@ -979,7 +980,7 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) { codesign_args.push_back("-s"); codesign_args.push_back(data->preset->get(data->debug ? "application/code_sign_identity_debug" : "application/code_sign_identity_release")); codesign_args.push_back(p_file); - return OS::get_singleton()->execute("codesign", codesign_args, true); + return OS::get_singleton()->execute("codesign", codesign_args); } return OK; } @@ -1229,7 +1230,7 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String install_name_args.push_back(String("@rpath").plus_file(framework_name).plus_file(file_name)); install_name_args.push_back(destination); - OS::get_singleton()->execute("install_name_tool", install_name_args, true); + OS::get_singleton()->execute("install_name_tool", install_name_args); } // Creating Info.plist @@ -1345,28 +1346,25 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> Vector<String> plugin_embedded_dependencies; Vector<String> plugin_files; - Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset); + Vector<PluginConfigIOS> enabled_plugins = get_enabled_plugins(p_preset); Vector<String> added_linked_dependenciy_names; Vector<String> added_embedded_dependenciy_names; HashMap<String, String> plist_values; + Set<String> plugin_linker_flags; + Error err; for (int i = 0; i < enabled_plugins.size(); i++) { - PluginConfig plugin = enabled_plugins[i]; + PluginConfigIOS plugin = enabled_plugins[i]; // Export plugin binary. - if (!plugin.supports_targets) { - err = _copy_asset(dest_dir, plugin.binary, nullptr, true, true, r_exported_assets); - } else { - String plugin_binary_dir = plugin.binary.get_base_dir(); - String plugin_name_prefix = plugin.binary.get_basename().get_file(); - String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + ".a"; - String result_file_name = plugin.binary.get_file(); - - err = _copy_asset(dest_dir, plugin_binary_dir.plus_file(plugin_file), &result_file_name, true, true, r_exported_assets); - } + String plugin_main_binary = get_plugin_main_binary(plugin, p_debug); + String plugin_binary_result_file = plugin.binary.get_file(); + // We shouldn't embed .xcframework that contains static libraries. + // Static libraries are not embedded anyway. + err = _copy_asset(dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets); ERR_FAIL_COND_V(err, err); @@ -1422,6 +1420,13 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> p_config_data.capabilities.push_back(capability); } + // Linker flags + // Checking duplicates + for (int j = 0; j < plugin.linker_flags.size(); j++) { + String linker_flag = plugin.linker_flags[j]; + plugin_linker_flags.insert(linker_flag); + } + // Plist // Using hash map container to remove duplicates const String *K = nullptr; @@ -1502,6 +1507,27 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_"); } + + // Update Linker Flag Values + { + String result_linker_flags = " "; + for (Set<String>::Element *E = plugin_linker_flags.front(); E; E = E->next()) { + const String &flag = E->get(); + + if (flag.length() == 0) { + continue; + } + + if (result_linker_flags.length() > 0) { + result_linker_flags += ' '; + } + + result_linker_flags += flag; + } + result_linker_flags = result_linker_flags.replace("\"", "\\\""); + p_config_data.linker_flags += result_linker_flags; + } + return OK; } @@ -1575,9 +1601,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p return ERR_SKIP; } - String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".fat.a"; + String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework"; - print_line("Static library: " + library_to_use); + print_line("Static framework: " + library_to_use); String pkg_name; if (p_preset->get("application/name") != "") { pkg_name = p_preset->get("application/name"); // app_name @@ -1663,7 +1689,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p if (files_to_parse.has(file)) { _fix_config_file(p_preset, data, config_data, p_debug); } else if (file.begins_with("libgodot.iphone")) { - if (file != library_to_use) { + if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) { ret = unzGoToNextFile(src_pkg_zip); continue; //ignore! } @@ -1671,7 +1697,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p #if defined(OSX_ENABLED) || defined(X11_ENABLED) is_execute = true; #endif - file = "godot_ios.a"; + file = file.replace(library_to_use, binary_name + ".xcframework"); } if (file == project_file) { @@ -1848,7 +1874,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p archive_args.push_back("archive"); archive_args.push_back("-archivePath"); archive_args.push_back(archive_path); - err = OS::get_singleton()->execute("xcodebuild", archive_args, true); + err = OS::get_singleton()->execute("xcodebuild", archive_args); ERR_FAIL_COND_V(err, err); if (ep.step("Making .ipa", 4)) { @@ -1863,7 +1889,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p export_args.push_back("-allowProvisioningUpdates"); export_args.push_back("-exportPath"); export_args.push_back(dest_dir); - err = OS::get_singleton()->execute("xcodebuild", export_args, true); + err = OS::get_singleton()->execute("xcodebuild", export_args); ERR_FAIL_COND_V(err, err); #else print_line(".ipa can only be built on macOS. Leaving Xcode project without building the package."); @@ -1942,16 +1968,14 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() { logo.instance(); logo->create_from_image(img); - plugins_changed = true; - quit_request = false; + plugins_changed.set(); - check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this); + check_for_changes_thread.start(_check_for_changes_poll_thread, this); } EditorExportPlatformIOS::~EditorExportPlatformIOS() { - quit_request = true; - Thread::wait_to_finish(check_for_changes_thread); - memdelete(check_for_changes_thread); + quit_request.set(); + check_for_changes_thread.wait_to_finish(); } void register_iphone_exporter() { diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m index 7b9cf7893c..3ce9bffc79 100644 --- a/platform/iphone/godot_app_delegate.m +++ b/platform/iphone/godot_app_delegate.m @@ -302,37 +302,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil; // MARK: Remote Notification -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - for (ApplicationDelegateService *service in services) { - if (![service respondsToSelector:_cmd]) { - continue; - } - - [service application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; - } -} - -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { - for (ApplicationDelegateService *service in services) { - if (![service respondsToSelector:_cmd]) { - continue; - } - - [service application:application didFailToRegisterForRemoteNotificationsWithError:error]; - } -} - -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler { - for (ApplicationDelegateService *service in services) { - if (![service respondsToSelector:_cmd]) { - continue; - } - - [service application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; - } - - completionHandler(UIBackgroundFetchResultNoData); -} +// Moved to the iOS Plugin // MARK: User Activity and Handling Quick Actions diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h index 29960c47a8..265f826173 100644 --- a/platform/iphone/godot_view.h +++ b/platform/iphone/godot_view.h @@ -32,12 +32,20 @@ class String; +@class GodotView; @protocol DisplayLayer; @protocol GodotViewRendererProtocol; +@protocol GodotViewDelegate + +- (BOOL)godotViewFinishedSetup:(GodotView *)view; + +@end + @interface GodotView : UIView @property(assign, nonatomic) id<GodotViewRendererProtocol> renderer; +@property(assign, nonatomic) id<GodotViewDelegate> delegate; @property(assign, readonly, nonatomic) BOOL isActive; diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm index bf073ae295..887297848e 100644 --- a/platform/iphone/godot_view.mm +++ b/platform/iphone/godot_view.mm @@ -120,6 +120,7 @@ static const int max_touches = 8; [self stopRendering]; self.renderer = nil; + self.delegate = nil; if (self.renderingLayer) { [self.renderingLayer removeFromSuperlayer]; @@ -241,6 +242,14 @@ static const int max_touches = 8; return; } + if (self.delegate) { + BOOL delegateFinishedSetup = [self.delegate godotViewFinishedSetup:self]; + + if (!delegateFinishedSetup) { + return; + } + } + [self handleMotion]; [self.renderer renderOnView:self]; } diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index 625cbf178e..51c4da2960 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -144,8 +144,6 @@ void OSIPhone::deinitialize_modules() { } void OSIPhone::set_main_loop(MainLoop *p_main_loop) { - godot_ios_plugins_initialize(); - main_loop = p_main_loop; if (main_loop) { @@ -179,6 +177,8 @@ bool OSIPhone::iterate() { } void OSIPhone::start() { + godot_ios_plugins_initialize(); + Main::start(); if (joypad_iphone) { diff --git a/platform/iphone/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h index 89f657821e..f4e30c8349 100644 --- a/platform/iphone/plugin/godot_plugin_config.h +++ b/platform/iphone/plugin/godot_plugin_config.h @@ -35,23 +35,6 @@ #include "core/io/config_file.h" #include "core/string/ustring.h" -static const char *PLUGIN_CONFIG_EXT = ".gdip"; - -static const char *CONFIG_SECTION = "config"; -static const char *CONFIG_NAME_KEY = "name"; -static const char *CONFIG_BINARY_KEY = "binary"; -static const char *CONFIG_INITIALIZE_KEY = "initialization"; -static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization"; - -static const char *DEPENDENCIES_SECTION = "dependencies"; -static const char *DEPENDENCIES_LINKED_KEY = "linked"; -static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded"; -static const char *DEPENDENCIES_SYSTEM_KEY = "system"; -static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities"; -static const char *DEPENDENCIES_FILES_KEY = "files"; - -static const char *PLIST_SECTION = "plist"; - /* The `config` section and fields are required and defined as follow: - **name**: name of the plugin @@ -68,7 +51,25 @@ The `plist` section are optional. - **key**: key and value that would be added in Info.plist file. */ -struct PluginConfig { +struct PluginConfigIOS { + inline static const char *PLUGIN_CONFIG_EXT = ".gdip"; + + inline static const char *CONFIG_SECTION = "config"; + inline static const char *CONFIG_NAME_KEY = "name"; + inline static const char *CONFIG_BINARY_KEY = "binary"; + inline static const char *CONFIG_INITIALIZE_KEY = "initialization"; + inline static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization"; + + inline static const char *DEPENDENCIES_SECTION = "dependencies"; + inline static const char *DEPENDENCIES_LINKED_KEY = "linked"; + inline static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded"; + inline static const char *DEPENDENCIES_SYSTEM_KEY = "system"; + inline static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities"; + inline static const char *DEPENDENCIES_FILES_KEY = "files"; + inline static const char *DEPENDENCIES_LINKER_FLAGS = "linker_flags"; + + inline static const char *PLIST_SECTION = "plist"; + // Set to true when the config file is properly loaded. bool valid_config = false; bool supports_targets = false; @@ -89,6 +90,8 @@ struct PluginConfig { Vector<String> files_to_copy; Vector<String> capabilities; + Vector<String> linker_flags; + // Optional plist section // Supports only string types for now HashMap<String, String> plist; @@ -159,7 +162,7 @@ static inline Vector<String> resolve_system_dependencies(Vector<String> p_paths) return paths; } -static inline bool validate_plugin(PluginConfig &plugin_config) { +static inline bool validate_plugin(PluginConfigIOS &plugin_config) { bool valid_name = !plugin_config.name.is_empty(); bool valid_binary_name = !plugin_config.binary.is_empty(); bool valid_initialize = !plugin_config.initialization_method.is_empty(); @@ -167,16 +170,25 @@ static inline bool validate_plugin(PluginConfig &plugin_config) { bool fields_value = valid_name && valid_binary_name && valid_initialize && valid_deinitialize; - if (fields_value && FileAccess::exists(plugin_config.binary)) { + if (!fields_value) { + return false; + } + + String plugin_extension = plugin_config.binary.get_extension().to_lower(); + + if ((plugin_extension == "a" && FileAccess::exists(plugin_config.binary)) || + (plugin_extension == "xcframework" && DirAccess::exists(plugin_config.binary))) { plugin_config.valid_config = true; plugin_config.supports_targets = false; - } else if (fields_value) { + } else { String file_path = plugin_config.binary.get_base_dir(); String file_name = plugin_config.binary.get_basename().get_file(); - String release_file_name = file_path.plus_file(file_name + ".release.a"); - String debug_file_name = file_path.plus_file(file_name + ".debug.a"); + String file_extension = plugin_config.binary.get_extension(); + String release_file_name = file_path.plus_file(file_name + ".release." + file_extension); + String debug_file_name = file_path.plus_file(file_name + ".debug." + file_extension); - if (FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) { + if ((plugin_extension == "a" && FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) || + (plugin_extension == "xcframework" && DirAccess::exists(release_file_name) && DirAccess::exists(debug_file_name))) { plugin_config.valid_config = true; plugin_config.supports_targets = true; } @@ -185,7 +197,20 @@ static inline bool validate_plugin(PluginConfig &plugin_config) { return plugin_config.valid_config; } -static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) { +static inline String get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug) { + if (!plugin_config.supports_targets) { + return plugin_config.binary; + } + + String plugin_binary_dir = plugin_config.binary.get_base_dir(); + String plugin_name_prefix = plugin_config.binary.get_basename().get_file(); + String plugin_extension = plugin_config.binary.get_extension(); + String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + "." + plugin_extension; + + return plugin_binary_dir.plus_file(plugin_file); +} + +static inline uint64_t get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path) { uint64_t last_updated = FileAccess::get_modified_time(config_path); if (!plugin_config.supports_targets) { @@ -203,8 +228,8 @@ static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_c return last_updated; } -static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) { - PluginConfig plugin_config = {}; +static inline PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path) { + PluginConfigIOS plugin_config = {}; if (!config_file.is_valid()) { return plugin_config; @@ -218,18 +243,18 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String config_base_dir = path.get_base_dir(); - plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String()); - plugin_config.initialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_INITIALIZE_KEY, String()); - plugin_config.deinitialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_DEINITIALIZE_KEY, String()); + plugin_config.name = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_NAME_KEY, String()); + plugin_config.initialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_INITIALIZE_KEY, String()); + plugin_config.deinitialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_DEINITIALIZE_KEY, String()); - String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String()); + String binary_path = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_BINARY_KEY, String()); plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path); - if (config_file->has_section(DEPENDENCIES_SECTION)) { - Vector<String> linked_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LINKED_KEY, Vector<String>()); - Vector<String> embedded_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_EMBEDDED_KEY, Vector<String>()); - Vector<String> system_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_SYSTEM_KEY, Vector<String>()); - Vector<String> files = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_FILES_KEY, Vector<String>()); + if (config_file->has_section(PluginConfigIOS::DEPENDENCIES_SECTION)) { + Vector<String> linked_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKED_KEY, Vector<String>()); + Vector<String> embedded_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_EMBEDDED_KEY, Vector<String>()); + Vector<String> system_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_SYSTEM_KEY, Vector<String>()); + Vector<String> files = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_FILES_KEY, Vector<String>()); plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies); plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies); @@ -237,15 +262,17 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files); - plugin_config.capabilities = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CAPABILITIES_KEY, Vector<String>()); + plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>()); + + plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>()); } - if (config_file->has_section(PLIST_SECTION)) { + if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) { List<String> keys; - config_file->get_section_keys(PLIST_SECTION, &keys); + config_file->get_section_keys(PluginConfigIOS::PLIST_SECTION, &keys); for (int i = 0; i < keys.size(); i++) { - String value = config_file->get_value(PLIST_SECTION, keys[i], String()); + String value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, keys[i], String()); if (value.is_empty()) { continue; diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index c41aa13bb7..6cef244567 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -40,12 +40,14 @@ #import <AVFoundation/AVFoundation.h> #import <GameController/GameController.h> -@interface ViewController () +@interface ViewController () <GodotViewDelegate> @property(strong, nonatomic) GodotViewRenderer *renderer; @property(strong, nonatomic) GodotNativeVideoView *videoView; @property(strong, nonatomic) GodotKeyboardInputView *keyboardView; +@property(strong, nonatomic) UIView *godotLoadingOverlay; + @end @implementation ViewController @@ -62,6 +64,7 @@ self.view = view; view.renderer = self.renderer; + view.delegate = self; } - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { @@ -97,6 +100,7 @@ [super viewDidLoad]; [self observeKeyboard]; + [self displayLoadingOverlay]; if (@available(iOS 11.0, *)) { [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; @@ -121,6 +125,31 @@ object:nil]; } +- (void)displayLoadingOverlay { + NSBundle *bundle = [NSBundle mainBundle]; + NSString *storyboardName = @"Launch Screen"; + + if ([bundle pathForResource:storyboardName ofType:@"storyboardc"] == nil) { + return; + } + + UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle]; + + UIViewController *controller = [launchStoryboard instantiateInitialViewController]; + self.godotLoadingOverlay = controller.view; + self.godotLoadingOverlay.frame = self.view.bounds; + self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + + [self.view addSubview:self.godotLoadingOverlay]; +} + +- (BOOL)godotViewFinishedSetup:(GodotView *)view { + [self.godotLoadingOverlay removeFromSuperview]; + self.godotLoadingOverlay = nil; + + return YES; +} + - (void)dealloc { [self.videoView stopVideo]; @@ -130,6 +159,11 @@ self.renderer = nil; + if (self.godotLoadingOverlay) { + [self.godotLoadingOverlay removeFromSuperview]; + self.godotLoadingOverlay = nil; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; } diff --git a/platform/javascript/.eslintrc.engine.js b/platform/javascript/.eslintrc.engine.js index 00f0f147a9..78df6d41d9 100644 --- a/platform/javascript/.eslintrc.engine.js +++ b/platform/javascript/.eslintrc.engine.js @@ -3,8 +3,8 @@ module.exports = { "./.eslintrc.js", ], "globals": { + "InternalConfig": true, "Godot": true, "Preloader": true, - "Utils": true, }, }; diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index 1d3f96a6b8..50b61c0db3 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -27,8 +27,13 @@ if env["tools"]: sys_env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"]) if env["javascript_eval"]: sys_env.AddJSLibraries(["js/libs/library_godot_eval.js"]) + for lib in sys_env["JS_LIBS"]: sys_env.Append(LINKFLAGS=["--js-library", lib]) +for js in env["JS_PRE"]: + sys_env.Append(LINKFLAGS=["--pre-js", env.File(js).path]) +for ext in env["JS_EXTERNS"]: + sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path build = [] if env["gdnative_enabled"]: @@ -37,8 +42,6 @@ if env["gdnative_enabled"]: sys_env["LIBS"] = [] # We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly. sys_env.Append(LIBS=["idbfs.js"]) - # JS prepended to the module code loading the side library. - sys_env.Append(LINKFLAGS=["--pre-js", sys_env.File("js/dynlink.pre.js")]) # Configure it as a main module (dynamic linking support). sys_env.Append(CCFLAGS=["-s", "MAIN_MODULE=1"]) sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"]) @@ -48,7 +51,6 @@ if env["gdnative_enabled"]: sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi" # The main emscripten runtime, with exported standard libraries. sys = sys_env.Program(build_targets, ["javascript_runtime.cpp"]) - sys_env.Depends(sys, "js/dynlink.pre.js") # The side library, containing all Godot code. wasm_env = env.Clone() @@ -66,20 +68,12 @@ else: build = sys_env.Program(build_targets, javascript_files + ["javascript_runtime.cpp"]) sys_env.Depends(build[0], sys_env["JS_LIBS"]) - -if "JS_PRE" in env: - for js in env["JS_PRE"]: - env.Append(LINKFLAGS=["--pre-js", env.File(js).path]) - env.Depends(build, env["JS_PRE"]) - -if "JS_EXTERNS" in env: - for ext in env["JS_EXTERNS"]: - env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path - env.Depends(build, env["JS_EXTERNS"]) +sys_env.Depends(build[0], sys_env["JS_PRE"]) +sys_env.Depends(build[0], sys_env["JS_EXTERNS"]) engine = [ "js/engine/preloader.js", - "js/engine/utils.js", + "js/engine/config.js", "js/engine/engine.js", ] externs = [env.File("#platform/javascript/js/engine/engine.externs.js")] @@ -100,7 +94,13 @@ out_files = [ zip_dir.File(binary_name + ".html"), zip_dir.File(binary_name + ".audio.worklet.js"), ] -html_file = "#misc/dist/html/editor.html" if env["tools"] else "#misc/dist/html/full-size.html" +html_file = "#misc/dist/html/full-size.html" +if env["tools"]: + subst_dict = {"@GODOT_VERSION@": env.GetBuildVersion()} + html_file = env.Substfile( + target="#bin/godot${PROGSUFFIX}.html", source="#misc/dist/html/editor.html", SUBST_DICT=subst_dict + ) + in_files = [js_wrapped, build[1], html_file, "#platform/javascript/js/libs/audio.worklet.js"] if env["gdnative_enabled"]: in_files.append(build[2]) # Runtime diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index 6395fdf721..478e848675 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -105,8 +105,8 @@ void AudioDriverJavaScript::_audio_driver_capture(int p_from, int p_samples) { } Error AudioDriverJavaScript::init() { - mix_rate = GLOBAL_GET("audio/mix_rate"); - int latency = GLOBAL_GET("audio/output_latency"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); + int latency = GLOBAL_GET("audio/driver/output_latency"); channel_count = godot_audio_init(mix_rate, latency, &_state_change_callback, &_latency_update_callback); buffer_length = closest_power_of_2((latency * mix_rate / 1000)); @@ -267,7 +267,7 @@ int AudioDriverJavaScript::WorkletNode::create(int p_buffer_size, int p_channels void AudioDriverJavaScript::WorkletNode::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) { godot_audio_worklet_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, state); - thread = Thread::create(_audio_thread_func, this); + thread.start(_audio_thread_func, this); } void AudioDriverJavaScript::WorkletNode::lock() { @@ -280,8 +280,6 @@ void AudioDriverJavaScript::WorkletNode::unlock() { void AudioDriverJavaScript::WorkletNode::finish() { quit = true; // Ask thread to quit. - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread.wait_to_finish(); } #endif diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index d55ec261a4..393693640f 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -59,7 +59,7 @@ public: STATE_MAX, }; Mutex mutex; - Thread *thread = nullptr; + Thread thread; bool quit = false; int32_t state[STATE_MAX] = { 0 }; diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 7d501e94b2..4297088c09 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -1,7 +1,14 @@ import os import sys -from emscripten_helpers import run_closure_compiler, create_engine_file, add_js_libraries, add_js_pre, add_js_externs +from emscripten_helpers import ( + run_closure_compiler, + create_engine_file, + add_js_libraries, + add_js_pre, + add_js_externs, + get_build_version, +) from methods import get_compiler_version from SCons.Util import WhereIs @@ -50,12 +57,13 @@ def get_flags(): def configure(env): - if not isinstance(env["initial_memory"], int): + try: + env["initial_memory"] = int(env["initial_memory"]) + except Exception: print("Initial memory must be a valid integer") sys.exit(255) ## Build type - if env["target"] == "release": # Use -Os to prioritize optimizing for reduced file size. This is # particularly valuable for the web platform because it directly @@ -84,9 +92,9 @@ def configure(env): if not env["threads_enabled"]: print("Threads must be enabled to build the editor. Please add the 'threads_enabled=yes' option") sys.exit(255) - if env["initial_memory"] < 32: - print("Editor build requires at least 32MiB of initial memory. Forcing it.") - env["initial_memory"] = 32 + if env["initial_memory"] < 64: + print("Editor build requires at least 64MiB of initial memory. Forcing it.") + env["initial_memory"] = 64 elif env["builtin_icu"]: env.Append(CCFLAGS=["-frtti"]) else: @@ -131,11 +139,17 @@ def configure(env): jscc = env.Builder(generator=run_closure_compiler, suffix=".cc.js", src_suffix=".js") env.Append(BUILDERS={"BuildJS": jscc}) - # Add helper method for adding libraries. + # Add helper method for adding libraries, externs, pre-js. + env["JS_LIBS"] = [] + env["JS_PRE"] = [] + env["JS_EXTERNS"] = [] env.AddMethod(add_js_libraries, "AddJSLibraries") env.AddMethod(add_js_pre, "AddJSPre") env.AddMethod(add_js_externs, "AddJSExterns") + # Add method for getting build version string. + env.AddMethod(get_build_version, "GetBuildVersion") + # Add method that joins/compiles our Engine files. env.AddMethod(create_engine_file, "CreateEngineFile") @@ -215,7 +229,15 @@ def configure(env): env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"]) # callMain for manual start. - env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"]) + env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"]) # Add code that allow exiting runtime. env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"]) + + # TODO remove once we have GLES support back (temporary fix undefined symbols due to dead code elimination). + env.Append( + LINKFLAGS=[ + "-s", + "EXPORTED_FUNCTIONS=['_main', '_emscripten_webgl_get_current_context', '_emscripten_webgl_commit_frame', '_emscripten_webgl_create_context']", + ] + ) diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index f10627b0b6..a605f22e16 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -59,41 +59,20 @@ bool DisplayServerJavaScript::is_canvas_focused() { } bool DisplayServerJavaScript::check_size_force_redraw() { - int canvas_width; - int canvas_height; - emscripten_get_canvas_element_size(DisplayServerJavaScript::canvas_id, &canvas_width, &canvas_height); - if (last_width != canvas_width || last_height != canvas_height) { - last_width = canvas_width; - last_height = canvas_height; - // Update the framebuffer size for redraw. - emscripten_set_canvas_element_size(DisplayServerJavaScript::canvas_id, canvas_width, canvas_height); - return true; - } - return false; + return godot_js_display_size_update() != 0; } Point2 DisplayServerJavaScript::compute_position_in_canvas(int p_x, int p_y) { - DisplayServerJavaScript *display = get_singleton(); - int canvas_x; - int canvas_y; - godot_js_display_canvas_bounding_rect_position_get(&canvas_x, &canvas_y); - int canvas_width; - int canvas_height; - emscripten_get_canvas_element_size(display->canvas_id, &canvas_width, &canvas_height); - - double element_width; - double element_height; - emscripten_get_element_css_size(display->canvas_id, &element_width, &element_height); - - return Point2((int)(canvas_width / element_width * (p_x - canvas_x)), - (int)(canvas_height / element_height * (p_y - canvas_y))); + int point[2]; + godot_js_display_compute_position(p_x, p_y, point, point + 1); + return Point2(point[0], point[1]); } EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) { DisplayServerJavaScript *display = get_singleton(); // Empty ID is canvas. String target_id = String::utf8(p_event->id); - if (target_id.is_empty() || target_id == String::utf8(display->canvas_id)) { + if (target_id.is_empty() || target_id == String::utf8(&(display->canvas_id[1]))) { // This event property is the only reliable data on // browser fullscreen state. if (p_event->isFullscreen) { @@ -455,7 +434,7 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const { EmscriptenPointerlockChangeEvent ev; emscripten_get_pointerlock_status(&ev); - return (ev.isActive && String::utf8(ev.id) == String::utf8(canvas_id)) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; + return (ev.isActive && String::utf8(ev.id) == String::utf8(&canvas_id[1])) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; } // Wheel @@ -558,57 +537,51 @@ bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const { } // Gamepad - -EM_BOOL DisplayServerJavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) { +void DisplayServerJavaScript::gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) { Input *input = Input::get_singleton(); - if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) { - String guid = ""; - if (String::utf8(p_event->mapping) == "standard") - guid = "Default HTML5 Gamepad"; - input->joy_connection_changed(p_event->index, true, String::utf8(p_event->id), guid); + if (p_connected) { + input->joy_connection_changed(p_index, true, String::utf8(p_id), String::utf8(p_guid)); } else { - input->joy_connection_changed(p_event->index, false, ""); + input->joy_connection_changed(p_index, false, ""); } - return true; } void DisplayServerJavaScript::process_joypads() { - int joypad_count = emscripten_get_num_gamepads(); Input *input = Input::get_singleton(); - for (int joypad = 0; joypad < joypad_count; joypad++) { - EmscriptenGamepadEvent state; - EMSCRIPTEN_RESULT query_result = emscripten_get_gamepad_status(joypad, &state); - // Chromium reserves gamepads slots, so NO_DATA is an expected result. - ERR_CONTINUE(query_result != EMSCRIPTEN_RESULT_SUCCESS && - query_result != EMSCRIPTEN_RESULT_NO_DATA); - if (query_result == EMSCRIPTEN_RESULT_SUCCESS && state.connected) { - int button_count = MIN(state.numButtons, 18); - int axis_count = MIN(state.numAxes, 8); - for (int button = 0; button < button_count; button++) { - float value = state.analogButton[button]; - input->joy_button(joypad, button, value); - } - for (int axis = 0; axis < axis_count; axis++) { + int32_t pads = godot_js_display_gamepad_sample_count(); + int32_t s_btns_num = 0; + int32_t s_axes_num = 0; + int32_t s_standard = 0; + float s_btns[16]; + float s_axes[10]; + for (int idx = 0; idx < pads; idx++) { + int err = godot_js_display_gamepad_sample_get(idx, s_btns, &s_btns_num, s_axes, &s_axes_num, &s_standard); + if (err) { + continue; + } + for (int b = 0; b < s_btns_num; b++) { + float value = s_btns[b]; + // Buttons 6 and 7 in the standard mapping need to be + // axis to be handled as JOY_AXIS_TRIGGER by Godot. + if (s_standard && (b == 6 || b == 7)) { Input::JoyAxis joy_axis; - joy_axis.min = -1; - joy_axis.value = state.axis[axis]; - input->joy_axis(joypad, axis, joy_axis); + joy_axis.min = 0; + joy_axis.value = value; + int a = b == 6 ? JOY_AXIS_TRIGGER_LEFT : JOY_AXIS_TRIGGER_RIGHT; + input->joy_axis(idx, a, joy_axis); + } else { + input->joy_button(idx, b, value); } } + for (int a = 0; a < s_axes_num; a++) { + Input::JoyAxis joy_axis; + joy_axis.min = -1; + joy_axis.value = s_axes[a]; + input->joy_axis(idx, a, joy_axis); + } } } -#if 0 -bool DisplayServerJavaScript::is_joy_known(int p_device) { - return Input::get_singleton()->is_joy_mapped(p_device); -} - - -String DisplayServerJavaScript::get_joy_guid(int p_device) const { - return Input::get_singleton()->get_joy_guid_remapped(p_device); -} -#endif - Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() { Vector<String> drivers; drivers.push_back("dummy"); @@ -709,6 +682,9 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive // Ensure the canvas ID. godot_js_config_canvas_id_get(canvas_id, 256); + // Handle contextmenu, webglcontextlost + godot_js_display_setup_canvas(p_resolution.x, p_resolution.y, p_mode == WINDOW_MODE_FULLSCREEN); + // Check if it's windows. swap_cancel_ok = godot_js_display_is_swap_ok_cancel() == 1; @@ -751,11 +727,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive video_driver_index = p_video_driver; #endif - window_set_mode(p_mode); - if (godot_js_config_is_resize_on_start()) { - window_set_size(p_resolution); - } - EMSCRIPTEN_RESULT result; #define EM_CHECK(ev) \ if (result != EMSCRIPTEN_RESULT_SUCCESS) \ @@ -766,9 +737,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive #define SET_EM_WINDOW_CALLBACK(ev, cb) \ result = emscripten_set_##ev##_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, &cb); \ EM_CHECK(ev) -#define SET_EM_CALLBACK_NOTARGET(ev, cb) \ - result = emscripten_set_##ev##_callback(nullptr, true, &cb); \ - EM_CHECK(ev) // These callbacks from Emscripten's html5.h suffice to access most // JavaScript APIs. SET_EM_CALLBACK(canvas_id, mousedown, mouse_button_callback) @@ -783,9 +751,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive SET_EM_CALLBACK(canvas_id, keypress, keypress_callback) SET_EM_CALLBACK(canvas_id, keyup, keyup_callback) SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback) - SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback) - SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback) -#undef SET_EM_CALLBACK_NOTARGET #undef SET_EM_CALLBACK #undef EM_CHECK @@ -798,6 +763,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive WINDOW_EVENT_FOCUS_OUT); godot_js_display_paste_cb(update_clipboard_callback); godot_js_display_drop_files_cb(drop_files_js_callback); + godot_js_display_gamepad_cb(&DisplayServerJavaScript::gamepad_callback); Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event); } @@ -850,20 +816,23 @@ Point2i DisplayServerJavaScript::screen_get_position(int p_screen) const { } Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const { - EmscriptenFullscreenChangeEvent ev; - EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev); - ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i()); - return Size2i(ev.screenWidth, ev.screenHeight); + int size[2]; + godot_js_display_screen_size_get(size, size + 1); + return Size2(size[0], size[1]); } Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const { - int canvas[2]; - emscripten_get_canvas_element_size(canvas_id, canvas, canvas + 1); - return Rect2i(0, 0, canvas[0], canvas[1]); + int size[2]; + godot_js_display_window_size_get(size, size + 1); + return Rect2i(0, 0, size[0], size[1]); } int DisplayServerJavaScript::screen_get_dpi(int p_screen) const { - return 96; // TODO maybe check pixel ratio via window.devicePixelRatio * 96? Inexact. + return godot_js_display_screen_dpi_get(); +} + +float DisplayServerJavaScript::screen_get_scale(int p_screen) const { + return godot_js_display_pixel_ratio_get(); } Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const { @@ -945,17 +914,13 @@ Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const { } void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) { - last_width = p_size.x; - last_height = p_size.y; - double scale = godot_js_display_pixel_ratio_get(); - emscripten_set_canvas_element_size(canvas_id, p_size.x, p_size.y); - emscripten_set_element_css_size(canvas_id, p_size.x / scale, p_size.y / scale); + godot_js_display_desired_size_set(p_size.x, p_size.y); } Size2i DisplayServerJavaScript::window_get_size(WindowID p_window) const { - int canvas[2]; - emscripten_get_canvas_element_size(canvas_id, canvas, canvas + 1); - return Size2(canvas[0], canvas[1]); + int size[2]; + godot_js_display_window_size_get(size, size + 1); + return Size2i(size[0], size[1]); } Size2i DisplayServerJavaScript::window_get_real_size(WindowID p_window) const { @@ -969,20 +934,13 @@ void DisplayServerJavaScript::window_set_mode(WindowMode p_mode, WindowID p_wind switch (p_mode) { case WINDOW_MODE_WINDOWED: { if (window_mode == WINDOW_MODE_FULLSCREEN) { - emscripten_exit_fullscreen(); + godot_js_display_fullscreen_exit(); } window_mode = WINDOW_MODE_WINDOWED; - window_set_size(Size2i(last_width, last_height)); } break; case WINDOW_MODE_FULLSCREEN: { - EmscriptenFullscreenStrategy strategy; - strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH; - strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; - strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; - strategy.canvasResizedCallback = nullptr; - EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(canvas_id, false, &strategy); - ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform."); - ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform."); + int result = godot_js_display_fullscreen_request(); + ERR_FAIL_COND_MSG(result, "The request was denied. Remember that enabling fullscreen is only possible from an input callback for the HTML5 platform."); } break; case WINDOW_MODE_MAXIMIZED: case WINDOW_MODE_MINIMIZED: @@ -1026,8 +984,9 @@ bool DisplayServerJavaScript::can_any_window_draw() const { } void DisplayServerJavaScript::process_events() { - if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS) + if (godot_js_display_gamepad_sample() == OK) { process_joypads(); + } } int DisplayServerJavaScript::get_current_video_driver() const { diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index 916be1ae45..47e25ab2a0 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -57,9 +57,6 @@ private: double last_click_ms = 0; int last_click_button_index = -1; - int last_width = 0; - int last_height = 0; - bool swap_cancel_ok = false; // utilities @@ -86,7 +83,7 @@ private: static EM_BOOL touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data); static EM_BOOL touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data); - static EM_BOOL gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data); + static void gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid); void process_joypads(); static Vector<String> get_rendering_drivers_func(); @@ -136,6 +133,7 @@ public: Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; // windows Vector<DisplayServer::WindowID> get_window_list() const override; diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py index 278186e4c0..d08555916b 100644 --- a/platform/javascript/emscripten_helpers.py +++ b/platform/javascript/emscripten_helpers.py @@ -15,6 +15,15 @@ def run_closure_compiler(target, source, env, for_signature): return " ".join(cmd) +def get_build_version(env): + import version + + name = "custom_build" + if os.getenv("BUILD_NAME") != None: + name = os.getenv("BUILD_NAME") + return "%d.%d.%d.%s.%s" % (version.major, version.minor, version.patch, version.status, name) + + def create_engine_file(env, target, source, externs): if env["use_closure_compiler"]: return env.BuildJS(target, source, JSEXTERNS=externs) @@ -22,18 +31,12 @@ def create_engine_file(env, target, source, externs): def add_js_libraries(env, libraries): - if "JS_LIBS" not in env: - env["JS_LIBS"] = [] env.Append(JS_LIBS=env.File(libraries)) def add_js_pre(env, js_pre): - if "JS_PRE" not in env: - env["JS_PRE"] = [] env.Append(JS_PRE=env.File(js_pre)) def add_js_externs(env, externs): - if "JS_EXTERNS" not in env: - env["JS_EXTERNS"] = [] env.Append(JS_EXTERNS=env.File(externs)) diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 48ccc1f87a..353cc49ef8 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -135,6 +135,7 @@ public: s += "Access-Control-Allow-Origin: *\r\n"; s += "Cross-Origin-Opener-Policy: same-origin\r\n"; s += "Cross-Origin-Embedder-Policy: require-corp\r\n"; + s += "Cache-Control: no-store, max-age=0\r\n"; s += "\r\n"; CharString cs = s.utf8(); Error err = connection->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); @@ -213,7 +214,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform { Ref<EditorHTTPServer> server; bool server_quit = false; Mutex server_lock; - Thread *server_thread = nullptr; + Thread server_thread; enum ExportMode { EXPORT_MODE_NORMAL = 0, @@ -284,24 +285,29 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size()); String str_export; Vector<String> lines = str_template.split("\n"); - Vector<String> flags; - String flags_json; - gen_export_flags(flags, p_flags); - flags_json = JSON::print(flags); - String libs; + Array libs; for (int i = 0; i < p_shared_objects.size(); i++) { - libs += "\"" + p_shared_objects[i].path.get_file() + "\","; + libs.push_back(p_shared_objects[i].path.get_file()); } + Vector<String> flags; + gen_export_flags(flags, p_flags & (~DEBUG_FLAG_DUMB_CLIENT)); + Array args; + for (int i = 0; i < flags.size(); i++) { + args.push_back(flags[i]); + } + Dictionary config; + config["canvasResizePolicy"] = p_preset->get("html/canvas_resize_policy"); + config["gdnativeLibs"] = libs; + config["executable"] = p_name; + config["args"] = args; + const String str_config = JSON::print(config); for (int i = 0; i < lines.size(); i++) { String current_line = lines[i]; - current_line = current_line.replace("$GODOT_BASENAME", p_name); + current_line = current_line.replace("$GODOT_URL", p_name + ".js"); current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name")); current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include")); - current_line = current_line.replace("$GODOT_FULL_WINDOW", p_preset->get("html/full_window_size") ? "true" : "false"); - current_line = current_line.replace("$GODOT_GDNATIVE_LIBS", libs); - current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false"); - current_line = current_line.replace("$GODOT_ARGS", flags_json); + current_line = current_line.replace("$GODOT_CONFIG", str_config); str_export += current_line + "\n"; } @@ -318,7 +324,7 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP } if (p_preset->get("vram_texture_compression/for_mobile")) { - String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); + String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name"); if (driver == "GLES2") { r_features->push_back("etc"); } else if (driver == "Vulkan") { @@ -344,7 +350,7 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/full_window_size"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "html/canvas_resize_policy", PROPERTY_HINT_ENUM, "None,Project,Adaptive"), 2)); } String EditorExportPlatformJavaScript::get_name() const { @@ -681,7 +687,7 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) { EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { server.instance(); - server_thread = Thread::create(_server_thread_poll, this); + server_thread.start(_server_thread_poll, this); Ref<Image> img = memnew(Image(_javascript_logo)); logo.instance(); @@ -702,8 +708,7 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() { server->stop(); server_quit = true; - Thread::wait_to_finish(server_thread); - memdelete(server_thread); + server_thread.wait_to_finish(); } void register_javascript_exporter() { diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h index 5b98253b08..5aa8677a54 100644 --- a/platform/javascript/godot_js.h +++ b/platform/javascript/godot_js.h @@ -40,7 +40,6 @@ extern "C" { // Config extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max); extern void godot_js_config_canvas_id_get(char *p_ptr, int p_ptr_max); -extern int godot_js_config_is_resize_on_start(); // OS extern void godot_js_os_finish_async(void (*p_callback)()); @@ -49,8 +48,10 @@ extern int godot_js_os_fs_is_persistent(); extern void godot_js_os_fs_sync(void (*p_callback)()); extern int godot_js_os_execute(const char *p_json); extern void godot_js_os_shell_open(const char *p_uri); +extern int godot_js_os_hw_concurrency_get(); // Display +extern int godot_js_display_screen_dpi_get(); extern double godot_js_display_pixel_ratio_get(); extern void godot_js_display_alert(const char *p_text); extern int godot_js_display_touchscreen_is_available(); @@ -59,10 +60,15 @@ extern int godot_js_display_is_swap_ok_cancel(); // Display canvas extern void godot_js_display_canvas_focus(); extern int godot_js_display_canvas_is_focused(); -extern void godot_js_display_canvas_bounding_rect_position_get(int32_t *p_x, int32_t *p_y); // Display window -extern void godot_js_display_window_request_fullscreen(); +extern void godot_js_display_desired_size_set(int p_width, int p_height); +extern int godot_js_display_size_update(); +extern void godot_js_display_window_size_get(int32_t *p_x, int32_t *p_y); +extern void godot_js_display_screen_size_get(int32_t *p_x, int32_t *p_y); +extern int godot_js_display_fullscreen_request(); +extern int godot_js_display_fullscreen_exit(); +extern void godot_js_display_compute_position(int p_x, int p_y, int32_t *r_x, int32_t *r_y); extern void godot_js_display_window_title_set(const char *p_text); extern void godot_js_display_window_icon_set(const uint8_t *p_ptr, int p_len); @@ -76,10 +82,17 @@ extern int godot_js_display_cursor_is_hidden(); extern void godot_js_display_cursor_set_custom_shape(const char *p_shape, const uint8_t *p_ptr, int p_len, int p_hotspot_x, int p_hotspot_y); extern void godot_js_display_cursor_set_visible(int p_visible); +// Display gamepad +extern char *godot_js_display_gamepad_cb(void (*p_on_change)(int p_index, int p_connected, const char *p_id, const char *p_guid)); +extern int godot_js_display_gamepad_sample(); +extern int godot_js_display_gamepad_sample_count(); +extern int godot_js_display_gamepad_sample_get(int p_idx, float r_btns[16], int32_t *r_btns_num, float r_axes[10], int32_t *r_axes_num, int32_t *r_standard); + // Display listeners extern void godot_js_display_notification_cb(void (*p_callback)(int p_notification), int p_enter, int p_exit, int p_in, int p_out); extern void godot_js_display_paste_cb(void (*p_callback)(const char *p_text)); extern void godot_js_display_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec)); +extern void godot_js_display_setup_canvas(int p_width, int p_height, int p_fullscreen); #ifdef __cplusplus } #endif diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index 44819c495c..1136ea299d 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -104,7 +104,11 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector Error err = prepare_request(p_method, p_url, p_headers); if (err != OK) return err; - godot_xhr_send_data(xhr_id, p_body.ptr(), p_body.size()); + if (p_body.is_empty()) { + godot_xhr_send(xhr_id, nullptr, 0); + } else { + godot_xhr_send(xhr_id, p_body.ptr(), p_body.size()); + } return OK; } @@ -112,7 +116,12 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str Error err = prepare_request(p_method, p_url, p_headers); if (err != OK) return err; - godot_xhr_send_string(xhr_id, p_body.utf8().get_data()); + if (p_body.is_empty()) { + godot_xhr_send(xhr_id, nullptr, 0); + } else { + const CharString cs = p_body.utf8(); + godot_xhr_send(xhr_id, cs.get_data(), cs.length()); + } return OK; } @@ -220,13 +229,13 @@ Error HTTPClient::poll() { has_polled = true; } else { // forcing synchronous requests is not possible on the web - if (last_polling_frame == Engine::get_singleton()->get_idle_frames()) { + if (last_polling_frame == Engine::get_singleton()->get_process_frames()) { WARN_PRINT("HTTPClient polled multiple times in one frame, " "but request cannot progress more than once per " "frame on the HTML5 platform."); } } - last_polling_frame = Engine::get_singleton()->get_idle_frames(); + last_polling_frame = Engine::get_singleton()->get_process_frames(); #endif polled_response_code = godot_xhr_get_status(xhr_id); diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h index d32b2f265e..a9d6faade2 100644 --- a/platform/javascript/http_request.h +++ b/platform/javascript/http_request.h @@ -53,9 +53,7 @@ extern int godot_xhr_open(int p_xhr_id, const char *p_method, const char *p_url, extern void godot_xhr_set_request_header(int p_xhr_id, const char *p_header, const char *p_value); -extern void godot_xhr_send_null(int p_xhr_id); -extern void godot_xhr_send_string(int p_xhr_id, const char *p_data); -extern void godot_xhr_send_data(int p_xhr_id, const void *p_data, int p_len); +extern void godot_xhr_send(int p_xhr_id, const void *p_data, int p_len); extern void godot_xhr_abort(int p_xhr_id); /* this is an HTTPClient::ResponseCode, not ::Status */ diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 5656ecd7dc..0fe95b0a8f 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -87,7 +87,14 @@ extern EMSCRIPTEN_KEEPALIVE int godot_js_main(int argc, char *argv[]) { ResourceLoader::set_abort_on_missing_resources(false); Main::start(); - os->get_main_loop()->init(); + os->get_main_loop()->initialize(); +#ifdef TOOLS_ENABLED + if (Main::is_project_manager() && FileAccess::exists("/tmp/preload.zip")) { + PackedStringArray ps; + ps.push_back("/tmp/preload.zip"); + os->get_main_loop()->emit_signal("files_dropped", ps, -1); + } +#endif emscripten_set_main_loop(main_loop_callback, -1, false); // Immediately run the first iteration. // We are inside an animation frame, we want to immediately draw on the newly setup canvas. diff --git a/platform/javascript/js/dynlink.pre.js b/platform/javascript/js/dynlink.pre.js deleted file mode 100644 index 34bc371ea9..0000000000 --- a/platform/javascript/js/dynlink.pre.js +++ /dev/null @@ -1 +0,0 @@ -Module['dynamicLibraries'] = [Module['thisProgram'] + '.side.wasm'].concat(Module['dynamicLibraries'] ? Module['dynamicLibraries'] : []); diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js new file mode 100644 index 0000000000..bba20dc360 --- /dev/null +++ b/platform/javascript/js/engine/config.js @@ -0,0 +1,309 @@ +/** + * An object used to configure the Engine instance based on godot export options, and to override those in custom HTML + * templates if needed. + * + * @header Engine configuration + * @summary The Engine configuration object. This is just a typedef, create it like a regular object, e.g.: + * + * ``const MyConfig = { executable: 'godot', unloadAfterInit: false }`` + * + * @typedef {Object} EngineConfig + */ +const EngineConfig = {}; // eslint-disable-line no-unused-vars + +/** + * @struct + * @constructor + * @ignore + */ +const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-vars + const cfg = /** @lends {InternalConfig.prototype} */ { + /** + * Whether the unload the engine automatically after the instance is initialized. + * + * @memberof EngineConfig + * @default + * @type {boolean} + */ + unloadAfterInit: true, + /** + * The HTML DOM Canvas object to use. + * + * By default, the first canvas element in the document will be used is none is specified. + * + * @memberof EngineConfig + * @default + * @type {?HTMLCanvasElement} + */ + canvas: null, + /** + * The name of the WASM file without the extension. (Set by Godot Editor export process). + * + * @memberof EngineConfig + * @default + * @type {string} + */ + executable: '', + /** + * An alternative name for the game pck to load. The executable name is used otherwise. + * + * @memberof EngineConfig + * @default + * @type {?string} + */ + mainPack: null, + /** + * Specify a language code to select the proper localization for the game. + * + * The browser locale will be used if none is specified. See complete list of + * :ref:`supported locales <doc_locales>`. + * + * @memberof EngineConfig + * @type {?string} + * @default + */ + locale: null, + /** + * The canvas resize policy determines how the canvas should be resized by Godot. + * + * ``0`` means Godot won't do any resizing. This is useful if you want to control the canvas size from + * javascript code in your template. + * + * ``1`` means Godot will resize the canvas on start, and when changing window size via engine functions. + * + * ``2`` means Godot will adapt the canvas size to match the whole browser window. + * + * @memberof EngineConfig + * @type {number} + * @default + */ + canvasResizePolicy: 2, + /** + * The arguments to be passed as command line arguments on startup. + * + * See :ref:`command line tutorial <doc_command_line_tutorial>`. + * + * **Note**: :js:meth:`startGame <Engine.prototype.startGame>` will always add the ``--main-pack`` argument. + * + * @memberof EngineConfig + * @type {Array<string>} + * @default + */ + args: [], + /** + * @ignore + * @type {Array.<string>} + */ + persistentPaths: ['/userfs'], + /** + * @ignore + * @type {Array.<string>} + */ + gdnativeLibs: [], + /** + * A callback function for handling Godot's ``OS.execute`` calls. + * + * This is for example used in the Web Editor template to switch between project manager and editor, and for running the game. + * + * @callback EngineConfig.onExecute + * @param {string} path The path that Godot's wants executed. + * @param {Array.<string>} args The arguments of the "command" to execute. + */ + /** + * @ignore + * @type {?function(string, Array.<string>)} + */ + onExecute: null, + /** + * A callback function for being notified when the Godot instance quits. + * + * **Note**: This function will not be called if the engine crashes or become unresponsive. + * + * @callback EngineConfig.onExit + * @param {number} status_code The status code returned by Godot on exit. + */ + /** + * @ignore + * @type {?function(number)} + */ + onExit: null, + /** + * A callback function for displaying download progress. + * + * The function is called once per frame while downloading files, so the usage of ``requestAnimationFrame()`` + * is not necessary. + * + * If the callback function receives a total amount of bytes as 0, this means that it is impossible to calculate. + * Possible reasons include: + * + * - Files are delivered with server-side chunked compression + * - Files are delivered with server-side compression on Chromium + * - Not all file downloads have started yet (usually on servers without multi-threading) + * + * @callback EngineConfig.onProgress + * @param {number} current The current amount of downloaded bytes so far. + * @param {number} total The total amount of bytes to be downloaded. + */ + /** + * @ignore + * @type {?function(number, number)} + */ + onProgress: null, + /** + * A callback function for handling the standard output stream. This method should usually only be used in debug pages. + * + * By default, ``console.log()`` is used. + * + * @callback EngineConfig.onPrint + * @param {...*} [var_args] A variadic number of arguments to be printed. + */ + /** + * @ignore + * @type {?function(...*)} + */ + onPrint: function () { + console.log.apply(console, Array.from(arguments)); // eslint-disable-line no-console + }, + /** + * A callback function for handling the standard error stream. This method should usually only be used in debug pages. + * + * By default, ``console.error()`` is used. + * + * @callback EngineConfig.onPrintError + * @param {...*} [var_args] A variadic number of arguments to be printed as errors. + */ + /** + * @ignore + * @type {?function(...*)} + */ + onPrintError: function (var_args) { + console.error.apply(console, Array.from(arguments)); // eslint-disable-line no-console + }, + }; + + /** + * @ignore + * @struct + * @constructor + * @param {EngineConfig} opts + */ + function Config(opts) { + this.update(opts); + } + + Config.prototype = cfg; + + /** + * @ignore + * @param {EngineConfig} opts + */ + Config.prototype.update = function (opts) { + const config = opts || {}; + function parse(key, def) { + if (typeof (config[key]) === 'undefined') { + return def; + } + return config[key]; + } + // Module config + this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit); + this.onPrintError = parse('onPrintError', this.onPrintError); + this.onPrint = parse('onPrint', this.onPrint); + this.onProgress = parse('onProgress', this.onProgress); + + // Godot config + this.canvas = parse('canvas', this.canvas); + this.executable = parse('executable', this.executable); + this.mainPack = parse('mainPack', this.mainPack); + this.locale = parse('locale', this.locale); + this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy); + this.persistentPaths = parse('persistentPaths', this.persistentPaths); + this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs); + this.args = parse('args', this.args); + this.onExecute = parse('onExecute', this.onExecute); + this.onExit = parse('onExit', this.onExit); + }; + + /** + * @ignore + * @param {string} loadPath + * @param {Promise} loadPromise + */ + Config.prototype.getModuleConfig = function (loadPath, loadPromise) { + let loader = loadPromise; + return { + 'print': this.onPrint, + 'printErr': this.onPrintError, + 'thisProgram': this.executable, + 'noExitRuntime': true, + 'dynamicLibraries': [`${loadPath}.side.wasm`], + 'instantiateWasm': function (imports, onSuccess) { + loader.then(function (xhr) { + WebAssembly.instantiate(xhr.response, imports).then(function (result) { + onSuccess(result['instance'], result['module']); + }); + }); + loader = null; + return {}; + }, + 'locateFile': function (path) { + if (path.endsWith('.worker.js')) { + return `${loadPath}.worker.js`; + } else if (path.endsWith('.audio.worklet.js')) { + return `${loadPath}.audio.worklet.js`; + } else if (path.endsWith('.js')) { + return `${loadPath}.js`; + } else if (path.endsWith('.side.wasm')) { + return `${loadPath}.side.wasm`; + } else if (path.endsWith('.wasm')) { + return `${loadPath}.wasm`; + } + return path; + }, + }; + }; + + /** + * @ignore + * @param {function()} cleanup + */ + Config.prototype.getGodotConfig = function (cleanup) { + // Try to find a canvas + if (!(this.canvas instanceof HTMLCanvasElement)) { + const nodes = document.getElementsByTagName('canvas'); + if (nodes.length && nodes[0] instanceof HTMLCanvasElement) { + this.canvas = nodes[0]; + } + if (!this.canvas) { + throw new Error('No canvas found in page'); + } + } + // Canvas can grab focus on click, or key events won't work. + if (this.canvas.tabIndex < 0) { + this.canvas.tabIndex = 0; + } + + // Browser locale, or custom one if defined. + let locale = this.locale; + if (!locale) { + locale = navigator.languages ? navigator.languages[0] : navigator.language; + locale = locale.split('.')[0]; + } + const onExit = this.onExit; + + // Godot configuration. + return { + 'canvas': this.canvas, + 'canvasResizePolicy': this.canvasResizePolicy, + 'locale': locale, + 'onExecute': this.onExecute, + 'onExit': function (p_code) { + cleanup(); // We always need to call the cleanup callback to free memory. + if (typeof (onExit) === 'function') { + onExit(p_code); + } + }, + }; + }; + return new Config(initConfig); +}; diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js index 4b8a7dde69..c51955ed3d 100644 --- a/platform/javascript/js/engine/engine.js +++ b/platform/javascript/js/engine/engine.js @@ -1,291 +1,268 @@ +/** + * Projects exported for the Web expose the :js:class:`Engine` class to the JavaScript environment, that allows + * fine control over the engine's start-up process. + * + * This API is built in an asynchronous manner and requires basic understanding + * of `Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises>`__. + * + * @module Engine + * @header HTML5 shell class reference + */ const Engine = (function () { const preloader = new Preloader(); - let wasmExt = '.wasm'; - let unloadAfterInit = true; - let loadPath = ''; let loadPromise = null; + let loadPath = ''; let initPromise = null; - let stderr = null; - let stdout = null; - let progressFunc = null; - function load(basePath) { + /** + * @classdesc The ``Engine`` class provides methods for loading and starting exported projects on the Web. For default export + * settings, this is already part of the exported HTML page. To understand practical use of the ``Engine`` class, + * see :ref:`Custom HTML page for Web export <doc_customizing_html5_shell>`. + * + * @description Create a new Engine instance with the given configuration. + * + * @global + * @constructor + * @param {EngineConfig} initConfig The initial config for this instance. + */ + function Engine(initConfig) { // eslint-disable-line no-shadow + this.config = new InternalConfig(initConfig); + this.rtenv = null; + } + + /** + * Load the engine from the specified base path. + * + * @param {string} basePath Base path of the engine to load. + * @returns {Promise} A Promise that resolves once the engine is loaded. + * + * @function Engine.load + */ + Engine.load = function (basePath) { if (loadPromise == null) { loadPath = basePath; - loadPromise = preloader.loadPromise(basePath + wasmExt); - preloader.setProgressFunc(progressFunc); + loadPromise = preloader.loadPromise(`${loadPath}.wasm`); requestAnimationFrame(preloader.animateProgress); } return loadPromise; - } + }; - function unload() { + /** + * Unload the engine to free memory. + * + * This method will be called automatically depending on the configuration. See :js:attr:`unloadAfterInit`. + * + * @function Engine.unload + */ + Engine.unload = function () { loadPromise = null; - } - - /** @constructor */ - function Engine() { // eslint-disable-line no-shadow - this.canvas = null; - this.executableName = ''; - this.rtenv = null; - this.customLocale = null; - this.resizeCanvasOnStart = false; - this.onExecute = null; - this.onExit = null; - this.persistentPaths = ['/userfs']; - this.gdnativeLibs = []; - } - - Engine.prototype.init = /** @param {string=} basePath */ function (basePath) { - if (initPromise) { - return initPromise; - } - if (loadPromise == null) { - if (!basePath) { - initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.')); - return initPromise; - } - load(basePath); - } - let config = {}; - if (typeof stdout === 'function') { - config.print = stdout; - } - if (typeof stderr === 'function') { - config.printErr = stderr; - } - const me = this; - initPromise = new Promise(function (resolve, reject) { - config['locateFile'] = Utils.createLocateRewrite(loadPath); - config['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise); - // Emscripten configuration. - config['thisProgram'] = me.executableName; - config['noExitRuntime'] = true; - config['dynamicLibraries'] = me.gdnativeLibs; - Godot(config).then(function (module) { - module['initFS'](me.persistentPaths).then(function (fs_err) { - me.rtenv = module; - if (unloadAfterInit) { - unload(); - } - resolve(); - config = null; - }); - }); - }); - return initPromise; }; - /** @type {function(string, string):Object} */ - Engine.prototype.preloadFile = function (file, path) { - return preloader.preload(file, path); + /** + * Check whether WebGL is available. Optionally, specify a particular version of WebGL to check for. + * + * @param {number=} [majorVersion=1] The major WebGL version to check for. + * @returns {boolean} If the given major version of WebGL is available. + * @function Engine.isWebGLAvailable + */ + Engine.isWebGLAvailable = function (majorVersion = 1) { + try { + return !!document.createElement('canvas').getContext(['webgl', 'webgl2'][majorVersion - 1]); + } catch (e) { /* Not available */ } + return false; }; - /** @type {function(...string):Object} */ - Engine.prototype.start = function () { - // Start from arguments. - const args = []; - for (let i = 0; i < arguments.length; i++) { - args.push(arguments[i]); - } - const me = this; - return me.init().then(function () { - if (!me.rtenv) { - return Promise.reject(new Error('The engine must be initialized before it can be started')); - } - - if (!(me.canvas instanceof HTMLCanvasElement)) { - me.canvas = Utils.findCanvas(); - if (!me.canvas) { - return Promise.reject(new Error('No canvas found in page')); + /** + * Safe Engine constructor, creates a new prototype for every new instance to avoid prototype pollution. + * @ignore + * @constructor + */ + function SafeEngine(initConfig) { + const proto = /** @lends Engine.prototype */ { + /** + * Initialize the engine instance. Optionally, pass the base path to the engine to load it, + * if it hasn't been loaded yet. See :js:meth:`Engine.load`. + * + * @param {string=} basePath Base path of the engine to load. + * @return {Promise} A ``Promise`` that resolves once the engine is loaded and initialized. + */ + init: function (basePath) { + if (initPromise) { + return initPromise; } - } - - // Canvas can grab focus on click, or key events won't work. - if (me.canvas.tabIndex < 0) { - me.canvas.tabIndex = 0; - } - - // Disable right-click context menu. - me.canvas.addEventListener('contextmenu', function (ev) { - ev.preventDefault(); - }, false); - - // Until context restoration is implemented warn the user of context loss. - me.canvas.addEventListener('webglcontextlost', function (ev) { - alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert - ev.preventDefault(); - }, false); - - // Browser locale, or custom one if defined. - let locale = me.customLocale; - if (!locale) { - locale = navigator.languages ? navigator.languages[0] : navigator.language; - locale = locale.split('.')[0]; - } - // Godot configuration. - me.rtenv['initConfig']({ - 'resizeCanvasOnStart': me.resizeCanvasOnStart, - 'canvas': me.canvas, - 'locale': locale, - 'onExecute': function (p_args) { - if (me.onExecute) { - me.onExecute(p_args); - return 0; + if (loadPromise == null) { + if (!basePath) { + initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.')); + return initPromise; } - return 1; - }, - 'onExit': function (p_code) { - me.rtenv['deinitFS'](); - if (me.onExit) { - me.onExit(p_code); - } - me.rtenv = null; - }, - }); - - return new Promise(function (resolve, reject) { - preloader.preloadedFiles.forEach(function (file) { - me.rtenv['copyToFS'](file.path, file.buffer); + Engine.load(basePath); + } + preloader.setProgressFunc(this.config.onProgress); + let config = this.config.getModuleConfig(loadPath, loadPromise); + const me = this; + initPromise = new Promise(function (resolve, reject) { + Godot(config).then(function (module) { + module['initFS'](me.config.persistentPaths).then(function (fs_err) { + me.rtenv = module; + if (me.config.unloadAfterInit) { + Engine.unload(); + } + resolve(); + config = null; + }); + }); }); - preloader.preloadedFiles.length = 0; // Clear memory - me.rtenv['callMain'](args); - initPromise = null; - resolve(); - }); - }); - }; - - Engine.prototype.startGame = function (execName, mainPack, extraArgs) { - // Start and init with execName as loadPath if not inited. - this.executableName = execName; - const me = this; - return Promise.all([ - this.init(execName), - this.preloadFile(mainPack, mainPack), - ]).then(function () { - let args = ['--main-pack', mainPack]; - if (extraArgs) { - args = args.concat(extraArgs); - } - return me.start.apply(me, args); - }); - }; - - Engine.prototype.setWebAssemblyFilenameExtension = function (override) { - if (String(override).length === 0) { - throw new Error('Invalid WebAssembly filename extension override'); - } - wasmExt = String(override); - }; - - Engine.prototype.setUnloadAfterInit = function (enabled) { - unloadAfterInit = enabled; - }; + return initPromise; + }, - Engine.prototype.setCanvas = function (canvasElem) { - this.canvas = canvasElem; - }; + /** + * Load a file so it is available in the instance's file system once it runs. Must be called **before** starting the + * instance. + * + * If not provided, the ``path`` is derived from the URL of the loaded file. + * + * @param {string|ArrayBuffer} file The file to preload. + * + * If a ``string`` the file will be loaded from that path. + * + * If an ``ArrayBuffer`` or a view on one, the buffer will used as the content of the file. + * + * @param {string=} path Path by which the file will be accessible. Required, if ``file`` is not a string. + * + * @returns {Promise} A Promise that resolves once the file is loaded. + */ + preloadFile: function (file, path) { + return preloader.preload(file, path); + }, - Engine.prototype.setCanvasResizedOnStart = function (enabled) { - this.resizeCanvasOnStart = enabled; - }; + /** + * Start the engine instance using the given override configuration (if any). + * :js:meth:`startGame <Engine.prototype.startGame>` can be used in typical cases instead. + * + * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init>`. + * The engine must be loaded beforehand. + * + * Fails if a canvas cannot be found on the page, or not specified in the configuration. + * + * @param {EngineConfig} override An optional configuration override. + * @return {Promise} Promise that resolves once the engine started. + */ + start: function (override) { + this.config.update(override); + const me = this; + return me.init().then(function () { + if (!me.rtenv) { + return Promise.reject(new Error('The engine must be initialized before it can be started')); + } - Engine.prototype.setLocale = function (locale) { - this.customLocale = locale; - }; + let config = {}; + try { + config = me.config.getGodotConfig(function () { + me.rtenv = null; + }); + } catch (e) { + return Promise.reject(e); + } + // Godot configuration. + me.rtenv['initConfig'](config); - Engine.prototype.setExecutableName = function (newName) { - this.executableName = newName; - }; + // Preload GDNative libraries. + const libs = []; + me.config.gdnativeLibs.forEach(function (lib) { + libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true })); + }); + return Promise.all(libs).then(function () { + return new Promise(function (resolve, reject) { + preloader.preloadedFiles.forEach(function (file) { + me.rtenv['copyToFS'](file.path, file.buffer); + }); + preloader.preloadedFiles.length = 0; // Clear memory + me.rtenv['callMain'](me.config.args); + initPromise = null; + resolve(); + }); + }); + }); + }, - Engine.prototype.setProgressFunc = function (func) { - progressFunc = func; - }; + /** + * Start the game instance using the given configuration override (if any). + * + * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init>`. + * + * This will load the engine if it is not loaded, and preload the main pck. + * + * This method expects the initial config (or the override) to have both the :js:attr:`executable` and :js:attr:`mainPack` + * properties set (normally done by the editor during export). + * + * @param {EngineConfig} override An optional configuration override. + * @return {Promise} Promise that resolves once the game started. + */ + startGame: function (override) { + this.config.update(override); + // Add main-pack argument. + const exe = this.config.executable; + const pack = this.config.mainPack || `${exe}.pck`; + this.config.args = ['--main-pack', pack].concat(this.config.args); + // Start and init with execName as loadPath if not inited. + const me = this; + return Promise.all([ + this.init(exe), + this.preloadFile(pack, pack), + ]).then(function () { + return me.start.apply(me); + }); + }, - Engine.prototype.setStdoutFunc = function (func) { - const print = function (text) { - let msg = text; - if (arguments.length > 1) { - msg = Array.prototype.slice.call(arguments).join(' '); - } - func(msg); - }; - if (this.rtenv) { - this.rtenv.print = print; - } - stdout = print; - }; + /** + * Create a file at the specified ``path`` with the passed as ``buffer`` in the instance's file system. + * + * @param {string} path The location where the file will be created. + * @param {ArrayBuffer} buffer The content of the file. + */ + copyToFS: function (path, buffer) { + if (this.rtenv == null) { + throw new Error('Engine must be inited before copying files'); + } + this.rtenv['copyToFS'](path, buffer); + }, - Engine.prototype.setStderrFunc = function (func) { - const printErr = function (text) { - let msg = text; - if (arguments.length > 1) { - msg = Array.prototype.slice.call(arguments).join(' '); - } - func(msg); + /** + * Request that the current instance quit. + * + * This is akin the user pressing the close button in the window manager, and will + * have no effect if the engine has crashed, or is stuck in a loop. + * + */ + requestQuit: function () { + if (this.rtenv) { + this.rtenv['request_quit'](); + } + }, }; - if (this.rtenv) { - this.rtenv.printErr = printErr; - } - stderr = printErr; - }; - - Engine.prototype.setOnExecute = function (onExecute) { - this.onExecute = onExecute; - }; - - Engine.prototype.setOnExit = function (onExit) { - this.onExit = onExit; - }; - - Engine.prototype.copyToFS = function (path, buffer) { - if (this.rtenv == null) { - throw new Error('Engine must be inited before copying files'); - } - this.rtenv['copyToFS'](path, buffer); - }; - - Engine.prototype.setPersistentPaths = function (persistentPaths) { - this.persistentPaths = persistentPaths; - }; - Engine.prototype.setGDNativeLibraries = function (gdnativeLibs) { - this.gdnativeLibs = gdnativeLibs; - }; + Engine.prototype = proto; + // Closure compiler exported instance methods. + Engine.prototype['init'] = Engine.prototype.init; + Engine.prototype['preloadFile'] = Engine.prototype.preloadFile; + Engine.prototype['start'] = Engine.prototype.start; + Engine.prototype['startGame'] = Engine.prototype.startGame; + Engine.prototype['copyToFS'] = Engine.prototype.copyToFS; + Engine.prototype['requestQuit'] = Engine.prototype.requestQuit; + // Also expose static methods as instance methods + Engine.prototype['load'] = Engine.load; + Engine.prototype['unload'] = Engine.unload; + Engine.prototype['isWebGLAvailable'] = Engine.isWebGLAvailable; + return new Engine(initConfig); + } - Engine.prototype.requestQuit = function () { - if (this.rtenv) { - this.rtenv['request_quit'](); - } - }; + // Closure compiler exported static methods. + SafeEngine['load'] = Engine.load; + SafeEngine['unload'] = Engine.unload; + SafeEngine['isWebGLAvailable'] = Engine.isWebGLAvailable; - // Closure compiler exported engine methods. - /** @export */ - Engine['isWebGLAvailable'] = Utils.isWebGLAvailable; - Engine['load'] = load; - Engine['unload'] = unload; - Engine.prototype['init'] = Engine.prototype.init; - Engine.prototype['preloadFile'] = Engine.prototype.preloadFile; - Engine.prototype['start'] = Engine.prototype.start; - Engine.prototype['startGame'] = Engine.prototype.startGame; - Engine.prototype['setWebAssemblyFilenameExtension'] = Engine.prototype.setWebAssemblyFilenameExtension; - Engine.prototype['setUnloadAfterInit'] = Engine.prototype.setUnloadAfterInit; - Engine.prototype['setCanvas'] = Engine.prototype.setCanvas; - Engine.prototype['setCanvasResizedOnStart'] = Engine.prototype.setCanvasResizedOnStart; - Engine.prototype['setLocale'] = Engine.prototype.setLocale; - Engine.prototype['setExecutableName'] = Engine.prototype.setExecutableName; - Engine.prototype['setProgressFunc'] = Engine.prototype.setProgressFunc; - Engine.prototype['setStdoutFunc'] = Engine.prototype.setStdoutFunc; - Engine.prototype['setStderrFunc'] = Engine.prototype.setStderrFunc; - Engine.prototype['setOnExecute'] = Engine.prototype.setOnExecute; - Engine.prototype['setOnExit'] = Engine.prototype.setOnExit; - Engine.prototype['copyToFS'] = Engine.prototype.copyToFS; - Engine.prototype['setPersistentPaths'] = Engine.prototype.setPersistentPaths; - Engine.prototype['setGDNativeLibraries'] = Engine.prototype.setGDNativeLibraries; - Engine.prototype['requestQuit'] = Engine.prototype.requestQuit; - return Engine; + return SafeEngine; }()); if (typeof window !== 'undefined') { window['Engine'] = Engine; diff --git a/platform/javascript/js/engine/utils.js b/platform/javascript/js/engine/utils.js deleted file mode 100644 index 9273bbad42..0000000000 --- a/platform/javascript/js/engine/utils.js +++ /dev/null @@ -1,58 +0,0 @@ -const Utils = { // eslint-disable-line no-unused-vars - - createLocateRewrite: function (execName) { - function rw(path) { - if (path.endsWith('.worker.js')) { - return `${execName}.worker.js`; - } else if (path.endsWith('.audio.worklet.js')) { - return `${execName}.audio.worklet.js`; - } else if (path.endsWith('.js')) { - return `${execName}.js`; - } else if (path.endsWith('.side.wasm')) { - return `${execName}.side.wasm`; - } else if (path.endsWith('.wasm')) { - return `${execName}.wasm`; - } - return path; - } - return rw; - }, - - createInstantiatePromise: function (wasmLoader) { - let loader = wasmLoader; - function instantiateWasm(imports, onSuccess) { - loader.then(function (xhr) { - WebAssembly.instantiate(xhr.response, imports).then(function (result) { - onSuccess(result['instance'], result['module']); - }); - }); - loader = null; - return {}; - } - - return instantiateWasm; - }, - - findCanvas: function () { - const nodes = document.getElementsByTagName('canvas'); - if (nodes.length && nodes[0] instanceof HTMLCanvasElement) { - return nodes[0]; - } - return null; - }, - - isWebGLAvailable: function (majorVersion = 1) { - let testContext = false; - try { - const testCanvas = document.createElement('canvas'); - if (majorVersion === 1) { - testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); - } else if (majorVersion === 2) { - testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2'); - } - } catch (e) { - // Not available - } - return !!testContext; - }, -}; diff --git a/platform/javascript/js/jsdoc2rst/publish.js b/platform/javascript/js/jsdoc2rst/publish.js new file mode 100644 index 0000000000..ad9c0fbaaa --- /dev/null +++ b/platform/javascript/js/jsdoc2rst/publish.js @@ -0,0 +1,354 @@ +/* eslint-disable strict */ + +'use strict'; + +const fs = require('fs'); + +class JSDoclet { + constructor(doc) { + this.doc = doc; + this.description = doc['description'] || ''; + this.name = doc['name'] || 'unknown'; + this.longname = doc['longname'] || ''; + this.types = []; + if (doc['type'] && doc['type']['names']) { + this.types = doc['type']['names'].slice(); + } + this.type = this.types.length > 0 ? this.types.join('\\|') : '*'; + this.variable = doc['variable'] || false; + this.kind = doc['kind'] || ''; + this.memberof = doc['memberof'] || null; + this.scope = doc['scope'] || ''; + this.members = []; + this.optional = doc['optional'] || false; + this.defaultvalue = doc['defaultvalue']; + this.summary = doc['summary'] || null; + this.classdesc = doc['classdesc'] || null; + + // Parameters (functions) + this.params = []; + this.returns = doc['returns'] ? doc['returns'][0]['type']['names'][0] : 'void'; + this.returns_desc = doc['returns'] ? doc['returns'][0]['description'] : null; + + this.params = (doc['params'] || []).slice().map((p) => new JSDoclet(p)); + + // Custom tags + this.tags = doc['tags'] || []; + this.header = this.tags.filter((t) => t['title'] === 'header').map((t) => t['text']).pop() || null; + } + + add_member(obj) { + this.members.push(obj); + } + + is_static() { + return this.scope === 'static'; + } + + is_instance() { + return this.scope === 'instance'; + } + + is_object() { + return this.kind === 'Object' || (this.kind === 'typedef' && this.type === 'Object'); + } + + is_class() { + return this.kind === 'class'; + } + + is_function() { + return this.kind === 'function' || (this.kind === 'typedef' && this.type === 'function'); + } + + is_module() { + return this.kind === 'module'; + } +} + +function format_table(f, data, depth = 0) { + if (!data.length) { + return; + } + + const column_sizes = new Array(data[0].length).fill(0); + + data.forEach((row) => { + row.forEach((e, idx) => { + column_sizes[idx] = Math.max(e.length, column_sizes[idx]); + }); + }); + + const indent = ' '.repeat(depth); + let sep = indent; + column_sizes.forEach((size) => { + sep += '+'; + sep += '-'.repeat(size + 2); + }); + sep += '+\n'; + f.write(sep); + + data.forEach((row) => { + let row_text = `${indent}|`; + row.forEach((entry, idx) => { + row_text += ` ${entry.padEnd(column_sizes[idx])} |`; + }); + row_text += '\n'; + f.write(row_text); + f.write(sep); + }); + + f.write('\n'); +} + +function make_header(header, sep) { + return `${header}\n${sep.repeat(header.length)}\n\n`; +} + +function indent_multiline(text, depth) { + const indent = ' '.repeat(depth); + return text.split('\n').map((l) => (l === '' ? l : indent + l)).join('\n'); +} + +function make_rst_signature(obj, types = false, style = false) { + let out = ''; + const fmt = style ? '*' : ''; + obj.params.forEach((arg, idx) => { + if (idx > 0) { + if (arg.optional) { + out += ` ${fmt}[`; + } + out += ', '; + } else { + out += ' '; + if (arg.optional) { + out += `${fmt}[ `; + } + } + if (types) { + out += `${arg.type} `; + } + const variable = arg.variable ? '...' : ''; + const defval = arg.defaultvalue !== undefined ? `=${arg.defaultvalue}` : ''; + out += `${variable}${arg.name}${defval}`; + if (arg.optional) { + out += ` ]${fmt}`; + } + }); + out += ' '; + return out; +} + +function make_rst_param(f, obj, depth = 0) { + const indent = ' '.repeat(depth * 3); + f.write(indent); + f.write(`:param ${obj.type} ${obj.name}:\n`); + f.write(indent_multiline(obj.description, (depth + 1) * 3)); + f.write('\n\n'); +} + +function make_rst_attribute(f, obj, depth = 0, brief = false) { + const indent = ' '.repeat(depth * 3); + f.write(indent); + f.write(`.. js:attribute:: ${obj.name}\n\n`); + + if (brief) { + if (obj.summary) { + f.write(indent_multiline(obj.summary, (depth + 1) * 3)); + } + f.write('\n\n'); + return; + } + + f.write(indent_multiline(obj.description, (depth + 1) * 3)); + f.write('\n\n'); + + f.write(indent); + f.write(` :type: ${obj.type}\n\n`); + + if (obj.defaultvalue !== undefined) { + let defval = obj.defaultvalue; + if (defval === '') { + defval = '""'; + } + f.write(indent); + f.write(` :value: \`\`${defval}\`\`\n\n`); + } +} + +function make_rst_function(f, obj, depth = 0) { + let prefix = ''; + if (obj.is_instance()) { + prefix = 'prototype.'; + } + + const indent = ' '.repeat(depth * 3); + const sig = make_rst_signature(obj); + f.write(indent); + f.write(`.. js:function:: ${prefix}${obj.name}(${sig})\n`); + f.write('\n'); + + f.write(indent_multiline(obj.description, (depth + 1) * 3)); + f.write('\n\n'); + + obj.params.forEach((param) => { + make_rst_param(f, param, depth + 1); + }); + + if (obj.returns !== 'void') { + f.write(indent); + f.write(' :return:\n'); + f.write(indent_multiline(obj.returns_desc, (depth + 2) * 3)); + f.write('\n\n'); + f.write(indent); + f.write(` :rtype: ${obj.returns}\n\n`); + } +} + +function make_rst_object(f, obj) { + let brief = false; + // Our custom header flag. + if (obj.header !== null) { + f.write(make_header(obj.header, '-')); + f.write(`${obj.description}\n\n`); + brief = true; + } + + // Format members table and descriptions + const data = [['type', 'name']].concat(obj.members.map((m) => [m.type, `:js:attr:\`${m.name}\``])); + + f.write(make_header('Properties', '^')); + format_table(f, data, 0); + + make_rst_attribute(f, obj, 0, brief); + + if (!obj.members.length) { + return; + } + + f.write(' **Property Descriptions**\n\n'); + + // Properties first + obj.members.filter((m) => !m.is_function()).forEach((m) => { + make_rst_attribute(f, m, 1); + }); + + // Callbacks last + obj.members.filter((m) => m.is_function()).forEach((m) => { + make_rst_function(f, m, 1); + }); +} + +function make_rst_class(f, obj) { + const header = obj.header ? obj.header : obj.name; + f.write(make_header(header, '-')); + + if (obj.classdesc) { + f.write(`${obj.classdesc}\n\n`); + } + + const funcs = obj.members.filter((m) => m.is_function()); + function make_data(m) { + const base = m.is_static() ? obj.name : `${obj.name}.prototype`; + const params = make_rst_signature(m, true, true); + const sig = `:js:attr:\`${m.name} <${base}.${m.name}>\` **(**${params}**)**`; + return [m.returns, sig]; + } + const sfuncs = funcs.filter((m) => m.is_static()); + const ifuncs = funcs.filter((m) => !m.is_static()); + + f.write(make_header('Static Methods', '^')); + format_table(f, sfuncs.map((m) => make_data(m))); + + f.write(make_header('Instance Methods', '^')); + format_table(f, ifuncs.map((m) => make_data(m))); + + const sig = make_rst_signature(obj); + f.write(`.. js:class:: ${obj.name}(${sig})\n\n`); + f.write(indent_multiline(obj.description, 3)); + f.write('\n\n'); + + obj.params.forEach((p) => { + make_rst_param(f, p, 1); + }); + + f.write(' **Static Methods**\n\n'); + sfuncs.forEach((m) => { + make_rst_function(f, m, 1); + }); + + f.write(' **Instance Methods**\n\n'); + ifuncs.forEach((m) => { + make_rst_function(f, m, 1); + }); +} + +function make_rst_module(f, obj) { + const header = obj.header !== null ? obj.header : obj.name; + f.write(make_header(header, '=')); + f.write(obj.description); + f.write('\n\n'); +} + +function write_base_object(f, obj) { + if (obj.is_object()) { + make_rst_object(f, obj); + } else if (obj.is_function()) { + make_rst_function(f, obj); + } else if (obj.is_class()) { + make_rst_class(f, obj); + } else if (obj.is_module()) { + make_rst_module(f, obj); + } +} + +function generate(f, docs) { + const globs = []; + const SYMBOLS = {}; + docs.filter((d) => !d.ignore && d.kind !== 'package').forEach((d) => { + SYMBOLS[d.name] = d; + if (d.memberof) { + const up = SYMBOLS[d.memberof]; + if (up === undefined) { + console.log(d); // eslint-disable-line no-console + console.log(`Undefined symbol! ${d.memberof}`); // eslint-disable-line no-console + throw new Error('Undefined symbol!'); + } + SYMBOLS[d.memberof].add_member(d); + } else { + globs.push(d); + } + }); + + f.write('.. _doc_html5_shell_classref:\n\n'); + globs.forEach((obj) => write_base_object(f, obj)); +} + +/** + * Generate documentation output. + * + * @param {TAFFY} data - A TaffyDB collection representing + * all the symbols documented in your code. + * @param {object} opts - An object with options information. + */ +exports.publish = function (data, opts) { + const docs = data().get().filter((doc) => !doc.undocumented && !doc.ignore).map((doc) => new JSDoclet(doc)); + const dest = opts.destination; + if (dest === 'dry-run') { + process.stdout.write('Dry run... '); + generate({ + write: function () { /* noop */ }, + }, docs); + process.stdout.write('Okay!\n'); + return; + } + if (dest !== '' && !dest.endsWith('.rst')) { + throw new Error('Destination file must be either a ".rst" file, or an empty string (for printing to stdout)'); + } + if (dest !== '') { + const f = fs.createWriteStream(dest); + generate(f, docs); + } else { + generate(process.stdout, docs); + } +}; diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js index d1f4d9595b..fdb5cc0ec2 100644 --- a/platform/javascript/js/libs/library_godot_display.js +++ b/platform/javascript/js/libs/library_godot_display.js @@ -269,15 +269,268 @@ const GodotDisplayCursor = { }; mergeInto(LibraryManager.library, GodotDisplayCursor); +/* + * Display Gamepad API helper. + */ +const GodotDisplayGamepads = { + $GodotDisplayGamepads__deps: ['$GodotRuntime', '$GodotDisplayListeners'], + $GodotDisplayGamepads: { + samples: [], + + get_pads: function () { + try { + // Will throw in iframe when permission is denied. + // Will throw/warn in the future for insecure contexts. + // See https://github.com/w3c/gamepad/pull/120 + const pads = navigator.getGamepads(); + if (pads) { + return pads; + } + return []; + } catch (e) { + return []; + } + }, + + get_samples: function () { + return GodotDisplayGamepads.samples; + }, + + get_sample: function (index) { + const samples = GodotDisplayGamepads.samples; + return index < samples.length ? samples[index] : null; + }, + + sample: function () { + const pads = GodotDisplayGamepads.get_pads(); + const samples = []; + for (let i = 0; i < pads.length; i++) { + const pad = pads[i]; + if (!pad) { + samples.push(null); + continue; + } + const s = { + standard: pad.mapping === 'standard', + buttons: [], + axes: [], + connected: pad.connected, + }; + for (let b = 0; b < pad.buttons.length; b++) { + s.buttons.push(pad.buttons[b].value); + } + for (let a = 0; a < pad.axes.length; a++) { + s.axes.push(pad.axes[a]); + } + samples.push(s); + } + GodotDisplayGamepads.samples = samples; + }, + + init: function (onchange) { + GodotDisplayListeners.samples = []; + function add(pad) { + const guid = GodotDisplayGamepads.get_guid(pad); + const c_id = GodotRuntime.allocString(pad.id); + const c_guid = GodotRuntime.allocString(guid); + onchange(pad.index, 1, c_id, c_guid); + GodotRuntime.free(c_id); + GodotRuntime.free(c_guid); + } + const pads = GodotDisplayGamepads.get_pads(); + for (let i = 0; i < pads.length; i++) { + // Might be reserved space. + if (pads[i]) { + add(pads[i]); + } + } + GodotDisplayListeners.add(window, 'gamepadconnected', function (evt) { + add(evt.gamepad); + }, false); + GodotDisplayListeners.add(window, 'gamepaddisconnected', function (evt) { + onchange(evt.gamepad.index, 0); + }, false); + }, + + get_guid: function (pad) { + if (pad.mapping) { + return pad.mapping; + } + const ua = navigator.userAgent; + let os = 'Unknown'; + if (ua.indexOf('Android') >= 0) { + os = 'Android'; + } else if (ua.indexOf('Linux') >= 0) { + os = 'Linux'; + } else if (ua.indexOf('iPhone') >= 0) { + os = 'iOS'; + } else if (ua.indexOf('Macintosh') >= 0) { + // Updated iPads will fall into this category. + os = 'MacOSX'; + } else if (ua.indexOf('Windows') >= 0) { + os = 'Windows'; + } + + const id = pad.id; + // Chrom* style: NAME (Vendor: xxxx Product: xxxx) + const exp1 = /vendor: ([0-9a-f]{4}) product: ([0-9a-f]{4})/i; + // Firefox/Safari style (safari may remove leading zeores) + const exp2 = /^([0-9a-f]+)-([0-9a-f]+)-/i; + let vendor = ''; + let product = ''; + if (exp1.test(id)) { + const match = exp1.exec(id); + vendor = match[1].padStart(4, '0'); + product = match[2].padStart(4, '0'); + } else if (exp2.test(id)) { + const match = exp2.exec(id); + vendor = match[1].padStart(4, '0'); + product = match[2].padStart(4, '0'); + } + if (!vendor || !product) { + return `${os}Unknown`; + } + return os + vendor + product; + }, + }, +}; +mergeInto(LibraryManager.library, GodotDisplayGamepads); + +const GodotDisplayScreen = { + $GodotDisplayScreen__deps: ['$GodotConfig', '$GodotOS', '$GL', 'emscripten_webgl_get_current_context'], + $GodotDisplayScreen: { + desired_size: [0, 0], + isFullscreen: function () { + const elem = document.fullscreenElement || document.mozFullscreenElement + || document.webkitFullscreenElement || document.msFullscreenElement; + if (elem) { + return elem === GodotConfig.canvas; + } + // But maybe knowing the element is not supported. + return document.fullscreen || document.mozFullScreen + || document.webkitIsFullscreen; + }, + hasFullscreen: function () { + return document.fullscreenEnabled || document.mozFullScreenEnabled + || document.webkitFullscreenEnabled; + }, + requestFullscreen: function () { + if (!GodotDisplayScreen.hasFullscreen()) { + return 1; + } + const canvas = GodotConfig.canvas; + try { + const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen + || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen + || canvas.webkitRequestFullscreen + ).call(canvas); + // Some browsers (Safari) return undefined. + // For the standard ones, we need to catch it. + if (promise) { + promise.catch(function () { + // nothing to do. + }); + } + } catch (e) { + return 1; + } + return 0; + }, + exitFullscreen: function () { + if (!GodotDisplayScreen.isFullscreen()) { + return 0; + } + try { + const promise = document.exitFullscreen(); + if (promise) { + promise.catch(function () { + // nothing to do. + }); + } + } catch (e) { + return 1; + } + return 0; + }, + _updateGL: function () { + const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef + const gl = GL.getContext(gl_context_handle); + if (gl) { + GL.resizeOffscreenFramebuffer(gl); + } + }, + updateSize: function () { + const isFullscreen = GodotDisplayScreen.isFullscreen(); + const wantsFullWindow = GodotConfig.canvas_resize_policy === 2; + const noResize = GodotConfig.canvas_resize_policy === 0; + const wwidth = GodotDisplayScreen.desired_size[0]; + const wheight = GodotDisplayScreen.desired_size[1]; + const canvas = GodotConfig.canvas; + let width = wwidth; + let height = wheight; + if (noResize) { + // Don't resize canvas, just update GL if needed. + if (canvas.width !== width || canvas.height !== height) { + GodotDisplayScreen.desired_size = [canvas.width, canvas.height]; + GodotDisplayScreen._updateGL(); + return 1; + } + return 0; + } + const scale = window.devicePixelRatio || 1; + if (isFullscreen || wantsFullWindow) { + // We need to match screen size. + width = window.innerWidth * scale; + height = window.innerHeight * scale; + } + const csw = `${width / scale}px`; + const csh = `${height / scale}px`; + if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) { + // Size doesn't match. + // Resize canvas, set correct CSS pixel size, update GL. + canvas.width = width; + canvas.height = height; + canvas.style.width = csw; + canvas.style.height = csh; + GodotDisplayScreen._updateGL(); + return 1; + } + return 0; + }, + }, +}; +mergeInto(LibraryManager.library, GodotDisplayScreen); + /** * Display server interface. * * Exposes all the functions needed by DisplayServer implementation. */ const GodotDisplay = { - $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop'], + $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads', '$GodotDisplayScreen'], $GodotDisplay: { window_icon: '', + findDPI: function () { + function testDPI(dpi) { + return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches; + } + function bisect(low, high, func) { + const mid = parseInt(((high - low) / 2) + low, 10); + if (high - low <= 1) { + return func(high) ? high : low; + } + if (func(mid)) { + return bisect(low, mid, func); + } + return bisect(mid, high, func); + } + try { + const dpi = bisect(0, 800, testDPI); + return dpi >= 96 ? dpi : 96; + } catch (e) { + return 96; + } + }, }, godot_js_display_is_swap_ok_cancel__sig: 'i', @@ -295,11 +548,58 @@ const GodotDisplay = { window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert }, + godot_js_display_screen_dpi_get__sig: 'i', + godot_js_display_screen_dpi_get: function () { + return GodotDisplay.findDPI(); + }, + godot_js_display_pixel_ratio_get__sig: 'f', godot_js_display_pixel_ratio_get: function () { return window.devicePixelRatio || 1; }, + godot_js_display_fullscreen_request__sig: 'i', + godot_js_display_fullscreen_request: function () { + return GodotDisplayScreen.requestFullscreen(); + }, + + godot_js_display_fullscreen_exit__sig: 'i', + godot_js_display_fullscreen_exit: function () { + return GodotDisplayScreen.exitFullscreen(); + }, + + godot_js_display_desired_size_set__sig: 'v', + godot_js_display_desired_size_set: function (width, height) { + GodotDisplayScreen.desired_size = [width, height]; + GodotDisplayScreen.updateSize(); + }, + + godot_js_display_size_update__sig: 'i', + godot_js_display_size_update: function () { + return GodotDisplayScreen.updateSize(); + }, + + godot_js_display_screen_size_get__sig: 'vii', + godot_js_display_screen_size_get: function (width, height) { + const scale = window.devicePixelRatio || 1; + GodotRuntime.setHeapValue(width, window.screen.width * scale, 'i32'); + GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32'); + }, + + godot_js_display_window_size_get: function (p_width, p_height) { + GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32'); + GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32'); + }, + + godot_js_display_compute_position: function (x, y, r_x, r_y) { + const canvas = GodotConfig.canvas; + const rect = canvas.getBoundingClientRect(); + const rw = canvas.width / rect.width; + const rh = canvas.height / rect.height; + GodotRuntime.setHeapValue(r_x, (x - rect.x) * rw, 'i32'); + GodotRuntime.setHeapValue(r_y, (y - rect.y) * rh, 'i32'); + }, + /* * Canvas */ @@ -313,13 +613,6 @@ const GodotDisplay = { return document.activeElement === GodotConfig.canvas; }, - godot_js_display_canvas_bounding_rect_position_get__sig: 'vii', - godot_js_display_canvas_bounding_rect_position_get: function (r_x, r_y) { - const brect = GodotConfig.canvas.getBoundingClientRect(); - GodotRuntime.setHeapValue(r_x, brect.x, 'i32'); - GodotRuntime.setHeapValue(r_y, brect.y, 'i32'); - }, - /* * Touchscreen */ @@ -363,15 +656,6 @@ const GodotDisplay = { /* * Window */ - godot_js_display_window_request_fullscreen__sig: 'v', - godot_js_display_window_request_fullscreen: function () { - const canvas = GodotConfig.canvas; - (canvas.requestFullscreen || canvas.msRequestFullscreen - || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen - || canvas.webkitRequestFullscreen - ).call(canvas); - }, - godot_js_display_window_title_set__sig: 'vi', godot_js_display_window_title_set: function (p_data) { document.title = GodotRuntime.parseString(p_data); @@ -491,6 +775,78 @@ const GodotDisplay = { }, false); GodotDisplayListeners.add(canvas, 'drop', GodotDisplayDragDrop.handler(dropFiles)); }, + + godot_js_display_setup_canvas__sig: 'viii', + godot_js_display_setup_canvas: function (p_width, p_height, p_fullscreen) { + const canvas = GodotConfig.canvas; + GodotDisplayListeners.add(canvas, 'contextmenu', function (ev) { + ev.preventDefault(); + }, false); + GodotDisplayListeners.add(canvas, 'webglcontextlost', function (ev) { + alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert + ev.preventDefault(); + }, false); + switch (GodotConfig.canvas_resize_policy) { + case 0: // None + GodotDisplayScreen.desired_size = [canvas.width, canvas.height]; + break; + case 1: // Project + GodotDisplayScreen.desired_size = [p_width, p_height]; + break; + default: // Full window + // Ensure we display in the right place, the size will be handled by updateSize + canvas.style.position = 'absolute'; + canvas.style.top = 0; + canvas.style.left = 0; + break; + } + if (p_fullscreen) { + GodotDisplayScreen.requestFullscreen(); + } + }, + + /* + * Gamepads + */ + godot_js_display_gamepad_cb__sig: 'vi', + godot_js_display_gamepad_cb: function (change_cb) { + const onchange = GodotRuntime.get_func(change_cb); + GodotDisplayGamepads.init(onchange); + }, + + godot_js_display_gamepad_sample_count__sig: 'i', + godot_js_display_gamepad_sample_count: function () { + return GodotDisplayGamepads.get_samples().length; + }, + + godot_js_display_gamepad_sample__sig: 'i', + godot_js_display_gamepad_sample: function () { + GodotDisplayGamepads.sample(); + return 0; + }, + + godot_js_display_gamepad_sample_get__sig: 'iiiiiii', + godot_js_display_gamepad_sample_get: function (p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard) { + const sample = GodotDisplayGamepads.get_sample(p_index); + if (!sample || !sample.connected) { + return 1; + } + const btns = sample.buttons; + const btns_len = btns.length < 16 ? btns.length : 16; + for (let i = 0; i < btns_len; i++) { + GodotRuntime.setHeapValue(r_btns + (i << 2), btns[i], 'float'); + } + GodotRuntime.setHeapValue(r_btns_num, btns_len, 'i32'); + const axes = sample.axes; + const axes_len = axes.length < 10 ? axes.length : 10; + for (let i = 0; i < axes_len; i++) { + GodotRuntime.setHeapValue(r_axes + (i << 2), axes[i], 'float'); + } + GodotRuntime.setHeapValue(r_axes_num, axes_len, 'i32'); + const is_standard = sample.standard ? 1 : 0; + GodotRuntime.setHeapValue(r_standard, is_standard, 'i32'); + return 0; + }, }; autoAddDeps(GodotDisplay, '$GodotDisplay'); diff --git a/platform/javascript/js/libs/library_godot_http_request.js b/platform/javascript/js/libs/library_godot_http_request.js index 930d3209f8..7dc2a2df29 100644 --- a/platform/javascript/js/libs/library_godot_http_request.js +++ b/platform/javascript/js/libs/library_godot_http_request.js @@ -82,31 +82,13 @@ const GodotHTTPRequest = { GodotHTTPRequest.requests[xhrId].setRequestHeader(GodotRuntime.parseString(header), GodotRuntime.parseString(value)); }, - godot_xhr_send_null__sig: 'vi', - godot_xhr_send_null: function (xhrId) { - GodotHTTPRequest.requests[xhrId].send(); - }, - - godot_xhr_send_string__sig: 'vii', - godot_xhr_send_string: function (xhrId, strPtr) { - if (!strPtr) { - GodotRuntime.error('Failed to send string per XHR: null pointer'); - return; - } - GodotHTTPRequest.requests[xhrId].send(GodotRuntime.parseString(strPtr)); - }, - - godot_xhr_send_data__sig: 'viii', - godot_xhr_send_data: function (xhrId, ptr, len) { - if (!ptr) { - GodotRuntime.error('Failed to send data per XHR: null pointer'); - return; - } - if (len < 0) { - GodotRuntime.error('Failed to send data per XHR: buffer length less than 0'); - return; + godot_xhr_send__sig: 'viii', + godot_xhr_send: function (xhrId, p_ptr, p_len) { + let data = null; + if (p_ptr && p_len) { + data = GodotRuntime.heapCopy(HEAP8, p_ptr, p_len); } - GodotHTTPRequest.requests[xhrId].send(HEAPU8.subarray(ptr, ptr + len)); + GodotHTTPRequest.requests[xhrId].send(data); }, godot_xhr_abort__sig: 'vi', diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js index 9fde4a84e1..0f189b013c 100644 --- a/platform/javascript/js/libs/library_godot_os.js +++ b/platform/javascript/js/libs/library_godot_os.js @@ -58,21 +58,28 @@ const GodotConfig = { $GodotConfig: { canvas: null, locale: 'en', - resize_on_start: false, + canvas_resize_policy: 2, // Adaptive on_execute: null, + on_exit: null, init_config: function (p_opts) { - GodotConfig.resize_on_start = !!p_opts['resizeCanvasOnStart']; + GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy']; GodotConfig.canvas = p_opts['canvas']; GodotConfig.locale = p_opts['locale'] || GodotConfig.locale; GodotConfig.on_execute = p_opts['onExecute']; - // This is called by emscripten, even if undocumented. - Module['onExit'] = p_opts['onExit']; // eslint-disable-line no-undef + GodotConfig.on_exit = p_opts['onExit']; }, locate_file: function (file) { return Module['locateFile'](file); // eslint-disable-line no-undef }, + clear: function () { + GodotConfig.canvas = null; + GodotConfig.locale = 'en'; + GodotConfig.canvas_resize_policy = 2; + GodotConfig.on_execute = null; + GodotConfig.on_exit = null; + }, }, godot_js_config_canvas_id_get__sig: 'vii', @@ -84,11 +91,6 @@ const GodotConfig = { godot_js_config_locale_get: function (p_ptr, p_ptr_max) { GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max); }, - - godot_js_config_is_resize_on_start__sig: 'i', - godot_js_config_is_resize_on_start: function () { - return GodotConfig.resize_on_start ? 1 : 0; - }, }; autoAddDeps(GodotConfig, '$GodotConfig'); @@ -98,7 +100,6 @@ const GodotFS = { $GodotFS__deps: ['$FS', '$IDBFS', '$GodotRuntime'], $GodotFS__postset: [ 'Module["initFS"] = GodotFS.init;', - 'Module["deinitFS"] = GodotFS.deinit;', 'Module["copyToFS"] = GodotFS.copy_to_fs;', ].join(''), $GodotFS: { @@ -210,9 +211,10 @@ const GodotFS = { mergeInto(LibraryManager.library, GodotFS); const GodotOS = { - $GodotOS__deps: ['$GodotFS', '$GodotRuntime'], + $GodotOS__deps: ['$GodotRuntime', '$GodotConfig', '$GodotFS'], $GodotOS__postset: [ 'Module["request_quit"] = function() { GodotOS.request_quit() };', + 'Module["onExit"] = GodotOS.cleanup;', 'GodotOS._fs_sync_promise = Promise.resolve();', ].join(''), $GodotOS: { @@ -224,6 +226,15 @@ const GodotOS = { GodotOS._async_cbs.push(p_promise_cb); }, + cleanup: function (exit_code) { + const cb = GodotConfig.on_exit; + GodotFS.deinit(); + GodotConfig.clear(); + if (cb) { + cb(exit_code); + } + }, + finish_async: function (callback) { GodotOS._fs_sync_promise.then(function (err) { const promises = []; @@ -282,6 +293,11 @@ const GodotOS = { godot_js_os_shell_open: function (p_uri) { window.open(GodotRuntime.parseString(p_uri), '_blank'); }, + + godot_js_os_hw_concurrency_get__sig: 'i', + godot_js_os_hw_concurrency_get: function () { + return navigator.hardwareConcurrency || 1; + }, }; autoAddDeps(GodotOS, '$GodotOS'); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 3fb5d4ad6a..0b1650076c 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -106,14 +106,18 @@ void OS_JavaScript::finalize() { // Miscellaneous -Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { +Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { + return create_process(p_path, p_arguments); +} + +Error OS_JavaScript::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { Array args; for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { args.push_back(E->get()); } String json_args = JSON::print(args); int failed = godot_js_os_execute(json_args.utf8().get_data()); - ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() must be implemented in JavaScript via 'engine.setOnExecute' if required."); + ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() or create_process() must be implemented in JavaScript via 'engine.setOnExecute' if required."); return OK; } @@ -125,6 +129,10 @@ int OS_JavaScript::get_process_id() const { ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform."); } +int OS_JavaScript::get_processor_count() const { + return godot_js_os_hw_concurrency_get(); +} + bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { if (p_feature == "HTML5" || p_feature == "web") { return true; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 9c8da0c898..81bb9c5f3d 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -70,9 +70,11 @@ public: MainLoop *get_main_loop() const override; bool main_loop_iterate(); - Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; + Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; + Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; Error kill(const ProcessID &p_pid) override; int get_process_id() const override; + int get_processor_count() const override; String get_executable_path() const override; Error shell_open(String p_uri) override; diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json index 8e298a495e..b8c434b3dd 100644 --- a/platform/javascript/package-lock.json +++ b/platform/javascript/package-lock.json @@ -43,6 +43,12 @@ } } }, + "@babel/parser": { + "version": "7.13.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.4.tgz", + "integrity": "sha512-uvoOulWHhI+0+1f9L4BoozY7U5cIkZ9PgJqvb041d6vypgUmtVPG4vmGm4pSggjl8BELzvHyUeJSUyEMY6b+qA==", + "dev": true + }, "@eslint/eslintrc": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", @@ -202,6 +208,12 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -218,6 +230,15 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "catharsis": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", + "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -362,6 +383,12 @@ "ansi-colors": "^4.1.1" } }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -925,6 +952,51 @@ "esprima": "^4.0.0" } }, + "js2xmlparser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", + "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.3" + } + }, + "jsdoc": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz", + "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.9.4", + "bluebird": "^3.7.2", + "catharsis": "^0.8.11", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.1", + "klaw": "^3.0.0", + "markdown-it": "^10.0.0", + "markdown-it-anchor": "^5.2.7", + "marked": "^0.8.2", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "taffydb": "2.6.2", + "underscore": "~1.10.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -946,6 +1018,15 @@ "minimist": "^1.2.0" } }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -956,6 +1037,15 @@ "type-check": "~0.4.0" } }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -984,6 +1074,37 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "dev": true + }, + "marked": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", + "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==", + "dev": true + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1287,6 +1408,15 @@ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, + "requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -1513,6 +1643,12 @@ "string-width": "^3.0.0" } }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -1546,6 +1682,18 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "underscore": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", + "dev": true + }, "uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", @@ -1600,6 +1748,12 @@ "requires": { "mkdirp": "^0.5.1" } + }, + "xmlcreate": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", + "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", + "dev": true } } } diff --git a/platform/javascript/package.json b/platform/javascript/package.json index 630b584f5b..d9d272923e 100644 --- a/platform/javascript/package.json +++ b/platform/javascript/package.json @@ -5,20 +5,24 @@ "description": "Linting setup for Godot's HTML5 platform code", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "lint": "npm run lint:engine && npm run lint:libs && npm run lint:modules", + "docs": "jsdoc --template js/jsdoc2rst/ js/engine/engine.js js/engine/config.js --destination ''", + "lint": "npm run lint:engine && npm run lint:libs && npm run lint:modules && npm run lint:tools", "lint:engine": "eslint \"js/engine/*.js\" --no-eslintrc -c .eslintrc.engine.js", "lint:libs": "eslint \"js/libs/*.js\" --no-eslintrc -c .eslintrc.libs.js", "lint:modules": "eslint \"../../modules/**/*.js\" --no-eslintrc -c .eslintrc.libs.js", - "format": "npm run format:engine && npm run format:libs && npm run format:modules", + "lint:tools": "eslint \"js/jsdoc2rst/**/*.js\" --no-eslintrc -c .eslintrc.engine.js", + "format": "npm run format:engine && npm run format:libs && npm run format:modules && npm run format:tools", "format:engine": "npm run lint:engine -- --fix", "format:libs": "npm run lint:libs -- --fix", - "format:modules": "npm run lint:modules -- --fix" + "format:modules": "npm run lint:modules -- --fix", + "format:tools": "npm run lint:tools -- --fix" }, "author": "Godot Engine contributors", "license": "MIT", "devDependencies": { "eslint": "^7.9.0", "eslint-config-airbnb-base": "^14.2.0", - "eslint-plugin-import": "^2.22.0" + "eslint-plugin-import": "^2.22.0", + "jsdoc": "^3.6.6" } } diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index 6e43ffcedb..46714e9502 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -16,7 +16,10 @@ common_x11 = [ "key_mapping_x11.cpp", ] +if "udev" in env and env["udev"]: + common_x11.append("libudev-so_wrap.c") + prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_x11) -if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: +if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd)) diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp index 90e34f8e77..ea0222cb19 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.cpp +++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp @@ -104,7 +104,7 @@ static void handle_crash(int sig) { // Try to get the file/line number using addr2line int ret; - Error err = OS::get_singleton()->execute(String("addr2line"), args, true, nullptr, &output, &ret); + Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret); if (err == OK) { output.erase(output.length() - 1, 1); } diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index a819731328..8f1afe0e66 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -64,15 +64,15 @@ def get_opts(): BoolVariable("use_llvm", "Use the LLVM compiler", False), BoolVariable("use_lld", "Use the LLD linker", False), BoolVariable("use_thinlto", "Use ThinLTO", False), - BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False), + BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True), BoolVariable("use_coverage", "Test Godot coverage", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False), BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False), BoolVariable("pulseaudio", "Detect and use PulseAudio", True), - BoolVariable("udev", "Use udev for gamepad connection callbacks", False), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("udev", "Use udev for gamepad connection callbacks", True), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("touch", "Enable touch events", True), BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), @@ -92,7 +92,7 @@ def configure(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -102,7 +102,7 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": @@ -310,9 +310,8 @@ def configure(env): if os.system("pkg-config --exists alsa") == 0: # 0 means found print("Enabling ALSA") + env["alsa"] = True env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) - # Don't parse --cflags, we don't need to add /usr/include/alsa to include path - env.ParseConfig("pkg-config alsa --libs") else: print("ALSA libraries not found, disabling driver") @@ -320,20 +319,20 @@ def configure(env): if os.system("pkg-config --exists libpulse") == 0: # 0 means found print("Enabling PulseAudio") env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) - env.ParseConfig("pkg-config --cflags --libs libpulse") + env.ParseConfig("pkg-config --cflags libpulse") else: print("PulseAudio development libraries not found, disabling driver") if platform.system() == "Linux": env.Append(CPPDEFINES=["JOYDEV_ENABLED"]) - if env["udev"]: if os.system("pkg-config --exists libudev") == 0: # 0 means found print("Enabling udev support") env.Append(CPPDEFINES=["UDEV_ENABLED"]) - env.ParseConfig("pkg-config libudev --cflags --libs") else: print("libudev development libraries not found, disabling udev support") + else: + env["udev"] = False # Linux specific # Linkflags below this line should typically stay the last ones if not env["builtin_zlib"]: @@ -390,4 +389,13 @@ def configure(env): # Link those statically for portability if env["use_static_cpp"]: - env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) + # Workaround for GH-31743, Ubuntu 18.04 i386 crashes when it's used. + # That doesn't make any sense but it's likely a Ubuntu bug? + if is64 or env["bits"] == "64": + env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) + if env["use_llvm"]: + env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a" + + else: + if env["use_llvm"]: + env.Append(LIBS=["atomic"]) diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp index 0f8d108dff..da1c95a593 100644 --- a/platform/linuxbsd/detect_prime_x11.cpp +++ b/platform/linuxbsd/detect_prime_x11.cpp @@ -61,6 +61,7 @@ struct vendor { vendor vendormap[] = { { "Advanced Micro Devices, Inc.", 30 }, + { "AMD", 30 }, { "NVIDIA Corporation", 30 }, { "X.Org", 30 }, { "Intel Open Source Technology Center", 20 }, @@ -128,7 +129,7 @@ void create_context() { int detect_prime() { pid_t p; - int priorities[2]; + int priorities[2] = {}; String vendors[2]; String renderers[2]; diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 1ee5cd3923..d7f7054acb 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -191,7 +191,7 @@ void DisplayServerX11::alert(const String &p_alert, const String &p_title) { } if (program.length()) { - OS::get_singleton()->execute(program, args, true); + OS::get_singleton()->execute(program, args); } else { print_line(p_alert); } @@ -727,9 +727,9 @@ Point2i DisplayServerX11::screen_get_position(int p_screen) const { int count; XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count); - if (p_screen >= count) { - return Point2i(0, 0); - } + + // Check if screen is valid + ERR_FAIL_INDEX_V(p_screen, count, Point2i(0, 0)); Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org); @@ -758,9 +758,9 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { int count; XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count); - if (p_screen >= count) { - return Rect2i(0, 0, 0, 0); - } + + // Check if screen is valid + ERR_FAIL_INDEX_V(p_screen, count, Rect2i(0, 0, 0, 0)); Rect2i rect = Rect2i(xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height); XFree(xsi); @@ -1041,11 +1041,13 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - int count = get_screen_count(); - if (p_screen >= count) { - return; + if (p_screen == SCREEN_OF_MAIN_WINDOW) { + p_screen = window_get_current_screen(); } + // Check if screen is valid + ERR_FAIL_INDEX(p_screen, get_screen_count()); + if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN) { Point2i position = screen_get_position(p_screen); Size2i size = screen_get_size(p_screen); @@ -2697,7 +2699,7 @@ bool DisplayServerX11::_wait_for_events() const { } void DisplayServerX11::_poll_events() { - while (!events_thread_done) { + while (!events_thread_done.is_set()) { _wait_for_events(); // Process events from the queue. @@ -3360,7 +3362,7 @@ void DisplayServerX11::process_events() { Vector<String> files = String((char *)p.data).split("\n", false); for (int i = 0; i < files.size(); i++) { - files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges(); + files.write[i] = files[i].replace("file://", "").uri_decode().strip_edges(); } if (!windows[window_id].drop_files_callback.is_null()) { @@ -4266,7 +4268,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } } - events_thread = Thread::create(_poll_events_thread, this); + events_thread.start(_poll_events_thread, this); _update_real_mouse_position(windows[MAIN_WINDOW_ID]); @@ -4279,10 +4281,8 @@ DisplayServerX11::~DisplayServerX11() { _clipboard_transfer_ownership(XA_PRIMARY, x11_main_window); _clipboard_transfer_ownership(XInternAtom(x11_display, "CLIPBOARD", 0), x11_main_window); - events_thread_done = true; - Thread::wait_to_finish(events_thread); - memdelete(events_thread); - events_thread = nullptr; + events_thread_done.set(); + events_thread.wait_to_finish(); //destroy all windows for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 7784ba82b5..10686d8424 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -252,8 +252,8 @@ class DisplayServerX11 : public DisplayServer { void _dispatch_input_event(const Ref<InputEvent> &p_event); mutable Mutex events_mutex; - Thread *events_thread = nullptr; - bool events_thread_done = false; + Thread events_thread; + SafeFlag events_thread_done; LocalVector<XEvent> polled_events; static void _poll_events_thread(void *ud); bool _wait_for_events() const; diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index 291ca49585..471259e50f 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -32,13 +32,14 @@ #include "joypad_linux.h" +#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <linux/input.h> #include <unistd.h> #ifdef UDEV_ENABLED -#include <libudev.h> +#include "libudev-so_wrap.h" #endif #define LONG_BITS (sizeof(long) * 8) @@ -71,15 +72,28 @@ void JoypadLinux::Joypad::reset() { } JoypadLinux::JoypadLinux(Input *in) { - exit_udev = false; +#ifdef UDEV_ENABLED +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + use_udev = initialize_libudev(dylibloader_verbose) == 0; + if (use_udev) { + print_verbose("JoypadLinux: udev enabled and loaded successfully."); + } else { + print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads."); + } +#else + print_verbose("JoypadLinux: udev disabled, parsing /dev/input to detect joypads."); +#endif input = in; - joy_thread = Thread::create(joy_thread_func, this); + joy_thread.start(joy_thread_func, this); } JoypadLinux::~JoypadLinux() { - exit_udev = true; - Thread::wait_to_finish(joy_thread); - memdelete(joy_thread); + exit_monitor.set(); + joy_thread.wait_to_finish(); close_joypad(); } @@ -92,11 +106,20 @@ void JoypadLinux::joy_thread_func(void *p_user) { void JoypadLinux::run_joypad_thread() { #ifdef UDEV_ENABLED - udev *_udev = udev_new(); - ERR_FAIL_COND(!_udev); - enumerate_joypads(_udev); - monitor_joypads(_udev); - udev_unref(_udev); + if (use_udev) { + udev *_udev = udev_new(); + if (!_udev) { + use_udev = false; + ERR_PRINT("Failed getting an udev context, falling back to parsing /dev/input."); + monitor_joypads(); + } else { + enumerate_joypads(_udev); + monitor_joypads(_udev); + udev_unref(_udev); + } + } else { + monitor_joypads(); + } #else monitor_joypads(); #endif @@ -137,7 +160,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) { udev_monitor_enable_receiving(mon); int fd = udev_monitor_get_fd(mon); - while (!exit_udev) { + while (!exit_monitor.is_set()) { fd_set fds; struct timeval tv; int ret; @@ -179,17 +202,27 @@ void JoypadLinux::monitor_joypads(udev *p_udev) { #endif void JoypadLinux::monitor_joypads() { - while (!exit_udev) { + while (!exit_monitor.is_set()) { { MutexLock lock(joy_mutex); - for (int i = 0; i < 32; i++) { + DIR *input_directory; + input_directory = opendir("/dev/input"); + if (input_directory) { + struct dirent *current; char fname[64]; - sprintf(fname, "/dev/input/event%d", i); - if (attached_devices.find(fname) == -1) { - open_joypad(fname); + + while ((current = readdir(input_directory)) != NULL) { + if (strncmp(current->d_name, "event", 5) != 0) { + continue; + } + sprintf(fname, "/dev/input/%.*s", 16, current->d_name); + if (attached_devices.find(fname) == -1) { + open_joypad(fname); + } } } + closedir(input_directory); } usleep(1000000); // 1s } diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h index 20d30b510c..b0d0db047b 100644 --- a/platform/linuxbsd/joypad_linux.h +++ b/platform/linuxbsd/joypad_linux.h @@ -70,10 +70,13 @@ private: void reset(); }; - bool exit_udev; +#ifdef UDEV_ENABLED + bool use_udev = false; +#endif + SafeFlag exit_monitor; Mutex joy_mutex; - Thread *joy_thread; - Input *input; + Thread joy_thread; + Input *input = nullptr; Joypad joypads[JOYPADS_MAX]; Vector<String> attached_devices; diff --git a/platform/linuxbsd/libudev-so_wrap.c b/platform/linuxbsd/libudev-so_wrap.c new file mode 100644 index 0000000000..a9fa4a494a --- /dev/null +++ b/platform/linuxbsd/libudev-so_wrap.c @@ -0,0 +1,1013 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59 +// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c +// +#include <stdint.h> + +#define udev_ref udev_ref_dylibloader_orig_libudev +#define udev_unref udev_unref_dylibloader_orig_libudev +#define udev_new udev_new_dylibloader_orig_libudev +#define udev_set_log_fn udev_set_log_fn_dylibloader_orig_libudev +#define udev_get_log_priority udev_get_log_priority_dylibloader_orig_libudev +#define udev_set_log_priority udev_set_log_priority_dylibloader_orig_libudev +#define udev_get_userdata udev_get_userdata_dylibloader_orig_libudev +#define udev_set_userdata udev_set_userdata_dylibloader_orig_libudev +#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_orig_libudev +#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_orig_libudev +#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_orig_libudev +#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_orig_libudev +#define udev_device_ref udev_device_ref_dylibloader_orig_libudev +#define udev_device_unref udev_device_unref_dylibloader_orig_libudev +#define udev_device_get_udev udev_device_get_udev_dylibloader_orig_libudev +#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_orig_libudev +#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_orig_libudev +#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_orig_libudev +#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_orig_libudev +#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_orig_libudev +#define udev_device_get_parent udev_device_get_parent_dylibloader_orig_libudev +#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_orig_libudev +#define udev_device_get_devpath udev_device_get_devpath_dylibloader_orig_libudev +#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_orig_libudev +#define udev_device_get_devtype udev_device_get_devtype_dylibloader_orig_libudev +#define udev_device_get_syspath udev_device_get_syspath_dylibloader_orig_libudev +#define udev_device_get_sysname udev_device_get_sysname_dylibloader_orig_libudev +#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_orig_libudev +#define udev_device_get_devnode udev_device_get_devnode_dylibloader_orig_libudev +#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_orig_libudev +#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_orig_libudev +#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_orig_libudev +#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_orig_libudev +#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_orig_libudev +#define udev_device_get_property_value udev_device_get_property_value_dylibloader_orig_libudev +#define udev_device_get_driver udev_device_get_driver_dylibloader_orig_libudev +#define udev_device_get_devnum udev_device_get_devnum_dylibloader_orig_libudev +#define udev_device_get_action udev_device_get_action_dylibloader_orig_libudev +#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_orig_libudev +#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_orig_libudev +#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_orig_libudev +#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_orig_libudev +#define udev_device_has_tag udev_device_has_tag_dylibloader_orig_libudev +#define udev_monitor_ref udev_monitor_ref_dylibloader_orig_libudev +#define udev_monitor_unref udev_monitor_unref_dylibloader_orig_libudev +#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_orig_libudev +#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_orig_libudev +#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_orig_libudev +#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_orig_libudev +#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_orig_libudev +#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_orig_libudev +#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_orig_libudev +#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_orig_libudev +#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_orig_libudev +#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_orig_libudev +#define udev_enumerate_ref udev_enumerate_ref_dylibloader_orig_libudev +#define udev_enumerate_unref udev_enumerate_unref_dylibloader_orig_libudev +#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_orig_libudev +#define udev_enumerate_new udev_enumerate_new_dylibloader_orig_libudev +#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_orig_libudev +#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_orig_libudev +#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_orig_libudev +#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_orig_libudev +#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_orig_libudev +#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_orig_libudev +#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_orig_libudev +#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_orig_libudev +#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_orig_libudev +#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_orig_libudev +#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_orig_libudev +#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_orig_libudev +#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_orig_libudev +#define udev_queue_ref udev_queue_ref_dylibloader_orig_libudev +#define udev_queue_unref udev_queue_unref_dylibloader_orig_libudev +#define udev_queue_get_udev udev_queue_get_udev_dylibloader_orig_libudev +#define udev_queue_new udev_queue_new_dylibloader_orig_libudev +#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_orig_libudev +#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_orig_libudev +#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_orig_libudev +#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_orig_libudev +#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_orig_libudev +#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_orig_libudev +#define udev_queue_get_fd udev_queue_get_fd_dylibloader_orig_libudev +#define udev_queue_flush udev_queue_flush_dylibloader_orig_libudev +#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_orig_libudev +#define udev_hwdb_new udev_hwdb_new_dylibloader_orig_libudev +#define udev_hwdb_ref udev_hwdb_ref_dylibloader_orig_libudev +#define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev +#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev +#define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev +#include <libudev.h> +#undef udev_ref +#undef udev_unref +#undef udev_new +#undef udev_set_log_fn +#undef udev_get_log_priority +#undef udev_set_log_priority +#undef udev_get_userdata +#undef udev_set_userdata +#undef udev_list_entry_get_next +#undef udev_list_entry_get_by_name +#undef udev_list_entry_get_name +#undef udev_list_entry_get_value +#undef udev_device_ref +#undef udev_device_unref +#undef udev_device_get_udev +#undef udev_device_new_from_syspath +#undef udev_device_new_from_devnum +#undef udev_device_new_from_subsystem_sysname +#undef udev_device_new_from_device_id +#undef udev_device_new_from_environment +#undef udev_device_get_parent +#undef udev_device_get_parent_with_subsystem_devtype +#undef udev_device_get_devpath +#undef udev_device_get_subsystem +#undef udev_device_get_devtype +#undef udev_device_get_syspath +#undef udev_device_get_sysname +#undef udev_device_get_sysnum +#undef udev_device_get_devnode +#undef udev_device_get_is_initialized +#undef udev_device_get_devlinks_list_entry +#undef udev_device_get_properties_list_entry +#undef udev_device_get_tags_list_entry +#undef udev_device_get_sysattr_list_entry +#undef udev_device_get_property_value +#undef udev_device_get_driver +#undef udev_device_get_devnum +#undef udev_device_get_action +#undef udev_device_get_seqnum +#undef udev_device_get_usec_since_initialized +#undef udev_device_get_sysattr_value +#undef udev_device_set_sysattr_value +#undef udev_device_has_tag +#undef udev_monitor_ref +#undef udev_monitor_unref +#undef udev_monitor_get_udev +#undef udev_monitor_new_from_netlink +#undef udev_monitor_enable_receiving +#undef udev_monitor_set_receive_buffer_size +#undef udev_monitor_get_fd +#undef udev_monitor_receive_device +#undef udev_monitor_filter_add_match_subsystem_devtype +#undef udev_monitor_filter_add_match_tag +#undef udev_monitor_filter_update +#undef udev_monitor_filter_remove +#undef udev_enumerate_ref +#undef udev_enumerate_unref +#undef udev_enumerate_get_udev +#undef udev_enumerate_new +#undef udev_enumerate_add_match_subsystem +#undef udev_enumerate_add_nomatch_subsystem +#undef udev_enumerate_add_match_sysattr +#undef udev_enumerate_add_nomatch_sysattr +#undef udev_enumerate_add_match_property +#undef udev_enumerate_add_match_sysname +#undef udev_enumerate_add_match_tag +#undef udev_enumerate_add_match_parent +#undef udev_enumerate_add_match_is_initialized +#undef udev_enumerate_add_syspath +#undef udev_enumerate_scan_devices +#undef udev_enumerate_scan_subsystems +#undef udev_enumerate_get_list_entry +#undef udev_queue_ref +#undef udev_queue_unref +#undef udev_queue_get_udev +#undef udev_queue_new +#undef udev_queue_get_kernel_seqnum +#undef udev_queue_get_udev_seqnum +#undef udev_queue_get_udev_is_active +#undef udev_queue_get_queue_is_empty +#undef udev_queue_get_seqnum_is_finished +#undef udev_queue_get_seqnum_sequence_is_finished +#undef udev_queue_get_fd +#undef udev_queue_flush +#undef udev_queue_get_queued_list_entry +#undef udev_hwdb_new +#undef udev_hwdb_ref +#undef udev_hwdb_unref +#undef udev_hwdb_get_properties_list_entry +#undef udev_util_encode_string +#include <dlfcn.h> +#include <stdio.h> +struct udev* (*udev_ref_dylibloader_wrapper_libudev)(struct udev*); +struct udev* (*udev_unref_dylibloader_wrapper_libudev)(struct udev*); +struct udev* (*udev_new_dylibloader_wrapper_libudev)( void); +void (*udev_set_log_fn_dylibloader_wrapper_libudev)(struct udev*, void*); +int (*udev_get_log_priority_dylibloader_wrapper_libudev)(struct udev*); +void (*udev_set_log_priority_dylibloader_wrapper_libudev)(struct udev*, int); +void* (*udev_get_userdata_dylibloader_wrapper_libudev)(struct udev*); +void (*udev_set_userdata_dylibloader_wrapper_libudev)(struct udev*, void*); +struct udev_list_entry* (*udev_list_entry_get_next_dylibloader_wrapper_libudev)(struct udev_list_entry*); +struct udev_list_entry* (*udev_list_entry_get_by_name_dylibloader_wrapper_libudev)(struct udev_list_entry*,const char*); +const char* (*udev_list_entry_get_name_dylibloader_wrapper_libudev)(struct udev_list_entry*); +const char* (*udev_list_entry_get_value_dylibloader_wrapper_libudev)(struct udev_list_entry*); +struct udev_device* (*udev_device_ref_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_device* (*udev_device_unref_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev* (*udev_device_get_udev_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_device* (*udev_device_new_from_syspath_dylibloader_wrapper_libudev)(struct udev*,const char*); +struct udev_device* (*udev_device_new_from_devnum_dylibloader_wrapper_libudev)(struct udev*, char, dev_t); +struct udev_device* (*udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev)(struct udev*,const char*,const char*); +struct udev_device* (*udev_device_new_from_device_id_dylibloader_wrapper_libudev)(struct udev*,const char*); +struct udev_device* (*udev_device_new_from_environment_dylibloader_wrapper_libudev)(struct udev*); +struct udev_device* (*udev_device_get_parent_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_device* (*udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*); +const char* (*udev_device_get_devpath_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_subsystem_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_devtype_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_syspath_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_sysname_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_sysnum_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_devnode_dylibloader_wrapper_libudev)(struct udev_device*); +int (*udev_device_get_is_initialized_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_list_entry* (*udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_list_entry* (*udev_device_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_list_entry* (*udev_device_get_tags_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +struct udev_list_entry* (*udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_property_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*); +const char* (*udev_device_get_driver_dylibloader_wrapper_libudev)(struct udev_device*); +dev_t (*udev_device_get_devnum_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_device*); +unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*); +unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*); +const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*); +int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*); +int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*); +struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*); +struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*); +struct udev* (*udev_monitor_get_udev_dylibloader_wrapper_libudev)(struct udev_monitor*); +struct udev_monitor* (*udev_monitor_new_from_netlink_dylibloader_wrapper_libudev)(struct udev*,const char*); +int (*udev_monitor_enable_receiving_dylibloader_wrapper_libudev)(struct udev_monitor*); +int (*udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev)(struct udev_monitor*, int); +int (*udev_monitor_get_fd_dylibloader_wrapper_libudev)(struct udev_monitor*); +struct udev_device* (*udev_monitor_receive_device_dylibloader_wrapper_libudev)(struct udev_monitor*); +int (*udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*,const char*); +int (*udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*); +int (*udev_monitor_filter_update_dylibloader_wrapper_libudev)(struct udev_monitor*); +int (*udev_monitor_filter_remove_dylibloader_wrapper_libudev)(struct udev_monitor*); +struct udev_enumerate* (*udev_enumerate_ref_dylibloader_wrapper_libudev)(struct udev_enumerate*); +struct udev_enumerate* (*udev_enumerate_unref_dylibloader_wrapper_libudev)(struct udev_enumerate*); +struct udev* (*udev_enumerate_get_udev_dylibloader_wrapper_libudev)(struct udev_enumerate*); +struct udev_enumerate* (*udev_enumerate_new_dylibloader_wrapper_libudev)(struct udev*); +int (*udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +int (*udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +int (*udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*); +int (*udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*); +int (*udev_enumerate_add_match_property_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*); +int (*udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +int (*udev_enumerate_add_match_tag_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +int (*udev_enumerate_add_match_parent_dylibloader_wrapper_libudev)(struct udev_enumerate*,struct udev_device*); +int (*udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev)(struct udev_enumerate*); +int (*udev_enumerate_add_syspath_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +int (*udev_enumerate_scan_devices_dylibloader_wrapper_libudev)(struct udev_enumerate*); +int (*udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev)(struct udev_enumerate*); +struct udev_list_entry* (*udev_enumerate_get_list_entry_dylibloader_wrapper_libudev)(struct udev_enumerate*); +struct udev_queue* (*udev_queue_ref_dylibloader_wrapper_libudev)(struct udev_queue*); +struct udev_queue* (*udev_queue_unref_dylibloader_wrapper_libudev)(struct udev_queue*); +struct udev* (*udev_queue_get_udev_dylibloader_wrapper_libudev)(struct udev_queue*); +struct udev_queue* (*udev_queue_new_dylibloader_wrapper_libudev)(struct udev*); +unsigned long long int (*udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*); +unsigned long long int (*udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*); +int (*udev_queue_get_udev_is_active_dylibloader_wrapper_libudev)(struct udev_queue*); +int (*udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev)(struct udev_queue*); +int (*udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int); +int (*udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int, unsigned long long int); +int (*udev_queue_get_fd_dylibloader_wrapper_libudev)(struct udev_queue*); +int (*udev_queue_flush_dylibloader_wrapper_libudev)(struct udev_queue*); +struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev)(struct udev_queue*); +struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*); +struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*); +struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*); +struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned); +int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t); +int initialize_libudev(int verbose) { + void *handle; + char *error; + handle = dlopen("libudev.so.1", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// udev_ref + *(void **) (&udev_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_unref + *(void **) (&udev_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_new + *(void **) (&udev_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_set_log_fn + *(void **) (&udev_set_log_fn_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_log_fn"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_get_log_priority + *(void **) (&udev_get_log_priority_dylibloader_wrapper_libudev) = dlsym(handle, "udev_get_log_priority"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_set_log_priority + *(void **) (&udev_set_log_priority_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_log_priority"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_get_userdata + *(void **) (&udev_get_userdata_dylibloader_wrapper_libudev) = dlsym(handle, "udev_get_userdata"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_set_userdata + *(void **) (&udev_set_userdata_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_userdata"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_list_entry_get_next + *(void **) (&udev_list_entry_get_next_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_next"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_list_entry_get_by_name + *(void **) (&udev_list_entry_get_by_name_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_by_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_list_entry_get_name + *(void **) (&udev_list_entry_get_name_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_name"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_list_entry_get_value + *(void **) (&udev_list_entry_get_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_ref + *(void **) (&udev_device_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_unref + *(void **) (&udev_device_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_udev + *(void **) (&udev_device_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_udev"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_new_from_syspath + *(void **) (&udev_device_new_from_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_syspath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_new_from_devnum + *(void **) (&udev_device_new_from_devnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_devnum"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_new_from_subsystem_sysname + *(void **) (&udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_subsystem_sysname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_new_from_device_id + *(void **) (&udev_device_new_from_device_id_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_device_id"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_new_from_environment + *(void **) (&udev_device_new_from_environment_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_environment"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_parent + *(void **) (&udev_device_get_parent_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_parent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_parent_with_subsystem_devtype + *(void **) (&udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_parent_with_subsystem_devtype"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_devpath + *(void **) (&udev_device_get_devpath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devpath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_subsystem + *(void **) (&udev_device_get_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_subsystem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_devtype + *(void **) (&udev_device_get_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devtype"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_syspath + *(void **) (&udev_device_get_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_syspath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_sysname + *(void **) (&udev_device_get_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_sysnum + *(void **) (&udev_device_get_sysnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysnum"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_devnode + *(void **) (&udev_device_get_devnode_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devnode"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_is_initialized + *(void **) (&udev_device_get_is_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_is_initialized"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_devlinks_list_entry + *(void **) (&udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devlinks_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_properties_list_entry + *(void **) (&udev_device_get_properties_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_properties_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_tags_list_entry + *(void **) (&udev_device_get_tags_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_tags_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_sysattr_list_entry + *(void **) (&udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysattr_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_property_value + *(void **) (&udev_device_get_property_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_property_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_driver + *(void **) (&udev_device_get_driver_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_driver"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_devnum + *(void **) (&udev_device_get_devnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devnum"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_action + *(void **) (&udev_device_get_action_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_action"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_seqnum + *(void **) (&udev_device_get_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_seqnum"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_usec_since_initialized + *(void **) (&udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_usec_since_initialized"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_get_sysattr_value + *(void **) (&udev_device_get_sysattr_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysattr_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_set_sysattr_value + *(void **) (&udev_device_set_sysattr_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_set_sysattr_value"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_device_has_tag + *(void **) (&udev_device_has_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_has_tag"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_ref + *(void **) (&udev_monitor_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_unref + *(void **) (&udev_monitor_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_get_udev + *(void **) (&udev_monitor_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_get_udev"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_new_from_netlink + *(void **) (&udev_monitor_new_from_netlink_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_new_from_netlink"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_enable_receiving + *(void **) (&udev_monitor_enable_receiving_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_enable_receiving"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_set_receive_buffer_size + *(void **) (&udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_set_receive_buffer_size"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_get_fd + *(void **) (&udev_monitor_get_fd_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_get_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_receive_device + *(void **) (&udev_monitor_receive_device_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_receive_device"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_filter_add_match_subsystem_devtype + *(void **) (&udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_add_match_subsystem_devtype"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_filter_add_match_tag + *(void **) (&udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_add_match_tag"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_filter_update + *(void **) (&udev_monitor_filter_update_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_update"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_monitor_filter_remove + *(void **) (&udev_monitor_filter_remove_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_remove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_ref + *(void **) (&udev_enumerate_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_unref + *(void **) (&udev_enumerate_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_get_udev + *(void **) (&udev_enumerate_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_get_udev"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_new + *(void **) (&udev_enumerate_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_subsystem + *(void **) (&udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_subsystem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_nomatch_subsystem + *(void **) (&udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_nomatch_subsystem"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_sysattr + *(void **) (&udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_sysattr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_nomatch_sysattr + *(void **) (&udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_nomatch_sysattr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_property + *(void **) (&udev_enumerate_add_match_property_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_property"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_sysname + *(void **) (&udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_sysname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_tag + *(void **) (&udev_enumerate_add_match_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_tag"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_parent + *(void **) (&udev_enumerate_add_match_parent_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_parent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_match_is_initialized + *(void **) (&udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_is_initialized"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_add_syspath + *(void **) (&udev_enumerate_add_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_syspath"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_scan_devices + *(void **) (&udev_enumerate_scan_devices_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_scan_devices"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_scan_subsystems + *(void **) (&udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_scan_subsystems"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_enumerate_get_list_entry + *(void **) (&udev_enumerate_get_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_get_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_ref + *(void **) (&udev_queue_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_unref + *(void **) (&udev_queue_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_udev + *(void **) (&udev_queue_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_new + *(void **) (&udev_queue_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_kernel_seqnum + *(void **) (&udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_kernel_seqnum"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_udev_seqnum + *(void **) (&udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev_seqnum"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_udev_is_active + *(void **) (&udev_queue_get_udev_is_active_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev_is_active"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_queue_is_empty + *(void **) (&udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_queue_is_empty"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_seqnum_is_finished + *(void **) (&udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_seqnum_is_finished"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_seqnum_sequence_is_finished + *(void **) (&udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_seqnum_sequence_is_finished"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_fd + *(void **) (&udev_queue_get_fd_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_fd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_flush + *(void **) (&udev_queue_flush_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_flush"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_queue_get_queued_list_entry + *(void **) (&udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_queued_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_hwdb_new + *(void **) (&udev_hwdb_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_new"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_hwdb_ref + *(void **) (&udev_hwdb_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_ref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_hwdb_unref + *(void **) (&udev_hwdb_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_unref"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_hwdb_get_properties_list_entry + *(void **) (&udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_get_properties_list_entry"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// udev_util_encode_string + *(void **) (&udev_util_encode_string_dylibloader_wrapper_libudev) = dlsym(handle, "udev_util_encode_string"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/libudev-so_wrap.h b/platform/linuxbsd/libudev-so_wrap.h new file mode 100644 index 0000000000..dd43fd1191 --- /dev/null +++ b/platform/linuxbsd/libudev-so_wrap.h @@ -0,0 +1,378 @@ +#ifndef DYLIBLOAD_WRAPPER_LIBUDEV +#define DYLIBLOAD_WRAPPER_LIBUDEV +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59 +// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c +// +#include <stdint.h> + +#define udev_ref udev_ref_dylibloader_orig_libudev +#define udev_unref udev_unref_dylibloader_orig_libudev +#define udev_new udev_new_dylibloader_orig_libudev +#define udev_set_log_fn udev_set_log_fn_dylibloader_orig_libudev +#define udev_get_log_priority udev_get_log_priority_dylibloader_orig_libudev +#define udev_set_log_priority udev_set_log_priority_dylibloader_orig_libudev +#define udev_get_userdata udev_get_userdata_dylibloader_orig_libudev +#define udev_set_userdata udev_set_userdata_dylibloader_orig_libudev +#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_orig_libudev +#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_orig_libudev +#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_orig_libudev +#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_orig_libudev +#define udev_device_ref udev_device_ref_dylibloader_orig_libudev +#define udev_device_unref udev_device_unref_dylibloader_orig_libudev +#define udev_device_get_udev udev_device_get_udev_dylibloader_orig_libudev +#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_orig_libudev +#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_orig_libudev +#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_orig_libudev +#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_orig_libudev +#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_orig_libudev +#define udev_device_get_parent udev_device_get_parent_dylibloader_orig_libudev +#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_orig_libudev +#define udev_device_get_devpath udev_device_get_devpath_dylibloader_orig_libudev +#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_orig_libudev +#define udev_device_get_devtype udev_device_get_devtype_dylibloader_orig_libudev +#define udev_device_get_syspath udev_device_get_syspath_dylibloader_orig_libudev +#define udev_device_get_sysname udev_device_get_sysname_dylibloader_orig_libudev +#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_orig_libudev +#define udev_device_get_devnode udev_device_get_devnode_dylibloader_orig_libudev +#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_orig_libudev +#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_orig_libudev +#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_orig_libudev +#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_orig_libudev +#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_orig_libudev +#define udev_device_get_property_value udev_device_get_property_value_dylibloader_orig_libudev +#define udev_device_get_driver udev_device_get_driver_dylibloader_orig_libudev +#define udev_device_get_devnum udev_device_get_devnum_dylibloader_orig_libudev +#define udev_device_get_action udev_device_get_action_dylibloader_orig_libudev +#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_orig_libudev +#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_orig_libudev +#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_orig_libudev +#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_orig_libudev +#define udev_device_has_tag udev_device_has_tag_dylibloader_orig_libudev +#define udev_monitor_ref udev_monitor_ref_dylibloader_orig_libudev +#define udev_monitor_unref udev_monitor_unref_dylibloader_orig_libudev +#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_orig_libudev +#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_orig_libudev +#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_orig_libudev +#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_orig_libudev +#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_orig_libudev +#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_orig_libudev +#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_orig_libudev +#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_orig_libudev +#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_orig_libudev +#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_orig_libudev +#define udev_enumerate_ref udev_enumerate_ref_dylibloader_orig_libudev +#define udev_enumerate_unref udev_enumerate_unref_dylibloader_orig_libudev +#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_orig_libudev +#define udev_enumerate_new udev_enumerate_new_dylibloader_orig_libudev +#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_orig_libudev +#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_orig_libudev +#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_orig_libudev +#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_orig_libudev +#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_orig_libudev +#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_orig_libudev +#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_orig_libudev +#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_orig_libudev +#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_orig_libudev +#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_orig_libudev +#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_orig_libudev +#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_orig_libudev +#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_orig_libudev +#define udev_queue_ref udev_queue_ref_dylibloader_orig_libudev +#define udev_queue_unref udev_queue_unref_dylibloader_orig_libudev +#define udev_queue_get_udev udev_queue_get_udev_dylibloader_orig_libudev +#define udev_queue_new udev_queue_new_dylibloader_orig_libudev +#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_orig_libudev +#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_orig_libudev +#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_orig_libudev +#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_orig_libudev +#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_orig_libudev +#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_orig_libudev +#define udev_queue_get_fd udev_queue_get_fd_dylibloader_orig_libudev +#define udev_queue_flush udev_queue_flush_dylibloader_orig_libudev +#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_orig_libudev +#define udev_hwdb_new udev_hwdb_new_dylibloader_orig_libudev +#define udev_hwdb_ref udev_hwdb_ref_dylibloader_orig_libudev +#define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev +#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev +#define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev +#include <libudev.h> +#undef udev_ref +#undef udev_unref +#undef udev_new +#undef udev_set_log_fn +#undef udev_get_log_priority +#undef udev_set_log_priority +#undef udev_get_userdata +#undef udev_set_userdata +#undef udev_list_entry_get_next +#undef udev_list_entry_get_by_name +#undef udev_list_entry_get_name +#undef udev_list_entry_get_value +#undef udev_device_ref +#undef udev_device_unref +#undef udev_device_get_udev +#undef udev_device_new_from_syspath +#undef udev_device_new_from_devnum +#undef udev_device_new_from_subsystem_sysname +#undef udev_device_new_from_device_id +#undef udev_device_new_from_environment +#undef udev_device_get_parent +#undef udev_device_get_parent_with_subsystem_devtype +#undef udev_device_get_devpath +#undef udev_device_get_subsystem +#undef udev_device_get_devtype +#undef udev_device_get_syspath +#undef udev_device_get_sysname +#undef udev_device_get_sysnum +#undef udev_device_get_devnode +#undef udev_device_get_is_initialized +#undef udev_device_get_devlinks_list_entry +#undef udev_device_get_properties_list_entry +#undef udev_device_get_tags_list_entry +#undef udev_device_get_sysattr_list_entry +#undef udev_device_get_property_value +#undef udev_device_get_driver +#undef udev_device_get_devnum +#undef udev_device_get_action +#undef udev_device_get_seqnum +#undef udev_device_get_usec_since_initialized +#undef udev_device_get_sysattr_value +#undef udev_device_set_sysattr_value +#undef udev_device_has_tag +#undef udev_monitor_ref +#undef udev_monitor_unref +#undef udev_monitor_get_udev +#undef udev_monitor_new_from_netlink +#undef udev_monitor_enable_receiving +#undef udev_monitor_set_receive_buffer_size +#undef udev_monitor_get_fd +#undef udev_monitor_receive_device +#undef udev_monitor_filter_add_match_subsystem_devtype +#undef udev_monitor_filter_add_match_tag +#undef udev_monitor_filter_update +#undef udev_monitor_filter_remove +#undef udev_enumerate_ref +#undef udev_enumerate_unref +#undef udev_enumerate_get_udev +#undef udev_enumerate_new +#undef udev_enumerate_add_match_subsystem +#undef udev_enumerate_add_nomatch_subsystem +#undef udev_enumerate_add_match_sysattr +#undef udev_enumerate_add_nomatch_sysattr +#undef udev_enumerate_add_match_property +#undef udev_enumerate_add_match_sysname +#undef udev_enumerate_add_match_tag +#undef udev_enumerate_add_match_parent +#undef udev_enumerate_add_match_is_initialized +#undef udev_enumerate_add_syspath +#undef udev_enumerate_scan_devices +#undef udev_enumerate_scan_subsystems +#undef udev_enumerate_get_list_entry +#undef udev_queue_ref +#undef udev_queue_unref +#undef udev_queue_get_udev +#undef udev_queue_new +#undef udev_queue_get_kernel_seqnum +#undef udev_queue_get_udev_seqnum +#undef udev_queue_get_udev_is_active +#undef udev_queue_get_queue_is_empty +#undef udev_queue_get_seqnum_is_finished +#undef udev_queue_get_seqnum_sequence_is_finished +#undef udev_queue_get_fd +#undef udev_queue_flush +#undef udev_queue_get_queued_list_entry +#undef udev_hwdb_new +#undef udev_hwdb_ref +#undef udev_hwdb_unref +#undef udev_hwdb_get_properties_list_entry +#undef udev_util_encode_string +#ifdef __cplusplus +extern "C" { +#endif +#define udev_ref udev_ref_dylibloader_wrapper_libudev +#define udev_unref udev_unref_dylibloader_wrapper_libudev +#define udev_new udev_new_dylibloader_wrapper_libudev +#define udev_set_log_fn udev_set_log_fn_dylibloader_wrapper_libudev +#define udev_get_log_priority udev_get_log_priority_dylibloader_wrapper_libudev +#define udev_set_log_priority udev_set_log_priority_dylibloader_wrapper_libudev +#define udev_get_userdata udev_get_userdata_dylibloader_wrapper_libudev +#define udev_set_userdata udev_set_userdata_dylibloader_wrapper_libudev +#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_wrapper_libudev +#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_wrapper_libudev +#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_wrapper_libudev +#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_wrapper_libudev +#define udev_device_ref udev_device_ref_dylibloader_wrapper_libudev +#define udev_device_unref udev_device_unref_dylibloader_wrapper_libudev +#define udev_device_get_udev udev_device_get_udev_dylibloader_wrapper_libudev +#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_wrapper_libudev +#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_wrapper_libudev +#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev +#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_wrapper_libudev +#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_wrapper_libudev +#define udev_device_get_parent udev_device_get_parent_dylibloader_wrapper_libudev +#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev +#define udev_device_get_devpath udev_device_get_devpath_dylibloader_wrapper_libudev +#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_wrapper_libudev +#define udev_device_get_devtype udev_device_get_devtype_dylibloader_wrapper_libudev +#define udev_device_get_syspath udev_device_get_syspath_dylibloader_wrapper_libudev +#define udev_device_get_sysname udev_device_get_sysname_dylibloader_wrapper_libudev +#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_wrapper_libudev +#define udev_device_get_devnode udev_device_get_devnode_dylibloader_wrapper_libudev +#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_wrapper_libudev +#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev +#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_wrapper_libudev +#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_wrapper_libudev +#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev +#define udev_device_get_property_value udev_device_get_property_value_dylibloader_wrapper_libudev +#define udev_device_get_driver udev_device_get_driver_dylibloader_wrapper_libudev +#define udev_device_get_devnum udev_device_get_devnum_dylibloader_wrapper_libudev +#define udev_device_get_action udev_device_get_action_dylibloader_wrapper_libudev +#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_wrapper_libudev +#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev +#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_wrapper_libudev +#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_wrapper_libudev +#define udev_device_has_tag udev_device_has_tag_dylibloader_wrapper_libudev +#define udev_monitor_ref udev_monitor_ref_dylibloader_wrapper_libudev +#define udev_monitor_unref udev_monitor_unref_dylibloader_wrapper_libudev +#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_wrapper_libudev +#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_wrapper_libudev +#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_wrapper_libudev +#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev +#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_wrapper_libudev +#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_wrapper_libudev +#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev +#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev +#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_wrapper_libudev +#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_wrapper_libudev +#define udev_enumerate_ref udev_enumerate_ref_dylibloader_wrapper_libudev +#define udev_enumerate_unref udev_enumerate_unref_dylibloader_wrapper_libudev +#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_wrapper_libudev +#define udev_enumerate_new udev_enumerate_new_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev +#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev +#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_wrapper_libudev +#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev +#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_wrapper_libudev +#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_wrapper_libudev +#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev +#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_wrapper_libudev +#define udev_queue_ref udev_queue_ref_dylibloader_wrapper_libudev +#define udev_queue_unref udev_queue_unref_dylibloader_wrapper_libudev +#define udev_queue_get_udev udev_queue_get_udev_dylibloader_wrapper_libudev +#define udev_queue_new udev_queue_new_dylibloader_wrapper_libudev +#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev +#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev +#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_wrapper_libudev +#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev +#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev +#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev +#define udev_queue_get_fd udev_queue_get_fd_dylibloader_wrapper_libudev +#define udev_queue_flush udev_queue_flush_dylibloader_wrapper_libudev +#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev +#define udev_hwdb_new udev_hwdb_new_dylibloader_wrapper_libudev +#define udev_hwdb_ref udev_hwdb_ref_dylibloader_wrapper_libudev +#define udev_hwdb_unref udev_hwdb_unref_dylibloader_wrapper_libudev +#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev +#define udev_util_encode_string udev_util_encode_string_dylibloader_wrapper_libudev +extern struct udev* (*udev_ref_dylibloader_wrapper_libudev)(struct udev*); +extern struct udev* (*udev_unref_dylibloader_wrapper_libudev)(struct udev*); +extern struct udev* (*udev_new_dylibloader_wrapper_libudev)( void); +extern void (*udev_set_log_fn_dylibloader_wrapper_libudev)(struct udev*, void*); +extern int (*udev_get_log_priority_dylibloader_wrapper_libudev)(struct udev*); +extern void (*udev_set_log_priority_dylibloader_wrapper_libudev)(struct udev*, int); +extern void* (*udev_get_userdata_dylibloader_wrapper_libudev)(struct udev*); +extern void (*udev_set_userdata_dylibloader_wrapper_libudev)(struct udev*, void*); +extern struct udev_list_entry* (*udev_list_entry_get_next_dylibloader_wrapper_libudev)(struct udev_list_entry*); +extern struct udev_list_entry* (*udev_list_entry_get_by_name_dylibloader_wrapper_libudev)(struct udev_list_entry*,const char*); +extern const char* (*udev_list_entry_get_name_dylibloader_wrapper_libudev)(struct udev_list_entry*); +extern const char* (*udev_list_entry_get_value_dylibloader_wrapper_libudev)(struct udev_list_entry*); +extern struct udev_device* (*udev_device_ref_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_device* (*udev_device_unref_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev* (*udev_device_get_udev_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_device* (*udev_device_new_from_syspath_dylibloader_wrapper_libudev)(struct udev*,const char*); +extern struct udev_device* (*udev_device_new_from_devnum_dylibloader_wrapper_libudev)(struct udev*, char, dev_t); +extern struct udev_device* (*udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev)(struct udev*,const char*,const char*); +extern struct udev_device* (*udev_device_new_from_device_id_dylibloader_wrapper_libudev)(struct udev*,const char*); +extern struct udev_device* (*udev_device_new_from_environment_dylibloader_wrapper_libudev)(struct udev*); +extern struct udev_device* (*udev_device_get_parent_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_device* (*udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*); +extern const char* (*udev_device_get_devpath_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_subsystem_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_devtype_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_syspath_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_sysname_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_sysnum_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_devnode_dylibloader_wrapper_libudev)(struct udev_device*); +extern int (*udev_device_get_is_initialized_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_list_entry* (*udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_list_entry* (*udev_device_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_list_entry* (*udev_device_get_tags_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +extern struct udev_list_entry* (*udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_property_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*); +extern const char* (*udev_device_get_driver_dylibloader_wrapper_libudev)(struct udev_device*); +extern dev_t (*udev_device_get_devnum_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_device*); +extern unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*); +extern unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*); +extern const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*); +extern int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*); +extern int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*); +extern struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern struct udev* (*udev_monitor_get_udev_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern struct udev_monitor* (*udev_monitor_new_from_netlink_dylibloader_wrapper_libudev)(struct udev*,const char*); +extern int (*udev_monitor_enable_receiving_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern int (*udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev)(struct udev_monitor*, int); +extern int (*udev_monitor_get_fd_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern struct udev_device* (*udev_monitor_receive_device_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern int (*udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*,const char*); +extern int (*udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*); +extern int (*udev_monitor_filter_update_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern int (*udev_monitor_filter_remove_dylibloader_wrapper_libudev)(struct udev_monitor*); +extern struct udev_enumerate* (*udev_enumerate_ref_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern struct udev_enumerate* (*udev_enumerate_unref_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern struct udev* (*udev_enumerate_get_udev_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern struct udev_enumerate* (*udev_enumerate_new_dylibloader_wrapper_libudev)(struct udev*); +extern int (*udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +extern int (*udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +extern int (*udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*); +extern int (*udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*); +extern int (*udev_enumerate_add_match_property_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*); +extern int (*udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +extern int (*udev_enumerate_add_match_tag_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +extern int (*udev_enumerate_add_match_parent_dylibloader_wrapper_libudev)(struct udev_enumerate*,struct udev_device*); +extern int (*udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern int (*udev_enumerate_add_syspath_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*); +extern int (*udev_enumerate_scan_devices_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern int (*udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern struct udev_list_entry* (*udev_enumerate_get_list_entry_dylibloader_wrapper_libudev)(struct udev_enumerate*); +extern struct udev_queue* (*udev_queue_ref_dylibloader_wrapper_libudev)(struct udev_queue*); +extern struct udev_queue* (*udev_queue_unref_dylibloader_wrapper_libudev)(struct udev_queue*); +extern struct udev* (*udev_queue_get_udev_dylibloader_wrapper_libudev)(struct udev_queue*); +extern struct udev_queue* (*udev_queue_new_dylibloader_wrapper_libudev)(struct udev*); +extern unsigned long long int (*udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*); +extern unsigned long long int (*udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*); +extern int (*udev_queue_get_udev_is_active_dylibloader_wrapper_libudev)(struct udev_queue*); +extern int (*udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev)(struct udev_queue*); +extern int (*udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int); +extern int (*udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int, unsigned long long int); +extern int (*udev_queue_get_fd_dylibloader_wrapper_libudev)(struct udev_queue*); +extern int (*udev_queue_flush_dylibloader_wrapper_libudev)(struct udev_queue*); +extern struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev)(struct udev_queue*); +extern struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*); +extern struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*); +extern struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*); +extern struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned); +extern int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t); +int initialize_libudev(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 68290bb4ec..09e1f9461c 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -128,7 +128,7 @@ Error OS_LinuxBSD::shell_open(String p_uri) { args.push_back(p_uri); // Agnostic - ok = execute("xdg-open", args, true, nullptr, nullptr, &err_code); + ok = execute("xdg-open", args, nullptr, &err_code); if (ok == OK && !err_code) { return OK; } else if (err_code == 2) { @@ -136,25 +136,25 @@ Error OS_LinuxBSD::shell_open(String p_uri) { } // GNOME args.push_front("open"); // The command is `gio open`, so we need to add it to args - ok = execute("gio", args, true, nullptr, nullptr, &err_code); + ok = execute("gio", args, nullptr, &err_code); if (ok == OK && !err_code) { return OK; } else if (err_code == 2) { return ERR_FILE_NOT_FOUND; } args.pop_front(); - ok = execute("gvfs-open", args, true, nullptr, nullptr, &err_code); + ok = execute("gvfs-open", args, nullptr, &err_code); if (ok == OK && !err_code) { return OK; } else if (err_code == 2) { return ERR_FILE_NOT_FOUND; } // KDE - ok = execute("kde-open5", args, true, nullptr, nullptr, &err_code); + ok = execute("kde-open5", args, nullptr, &err_code); if (ok == OK && !err_code) { return OK; } - ok = execute("kde-open", args, true, nullptr, nullptr, &err_code); + ok = execute("kde-open", args, nullptr, &err_code); return !err_code ? ok : FAILED; } @@ -232,7 +232,7 @@ String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const { String pipe; List<String> arg; arg.push_back(xdgparam); - Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, true, nullptr, &pipe); + Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, &pipe); if (err != OK) { return "."; } @@ -307,7 +307,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { List<String> args; args.push_back(p_path); args.push_front("trash"); // The command is `gio trash <file_name>` so we need to add it to args. - Error result = execute("gio", args, true, nullptr, nullptr, &err_code); // For GNOME based machines. + Error result = execute("gio", args, nullptr, &err_code); // For GNOME based machines. if (result == OK && !err_code) { return OK; } else if (err_code == 2) { @@ -317,7 +317,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { args.pop_front(); args.push_front("move"); args.push_back("trash:/"); // The command is `kioclient5 move <file_name> trash:/`. - result = execute("kioclient5", args, true, nullptr, nullptr, &err_code); // For KDE based machines. + result = execute("kioclient5", args, nullptr, &err_code); // For KDE based machines. if (result == OK && !err_code) { return OK; } else if (err_code == 2) { @@ -326,7 +326,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { args.pop_front(); args.pop_back(); - result = execute("gvfs-trash", args, true, nullptr, nullptr, &err_code); // For older Linux machines. + result = execute("gvfs-trash", args, nullptr, &err_code); // For older Linux machines. if (result == OK && !err_code) { return OK; } else if (err_code == 2) { @@ -410,7 +410,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { OS::Time time = OS::get_singleton()->get_time(false); String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, date.month, date.day, time.hour, time.min); timestamp = vformat("%s%02d", timestamp, time.sec); // vformat only supports up to 6 arguments. - String trash_info = "[Trash Info]\nPath=" + p_path.http_escape() + "\nDeletionDate=" + timestamp + "\n"; + String trash_info = "[Trash Info]\nPath=" + p_path.uri_encode() + "\nDeletionDate=" + timestamp + "\n"; { Error err; FileAccess *file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err); @@ -432,7 +432,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { mv_args.push_back(trash_path + "/files"); { int retval; - Error err = execute("mv", mv_args, true, nullptr, nullptr, &retval); + Error err = execute("mv", mv_args, nullptr, &retval); // Issue an error if "mv" failed to move the given resource to the trash can. if (err != OK || retval != 0) { diff --git a/platform/osx/SCsub b/platform/osx/SCsub index aa95a89444..46c13d8550 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -18,5 +18,5 @@ files = [ prog = env.add_program("#bin/godot", files) -if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: +if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_osx_builders.make_debug_osx)) diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 4d6ed41a73..147ce26779 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -135,7 +135,7 @@ static void handle_crash(int sig) { int ret; String out = ""; - Error err = OS::get_singleton()->execute(String("atos"), args, true, NULL, &out, &ret); + Error err = OS::get_singleton()->execute(String("atos"), args, &out, &ret); if (err == OK && out.substr(0, 2) != "0x") { out.erase(out.length() - 1, 1); output = out; diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 466f68d269..acea00c5ac 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -31,7 +31,7 @@ def get_opts(): False, ), EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), @@ -54,7 +54,7 @@ def configure(env): if env["arch"] != "arm64": env.Prepend(CCFLAGS=["-msse2"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -63,7 +63,7 @@ def configure(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index 597ebce6ff..9fac99810b 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -93,6 +93,7 @@ public: List<WarpEvent> warp_events; NSTimeInterval last_warp = 0; + bool ignore_warp = false; Vector<KeyEvent> key_event_buffer; int key_event_pos; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index bb3c1d47b7..ed7d89009f 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -256,9 +256,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { List<String> args; args.push_back(((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename); String exec = OS::get_singleton()->get_executable_path(); - - OS::ProcessID pid = 0; - OS::get_singleton()->execute(exec, args, false, &pid); + OS::get_singleton()->create_process(exec, args); } #endif return YES; @@ -873,6 +871,15 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i NSPoint delta = NSMakePoint([event deltaX], [event deltaY]); NSPoint mpos = [event locationInWindow]; + if (DS_OSX->ignore_warp) { + // Discard late events, before warp + if (([event timestamp]) < DS_OSX->last_warp) { + return; + } + DS_OSX->ignore_warp = false; + return; + } + if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED) { // Discard late events if (([event timestamp]) < DS_OSX->last_warp) { @@ -2100,6 +2107,8 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) { CGAssociateMouseAndMouseCursorPosition(true); } + last_warp = [[NSProcessInfo processInfo] systemUptime]; + ignore_warp = true; warp_events.clear(); mouse_mode = p_mode; } diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 752b119958..337cfd6808 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -419,7 +419,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset args.push_back(p_path); String str; - Error err = OS::get_singleton()->execute("xcrun", args, true, nullptr, &str, nullptr, true); + Error err = OS::get_singleton()->execute("xcrun", args, &str, nullptr, true); ERR_FAIL_COND_V(err != OK, err); print_line("altool (" + p_path + "):\n" + str); @@ -470,7 +470,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese args.push_back(p_path); String str; - Error err = OS::get_singleton()->execute("codesign", args, true, nullptr, &str, nullptr, true); + Error err = OS::get_singleton()->execute("codesign", args, &str, nullptr, true); ERR_FAIL_COND_V(err != OK, err); print_line("codesign (" + p_path + "):\n" + str); @@ -504,7 +504,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin args.push_back(p_app_path_name); String str; - Error err = OS::get_singleton()->execute("hdiutil", args, true, nullptr, &str, nullptr, true); + Error err = OS::get_singleton()->execute("hdiutil", args, &str, nullptr, true); ERR_FAIL_COND_V(err != OK, err); print_line("hdiutil returned: " + str); diff --git a/platform/server/detect.py b/platform/server/detect.py index db503584d3..5be7e81e7a 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -32,13 +32,13 @@ def get_opts(): return [ BoolVariable("use_llvm", "Use the LLVM compiler", False), - BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False), + BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True), BoolVariable("use_coverage", "Test Godot coverage", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False), BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), ] @@ -58,7 +58,7 @@ def configure(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -68,7 +68,7 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": @@ -93,6 +93,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" env.extra_suffix = ".llvm" + env.extra_suffix + env.Append(LIBS=["atomic"]) if env["use_coverage"]: env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"]) diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 860448ceac..1aad2bfa1a 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -760,7 +760,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform { result = result.replace("$version_string$", version); Platform arch = (Platform)(int)p_preset->get("architecture/target"); - String architecture = arch == ARM ? "arm" : arch == X86 ? "x86" : "x64"; + String architecture = arch == ARM ? "arm" : (arch == X86 ? "x86" : "x64"); result = result.replace("$architecture$", architecture); result = result.replace("$display_name$", String(p_preset->get("package/display_name")).is_empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name"))); @@ -1411,7 +1411,7 @@ public: args.push_back(cert_pass); args.push_back(p_path); - OS::get_singleton()->execute(signtool_path, args, true); + OS::get_singleton()->execute(signtool_path, args); #endif // WINDOWS_ENABLED return OK; diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 18d5d7e08d..fa97948395 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -39,14 +39,11 @@ #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/mutex_windows.h" -#include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" #include "main/main.h" #include "platform/windows/windows_terminal_logger.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_default.h" -#include "servers/rendering/rendering_server_wrap_mt.h" -#include "thread_uwp.h" #include <ppltasks.h> #include <wrl.h> @@ -131,9 +128,6 @@ void OS_UWP::initialize_core() { //RedirectIOToConsole(); - ThreadUWP::make_default(); - RWLockWindows::make_default(); - FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM); @@ -638,7 +632,11 @@ void OS_UWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c // TODO } -Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { +Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { + return FAILED; +}; + +Error OS_UWP::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { return FAILED; }; diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index edc197ad08..a4d3d6d52a 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -199,7 +199,8 @@ public: virtual void delay_usec(uint32_t p_usec) const; virtual uint64_t get_ticks_usec() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr); + virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr); + virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr); virtual Error kill(const ProcessID &p_pid); virtual bool has_environment(const String &p_var) const; diff --git a/platform/uwp/thread_uwp.cpp b/platform/uwp/thread_uwp.cpp deleted file mode 100644 index 364c414375..0000000000 --- a/platform/uwp/thread_uwp.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ -/* thread_uwp.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "thread_uwp.h" - -#include "core/os/memory.h" - -Thread *ThreadUWP::create_func_uwp(ThreadCreateCallback p_callback, void *p_user, const Settings &) { - ThreadUWP *thread = memnew(ThreadUWP); - - std::thread new_thread(p_callback, p_user); - std::swap(thread->thread, new_thread); - - return thread; -}; - -Thread::ID ThreadUWP::get_thread_id_func_uwp() { - return std::hash<std::thread::id>()(std::this_thread::get_id()); -}; - -void ThreadUWP::wait_to_finish_func_uwp(Thread *p_thread) { - ThreadUWP *tp = static_cast<ThreadUWP *>(p_thread); - tp->thread.join(); -}; - -Thread::ID ThreadUWP::get_id() const { - return std::hash<std::thread::id>()(thread.get_id()); -}; - -void ThreadUWP::make_default() { - create_func = create_func_uwp; - get_thread_id_func = get_thread_id_func_uwp; - wait_to_finish_func = wait_to_finish_func_uwp; -}; diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h deleted file mode 100644 index 0bfc71d2e0..0000000000 --- a/platform/uwp/thread_uwp.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************/ -/* thread_uwp.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef THREAD_UWP_H -#define THREAD_UWP_H - -#ifdef UWP_ENABLED - -#include "core/os/thread.h" - -#include <thread> - -class ThreadUWP : public Thread { - std::thread thread; - - static Thread *create_func_uwp(ThreadCreateCallback p_callback, void *, const Settings &); - static ID get_thread_id_func_uwp(); - static void wait_to_finish_func_uwp(Thread *p_thread); - - ThreadUWP() {} - -public: - virtual ID get_id() const; - - static void make_default(); - - ~ThreadUWP() {} -}; - -#endif // UWP_ENABLED - -#endif // THREAD_UWP_H diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 0c9aa77803..47d8e14680 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -32,5 +32,5 @@ if env["vsproj"]: env.vs_srcs += ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): - if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: + if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw)) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 5216fca2ca..f26dea8d35 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -64,7 +64,7 @@ def get_opts(): # XP support dropped after EOL due to missing API for IPv6 and other issues # Vista support dropped after EOL due to GH-10243 ("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), EnumVariable("windows_subsystem", "Windows subsystem", "default", ("default", "console", "gui")), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), ("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None), @@ -204,12 +204,12 @@ def configure_msvc(env, manual_msvc_config): env.Append(LINKFLAGS=["/OPT:REF"]) elif env["target"] == "debug": - env.AppendUnique(CCFLAGS=["/Z7", "/Od", "/EHsc"]) + env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"]) env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"]) env.Append(LINKFLAGS=["/DEBUG"]) - if env["debug_symbols"] == "yes": - env.AppendUnique(CCFLAGS=["/Z7"]) + if env["debug_symbols"]: + env.AppendUnique(CCFLAGS=["/Zi", "/FS"]) env.AppendUnique(LINKFLAGS=["/DEBUG"]) if env["windows_subsystem"] == "gui": @@ -224,6 +224,7 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CCFLAGS=["/MT"]) else: env.AppendUnique(CCFLAGS=["/MD"]) + env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"]) # Force to use Unicode encoding env.AppendUnique(CCFLAGS=["/utf-8"]) @@ -339,13 +340,13 @@ def configure_mingw(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": env.Append(CCFLAGS=["-O2"]) env.Append(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) if env["optimize"] == "speed": # optimize for speed (default) env.Append(CCFLAGS=["-O2"]) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 14e7d395d3..b9b78f7bd4 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -535,7 +535,7 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { } #endif - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[p_window].wtctx) { + if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) { wintab_WTClose(windows[p_window].wtctx); windows[p_window].wtctx = 0; } @@ -1784,7 +1784,10 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) Ref<InputEventFromWindow> event_from_window = p_event; if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { //send to a window - ERR_FAIL_COND(!windows.has(event_from_window->get_window_id())); + if (!windows.has(event_from_window->get_window_id())) { + in_dispatch_input_event = false; + ERR_FAIL_MSG("DisplayServerWindows: Invalid window id in input event."); + } Callable callable = windows[event_from_window->get_window_id()].input_event_callback; if (callable.is_null()) { in_dispatch_input_event = false; @@ -2018,7 +2021,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WT_CSRCHANGE: case WT_PROXIMITY: { - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { + if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { AXIS pressure; if (wintab_WTInfo(WTI_DEVICES + windows[window_id].wtlc.lcDevice, DVC_NPRESSURE, &pressure)) { windows[window_id].min_pressure = int(pressure.axMin); @@ -2032,7 +2035,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } break; case WT_PACKET: { - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { + if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { PACKET packet; if (wintab_WTPacket(windows[window_id].wtctx, wParam, &packet)) { float pressure = float(packet.pkNormalPressure - windows[window_id].min_pressure) / float(windows[window_id].max_pressure - windows[window_id].min_pressure); @@ -2111,7 +2114,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) { + if ((tablet_get_current_driver() != "winink") || !winink_available) { break; } @@ -2137,7 +2140,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) { + if ((tablet_get_current_driver() != "winink") || !winink_available) { break; } @@ -2301,7 +2304,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_shift((wParam & MK_SHIFT) != 0); mm->set_alt(alt_mem); - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { + if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { // Note: WinTab sends both WT_PACKET and WM_xBUTTONDOWN/UP/MOUSEMOVE events, use mouse 1/0 pressure only when last_pressure was not update recently. if (windows[window_id].last_pressure_update < 10) { windows[window_id].last_pressure_update++; @@ -2796,7 +2799,7 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM alt_mem = false; } - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[p_window_id].wtctx) { + if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window_id].wtctx) { wintab_WTEnable(windows[p_window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam)); } } @@ -3034,7 +3037,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, DragAcceptFiles(wd.hWnd, true); - if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available) { + if ((tablet_get_current_driver() == "wintab") && wintab_available) { wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc); wd.wtlc.lcOptions |= CXO_MESSAGES; wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION; @@ -3101,6 +3104,40 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS { SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2 } SHC_PROCESS_DPI_AWARENESS; +int DisplayServerWindows::tablet_get_driver_count() const { + return tablet_drivers.size(); +} + +String DisplayServerWindows::tablet_get_driver_name(int p_driver) const { + if (p_driver < 0 || p_driver >= tablet_drivers.size()) { + return ""; + } else { + return tablet_drivers[p_driver]; + } +} + +String DisplayServerWindows::tablet_get_current_driver() const { + return tablet_driver; +} + +void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) { + if (tablet_get_driver_count() == 0) { + return; + } + bool found = false; + for (int i = 0; i < tablet_get_driver_count(); i++) { + if (p_driver == tablet_get_driver_name(i)) { + found = true; + } + } + if (found) { + _update_tablet_ctx(tablet_driver, p_driver); + tablet_driver = p_driver; + } else { + ERR_PRINT("Unknown tablet driver " + p_driver + "."); + } +} + DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { drop_events = false; key_event_pos = 0; @@ -3119,6 +3156,35 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win outside = true; + //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink. + HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll"); + if (wintab_lib) { + wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW"); + wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose"); + wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW"); + wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket"); + wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable"); + + wintab_available = wintab_WTOpen && wintab_WTClose && wintab_WTInfo && wintab_WTPacket && wintab_WTEnable; + } + + if (wintab_available) { + tablet_drivers.push_back("wintab"); + } + + //Note: Windows Ink API for pen input, available on Windows 8+ only. + HMODULE user32_lib = LoadLibraryW(L"user32.dll"); + if (user32_lib) { + win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType"); + win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo"); + + winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo; + } + + if (winink_available) { + tablet_drivers.push_back("winink"); + } + if (OS::get_singleton()->is_hidpi_allowed()) { HMODULE Shcore = LoadLibraryW(L"Shcore.dll"); diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 4a3f91eb21..a734077e59 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -264,7 +264,6 @@ class DisplayServerWindows : public DisplayServer { _THREAD_SAFE_CLASS_ -public: // WinTab API static bool wintab_available; static WTOpenPtr wintab_WTOpen; @@ -279,8 +278,9 @@ public: static GetPointerPenInfoPtr win8p_GetPointerPenInfo; void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver); + String tablet_driver; + Vector<String> tablet_drivers; -private: void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap); enum { @@ -417,7 +417,7 @@ private: WNDCLASSEXW wc; HCURSOR cursors[CURSOR_MAX] = { nullptr }; - CursorShape cursor_shape; + CursorShape cursor_shape = CursorShape::CURSOR_ARROW; Map<CursorShape, Vector<Variant>> cursors_cache; void _drag_event(WindowID p_window, float p_x, float p_y, int idx); @@ -542,6 +542,11 @@ public: virtual String keyboard_get_layout_language(int p_index) const; virtual String keyboard_get_layout_name(int p_index) const; + virtual int tablet_get_driver_count() const; + virtual String tablet_get_driver_name(int p_driver) const; + virtual String tablet_get_current_driver() const; + virtual void tablet_set_current_driver(const String &p_driver); + virtual void process_events(); virtual void force_process_and_drop_events(); diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 084a5bee1d..222597b3ff 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -173,11 +173,11 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> } #ifdef WINDOWS_ENABLED - OS::get_singleton()->execute(rcedit_path, args, true); + OS::get_singleton()->execute(rcedit_path, args); #else // On non-Windows we need WINE to run rcedit args.push_front(rcedit_path); - OS::get_singleton()->execute(wine_path, args, true); + OS::get_singleton()->execute(wine_path, args); #endif } @@ -314,7 +314,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #endif String str; - Error err = OS::get_singleton()->execute(signtool_path, args, true, nullptr, &str, nullptr, true); + Error err = OS::get_singleton()->execute(signtool_path, args, &str, nullptr, true); ERR_FAIL_COND_V(err != OK, err); print_line("codesign (" + p_path + "): " + str); diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index d85dfbc3d3..857c6a88f1 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -10,6 +10,16 @@ </Expand> </Type> + <Type Name="LocalVector<*>"> + <Expand> + <Item Name="[size]">count</Item> + <ArrayItems> + <Size>count</Size> + <ValuePointer>data</ValuePointer> + </ArrayItems> + </Expand> + </Type> + <Type Name="List<*>"> <Expand> <Item Name="[size]">_data ? (_data->size_cache) : 0</Item> diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 051b69e8d9..3280a36e9b 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -39,15 +39,12 @@ #include "core/version_generated.gen.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" -#include "drivers/windows/rw_lock_windows.h" -#include "drivers/windows/thread_windows.h" #include "joypad_windows.h" #include "lang_table.h" #include "main/main.h" #include "platform/windows/display_server_windows.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_default.h" -#include "servers/rendering/rendering_server_wrap_mt.h" #include "windows_terminal_logger.h" #include <avrt.h> @@ -177,9 +174,6 @@ void OS_Windows::initialize() { //RedirectIOToConsole(); - ThreadWindows::make_default(); - RWLockWindows::make_default(); - FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM); @@ -410,24 +404,23 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const { return p_text; } -Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { +Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) { String path = p_path.replace("/", "\\"); + String command = _quote_command_line_argument(path); + for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { + command += " " + _quote_command_line_argument(E->get()); + } - if (p_blocking && r_pipe) { - String argss = _quote_command_line_argument(path); - for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { - argss += " " + _quote_command_line_argument(E->get()); - } - + if (r_pipe) { if (read_stderr) { - argss += " 2>&1"; // Read stderr too + command += " 2>&1"; // Include stderr } - // Note: _wpopen is calling command as "cmd.exe /c argss", instead of executing it directly, add extra quotes around full command, to prevent it from stripping quotes in the command. - argss = _quote_command_line_argument(argss); - - FILE *f = _wpopen((LPCWSTR)(argss.utf16().get_data()), L"r"); - ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + // Add extra quotes around the full command, to prevent it from stripping quotes in the command, + // because _wpopen calls command as "cmd.exe /c command", instead of executing it directly + command = _quote_command_line_argument(command); + FILE *f = _wpopen((LPCWSTR)(command.utf16().get_data()), L"r"); + ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot create pipe from command: " + command); char buf[65535]; while (fgets(buf, 65535, f)) { if (p_pipe_mutex) { @@ -438,20 +431,40 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, p_pipe_mutex->unlock(); } } - int rv = _pclose(f); + if (r_exitcode) { *r_exitcode = rv; } - return OK; } - String cmdline = _quote_command_line_argument(path); - const List<String>::Element *I = p_arguments.front(); - while (I) { - cmdline += " " + _quote_command_line_argument(I->get()); - I = I->next(); + ProcessInfo pi; + ZeroMemory(&pi.si, sizeof(pi.si)); + pi.si.cb = sizeof(pi.si); + ZeroMemory(&pi.pi, sizeof(pi.pi)); + LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; + + int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); + ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); + + WaitForSingleObject(pi.pi.hProcess, INFINITE); + if (r_exitcode) { + DWORD ret2; + GetExitCodeProcess(pi.pi.hProcess, &ret2); + *r_exitcode = ret2; + } + CloseHandle(pi.pi.hProcess); + CloseHandle(pi.pi.hThread); + + return OK; +}; + +Error OS_Windows::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { + String path = p_path.replace("/", "\\"); + String command = _quote_command_line_argument(path); + for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) { + command += " " + _quote_command_line_argument(E->get()); } ProcessInfo pi; @@ -460,27 +473,15 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, ZeroMemory(&pi.pi, sizeof(pi.pi)); LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; - Char16String modstr = cmdline.utf16(); // Windows wants to change this no idea why. - int ret = CreateProcessW(nullptr, (LPWSTR)(modstr.ptrw()), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); - ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); + int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); + ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); - if (p_blocking) { - WaitForSingleObject(pi.pi.hProcess, INFINITE); - if (r_exitcode) { - DWORD ret2; - GetExitCodeProcess(pi.pi.hProcess, &ret2); - *r_exitcode = ret2; - } - - CloseHandle(pi.pi.hProcess); - CloseHandle(pi.pi.hThread); - } else { - ProcessID pid = pi.pi.dwProcessId; - if (r_child_id) { - *r_child_id = pid; - } - process_map->insert(pid, pi); + ProcessID pid = pi.pi.dwProcessId; + if (r_child_id) { + *r_child_id = pid; } + process_map->insert(pid, pi); + return OK; }; @@ -764,77 +765,12 @@ Error OS_Windows::move_to_trash(const String &p_path) { return OK; } -int OS_Windows::get_tablet_driver_count() const { - return tablet_drivers.size(); -} - -String OS_Windows::get_tablet_driver_name(int p_driver) const { - if (p_driver < 0 || p_driver >= tablet_drivers.size()) { - return ""; - } else { - return tablet_drivers[p_driver]; - } -} - -String OS_Windows::get_current_tablet_driver() const { - return tablet_driver; -} - -void OS_Windows::set_current_tablet_driver(const String &p_driver) { - if (get_tablet_driver_count() == 0) { - return; - } - bool found = false; - for (int i = 0; i < get_tablet_driver_count(); i++) { - if (p_driver == get_tablet_driver_name(i)) { - found = true; - } - } - if (found) { - if (DisplayServerWindows::get_singleton()) { - ((DisplayServerWindows *)DisplayServerWindows::get_singleton())->_update_tablet_ctx(tablet_driver, p_driver); - } - tablet_driver = p_driver; - } else { - ERR_PRINT("Unknown tablet driver " + p_driver + "."); - } -} - OS_Windows::OS_Windows(HINSTANCE _hInstance) { ticks_per_second = 0; ticks_start = 0; main_loop = nullptr; process_map = nullptr; - //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink. - HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll"); - if (wintab_lib) { - DisplayServerWindows::wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW"); - DisplayServerWindows::wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose"); - DisplayServerWindows::wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW"); - DisplayServerWindows::wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket"); - DisplayServerWindows::wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable"); - - DisplayServerWindows::wintab_available = DisplayServerWindows::wintab_WTOpen && DisplayServerWindows::wintab_WTClose && DisplayServerWindows::wintab_WTInfo && DisplayServerWindows::wintab_WTPacket && DisplayServerWindows::wintab_WTEnable; - } - - if (DisplayServerWindows::wintab_available) { - tablet_drivers.push_back("wintab"); - } - - //Note: Windows Ink API for pen input, available on Windows 8+ only. - HMODULE user32_lib = LoadLibraryW(L"user32.dll"); - if (user32_lib) { - DisplayServerWindows::win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType"); - DisplayServerWindows::win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo"); - - DisplayServerWindows::winink_available = DisplayServerWindows::win8p_GetPointerType && DisplayServerWindows::win8p_GetPointerPenInfo; - } - - if (DisplayServerWindows::winink_available) { - tablet_drivers.push_back("winink"); - } - force_quit = false; hInstance = _hInstance; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 78258f132b..8f9ef254f1 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -73,9 +73,6 @@ class OS_Windows : public OS { HINSTANCE hInstance; MainLoop *main_loop; - String tablet_driver; - Vector<String> tablet_drivers; - #ifdef WASAPI_ENABLED AudioDriverWASAPI driver_wasapi; #endif @@ -119,11 +116,6 @@ public: virtual String get_name() const override; - virtual int get_tablet_driver_count() const override; - virtual String get_tablet_driver_name(int p_driver) const override; - virtual String get_current_tablet_driver() const override; - virtual void set_current_tablet_driver(const String &p_driver) override; - virtual void initialize_joypads() override {} virtual Date get_date(bool utc) const override; @@ -136,7 +128,8 @@ public: virtual void delay_usec(uint32_t p_usec) const override; virtual uint64_t get_ticks_usec() const override; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; + virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override; + virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; virtual Error kill(const ProcessID &p_pid) override; virtual int get_process_id() const override; diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index d9d551074d..f39850441b 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -409,7 +409,7 @@ void AnimatedSprite2D::_notification(int p_what) { } update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -477,7 +477,7 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { set_frame(frame); } - _change_notify(); + notify_property_list_changed(); _reset_timeout(); update(); update_configuration_warning(); @@ -510,7 +510,7 @@ void AnimatedSprite2D::set_frame(int p_frame) { frame = p_frame; _reset_timeout(); update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -546,7 +546,6 @@ void AnimatedSprite2D::set_offset(const Point2 &p_offset) { offset = p_offset; update(); item_rect_changed(); - _change_notify("offset"); } Point2 AnimatedSprite2D::get_offset() const { @@ -573,8 +572,7 @@ bool AnimatedSprite2D::is_flipped_v() const { void AnimatedSprite2D::_res_changed() { set_frame(frame); - _change_notify("frame"); - _change_notify("animation"); + update(); } @@ -642,7 +640,7 @@ void AnimatedSprite2D::set_animation(const StringName &p_animation) { animation = p_animation; _reset_timeout(); set_frame(0); - _change_notify(); + notify_property_list_changed(); update(); } @@ -712,15 +710,4 @@ void AnimatedSprite2D::_bind_methods() { } AnimatedSprite2D::AnimatedSprite2D() { - centered = true; - hflip = false; - vflip = false; - - frame = 0; - speed_scale = 1.0f; - playing = false; - backwards = false; - animation = "default"; - timeout = 0; - is_over = false; } diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index a558a3e657..5e53a401e2 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -38,14 +38,9 @@ class SpriteFrames : public Resource { GDCLASS(SpriteFrames, Resource); struct Anim { - float speed; - bool loop; + float speed = 5.0; + bool loop = true; Vector<Ref<Texture2D>> frames; - - Anim() { - loop = true; - speed = 5; - } }; Map<StringName, Anim> animations; @@ -109,20 +104,20 @@ class AnimatedSprite2D : public Node2D { GDCLASS(AnimatedSprite2D, Node2D); Ref<SpriteFrames> frames; - bool playing; - bool backwards; - StringName animation; - int frame; - float speed_scale; + bool playing = false; + bool backwards = false; + StringName animation = "default"; + int frame = 0; + float speed_scale = 1.0f; - bool centered; + bool centered = true; Point2 offset; - bool is_over; - float timeout; + bool is_over = false; + float timeout = 0.0; - bool hflip; - bool vflip; + bool hflip = false; + bool vflip = false; void _res_changed(); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index a4e15008a0..49d1654e3f 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -590,13 +590,13 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout); ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); - ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"))); + ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"))); - ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape"))); - ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"))); ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"))); @@ -627,20 +627,8 @@ void Area2D::_bind_methods() { Area2D::Area2D() : CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) { - space_override = SPACE_OVERRIDE_DISABLED; set_gravity(98); set_gravity_vector(Vector2(0, 1)); - gravity_is_point = false; - gravity_distance_scale = 0; - linear_damp = 0.1; - angular_damp = 1; - locked = false; - priority = 0; - monitoring = false; - monitorable = false; - collision_mask = 1; - collision_layer = 1; - audio_bus_override = false; set_monitoring(true); set_monitorable(true); } diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 0b45675555..39b022fd2c 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -47,19 +47,19 @@ public: }; private: - SpaceOverride space_override; + SpaceOverride space_override = SPACE_OVERRIDE_DISABLED; Vector2 gravity_vec; real_t gravity; - bool gravity_is_point; - real_t gravity_distance_scale; - real_t linear_damp; - real_t angular_damp; - uint32_t collision_mask; - uint32_t collision_layer; - int priority; - bool monitoring; - bool monitorable; - bool locked; + bool gravity_is_point = false; + real_t gravity_distance_scale = 0.0; + real_t linear_damp = 0.1; + real_t angular_damp = 1.0; + uint32_t collision_mask = 1; + uint32_t collision_layer = 1; + int priority = 0; + bool monitoring = false; + bool monitorable = false; + bool locked = false; void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); @@ -67,8 +67,8 @@ private: void _body_exit_tree(ObjectID p_id); struct ShapePair { - int body_shape; - int area_shape; + int body_shape = 0; + int area_shape = 0; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return area_shape < p_sp.area_shape; @@ -85,8 +85,8 @@ private: }; struct BodyState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<ShapePair> shapes; }; @@ -98,8 +98,8 @@ private: void _area_exit_tree(ObjectID p_id); struct AreaShapePair { - int area_shape; - int self_shape; + int area_shape = 0; + int self_shape = 0; bool operator<(const AreaShapePair &p_sp) const { if (area_shape == p_sp.area_shape) { return self_shape < p_sp.self_shape; @@ -116,15 +116,15 @@ private: }; struct AreaState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<AreaShapePair> shapes; }; Map<ObjectID, AreaState> area_map; void _clear_monitoring(); - bool audio_bus_override; + bool audio_bus_override = false; StringName audio_bus; protected: diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index f1eb7d017d..6d8d6058eb 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -35,14 +35,14 @@ #include "scene/main/window.h" void AudioStreamPlayer2D::_mix_audio() { - if (!stream_playback.is_valid() || !active || + if (!stream_playback.is_valid() || !active.is_set() || (stream_paused && !stream_paused_fade_out)) { return; } - if (setseek >= 0.0) { - stream_playback->start(setseek); - setseek = -1.0; //reset seek + if (setseek.get() >= 0.0) { + stream_playback->start(setseek.get()); + setseek.set(-1.0); //reset seek } //get data @@ -57,7 +57,8 @@ void AudioStreamPlayer2D::_mix_audio() { stream_playback->mix(buffer, pitch_scale, buffer_size); //write all outputs - for (int i = 0; i < output_count; i++) { + int oc = output_count.get(); + for (int i = 0; i < oc; i++) { Output current = outputs[i]; //see if current output exists, to keep volume ramp @@ -130,14 +131,14 @@ void AudioStreamPlayer2D::_mix_audio() { prev_outputs[i] = current; } - prev_output_count = output_count; + prev_output_count = oc; //stream is no longer active, disable this. if (!stream_playback->is_playing()) { - active = false; + active.clear(); } - output_ready = false; + output_ready.clear(); stream_paused_fade_in = false; stream_paused_fade_out = false; } @@ -168,7 +169,7 @@ void AudioStreamPlayer2D::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { //update anything related to position first, if possible of course - if (!output_ready) { + if (!output_ready.is_set()) { List<Viewport *> viewports; Ref<World2D> world_2d = get_world_2d(); ERR_FAIL_COND(world_2d.is_null()); @@ -240,24 +241,20 @@ void AudioStreamPlayer2D::_notification(int p_what) { } } - output_count = new_output_count; - output_ready = true; + output_count.set(new_output_count); + output_ready.set(); } //start playing if requested - if (setplay >= 0.0) { - setseek = setplay; - active = true; - setplay = -1; - //do not update, this makes it easier to animate (will shut off otherwise) - //_change_notify("playing"); //update property in editor + if (setplay.get() >= 0.0) { + setseek.set(setplay.get()); + active.set(); + setplay.set(-1); } //stop playing if no longer active - if (!active) { + if (!active.is_set()) { set_physics_process_internal(false); - //do not update, this makes it easier to animate (will shut off otherwise) - //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -271,8 +268,8 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) { if (stream_playback.is_valid()) { stream_playback.unref(); stream.unref(); - active = false; - setseek = -1; + active.clear(); + setseek.set(-1); } if (p_stream.is_valid()) { @@ -315,30 +312,29 @@ void AudioStreamPlayer2D::play(float p_from_pos) { } if (stream_playback.is_valid()) { - active = true; - setplay = p_from_pos; - output_ready = false; + setplay.set(p_from_pos); + output_ready.clear(); set_physics_process_internal(true); } } void AudioStreamPlayer2D::seek(float p_seconds) { if (stream_playback.is_valid()) { - setseek = p_seconds; + setseek.set(p_seconds); } } void AudioStreamPlayer2D::stop() { if (stream_playback.is_valid()) { - active = false; + active.clear(); set_physics_process_internal(false); - setplay = -1; + setplay.set(-1); } } bool AudioStreamPlayer2D::is_playing() const { if (stream_playback.is_valid()) { - return active; // && stream_playback->is_playing(); + return active.is_set() || setplay.get() >= 0; } return false; @@ -346,6 +342,10 @@ bool AudioStreamPlayer2D::is_playing() const { float AudioStreamPlayer2D::get_playback_position() { if (stream_playback.is_valid()) { + float ss = setseek.get(); + if (ss >= 0.0) { + return ss; + } return stream_playback->get_playback_position(); } @@ -385,7 +385,7 @@ void AudioStreamPlayer2D::_set_playing(bool p_enable) { } bool AudioStreamPlayer2D::_is_active() const { - return active; + return active.is_set(); } void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const { @@ -404,7 +404,7 @@ void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer2D::_bus_layout_changed() { - _change_notify(); + notify_property_list_changed(); } void AudioStreamPlayer2D::set_max_distance(float p_pixels) { @@ -503,21 +503,6 @@ void AudioStreamPlayer2D::_bind_methods() { } AudioStreamPlayer2D::AudioStreamPlayer2D() { - volume_db = 0; - pitch_scale = 1.0; - autoplay = false; - setseek = -1; - active = false; - output_count = 0; - prev_output_count = 0; - max_distance = 2000; - attenuation = 1; - setplay = -1; - output_ready = false; - area_mask = 1; - stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed)); } diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 4eb709facb..21f524c703 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -31,6 +31,7 @@ #ifndef AUDIO_STREAM_PLAYER_2D_H #define AUDIO_STREAM_PLAYER_2D_H +#include "core/templates/safe_refcount.h" #include "scene/2d/node_2d.h" #include "servers/audio/audio_stream.h" #include "servers/audio_server.h" @@ -47,32 +48,32 @@ private: struct Output { AudioFrame vol; - int bus_index; - Viewport *viewport; //pointer only used for reference to previous mix + int bus_index = 0; + Viewport *viewport = nullptr; //pointer only used for reference to previous mix }; Output outputs[MAX_OUTPUTS]; - volatile int output_count; - volatile bool output_ready; + SafeNumeric<int> output_count; + SafeFlag output_ready; //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks) Output prev_outputs[MAX_OUTPUTS]; - int prev_output_count; + int prev_output_count = 0; Ref<AudioStreamPlayback> stream_playback; Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; - volatile float setseek; - volatile bool active; - volatile float setplay; + SafeNumeric<float> setseek{ -1.0 }; + SafeFlag active; + SafeNumeric<float> setplay{ -1.0 }; - float volume_db; - float pitch_scale; - bool autoplay; - bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + float volume_db = 0.0; + float pitch_scale = 1.0; + bool autoplay = false; + bool stream_paused = false; + bool stream_paused_fade_in = false; + bool stream_paused_fade_out = false; StringName bus; void _mix_audio(); @@ -83,10 +84,10 @@ private: void _bus_layout_changed(); - uint32_t area_mask; + uint32_t area_mask = 1; - float max_distance; - float attenuation; + float max_distance = 2000.0; + float attenuation = 1.0; protected: void _validate_property(PropertyInfo &property) const override; diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 91c887cb84..539a66b881 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -93,8 +93,6 @@ void BackBufferCopy::_bind_methods() { } BackBufferCopy::BackBufferCopy() { - rect = Rect2(-100, -100, 200, 200); - copy_mode = COPY_MODE_RECT; _update_copy_mode(); } diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 0916d344f9..6bdb3aaab2 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -44,8 +44,8 @@ public: }; private: - Rect2 rect; - CopyMode copy_mode; + Rect2 rect = Rect2(-100, -100, 200, 200); + CopyMode copy_mode = COPY_MODE_RECT; void _update_copy_mode(); diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 4f45325d3a..b4de12b113 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -63,11 +63,11 @@ void Camera2D::_update_scroll() { }; } -void Camera2D::_update_process_mode() { +void Camera2D::_update_process_callback() { if (Engine::get_singleton()->is_editor_hint()) { set_process_internal(false); set_physics_process_internal(false); - } else if (process_mode == CAMERA2D_PROCESS_IDLE) { + } else if (process_callback == CAMERA2D_PROCESS_IDLE) { set_process_internal(true); set_physics_process_internal(false); } else { @@ -157,7 +157,7 @@ Transform2D Camera2D::get_camera_transform() { } if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) { - float c = smoothing * (process_mode == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time()); + float c = smoothing * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time()); smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos; ret_camera_pos = smoothed_camera_pos; //camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing; @@ -247,7 +247,7 @@ void Camera2D::_notification(int p_what) { add_to_group(group_name); add_to_group(canvas_group_name); - _update_process_mode(); + _update_process_callback(); _update_scroll(); first = true; @@ -375,17 +375,17 @@ bool Camera2D::is_rotating() const { return rotating; } -void Camera2D::set_process_mode(Camera2DProcessMode p_mode) { - if (process_mode == p_mode) { +void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) { + if (process_callback == p_mode) { return; } - process_mode = p_mode; - _update_process_mode(); + process_callback = p_mode; + _update_process_callback(); } -Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const { - return process_mode; +Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const { + return process_callback; } void Camera2D::_make_current(Object *p_which) { @@ -651,8 +651,8 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll); - ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Camera2D::set_process_mode); - ClassDB::bind_method(D_METHOD("get_process_mode"), &Camera2D::get_process_mode); + ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback); + ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback); ClassDB::bind_method(D_METHOD("_set_current", "current"), &Camera2D::_set_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current); @@ -714,7 +714,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "_set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom"), "set_zoom", "get_zoom"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback"); ADD_GROUP("Limit", "limit_"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left"), "set_limit", "get_limit", SIDE_LEFT); @@ -749,9 +749,6 @@ void Camera2D::_bind_methods() { } Camera2D::Camera2D() { - anchor_mode = ANCHOR_MODE_DRAG_CENTER; - rotating = false; - current = false; limit[SIDE_LEFT] = -10000000; limit[SIDE_TOP] = -10000000; limit[SIDE_RIGHT] = 10000000; @@ -761,27 +758,6 @@ Camera2D::Camera2D() { drag_margin[SIDE_TOP] = 0.2; drag_margin[SIDE_RIGHT] = 0.2; drag_margin[SIDE_BOTTOM] = 0.2; - camera_pos = Vector2(); - first = true; - smoothing_enabled = false; - limit_smoothing_enabled = false; - custom_viewport = nullptr; - - process_mode = CAMERA2D_PROCESS_IDLE; - - smoothing = 5.0; - zoom = Vector2(1, 1); - - screen_drawing_enabled = true; - limit_drawing_enabled = false; - margin_drawing_enabled = false; - - drag_horizontal_enabled = false; - drag_vertical_enabled = false; - drag_horizontal_offset = 0; - drag_vertical_offset = 0; - drag_horizontal_offset_changed = false; - drag_vertical_offset_changed = false; set_notify_transform(true); } diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 8977d872f0..252d2686fc 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -43,7 +43,7 @@ public: ANCHOR_MODE_DRAG_CENTER }; - enum Camera2DProcessMode { + enum Camera2DProcessCallback { CAMERA2D_PROCESS_PHYSICS, CAMERA2D_PROCESS_IDLE }; @@ -51,35 +51,35 @@ public: protected: Point2 camera_pos; Point2 smoothed_camera_pos; - bool first; + bool first = true; ObjectID custom_viewport_id; // to check validity - Viewport *custom_viewport; - Viewport *viewport; + Viewport *custom_viewport = nullptr; + Viewport *viewport = nullptr; StringName group_name; StringName canvas_group_name; RID canvas; Vector2 offset; - Vector2 zoom; - AnchorMode anchor_mode; - bool rotating; - bool current; - float smoothing; - bool smoothing_enabled; + Vector2 zoom = Vector2(1, 1); + AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER; + bool rotating = false; + bool current = false; + float smoothing = 5.0; + bool smoothing_enabled = false; int limit[4]; - bool limit_smoothing_enabled; + bool limit_smoothing_enabled = false; float drag_margin[4]; - bool drag_horizontal_enabled; - bool drag_vertical_enabled; - float drag_horizontal_offset; - float drag_vertical_offset; - bool drag_horizontal_offset_changed; - bool drag_vertical_offset_changed; + bool drag_horizontal_enabled = false; + bool drag_vertical_enabled = false; + float drag_horizontal_offset = 0.0; + float drag_vertical_offset = 0.0; + bool drag_horizontal_offset_changed = false; + bool drag_vertical_offset_changed = false; Point2 camera_screen_center; - void _update_process_mode(); + void _update_process_callback(); void _update_scroll(); void _make_current(Object *p_which); @@ -87,11 +87,11 @@ protected: void _set_old_smoothing(float p_enable); - bool screen_drawing_enabled; - bool limit_drawing_enabled; - bool margin_drawing_enabled; + bool screen_drawing_enabled = true; + bool limit_drawing_enabled = false; + bool margin_drawing_enabled = false; - Camera2DProcessMode process_mode; + Camera2DProcessCallback process_callback = CAMERA2D_PROCESS_IDLE; Size2 _get_camera_screen_size() const; @@ -137,8 +137,8 @@ public: void set_follow_smoothing(float p_speed); float get_follow_smoothing() const; - void set_process_mode(Camera2DProcessMode p_mode); - Camera2DProcessMode get_process_mode() const; + void set_process_callback(Camera2DProcessCallback p_mode); + Camera2DProcessCallback get_process_callback() const; void make_current(); void clear_current(); @@ -170,6 +170,6 @@ public: }; VARIANT_ENUM_CAST(Camera2D::AnchorMode); -VARIANT_ENUM_CAST(Camera2D::Camera2DProcessMode); +VARIANT_ENUM_CAST(Camera2D::Camera2DProcessCallback); #endif // CAMERA_2D_H diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 6e90afde21..5d5aaae505 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -94,7 +94,6 @@ String CanvasModulate::get_configuration_warning() const { } CanvasModulate::CanvasModulate() { - color = Color(1, 1, 1, 1); } CanvasModulate::~CanvasModulate() { diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index 6efc0cab9b..4d55a5d9cb 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -36,7 +36,7 @@ class CanvasModulate : public Node2D { GDCLASS(CanvasModulate, Node2D); - Color color; + Color color = Color(1, 1, 1, 1); protected: void _notification(int p_what); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index f0b007f843..c83ed36917 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -165,7 +165,7 @@ bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owne return shapes[p_owner].one_way_collision; } -void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin) { +void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin) { if (area) { return; //not for areas } @@ -179,7 +179,7 @@ void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owne } } -float CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const { +real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const { ERR_FAIL_COND_V(!shapes.has(p_owner), 0); return shapes[p_owner].one_way_collision_margin; diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index a2112c27f4..e82b61d441 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -37,35 +37,29 @@ class CollisionObject2D : public Node2D { GDCLASS(CollisionObject2D, Node2D); - bool area; + bool area = false; RID rid; - bool pickable; + bool pickable = false; struct ShapeData { - Object *owner; + Object *owner = nullptr; Transform2D xform; struct Shape { Ref<Shape2D> shape; - int index; + int index = 0; }; Vector<Shape> shapes; - bool disabled; - bool one_way_collision; - float one_way_collision_margin; - - ShapeData() { - disabled = false; - one_way_collision = false; - one_way_collision_margin = 0; - owner = nullptr; - } + + bool disabled = false; + bool one_way_collision = false; + real_t one_way_collision_margin = 0.0; }; - int total_subshapes; + int total_subshapes = 0; Map<uint32_t, ShapeData> shapes; - bool only_update_transform_changes; //this is used for sync physics in KinematicBody + bool only_update_transform_changes = false; //this is used for sync physics in KinematicBody protected: CollisionObject2D(RID p_rid, bool p_area); @@ -97,8 +91,8 @@ public: void shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable); bool is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const; - void shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin); - float get_shape_owner_one_way_collision_margin(uint32_t p_owner) const; + void shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin); + real_t get_shape_owner_one_way_collision_margin(uint32_t p_owner) const; void shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape); int shape_owner_get_shape_count(uint32_t p_owner) const; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 7347b7829a..39d7705226 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -36,7 +36,7 @@ #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" -#include "thirdparty/misc/triangulator.h" +#include "thirdparty/misc/polypartition.h" void CollisionPolygon2D::_build_polygon() { parent->shape_owner_clear_shapes(owner_id); @@ -158,7 +158,7 @@ void CollisionPolygon2D::_notification(int p_what) { Vector2 line_to(0, 20); draw_line(Vector2(), line_to, dcol, 3); Vector<Vector2> pts; - float tsize = 8; + real_t tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); @@ -194,6 +194,7 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) { if (parent) { _build_polygon(); + _update_in_shape_owner(); } update(); update_configuration_warning(); @@ -208,6 +209,7 @@ void CollisionPolygon2D::set_build_mode(BuildMode p_mode) { build_mode = p_mode; if (parent) { _build_polygon(); + _update_in_shape_owner(); } } @@ -273,14 +275,14 @@ bool CollisionPolygon2D::is_one_way_collision_enabled() const { return one_way_collision; } -void CollisionPolygon2D::set_one_way_collision_margin(float p_margin) { +void CollisionPolygon2D::set_one_way_collision_margin(real_t p_margin) { one_way_collision_margin = p_margin; if (parent) { parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } } -float CollisionPolygon2D::get_one_way_collision_margin() const { +real_t CollisionPolygon2D::get_one_way_collision_margin() const { return one_way_collision_margin; } @@ -308,12 +310,5 @@ void CollisionPolygon2D::_bind_methods() { } CollisionPolygon2D::CollisionPolygon2D() { - aabb = Rect2(-10, -10, 20, 20); - build_mode = BUILD_SOLIDS; set_notify_local_transform(true); - parent = nullptr; - owner_id = 0; - disabled = false; - one_way_collision = false; - one_way_collision_margin = 1.0; } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index caa5b2c3ec..9df9802629 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -46,14 +46,14 @@ public: }; protected: - Rect2 aabb; - BuildMode build_mode; + Rect2 aabb = Rect2(-10, -10, 20, 20); + BuildMode build_mode = BUILD_SOLIDS; Vector<Point2> polygon; - uint32_t owner_id; - CollisionObject2D *parent; - bool disabled; - bool one_way_collision; - float one_way_collision_margin; + uint32_t owner_id = 0; + CollisionObject2D *parent = nullptr; + bool disabled = false; + bool one_way_collision = false; + real_t one_way_collision_margin = 1.0; Vector<Vector<Vector2>> _decompose_in_convex(); @@ -86,8 +86,8 @@ public: void set_one_way_collision(bool p_enable); bool is_one_way_collision_enabled() const; - void set_one_way_collision_margin(float p_margin); - float get_one_way_collision_margin() const; + void set_one_way_collision_margin(real_t p_margin); + real_t get_one_way_collision_margin() const; CollisionPolygon2D(); }; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index acdde96df0..93949f741b 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -110,6 +110,7 @@ void CollisionShape2D::_notification(int p_what) { draw_col.r = g; draw_col.g = g; draw_col.b = g; + draw_col.a *= 0.5; } shape->draw(get_canvas_item(), draw_col); @@ -125,7 +126,7 @@ void CollisionShape2D::_notification(int p_what) { Vector2 line_to(0, 20); draw_line(Vector2(), line_to, draw_col, 2); Vector<Vector2> pts; - float tsize = 8; + real_t tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); @@ -141,6 +142,9 @@ void CollisionShape2D::_notification(int p_what) { } void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) { + if (p_shape == shape) { + return; + } if (shape.is_valid()) { shape->disconnect("changed", callable_mp(this, &CollisionShape2D::_shape_changed)); } @@ -151,6 +155,7 @@ void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) { if (shape.is_valid()) { parent->shape_owner_add_shape(owner_id, shape); } + _update_in_shape_owner(); } if (shape.is_valid()) { @@ -211,14 +216,14 @@ bool CollisionShape2D::is_one_way_collision_enabled() const { return one_way_collision; } -void CollisionShape2D::set_one_way_collision_margin(float p_margin) { +void CollisionShape2D::set_one_way_collision_margin(real_t p_margin) { one_way_collision_margin = p_margin; if (parent) { parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } } -float CollisionShape2D::get_one_way_collision_margin() const { +real_t CollisionShape2D::get_one_way_collision_margin() const { return one_way_collision_margin; } @@ -239,11 +244,5 @@ void CollisionShape2D::_bind_methods() { } CollisionShape2D::CollisionShape2D() { - rect = Rect2(-Point2(10, 10), Point2(20, 20)); set_notify_local_transform(true); - owner_id = 0; - parent = nullptr; - disabled = false; - one_way_collision = false; - one_way_collision_margin = 1.0; } diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index 8a4d885393..695d0c6657 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -39,13 +39,13 @@ class CollisionObject2D; class CollisionShape2D : public Node2D { GDCLASS(CollisionShape2D, Node2D); Ref<Shape2D> shape; - Rect2 rect; - uint32_t owner_id; - CollisionObject2D *parent; + Rect2 rect = Rect2(-Point2(10, 10), Point2(20, 20)); + uint32_t owner_id = 0; + CollisionObject2D *parent = nullptr; void _shape_changed(); - bool disabled; - bool one_way_collision; - float one_way_collision_margin; + bool disabled = false; + bool one_way_collision = false; + real_t one_way_collision_margin = 1.0; void _update_in_shape_owner(bool p_xform_only = false); @@ -69,8 +69,8 @@ public: void set_one_way_collision(bool p_enable); bool is_one_way_collision_enabled() const; - void set_one_way_collision_margin(float p_margin); - float get_one_way_collision_margin() const; + void set_one_way_collision_margin(real_t p_margin); + real_t get_one_way_collision_margin() const; virtual String get_configuration_warning() const override; diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 7c9bd118d8..48acee1bc4 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -60,7 +60,7 @@ void CPUParticles2D::set_amount(int p_amount) { } particle_data.resize((8 + 4 + 4) * p_amount); - RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true); + RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true); particle_order.resize(p_amount); } @@ -410,7 +410,7 @@ bool CPUParticles2D::get_particle_flag(ParticleFlags p_particle_flag) const { void CPUParticles2D::set_emission_shape(EmissionShape p_shape) { ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; - _change_notify(); + notify_property_list_changed(); } void CPUParticles2D::set_emission_sphere_radius(float p_radius) { @@ -599,7 +599,7 @@ void CPUParticles2D::_particles_process(float p_delta) { cycle++; if (one_shot && cycle > 0) { set_emitting(false); - _change_notify(); + notify_property_list_changed(); } } @@ -671,6 +671,8 @@ void CPUParticles2D::_particles_process(float p_delta) { restart = true; } + float tv = 0.0; + if (restart) { if (!emitting) { p.active = false; @@ -685,12 +687,12 @@ void CPUParticles2D::_particles_process(float p_delta) { float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv); } p.seed = Math::rand(); @@ -700,7 +702,7 @@ void CPUParticles2D::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad)); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); @@ -721,7 +723,7 @@ void CPUParticles2D::_particles_process(float p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { - float s = Math::randf(), t = 2.0 * Math_PI * Math::randf(); + float s = Math::randf(), t = Math_TAU * Math::randf(); float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius; } break; @@ -765,59 +767,61 @@ void CPUParticles2D::_particles_process(float p_delta) { continue; } else if (p.time > p.lifetime) { p.active = false; + tv = 1.0; } else { uint32_t alt_seed = p.seed; p.time += local_delta; p.custom[1] = p.time / lifetime; + tv = p.time / p.lifetime; float tex_linear_velocity = 0.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]); + tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv); } float tex_orbit_velocity = 0.0; if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]); + tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv); } float tex_angular_velocity = 0.0; if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { - tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]); + tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv); } float tex_linear_accel = 0.0; if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) { - tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]); + tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv); } float tex_tangential_accel = 0.0; if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { - tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]); + tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv); } float tex_radial_accel = 0.0; if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) { - tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]); + tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv); } float tex_damping = 0.0; if (curve_parameters[PARAM_DAMPING].is_valid()) { - tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]); + tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv); } float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_speed = 0.0; if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) { - tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]); + tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]); + tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv); } Vector2 force = gravity; @@ -837,7 +841,7 @@ void CPUParticles2D::_particles_process(float p_delta) { //orbit velocity float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); if (orbit_amount != 0.0) { - float ang = orbit_amount * local_delta * Math_PI * 2.0; + float ang = orbit_amount * local_delta * Math_TAU; // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); @@ -869,15 +873,15 @@ void CPUParticles2D::_particles_process(float p_delta) { float tex_scale = 1.0; if (curve_parameters[PARAM_SCALE].is_valid()) { - tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]); + tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv); } float tex_hue_variation = 0.0; if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) { - tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]); + tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv); } - float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); + float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); float hue_rot_c = Math::cos(hue_rot_angle); float hue_rot_s = Math::sin(hue_rot_angle); @@ -893,7 +897,7 @@ void CPUParticles2D::_particles_process(float p_delta) { } if (color_ramp.is_valid()) { - p.color = color_ramp->get_color_at_offset(p.custom[1]) * color; + p.color = color_ramp->get_color_at_offset(tv) * color; } else { p.color = color; } @@ -1028,66 +1032,64 @@ void CPUParticles2D::_update_render_thread() { } void CPUParticles2D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - set_process_internal(emitting); - } - - if (p_what == NOTIFICATION_EXIT_TREE) { - _set_redraw(false); - } - - if (p_what == NOTIFICATION_DRAW) { - // first update before rendering to avoid one frame delay after emitting starts - if (emitting && (time == 0)) { - _update_internal(); - } - - if (!redraw) { - return; // don't add to render list - } - - RID texrid; - if (texture.is_valid()) { - texrid = texture->get_rid(); - } - - RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid); - } - - if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - _update_internal(); - } - - if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - inv_emission_transform = get_global_transform().affine_inverse(); + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + set_process_internal(emitting); + } break; + case NOTIFICATION_EXIT_TREE: { + _set_redraw(false); + } break; + case NOTIFICATION_DRAW: { + // first update before rendering to avoid one frame delay after emitting starts + if (emitting && (time == 0)) { + _update_internal(); + } - if (!local_coords) { - int pc = particles.size(); + if (!redraw) { + return; // don't add to render list + } - float *w = particle_data.ptrw(); - const Particle *r = particles.ptr(); - float *ptr = w; + RID texrid; + if (texture.is_valid()) { + texrid = texture->get_rid(); + } - for (int i = 0; i < pc; i++) { - Transform2D t = inv_emission_transform * r[i].transform; + RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid); + } break; + case NOTIFICATION_INTERNAL_PROCESS: { + _update_internal(); + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + inv_emission_transform = get_global_transform().affine_inverse(); - if (r[i].active) { - ptr[0] = t.elements[0][0]; - ptr[1] = t.elements[1][0]; - ptr[2] = 0; - ptr[3] = t.elements[2][0]; - ptr[4] = t.elements[0][1]; - ptr[5] = t.elements[1][1]; - ptr[6] = 0; - ptr[7] = t.elements[2][1]; + if (!local_coords) { + int pc = particles.size(); + + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; + + for (int i = 0; i < pc; i++) { + Transform2D t = inv_emission_transform * r[i].transform; + + if (r[i].active) { + ptr[0] = t.elements[0][0]; + ptr[1] = t.elements[1][0]; + ptr[2] = 0; + ptr[3] = t.elements[2][0]; + ptr[4] = t.elements[0][1]; + ptr[5] = t.elements[1][1]; + ptr[6] = 0; + ptr[7] = t.elements[2][1]; + + } else { + zeromem(ptr, sizeof(float) * 8); + } - } else { - zeromem(ptr, sizeof(float) * 8); + ptr += 16; } - - ptr += 16; } - } + } break; } } @@ -1365,34 +1367,14 @@ void CPUParticles2D::_bind_methods() { } CPUParticles2D::CPUParticles2D() { - time = 0; - inactive_time = 0; - frame_remainder = 0; - cycle = 0; - redraw = false; - emitting = false; - mesh = RenderingServer::get_singleton()->mesh_create(); multimesh = RenderingServer::get_singleton()->multimesh_create(); RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, mesh); set_emitting(true); - set_one_shot(false); set_amount(8); - set_lifetime(1); - set_fixed_fps(0); - set_fractional_delta(true); - set_pre_process_time(0); - set_explosiveness_ratio(0); - set_randomness_ratio(0); - set_lifetime_randomness(0); set_use_local_coordinates(true); - set_draw_order(DRAW_ORDER_INDEX); - set_speed_scale(1); - - set_direction(Vector2(1, 0)); - set_spread(45); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); set_param(PARAM_ANGULAR_VELOCITY, 0); set_param(PARAM_ORBIT_VELOCITY, 0); @@ -1405,11 +1387,6 @@ CPUParticles2D::CPUParticles2D() { set_param(PARAM_HUE_VARIATION, 0); set_param(PARAM_ANIM_SPEED, 0); set_param(PARAM_ANIM_OFFSET, 0); - set_emission_shape(EMISSION_SHAPE_POINT); - set_emission_sphere_radius(1); - set_emission_rect_extents(Vector2(1, 1)); - - set_gravity(Vector2(0, 98)); for (int i = 0; i < PARAM_MAX; i++) { set_param_randomness(Parameter(i), 0); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 3793f6a418..7ee165b3e1 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -78,31 +78,31 @@ public: }; private: - bool emitting; + bool emitting = false; struct Particle { Transform2D transform; Color color; - float custom[4]; - float rotation; + float custom[4] = {}; + float rotation = 0.0; Vector2 velocity; - bool active; - float angle_rand; - float scale_rand; - float hue_rot_rand; - float anim_offset_rand; - float time; - float lifetime; + bool active = false; + float angle_rand = 0.0; + float scale_rand = 0.0; + float hue_rot_rand = 0.0; + float anim_offset_rand = 0.0; + float time = 0.0; + float lifetime = 0.0; Color base_color; - uint32_t seed; + uint32_t seed = 0; }; - float time; - float inactive_time; - float frame_remainder; - int cycle; - bool redraw; + float time = 0.0; + float inactive_time = 0.0; + float frame_remainder = 0.0; + int cycle = 0; + bool redraw = false; RID mesh; RID multimesh; @@ -112,7 +112,7 @@ private: Vector<int> particle_order; struct SortLifetime { - const Particle *particles; + const Particle *particles = nullptr; bool operator()(int p_a, int p_b) const { return particles[p_a].time > particles[p_b].time; @@ -120,7 +120,7 @@ private: }; struct SortAxis { - const Particle *particles; + const Particle *particles = nullptr; Vector2 axis; bool operator()(int p_a, int p_b) const { return axis.dot(particles[p_a].transform[2]) < axis.dot(particles[p_b].transform[2]); @@ -129,28 +129,28 @@ private: // - bool one_shot; + bool one_shot = false; - float lifetime; - float pre_process_time; - float explosiveness_ratio; - float randomness_ratio; - float lifetime_randomness; - float speed_scale; + float lifetime = 1.0; + float pre_process_time = 0.0; + float explosiveness_ratio = 0.0; + float randomness_ratio = 0.0; + float lifetime_randomness = 0.0; + float speed_scale = 1.0; bool local_coords; - int fixed_fps; - bool fractional_delta; + int fixed_fps = 0; + bool fractional_delta = true; Transform2D inv_emission_transform; - DrawOrder draw_order; + DrawOrder draw_order = DRAW_ORDER_INDEX; Ref<Texture2D> texture; //////// - Vector2 direction; - float spread; + Vector2 direction = Vector2(1, 0); + float spread = 45.0; float parameters[PARAM_MAX]; float randomness[PARAM_MAX]; @@ -161,15 +161,15 @@ private: bool particle_flags[PARTICLE_FLAG_MAX]; - EmissionShape emission_shape; - float emission_sphere_radius; - Vector2 emission_rect_extents; + EmissionShape emission_shape = EMISSION_SHAPE_POINT; + float emission_sphere_radius = 1.0; + Vector2 emission_rect_extents = Vector2(1, 1); Vector<Vector2> emission_points; Vector<Vector2> emission_normals; Vector<Color> emission_colors; - int emission_point_count; + int emission_point_count = 0; - Vector2 gravity; + Vector2 gravity = Vector2(0, 98); void _update_internal(); void _particles_process(float p_delta); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 2e477a88a9..af70c47f7c 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -101,7 +101,6 @@ void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) { RS::get_singleton()->particles_set_custom_aabb(particles, aabb); - _change_notify("visibility_rect"); update(); } @@ -305,7 +304,7 @@ void GPUParticles2D::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (one_shot && !is_emitting()) { - _change_notify(); + notify_property_list_changed(); set_process_internal(false); } } diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 1a31f72a59..f4f08674c9 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -65,18 +65,16 @@ void Joint2D::_body_exit_tree(const ObjectID &p_body_id) { } void Joint2D::_update_joint(bool p_only_free) { - if (joint.is_valid()) { - if (ba.is_valid() && bb.is_valid() && exclude_from_collision) { - PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false); - } - - PhysicsServer2D::get_singleton()->free(joint); - joint = RID(); - ba = RID(); - bb = RID(); + if (ba.is_valid() && bb.is_valid() && exclude_from_collision) { + PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false); } + ba = RID(); + bb = RID(); + configured = false; + if (p_only_free || !is_inside_tree()) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = String(); return; } @@ -88,30 +86,35 @@ void Joint2D::_update_joint(bool p_only_free) { PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); if (node_a && !body_a && node_b && !body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be PhysicsBody2Ds"); update_configuration_warning(); return; } if (node_a && !body_a) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node A must be a PhysicsBody2D"); update_configuration_warning(); return; } if (node_b && !body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node B must be a PhysicsBody2D"); update_configuration_warning(); return; } if (!body_a || !body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Joint is not connected to two PhysicsBody2Ds"); update_configuration_warning(); return; } if (body_a == body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be different PhysicsBody2Ds"); update_configuration_warning(); return; @@ -128,7 +131,9 @@ void Joint2D::_update_joint(bool p_only_free) { body_b->force_update_transform(); } - joint = _configure_joint(body_a, body_b); + configured = true; + + _configure_joint(joint, body_a, body_b); ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); @@ -249,8 +254,11 @@ void Joint2D::_bind_methods() { } Joint2D::Joint2D() { - bias = 0; - exclude_from_collision = true; + joint = PhysicsServer2D::get_singleton()->joint_create(); +} + +Joint2D::~Joint2D() { + PhysicsServer2D::get_singleton()->free(joint); } /////////////////////////////////////////////////////////////////////////////// @@ -274,16 +282,15 @@ void PinJoint2D::_notification(int p_what) { } } -RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { - RID pj = PhysicsServer2D::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID()); - PhysicsServer2D::get_singleton()->pin_joint_set_param(pj, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness); - return pj; +void PinJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) { + PhysicsServer2D::get_singleton()->joint_make_pin(p_joint, get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID()); + PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness); } void PinJoint2D::set_softness(real_t p_softness) { softness = p_softness; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer2D::PIN_JOINT_SOFTNESS, p_softness); } } @@ -300,7 +307,6 @@ void PinJoint2D::_bind_methods() { } PinJoint2D::PinJoint2D() { - softness = 0; } /////////////////////////////////////////////////////////////////////////////// @@ -326,13 +332,13 @@ void GrooveJoint2D::_notification(int p_what) { } } -RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { +void GrooveJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) { Transform2D gt = get_global_transform(); Vector2 groove_A1 = gt.get_origin(); Vector2 groove_A2 = gt.xform(Vector2(0, length)); Vector2 anchor_B = gt.xform(Vector2(0, initial_offset)); - return PhysicsServer2D::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid()); + PhysicsServer2D::get_singleton()->joint_make_groove(p_joint, groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid()); } void GrooveJoint2D::set_length(real_t p_length) { @@ -364,8 +370,6 @@ void GrooveJoint2D::_bind_methods() { } GrooveJoint2D::GrooveJoint2D() { - length = 50; - initial_offset = 25; } /////////////////////////////////////////////////////////////////////////////// @@ -390,19 +394,17 @@ void DampedSpringJoint2D::_notification(int p_what) { } } -RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { +void DampedSpringJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) { Transform2D gt = get_global_transform(); Vector2 anchor_A = gt.get_origin(); Vector2 anchor_B = gt.xform(Vector2(0, length)); - RID dsj = PhysicsServer2D::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid()); + PhysicsServer2D::get_singleton()->joint_make_damped_spring(p_joint, anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid()); if (rest_length) { - PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length); + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length); } - PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness); - PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping); - - return dsj; + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness); + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping); } void DampedSpringJoint2D::set_length(real_t p_length) { @@ -417,7 +419,7 @@ real_t DampedSpringJoint2D::get_length() const { void DampedSpringJoint2D::set_rest_length(real_t p_rest_length) { rest_length = p_rest_length; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, p_rest_length ? p_rest_length : length); } } @@ -429,7 +431,7 @@ real_t DampedSpringJoint2D::get_rest_length() const { void DampedSpringJoint2D::set_stiffness(real_t p_stiffness) { stiffness = p_stiffness; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_STIFFNESS, p_stiffness); } } @@ -441,7 +443,7 @@ real_t DampedSpringJoint2D::get_stiffness() const { void DampedSpringJoint2D::set_damping(real_t p_damping) { damping = p_damping; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_DAMPING, p_damping); } } @@ -467,8 +469,4 @@ void DampedSpringJoint2D::_bind_methods() { } DampedSpringJoint2D::DampedSpringJoint2D() { - length = 50; - rest_length = 0; - stiffness = 20; - damping = 1; } diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h index d0fbb9fd3a..3607a6c176 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -43,9 +43,10 @@ class Joint2D : public Node2D { NodePath a; NodePath b; - real_t bias; + real_t bias = 0.0; - bool exclude_from_collision; + bool exclude_from_collision = true; + bool configured = false; String warning; protected: @@ -54,10 +55,12 @@ protected: void _update_joint(bool p_only_free = false); void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0; static void _bind_methods(); + _FORCE_INLINE_ bool is_configured() const { return configured; } + public: virtual String get_configuration_warning() const override; @@ -75,16 +78,17 @@ public: RID get_joint() const { return joint; } Joint2D(); + ~Joint2D(); }; class PinJoint2D : public Joint2D { GDCLASS(PinJoint2D, Joint2D); - real_t softness; + real_t softness = 0.0; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: @@ -97,12 +101,12 @@ public: class GrooveJoint2D : public Joint2D { GDCLASS(GrooveJoint2D, Joint2D); - real_t length; - real_t initial_offset; + real_t length = 50.0; + real_t initial_offset = 25.0; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: @@ -118,14 +122,14 @@ public: class DampedSpringJoint2D : public Joint2D { GDCLASS(DampedSpringJoint2D, Joint2D); - real_t stiffness; - real_t damping; - real_t rest_length; - real_t length; + real_t stiffness = 20.0; + real_t damping = 1.0; + real_t rest_length = 0.0; + real_t length = 50.0; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index ba4372f040..15fcb08422 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -300,22 +300,6 @@ void Light2D::_bind_methods() { Light2D::Light2D() { canvas_light = RenderingServer::get_singleton()->canvas_light_create(); - enabled = true; - editor_only = false; - shadow = false; - color = Color(1, 1, 1); - height = 0; - z_min = -1024; - z_max = 1024; - layer_min = 0; - layer_max = 0; - item_mask = 1; - item_shadow_mask = 1; - energy = 1.0; - shadow_color = Color(0, 0, 0, 0); - shadow_filter = SHADOW_FILTER_NONE; - shadow_smooth = 0; - blend_mode = BLEND_MODE_ADD; set_notify_transform(true); } @@ -393,7 +377,6 @@ void PointLight2D::set_texture_offset(const Vector2 &p_offset) { texture_offset = p_offset; RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset); item_rect_changed(); - _change_notify("offset"); } Vector2 PointLight2D::get_texture_offset() const { diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 0112ab1648..4279baf15b 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -52,24 +52,24 @@ public: private: RID canvas_light; - bool enabled; - bool editor_only; - bool shadow; - Color color; - Color shadow_color; - float height; - float energy; - int z_min; - int z_max; - int layer_min; - int layer_max; - int item_mask; - int item_shadow_mask; - float shadow_smooth; + bool enabled = true; + bool editor_only = false; + bool shadow = false; + Color color = Color(1, 1, 1); + Color shadow_color = Color(0, 0, 0, 0); + float height = 0.0; + float energy = 1.0; + int z_min = -1024; + int z_max = 1024; + int layer_min = 0; + int layer_max = 0; + int item_mask = 1; + int item_shadow_mask = 1; + float shadow_smooth = 0.0; Ref<Texture2D> texture; Vector2 texture_offset; - ShadowFilter shadow_filter; - BlendMode blend_mode; + ShadowFilter shadow_filter = SHADOW_FILTER_NONE; + BlendMode blend_mode = BLEND_MODE_ADD; void _update_light_visibility(); diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 3146e64c08..9589702e2e 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -145,9 +145,6 @@ void OccluderPolygon2D::_bind_methods() { OccluderPolygon2D::OccluderPolygon2D() { occ_polygon = RS::get_singleton()->canvas_occluder_polygon_create(); - closed = true; - cull = CULL_DISABLED; - rect_cache_dirty = true; } OccluderPolygon2D::~OccluderPolygon2D() { diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 7944ccad3a..f567c6d965 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -46,11 +46,11 @@ public: private: RID occ_polygon; Vector<Vector2> polygon; - bool closed; - CullMode cull; + bool closed = true; + CullMode cull = CULL_DISABLED; mutable Rect2 item_rect; - mutable bool rect_cache_dirty; + mutable bool rect_cache_dirty = true; protected: static void _bind_methods(); diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 0a3f5673f8..37eb45c21d 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -40,15 +40,6 @@ VARIANT_ENUM_CAST(Line2D::LineCapMode) VARIANT_ENUM_CAST(Line2D::LineTextureMode) Line2D::Line2D() { - _joint_mode = LINE_JOINT_SHARP; - _begin_cap_mode = LINE_CAP_NONE; - _end_cap_mode = LINE_CAP_NONE; - _width = 10; - _default_color = Color(1, 1, 1); - _texture_mode = LINE_TEXTURE_NONE; - _sharp_limit = 2.f; - _round_precision = 8; - _antialiased = false; } #ifdef TOOLS_ENABLED @@ -125,6 +116,7 @@ Vector<Vector2> Line2D::get_points() const { } void Line2D::set_point_position(int i, Vector2 p_pos) { + ERR_FAIL_INDEX(i, _points.size()); _points.set(i, p_pos); update(); } diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index e0b1cea60a..5e7eb4bac9 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -124,18 +124,18 @@ private: private: Vector<Vector2> _points; - LineJointMode _joint_mode; - LineCapMode _begin_cap_mode; - LineCapMode _end_cap_mode; - float _width; + LineJointMode _joint_mode = LINE_JOINT_SHARP; + LineCapMode _begin_cap_mode = LINE_CAP_NONE; + LineCapMode _end_cap_mode = LINE_CAP_NONE; + float _width = 10.0; Ref<Curve> _curve; - Color _default_color; + Color _default_color = Color(1, 1, 1); Ref<Gradient> _gradient; Ref<Texture2D> _texture; - LineTextureMode _texture_mode; - float _sharp_limit; - int _round_precision; - bool _antialiased; + LineTextureMode _texture_mode = LINE_TEXTURE_NONE; + float _sharp_limit = 2.f; + int _round_precision = 8; + bool _antialiased = false; }; #endif // LINE2D_H diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 2f4459785b..892ccadfda 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -94,20 +94,6 @@ static inline Vector2 interpolate(const Rect2 &r, const Vector2 &v) { //---------------------------------------------------------------------------- LineBuilder::LineBuilder() { - joint_mode = Line2D::LINE_JOINT_SHARP; - width = 10; - curve = nullptr; - default_color = Color(0.4, 0.5, 1); - gradient = nullptr; - sharp_limit = 2.f; - round_precision = 8; - begin_cap_mode = Line2D::LINE_CAP_NONE; - end_cap_mode = Line2D::LINE_CAP_NONE; - tile_aspect = 1.f; - - _interpolate_color = false; - _last_index[0] = 0; - _last_index[1] = 0; } void LineBuilder::clear_output() { @@ -554,7 +540,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col float t = Vector2(1, 0).angle_to(vbegin); float end_angle = t + angle_delta; Vector2 rpos(0, 0); - float tt_begin = -Math_PI / 2.f; + float tt_begin = -Math_PI / 2.0f; float tt = tt_begin; // Center vertice diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index bd419d330b..654e61422b 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -41,17 +41,17 @@ public: // TODO Move in a struct and reference it // Input Vector<Vector2> points; - Line2D::LineJointMode joint_mode; - Line2D::LineCapMode begin_cap_mode; - Line2D::LineCapMode end_cap_mode; - float width; - Curve *curve; - Color default_color; - Gradient *gradient; - Line2D::LineTextureMode texture_mode; - float sharp_limit; - int round_precision; - float tile_aspect; // w/h + Line2D::LineJointMode joint_mode = Line2D::LINE_JOINT_SHARP; + Line2D::LineCapMode begin_cap_mode = Line2D::LINE_CAP_NONE; + Line2D::LineCapMode end_cap_mode = Line2D::LINE_CAP_NONE; + float width = 10.0; + Curve *curve = nullptr; + Color default_color = Color(0.4, 0.5, 1); + Gradient *gradient = nullptr; + Line2D::LineTextureMode texture_mode = Line2D::LineTextureMode::LINE_TEXTURE_NONE; + float sharp_limit = 2.f; + int round_precision = 8; + float tile_aspect = 1.f; // w/h // TODO offset_joints option (offers alternative implementation of round joints) // TODO Move in a struct and reference it @@ -82,8 +82,8 @@ private: void new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Color color, Rect2 uv_rect); private: - bool _interpolate_color; - int _last_index[2]; // Index of last up and down vertices of the strip + bool _interpolate_color = false; + int _last_index[2] = {}; // Index of last up and down vertices of the strip }; #endif // LINE_BUILDER_H diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 430e655fc6..b7a0028199 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -71,7 +71,6 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); emit_signal("texture_changed"); - _change_notify("texture"); } void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 5164e5c7e9..72a899370e 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -71,7 +71,6 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); emit_signal("texture_changed"); - _change_notify("texture"); } Ref<Texture2D> MultiMeshInstance2D::get_texture() const { diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 72dc8bd9ad..b02cdf12ad 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -37,7 +37,7 @@ #include "navigation_2d.h" #include "servers/navigation_server_2d.h" -#include "thirdparty/misc/triangulator.h" +#include "thirdparty/misc/polypartition.h" #ifdef TOOLS_ENABLED Rect2 NavigationPolygon::_edit_get_rect() const { @@ -228,7 +228,7 @@ void NavigationPolygon::make_polygons_from_outlines() { MutexLock lock(navmesh_generation); navmesh.unref(); } - List<TriangulatorPoly> in_poly, out_poly; + List<TPPLPoly> in_poly, out_poly; Vector2 outside_point(-1e10, -1e10); @@ -278,23 +278,23 @@ void NavigationPolygon::make_polygons_from_outlines() { bool outer = (interscount % 2) == 0; - TriangulatorPoly tp; + TPPLPoly tp; tp.Init(olsize); for (int j = 0; j < olsize; j++) { tp[j] = r[j]; } if (outer) { - tp.SetOrientation(TRIANGULATOR_CCW); + tp.SetOrientation(TPPL_ORIENTATION_CCW); } else { - tp.SetOrientation(TRIANGULATOR_CW); + tp.SetOrientation(TPPL_ORIENTATION_CW); tp.SetHole(true); } in_poly.push_back(tp); } - TriangulatorPartition tpart; + TPPLPartition tpart; if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed! ERR_PRINT("NavigationPolygon: Convex partition failed!"); return; @@ -304,8 +304,8 @@ void NavigationPolygon::make_polygons_from_outlines() { vertices.resize(0); Map<Vector2, int> points; - for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { - TriangulatorPoly &tp = I->get(); + for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) { + TPPLPoly &tp = I->get(); struct Polygon p; @@ -481,7 +481,6 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_ } _navpoly_changed(); - _change_notify("navpoly"); update_configuration_warning(); } diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 70a4e3f0fb..bf311632c8 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -53,12 +53,6 @@ void Node2D::_edit_set_state(const Dictionary &p_state) { skew = p_state["skew"]; _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); - _change_notify("scale"); - _change_notify("skew"); - _change_notify("skew_degrees"); - _change_notify("position"); } void Node2D::_edit_set_position(const Point2 &p_position) { @@ -80,8 +74,6 @@ Size2 Node2D::_edit_get_scale() const { void Node2D::_edit_set_rotation(float p_rotation) { angle = p_rotation; _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); } float Node2D::_edit_get_rotation() const { @@ -124,8 +116,6 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { _scale *= new_scale; _update_transform(); - _change_notify("scale"); - _change_notify("position"); } #endif @@ -156,7 +146,6 @@ void Node2D::set_position(const Point2 &p_pos) { } pos = p_pos; _update_transform(); - _change_notify("position"); } void Node2D::set_rotation(float p_radians) { @@ -165,8 +154,6 @@ void Node2D::set_rotation(float p_radians) { } angle = p_radians; _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); } void Node2D::set_skew(float p_radians) { @@ -175,8 +162,6 @@ void Node2D::set_skew(float p_radians) { } skew = p_radians; _update_transform(); - _change_notify("skew"); - _change_notify("skew_degrees"); } void Node2D::set_rotation_degrees(float p_degrees) { @@ -200,7 +185,6 @@ void Node2D::set_scale(const Size2 &p_scale) { _scale.y = CMP_EPSILON; } _update_transform(); - _change_notify("scale"); } Point2 Node2D::get_position() const { @@ -358,7 +342,6 @@ void Node2D::set_z_index(int p_z) { ERR_FAIL_COND(p_z > RS::CANVAS_ITEM_Z_MAX); z_index = p_z; RS::get_singleton()->canvas_item_set_z_index(get_canvas_item(), z_index); - _change_notify("z_index"); } void Node2D::set_z_as_relative(bool p_enabled) { diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index a5ae5dae0e..c27d740b8a 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -37,9 +37,9 @@ class Node2D : public CanvasItem { GDCLASS(Node2D, CanvasItem); Point2 pos; - float angle = 0; + float angle = 0.0; Size2 _scale = Vector2(1, 1); - float skew = 0; + float skew = 0.0; int z_index = 0; bool z_relative = true; diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index a35ffaa668..c93915d1bc 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -185,9 +185,5 @@ void ParallaxBackground::_bind_methods() { } ParallaxBackground::ParallaxBackground() { - scale = 1.0; set_layer(-100); //behind all by default - - base_scale = Vector2(1, 1); - ignore_camera_zoom = false; } diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 578e615be9..c9991efc9d 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -39,15 +39,15 @@ class ParallaxBackground : public CanvasLayer { GDCLASS(ParallaxBackground, CanvasLayer); Point2 offset; - float scale; + float scale = 1.0; Point2 base_offset; - Point2 base_scale; + Point2 base_scale = Vector2(1, 1); Point2 screen_offset; String group_name; Point2 limit_begin; Point2 limit_end; Point2 final_offset; - bool ignore_camera_zoom; + bool ignore_camera_zoom = false; void _update_scroll(); diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 129082cb91..a38338e1e3 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -163,5 +163,4 @@ void ParallaxLayer::_bind_methods() { } ParallaxLayer::ParallaxLayer() { - motion_scale = Size2(1, 1); } diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index b6895b0aca..86694c7724 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -38,7 +38,7 @@ class ParallaxLayer : public Node2D { Point2 orig_offset; Point2 orig_scale; - Size2 motion_scale; + Size2 motion_scale = Size2(1, 1); Vector2 motion_offset; Vector2 mirroring; void _update_mirroring(); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 41c91115ad..724998641f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -240,7 +240,7 @@ bool PathFollow2D::get_cubic_interpolation() const { void PathFollow2D::_validate_property(PropertyInfo &property) const { if (property.name == "offset") { - float max = 10000; + float max = 10000.0; if (path && path->get_curve().is_valid()) { max = path->get_curve()->get_baked_length(); } @@ -319,8 +319,6 @@ void PathFollow2D::set_offset(float p_offset) { _update_transform(); } - _change_notify("offset"); - _change_notify("unit_offset"); } void PathFollow2D::set_h_offset(float p_h_offset) { diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 3c5e0e4180..a748817555 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -64,10 +64,10 @@ class PathFollow2D : public Node2D { public: private: Path2D *path = nullptr; - real_t offset = 0; - real_t h_offset = 0; - real_t v_offset = 0; - real_t lookahead = 4; + real_t offset = 0.0; + real_t h_offset = 0.0; + real_t v_offset = 0.0; + real_t lookahead = 4.0; bool cubic = true; bool loop = true; bool rotates = true; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index a65009d072..96d8fb609b 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -111,8 +111,6 @@ bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const { PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : CollisionObject2D(PhysicsServer2D::get_singleton()->body_create(), false) { PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), p_mode); - collision_layer = 1; - collision_mask = 1; set_pickable(false); } @@ -197,7 +195,6 @@ void StaticBody2D::_bind_methods() { StaticBody2D::StaticBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) { - constant_angular_velocity = 0; } StaticBody2D::~StaticBody2D() { @@ -320,11 +317,11 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap struct _RigidBody2DInOut { ObjectID id; - int shape; - int local_shape; + int shape = 0; + int local_shape = 0; }; -bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { +bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { PhysicsServer2D::MotionResult *r = nullptr; if (p_result.is_valid()) { r = p_result->get_result_ptr(); @@ -611,7 +608,7 @@ void RigidBody2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_posit PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position); } -void RigidBody2D::apply_torque_impulse(float p_torque) { +void RigidBody2D::apply_torque_impulse(real_t p_torque) { PhysicsServer2D::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque); } @@ -623,11 +620,11 @@ Vector2 RigidBody2D::get_applied_force() const { return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid()); }; -void RigidBody2D::set_applied_torque(const float p_torque) { +void RigidBody2D::set_applied_torque(const real_t p_torque) { PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque); }; -float RigidBody2D::get_applied_torque() const { +real_t RigidBody2D::get_applied_torque() const { return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid()); }; @@ -639,7 +636,7 @@ void RigidBody2D::add_force(const Vector2 &p_force, const Vector2 &p_position) { PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_force, p_position); } -void RigidBody2D::add_torque(const float p_torque) { +void RigidBody2D::add_torque(const real_t p_torque) { PhysicsServer2D::get_singleton()->body_add_torque(get_rid(), p_torque); } @@ -841,25 +838,6 @@ void RigidBody2D::_bind_methods() { RigidBody2D::RigidBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { - mode = MODE_RIGID; - - mass = 1; - - gravity_scale = 1; - linear_damp = -1; - angular_damp = -1; - - max_contacts_reported = 0; - state = nullptr; - - angular_velocity = 0; - sleeping = false; - ccd_mode = CCD_MODE_DISABLED; - - custom_integrator = false; - contact_monitor = nullptr; - can_sleep = true; - PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -906,7 +884,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision Vector2 recover; int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; - float deepest_depth; + real_t deepest_depth; for (int i = 0; i < hits; i++) { if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) { deepest = i; @@ -966,7 +944,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector2 body_velocity = p_linear_velocity; Vector2 body_velocity_normal = body_velocity.normalized(); Vector2 up_direction = p_up_direction.normalized(); @@ -1057,7 +1035,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const return body_velocity; } -Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector2 up_direction = p_up_direction.normalized(); bool was_on_floor = on_floor; @@ -1123,11 +1101,11 @@ bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_moti return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin); } -void KinematicBody2D::set_safe_margin(float p_margin) { +void KinematicBody2D::set_safe_margin(real_t p_margin) { margin = p_margin; } -float KinematicBody2D::get_safe_margin() const { +real_t KinematicBody2D::get_safe_margin() const { return margin; } @@ -1219,8 +1197,8 @@ void KinematicBody2D::_notification(int p_what) { void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true)); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 159f73b269..2dc853b23b 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -41,8 +41,8 @@ class KinematicCollision2D; class PhysicsBody2D : public CollisionObject2D { GDCLASS(PhysicsBody2D, CollisionObject2D); - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; protected: void _notification(int p_what); @@ -74,7 +74,7 @@ class StaticBody2D : public PhysicsBody2D { GDCLASS(StaticBody2D, PhysicsBody2D); Vector2 constant_linear_velocity; - real_t constant_angular_velocity; + real_t constant_angular_velocity = 0.0; Ref<PhysicsMaterial> physics_material_override; @@ -116,30 +116,30 @@ public: }; private: - bool can_sleep; - PhysicsDirectBodyState2D *state; - Mode mode; + bool can_sleep = true; + PhysicsDirectBodyState2D *state = nullptr; + Mode mode = MODE_RIGID; - real_t mass; + real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; - real_t gravity_scale; - real_t linear_damp; - real_t angular_damp; + real_t gravity_scale = 1.0; + real_t linear_damp = -1.0; + real_t angular_damp = -1.0; Vector2 linear_velocity; - real_t angular_velocity; - bool sleeping; + real_t angular_velocity = 0.0; + bool sleeping = false; - int max_contacts_reported; + int max_contacts_reported = 0; - bool custom_integrator; + bool custom_integrator = false; - CCDMode ccd_mode; + CCDMode ccd_mode = CCD_MODE_DISABLED; struct ShapePair { - int body_shape; - int local_shape; - bool tagged; + int body_shape = 0; + int local_shape = 0; + bool tagged = false; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return local_shape < p_sp.local_shape; @@ -160,23 +160,23 @@ private: }; struct BodyState { //int rc; - bool in_scene; + bool in_scene = false; VSet<ShapePair> shapes; }; struct ContactMonitor { - bool locked; + bool locked = false; Map<ObjectID, BodyState> body_map; }; - ContactMonitor *contact_monitor; + ContactMonitor *contact_monitor = nullptr; void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape); void _direct_state_changed(Object *p_state); - bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, float p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); + bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); protected: void _notification(int p_what); @@ -232,17 +232,17 @@ public: void apply_central_impulse(const Vector2 &p_impulse); void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()); - void apply_torque_impulse(float p_torque); + void apply_torque_impulse(real_t p_torque); void set_applied_force(const Vector2 &p_force); Vector2 get_applied_force() const; - void set_applied_torque(const float p_torque); - float get_applied_torque() const; + void set_applied_torque(const real_t p_torque); + real_t get_applied_torque() const; void add_central_force(const Vector2 &p_force); void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()); - void add_torque(float p_torque); + void add_torque(real_t p_torque); TypedArray<Node2D> get_colliding_bodies() const; //function for script @@ -268,15 +268,15 @@ public: Vector2 collider_vel; ObjectID collider; RID collider_rid; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; Vector2 remainder; Vector2 travel; - int local_shape; + int local_shape = 0; }; private: - float margin; + real_t margin; Vector2 floor_normal; Vector2 floor_velocity; @@ -309,11 +309,11 @@ public: bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); - void set_safe_margin(float p_margin); - float get_safe_margin() const; + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); + Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 82e1b7ac96..ecc05fb931 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -155,7 +155,7 @@ void Polygon2D::_notification(int p_what) { Rect2 bounds; int highest_idx = -1; float highest_y = -1e20; - float sum = 0; + float sum = 0.0; for (int i = 0; i < len; i++) { if (i == 0) { @@ -273,7 +273,7 @@ void Polygon2D::_notification(int p_what) { //normalize the weights for (int i = 0; i < vc; i++) { - float tw = 0; + float tw = 0.0; for (int j = 0; j < 4; j++) { tw += weightsw[i * 4 + j]; } @@ -483,7 +483,6 @@ void Polygon2D::set_offset(const Vector2 &p_offset) { offset = p_offset; rect_cache_dirty = true; update(); - _change_notify("offset"); } Vector2 Polygon2D::get_offset() const { @@ -649,13 +648,4 @@ void Polygon2D::_bind_methods() { } Polygon2D::Polygon2D() { - invert = false; - invert_border = 100; - antialiased = false; - tex_rot = 0; - tex_tile = true; - tex_scale = Vector2(1, 1); - color = Color(1, 1, 1); - rect_cache_dirty = true; - internal_vertices = 0; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index cdb3052225..ab01a4ffd0 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -40,7 +40,7 @@ class Polygon2D : public Node2D { Vector<Vector2> uv; Vector<Color> vertex_colors; Array polygons; - int internal_vertices; + int internal_vertices = 0; struct Bone { NodePath path; @@ -49,19 +49,19 @@ class Polygon2D : public Node2D { Vector<Bone> bone_weights; - Color color; + Color color = Color(1, 1, 1); Ref<Texture2D> texture; - Size2 tex_scale; + Size2 tex_scale = Vector2(1, 1); Vector2 tex_ofs; - bool tex_tile; - float tex_rot; - bool invert; - float invert_border; - bool antialiased; + bool tex_tile = true; + float tex_rot = 0.0; + bool invert = false; + float invert_border = 100.0; + bool antialiased = false; Vector2 offset; - mutable bool rect_cache_dirty; + mutable bool rect_cache_dirty = true; mutable Rect2 item_rect; NodePath skeleton; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 2c4a549acf..2cc3a74270 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -173,7 +173,7 @@ void RayCast2D::_notification(int p_what) { } draw_line(Vector2(), target_position, draw_col, 2); Vector<Vector2> pts; - float tsize = 8; + float tsize = 8.0; pts.push_back(xf.xform(Vector2(tsize, 0))); pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize))); pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize))); @@ -325,12 +325,4 @@ void RayCast2D::_bind_methods() { } RayCast2D::RayCast2D() { - enabled = true; - collided = false; - against_shape = 0; - collision_mask = 1; - target_position = Vector2(0, 50); - exclude_parent_body = true; - collide_with_bodies = true; - collide_with_areas = false; } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index ff7a970ebf..dab3302e25 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -36,20 +36,20 @@ class RayCast2D : public Node2D { GDCLASS(RayCast2D, Node2D); - bool enabled; - bool collided; + bool enabled = true; + bool collided = false; ObjectID against; - int against_shape; + int against_shape = 0; Vector2 collision_point; Vector2 collision_normal; Set<RID> exclude; - uint32_t collision_mask; - bool exclude_parent_body; + uint32_t collision_mask = 1; + bool exclude_parent_body = true; - Vector2 target_position; + Vector2 target_position = Vector2(0, 50); - bool collide_with_areas; - bool collide_with_bodies; + bool collide_with_areas = false; + bool collide_with_bodies = true; protected: void _notification(int p_what); diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 4ed4c3a8ff..f10714e28a 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -223,10 +223,5 @@ void RemoteTransform2D::_bind_methods() { } RemoteTransform2D::RemoteTransform2D() { - use_global_coordinates = true; - update_remote_position = true; - update_remote_rotation = true; - update_remote_scale = true; - set_notify_transform(true); } diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index cb4bd37f1f..4a26d7b339 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -40,10 +40,10 @@ class RemoteTransform2D : public Node2D { ObjectID cache; - bool use_global_coordinates; - bool update_remote_position; - bool update_remote_rotation; - bool update_remote_scale; + bool use_global_coordinates = true; + bool update_remote_position = true; + bool update_remote_rotation = true; + bool update_remote_scale = true; void _update_remote(); void _update_cache(); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index bb5a309f65..5728230a8c 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -157,10 +157,6 @@ String Bone2D::get_configuration_warning() const { } Bone2D::Bone2D() { - skeleton = nullptr; - parent_bone = nullptr; - skeleton_index = -1; - default_length = 16; set_notify_local_transform(true); //this is a clever hack so the bone knows no rest has been set yet, allowing to show an error. for (int i = 0; i < 3; i++) { @@ -186,7 +182,7 @@ void Skeleton2D::_update_bone_setup() { } bone_setup_dirty = false; - RS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true); + RS::get_singleton()->skeleton_allocate_data(skeleton, bones.size(), true); bones.sort(); //sorty so they are always in the same order/index @@ -293,9 +289,6 @@ void Skeleton2D::_bind_methods() { } Skeleton2D::Skeleton2D() { - bone_setup_dirty = true; - transform_dirty = true; - skeleton = RS::get_singleton()->skeleton_create(); set_notify_transform(true); } diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index 36b9e1b339..80ca8c80ac 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -43,12 +43,12 @@ class Bone2D : public Node2D { friend class AnimatedValuesBackup; #endif - Bone2D *parent_bone; - Skeleton2D *skeleton; + Bone2D *parent_bone = nullptr; + Skeleton2D *skeleton = nullptr; Transform2D rest; - float default_length; + float default_length = 16.0; - int skeleton_index; + int skeleton_index = -1; protected: void _notification(int p_what); @@ -82,19 +82,19 @@ class Skeleton2D : public Node2D { bool operator<(const Bone &p_bone) const { return p_bone.bone->is_greater_than(bone); } - Bone2D *bone; - int parent_index; + Bone2D *bone = nullptr; + int parent_index = 0; Transform2D accum_transform; Transform2D rest_inverse; }; Vector<Bone> bones; - bool bone_setup_dirty; + bool bone_setup_dirty = true; void _make_bone_setup_dirty(); void _update_bone_setup(); - bool transform_dirty; + bool transform_dirty = true; void _make_transform_dirty(); void _update_transform(); diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index 773214deeb..dde9790b44 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -155,7 +155,6 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { update(); emit_signal("texture_changed"); item_rect_changed(); - _change_notify("texture"); } Ref<Texture2D> Sprite2D::get_texture() const { @@ -176,7 +175,6 @@ void Sprite2D::set_offset(const Point2 &p_offset) { offset = p_offset; update(); item_rect_changed(); - _change_notify("offset"); } Point2 Sprite2D::get_offset() const { @@ -224,8 +222,6 @@ void Sprite2D::set_region_rect(const Rect2 &p_region_rect) { if (region) { item_rect_changed(); } - - _change_notify("region_rect"); } Rect2 Sprite2D::get_region_rect() const { @@ -250,8 +246,6 @@ void Sprite2D::set_frame(int p_frame) { frame = p_frame; - _change_notify("frame"); - _change_notify("frame_coords"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -275,7 +269,7 @@ void Sprite2D::set_vframes(int p_amount) { vframes = p_amount; update(); item_rect_changed(); - _change_notify(); + notify_property_list_changed(); } int Sprite2D::get_vframes() const { @@ -287,7 +281,7 @@ void Sprite2D::set_hframes(int p_amount) { hframes = p_amount; update(); item_rect_changed(); - _change_notify(); + notify_property_list_changed(); } int Sprite2D::get_hframes() const { @@ -462,16 +456,6 @@ void Sprite2D::_bind_methods() { } Sprite2D::Sprite2D() { - centered = true; - hflip = false; - vflip = false; - region = false; - region_filter_clip = false; - - frame = 0; - - vframes = 1; - hframes = 1; } Sprite2D::~Sprite2D() { diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h index 716882d485..fa765f457d 100644 --- a/scene/2d/sprite_2d.h +++ b/scene/2d/sprite_2d.h @@ -39,21 +39,21 @@ class Sprite2D : public Node2D { Ref<Texture2D> texture; Color specular_color; - float shininess; + float shininess = 0.0; - bool centered; + bool centered = true; Point2 offset; - bool hflip; - bool vflip; - bool region; + bool hflip = false; + bool vflip = false; + bool region = false; Rect2 region_rect; - bool region_filter_clip; + bool region_filter_clip = false; - int frame; + int frame = 0; - int vframes; - int hframes; + int vframes = 1; + int hframes = 1; void _get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 01b7a9c260..d868ebae25 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -165,7 +165,6 @@ void TileMap::_update_quadrant_transform() { void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { if (tile_set.is_valid()) { tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); - tile_set->remove_change_receptor(this); } _clear_quadrants(); @@ -173,7 +172,6 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { if (tile_set.is_valid()) { tile_set->connect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); - tile_set->add_change_receptor(this); } else { clear(); } @@ -1330,7 +1328,7 @@ void TileMap::set_collision_use_parent(bool p_use_parent) { } _recreate_quadrants(); - _change_notify(); + notify_property_list_changed(); update_configuration_warning(); } @@ -1865,47 +1863,11 @@ void TileMap::_bind_methods() { BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT); } -void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { - if (tile_set.is_valid() && tile_set.ptr() == p_changed) { - emit_signal("settings_changed"); - } -} - TileMap::TileMap() { - rect_cache_dirty = true; - used_size_cache_dirty = true; - pending_update = false; - quadrant_order_dirty = false; - quadrant_size = 16; - cell_size = Size2(64, 64); - custom_transform = Transform2D(64, 0, 0, 64, 0, 0); - collision_layer = 1; - collision_mask = 1; - friction = 1; - bounce = 0; - mode = MODE_SQUARE; - half_offset = HALF_OFFSET_DISABLED; - use_parent = false; - collision_parent = nullptr; - use_kinematic = false; - navigation = nullptr; - use_y_sort = false; - compatibility_mode = false; - centered_textures = false; - occluder_light_mask = 1; - clip_uv = false; - format = FORMAT_1; // Assume lowest possible format if none is present - - fp_adjust = 0.00001; - tile_origin = TILE_ORIGIN_TOP_LEFT; set_notify_transform(true); set_notify_local_transform(false); } TileMap::~TileMap() { - if (tile_set.is_valid()) { - tile_set->remove_change_receptor(this); - } - clear(); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index b1e54aafae..3bf4587921 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -70,22 +70,22 @@ private: }; Ref<TileSet> tile_set; - Size2i cell_size; - int quadrant_size; - Mode mode; - Transform2D custom_transform; - HalfOffset half_offset; - bool use_parent; - CollisionObject2D *collision_parent; - bool use_kinematic; - Navigation2D *navigation; + Size2i cell_size = Size2(64, 64); + int quadrant_size = 16; + Mode mode = MODE_SQUARE; + Transform2D custom_transform = Transform2D(64, 0, 0, 64, 0, 0); + HalfOffset half_offset = HALF_OFFSET_DISABLED; + bool use_parent = false; + CollisionObject2D *collision_parent = nullptr; + bool use_kinematic = false; + Navigation2D *navigation = nullptr; union PosKey { struct { int16_t x; int16_t y; }; - uint32_t key; + uint32_t key = 0; //using a more precise comparison so the regions can be sorted later bool operator<(const PosKey &p_k) const { return (y == p_k.y) ? x < p_k.x : y < p_k.y; } @@ -119,8 +119,7 @@ private: int16_t autotile_coord_y : 16; }; - uint64_t _u64t; - Cell() { _u64t = 0; } + uint64_t _u64t = 0; }; Map<PosKey, Cell> tile_map; @@ -130,7 +129,7 @@ private: Vector2 pos; List<RID> canvas_items; RID body; - uint32_t shape_owner_id; + uint32_t shape_owner_id = 0; SelfList<Quadrant> dirty_list; @@ -176,27 +175,27 @@ private: SelfList<Quadrant>::List dirty_quadrant_list; - bool pending_update; + bool pending_update = false; Rect2 rect_cache; - bool rect_cache_dirty; + bool rect_cache_dirty = true; Rect2 used_size_cache; - bool used_size_cache_dirty; - bool quadrant_order_dirty; - bool use_y_sort; - bool compatibility_mode; - bool centered_textures; - bool clip_uv; - float fp_adjust; - float friction; - float bounce; - uint32_t collision_layer; - uint32_t collision_mask; - mutable DataFormat format; - - TileOrigin tile_origin; - - int occluder_light_mask; + bool used_size_cache_dirty = true; + bool quadrant_order_dirty = false; + bool use_y_sort = false; + bool compatibility_mode = false; + bool centered_textures = false; + bool clip_uv = false; + float fp_adjust = 0.00001; + float friction = 1.0; + float bounce = 0.0; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; + mutable DataFormat format = FORMAT_1; // Assume lowest possible format if none is present + + TileOrigin tile_origin = TILE_ORIGIN_TOP_LEFT; + + int occluder_light_mask = 1; void _fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc); @@ -233,7 +232,6 @@ protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; public: enum { diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 04a1aedcd3..9d6868a1b2 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -129,8 +129,11 @@ void TouchScreenButton::_notification(int p_what) { if (shape.is_valid()) { Color draw_col = get_tree()->get_debug_collisions_color(); - Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size(); - Vector2 pos = shape_centered ? size * 0.5f : Vector2(); + Vector2 pos; + if (shape_centered && texture.is_valid()) { + pos = texture->get_size() * 0.5; + } + draw_set_transform_matrix(get_canvas_transform().translated(pos)); shape->draw(get_canvas_item(), draw_col); } @@ -251,9 +254,12 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { if (shape.is_valid()) { check_rect = false; - Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size(); - Transform2D xform = shape_centered ? Transform2D().translated(size * 0.5f) : Transform2D(); - touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); + Vector2 pos; + if (shape_centered && texture.is_valid()) { + pos = texture->get_size() * 0.5; + } + + touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); } if (bitmask.is_valid()) { @@ -399,11 +405,6 @@ void TouchScreenButton::_bind_methods() { } TouchScreenButton::TouchScreenButton() { - finger_pressed = -1; - passby_press = false; - visibility = VISIBILITY_ALWAYS; - shape_centered = true; - shape_visible = true; unit_rect = Ref<RectangleShape2D>(memnew(RectangleShape2D)); unit_rect->set_size(Vector2(1, 1)); } diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index f4ae3ca26c..10820ad059 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -50,16 +50,16 @@ private: Ref<Texture2D> texture_pressed; Ref<BitMap> bitmask; Ref<Shape2D> shape; - bool shape_centered; - bool shape_visible; + bool shape_centered = true; + bool shape_visible = true; Ref<RectangleShape2D> unit_rect; StringName action; - bool passby_press; - int finger_pressed; + bool passby_press = false; + int finger_pressed = -1; - VisibilityMode visibility; + VisibilityMode visibility = VISIBILITY_ALWAYS; void _input(const Ref<InputEvent> &p_event); diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index f3dddd5af8..916038a1f3 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -89,8 +89,6 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { item_rect_changed(); } } - - _change_notify("rect"); } Rect2 VisibilityNotifier2D::get_rect() const { @@ -363,6 +361,4 @@ VisibilityEnabler2D::VisibilityEnabler2D() { } enabler[ENABLER_PARENT_PROCESS] = false; enabler[ENABLER_PARENT_PHYSICS_PROCESS] = false; - - visible = false; } diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index ea3b5df37b..3d1701a1e5 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -85,7 +85,7 @@ protected: virtual void _screen_enter() override; virtual void _screen_exit() override; - bool visible; + bool visible = false; void _find_nodes(Node *p_node); diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp index 987e4581f4..7e7bc27cc2 100644 --- a/scene/2d/y_sort.cpp +++ b/scene/2d/y_sort.cpp @@ -48,6 +48,5 @@ void YSort::_bind_methods() { } YSort::YSort() { - sort_enabled = true; RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true); } diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h index 0882a88e3a..7d36ee3391 100644 --- a/scene/2d/y_sort.h +++ b/scene/2d/y_sort.h @@ -35,7 +35,7 @@ class YSort : public Node2D { GDCLASS(YSort, Node2D); - bool sort_enabled; + bool sort_enabled = true; static void _bind_methods(); public: diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index b69357387e..23eda379be 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -640,13 +640,13 @@ void Area3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area3D::set_reverb_uniformity); ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area3D::get_reverb_uniformity); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); - ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); + ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); - ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape"))); - ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"))); ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"))); @@ -681,29 +681,10 @@ void Area3D::_bind_methods() { Area3D::Area3D() : CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) { - space_override = SPACE_OVERRIDE_DISABLED; set_gravity(9.8); - locked = false; set_gravity_vector(Vector3(0, -1, 0)); - gravity_is_point = false; - gravity_distance_scale = 0; - linear_damp = 0.1; - angular_damp = 0.1; - priority = 0; - monitoring = false; - monitorable = false; - collision_mask = 1; - collision_layer = 1; set_monitoring(true); set_monitorable(true); - - audio_bus_override = false; - audio_bus = "Master"; - - use_reverb_bus = false; - reverb_bus = "Master"; - reverb_amount = 0.0; - reverb_uniformity = 0.0; } Area3D::~Area3D() { diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 5d8e1933ba..6d976115f7 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -47,19 +47,19 @@ public: }; private: - SpaceOverride space_override; + SpaceOverride space_override = SPACE_OVERRIDE_DISABLED; Vector3 gravity_vec; real_t gravity; - bool gravity_is_point; - real_t gravity_distance_scale; - real_t angular_damp; - real_t linear_damp; - uint32_t collision_mask; - uint32_t collision_layer; - int priority; - bool monitoring; - bool monitorable; - bool locked; + bool gravity_is_point = false; + real_t gravity_distance_scale = 0.0; + real_t angular_damp = 0.1; + real_t linear_damp = 0.1; + uint32_t collision_mask = 1; + uint32_t collision_layer = 1; + int priority = 0; + bool monitoring = false; + bool monitorable = false; + bool locked = false; void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); @@ -67,8 +67,8 @@ private: void _body_exit_tree(ObjectID p_id); struct ShapePair { - int body_shape; - int area_shape; + int body_shape = 0; + int area_shape = 0; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return area_shape < p_sp.area_shape; @@ -85,8 +85,8 @@ private: }; struct BodyState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<ShapePair> shapes; }; @@ -98,8 +98,8 @@ private: void _area_exit_tree(ObjectID p_id); struct AreaShapePair { - int area_shape; - int self_shape; + int area_shape = 0; + int self_shape = 0; bool operator<(const AreaShapePair &p_sp) const { if (area_shape == p_sp.area_shape) { return self_shape < p_sp.self_shape; @@ -116,21 +116,21 @@ private: }; struct AreaState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<AreaShapePair> shapes; }; Map<ObjectID, AreaState> area_map; void _clear_monitoring(); - bool audio_bus_override; - StringName audio_bus; + bool audio_bus_override = false; + StringName audio_bus = "Master"; - bool use_reverb_bus; - StringName reverb_bus; - float reverb_amount; - float reverb_uniformity; + bool use_reverb_bus = false; + StringName reverb_bus = "Master"; + float reverb_amount = 0.0; + float reverb_uniformity = 0.0; void _validate_property(PropertyInfo &property) const override; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 2bcf898ced..72392be5bd 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -42,8 +42,8 @@ class Spcap { private: struct Speaker { Vector3 direction; - real_t effective_number_of_speakers; // precalculated - mutable real_t squared_gain; // temporary + real_t effective_number_of_speakers = 0; // precalculated + mutable real_t squared_gain = 0; // temporary }; Vector<Speaker> speakers; @@ -138,15 +138,15 @@ void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tig } void AudioStreamPlayer3D::_mix_audio() { - if (!stream_playback.is_valid() || !active || + if (!stream_playback.is_valid() || !active.is_set() || (stream_paused && !stream_paused_fade_out)) { return; } bool started = false; - if (setseek >= 0.0) { - stream_playback->start(setseek); - setseek = -1.0; //reset seek + if (setseek.get() >= 0.0) { + stream_playback->start(setseek.get()); + setseek.set(-1.0); //reset seek started = true; } @@ -160,14 +160,14 @@ void AudioStreamPlayer3D::_mix_audio() { } // Mix if we're not paused or we're fading out - if ((output_count > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) { + if ((output_count.get() > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) { float output_pitch_scale = 0.0; - if (output_count) { + if (output_count.get()) { //used for doppler, not realistic but good enough - for (int i = 0; i < output_count; i++) { + for (int i = 0; i < output_count.get(); i++) { output_pitch_scale += outputs[i].pitch_scale; } - output_pitch_scale /= float(output_count); + output_pitch_scale /= float(output_count.get()); } else { output_pitch_scale = 1.0; } @@ -176,7 +176,7 @@ void AudioStreamPlayer3D::_mix_audio() { } //write all outputs - for (int i = 0; i < output_count; i++) { + for (int i = 0; i < output_count.get(); i++) { Output current = outputs[i]; //see if current output exists, to keep volume ramp @@ -285,14 +285,14 @@ void AudioStreamPlayer3D::_mix_audio() { prev_outputs[i] = current; } - prev_output_count = output_count; + prev_output_count = output_count.get(); //stream is no longer active, disable this. if (!stream_playback->is_playing()) { - active = false; + active.clear(); } - output_ready = false; + output_ready.clear(); stream_paused_fade_in = false; stream_paused_fade_out = false; } @@ -360,7 +360,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { //update anything related to position first, if possible of course - if (!output_ready) { + if (!output_ready.is_set()) { Vector3 linear_velocity; //compute linear velocity for doppler @@ -596,24 +596,20 @@ void AudioStreamPlayer3D::_notification(int p_what) { } } - output_count = new_output_count; - output_ready = true; + output_count.set(new_output_count); + output_ready.set(); } //start playing if requested - if (setplay >= 0.0) { - setseek = setplay; - active = true; - setplay = -1; - //do not update, this makes it easier to animate (will shut off otherwise) - ///_change_notify("playing"); //update property in editor + if (setplay.get() >= 0.0) { + setseek.set(setplay.get()); + active.set(); + setplay.set(-1); } //stop playing if no longer active - if (!active) { + if (!active.is_set()) { set_physics_process_internal(false); - //do not update, this makes it easier to animate (will shut off otherwise) - //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -627,8 +623,8 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) { if (stream_playback.is_valid()) { stream_playback.unref(); stream.unref(); - active = false; - setseek = -1; + active.clear(); + setseek.set(-1); } if (p_stream.is_valid()) { @@ -687,30 +683,29 @@ void AudioStreamPlayer3D::play(float p_from_pos) { } if (stream_playback.is_valid()) { - active = true; - setplay = p_from_pos; - output_ready = false; + setplay.set(p_from_pos); + output_ready.clear(); set_physics_process_internal(true); } } void AudioStreamPlayer3D::seek(float p_seconds) { if (stream_playback.is_valid()) { - setseek = p_seconds; + setseek.set(p_seconds); } } void AudioStreamPlayer3D::stop() { if (stream_playback.is_valid()) { - active = false; + active.clear(); set_physics_process_internal(false); - setplay = -1; + setplay.set(-1); } } bool AudioStreamPlayer3D::is_playing() const { if (stream_playback.is_valid()) { - return active; // && stream_playback->is_playing(); + return active.is_set() || setplay.get() >= 0; } return false; @@ -718,6 +713,10 @@ bool AudioStreamPlayer3D::is_playing() const { float AudioStreamPlayer3D::get_playback_position() { if (stream_playback.is_valid()) { + float ss = setseek.get(); + if (ss >= 0.0) { + return ss; + } return stream_playback->get_playback_position(); } @@ -757,7 +756,7 @@ void AudioStreamPlayer3D::_set_playing(bool p_enable) { } bool AudioStreamPlayer3D::_is_active() const { - return active; + return active.is_set(); } void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const { @@ -776,7 +775,7 @@ void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer3D::_bus_layout_changed() { - _change_notify(); + notify_property_list_changed(); } void AudioStreamPlayer3D::set_max_distance(float p_metres) { @@ -809,7 +808,6 @@ void AudioStreamPlayer3D::set_emission_angle(float p_angle) { ERR_FAIL_COND(p_angle < 0 || p_angle > 90); emission_angle = p_angle; update_gizmo(); - _change_notify("emission_angle"); } float AudioStreamPlayer3D::get_emission_angle() const { @@ -1002,31 +1000,6 @@ void AudioStreamPlayer3D::_bind_methods() { } AudioStreamPlayer3D::AudioStreamPlayer3D() { - unit_db = 0; - unit_size = 1; - attenuation_model = ATTENUATION_INVERSE_DISTANCE; - max_db = 3; - pitch_scale = 1.0; - autoplay = false; - setseek = -1; - active = false; - output_count = 0; - prev_output_count = 0; - max_distance = 0; - setplay = -1; - output_ready = false; - area_mask = 1; - emission_angle = 45; - emission_angle_enabled = false; - emission_angle_filter_attenuation_db = -12; - attenuation_filter_cutoff_hz = 5000; - attenuation_filter_db = -24; - out_of_range_mode = OUT_OF_RANGE_MIX; - doppler_tracking = DOPPLER_TRACKING_DISABLED; - stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; - velocity_tracker.instance(); AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed)); set_disable_scale(true); diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index bcfe2b2229..70c535bd89 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -31,6 +31,7 @@ #ifndef AUDIO_STREAM_PLAYER_3D_H #define AUDIO_STREAM_PLAYER_3D_H +#include "core/templates/safe_refcount.h" #include "scene/3d/node_3d.h" #include "scene/3d/velocity_tracker_3d.h" #include "servers/audio/audio_filter_sw.h" @@ -71,46 +72,39 @@ private: AudioFilterSW filter; AudioFilterSW::Processor filter_process[8]; AudioFrame vol[4]; - float filter_gain; - float pitch_scale; - int bus_index; - int reverb_bus_index; + float filter_gain = 0.0; + float pitch_scale = 0.0; + int bus_index = -1; + int reverb_bus_index = -1; AudioFrame reverb_vol[4]; - Viewport *viewport; //pointer only used for reference to previous mix - - Output() { - filter_gain = 0; - viewport = nullptr; - reverb_bus_index = -1; - bus_index = -1; - } + Viewport *viewport = nullptr; //pointer only used for reference to previous mix }; Output outputs[MAX_OUTPUTS]; - volatile int output_count; - volatile bool output_ready; + SafeNumeric<int> output_count; + SafeFlag output_ready; //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks) Output prev_outputs[MAX_OUTPUTS]; - int prev_output_count; + int prev_output_count = 0; Ref<AudioStreamPlayback> stream_playback; Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; - volatile float setseek; - volatile bool active; - volatile float setplay; - - AttenuationModel attenuation_model; - float unit_db; - float unit_size; - float max_db; - float pitch_scale; - bool autoplay; - bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + SafeNumeric<float> setseek{ -1.0 }; + SafeFlag active; + SafeNumeric<float> setplay{ -1.0 }; + + AttenuationModel attenuation_model = ATTENUATION_INVERSE_DISTANCE; + float unit_db = 0.0; + float unit_size = 1.0; + float max_db = 3.0; + float pitch_scale = 1.0; + bool autoplay = false; + bool stream_paused = false; + bool stream_paused_fade_in = false; + bool stream_paused_fade_out = false; StringName bus; static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output); @@ -122,21 +116,21 @@ private: void _bus_layout_changed(); - uint32_t area_mask; + uint32_t area_mask = 1; - bool emission_angle_enabled; - float emission_angle; - float emission_angle_filter_attenuation_db; - float attenuation_filter_cutoff_hz; - float attenuation_filter_db; + bool emission_angle_enabled = false; + float emission_angle = 45.0; + float emission_angle_filter_attenuation_db = -12.0; + float attenuation_filter_cutoff_hz = 5000.0; + float attenuation_filter_db = -24.0; - float max_distance; + float max_distance = 0.0; Ref<VelocityTracker3D> velocity_tracker; - DopplerTracking doppler_tracking; + DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED; - OutOfRangeMode out_of_range_mode; + OutOfRangeMode out_of_range_mode = OUT_OF_RANGE_MIX; float _get_attenuation_db(float p_distance) const; diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 14c8755d99..578ea823f0 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -195,7 +195,7 @@ void BakedLightmapData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &BakedLightmapData::set_uses_spherical_harmonics); ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &BakedLightmapData::is_using_spherical_harmonics); - ClassDB::bind_method(D_METHOD("add_user", "path", "lightmap", "offset"), &BakedLightmapData::add_user); + ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &BakedLightmapData::add_user); ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count); ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path); ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users); @@ -1302,7 +1302,7 @@ bool BakedLightmap::is_interior() const { void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) { environment_mode = p_mode; - _change_notify(); + notify_property_list_changed(); } BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const { @@ -1466,17 +1466,4 @@ void BakedLightmap::_bind_methods() { } BakedLightmap::BakedLightmap() { - environment_mode = ENVIRONMENT_MODE_DISABLED; - environment_custom_color = Color(0.2, 0.7, 1.0); - environment_custom_energy = 1.0; - - bake_quality = BAKE_QUALITY_MEDIUM; - interior = false; - directional = false; - - gen_probes = GENERATE_PROBES_DISABLED; - use_denoiser = true; - bounces = 1; - bias = 0.0005; - max_texture_size = 16384; } diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index 7fd1cf892e..e2d89ab2d0 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -53,9 +53,9 @@ class BakedLightmapData : public Resource { struct User { NodePath path; - int32_t sub_instance; + int32_t sub_instance = 0; Rect2 uv_scale; - int slice_index; + int slice_index = 0; }; Vector<User> users; @@ -136,32 +136,32 @@ public: }; private: - BakeQuality bake_quality; - bool use_denoiser; - int bounces; - float bias; - int max_texture_size; - bool interior; - EnvironmentMode environment_mode; + BakeQuality bake_quality = BAKE_QUALITY_MEDIUM; + bool use_denoiser = true; + int bounces = 1; + float bias = 0.0005; + int max_texture_size = 16384; + bool interior = false; + EnvironmentMode environment_mode = ENVIRONMENT_MODE_DISABLED; Ref<Sky> environment_custom_sky; - Color environment_custom_color; - float environment_custom_energy; - bool directional; - GenerateProbes gen_probes; + Color environment_custom_color = Color(0.2, 0.7, 1.0); + float environment_custom_energy = 1.0; + bool directional = false; + GenerateProbes gen_probes = GENERATE_PROBES_DISABLED; Ref<BakedLightmapData> light_data; struct LightsFound { Transform xform; - Light3D *light; + Light3D *light = nullptr; }; struct MeshesFound { Transform xform; NodePath node_path; - int32_t subindex; + int32_t subindex = 0; Ref<Mesh> mesh; - int32_t lightmap_scale; + int32_t lightmap_scale = 0; Vector<Ref<Material>> overrides; }; @@ -172,19 +172,20 @@ private: struct BakeTimeData { String text; - int pass; - uint64_t last_step; + int pass = 0; + uint64_t last_step = 0; }; struct BSPSimplex { - int vertices[4]; - int planes[4]; + int vertices[4] = {}; + int planes[4] = {}; }; struct BSPNode { static const int32_t EMPTY_LEAF = INT32_MIN; Plane plane; - int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; + int32_t over = EMPTY_LEAF; + int32_t under = EMPTY_LEAF; }; int _bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const; @@ -192,16 +193,16 @@ private: struct BakeStepUD { Lightmapper::BakeStepFunc func; - void *ud; - float from_percent; - float to_percent; + void *ud = nullptr; + float from_percent = 0.0; + float to_percent = 0.0; }; static bool _lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh); struct GenProbesOctree { Vector3i offset; - uint32_t size; + uint32_t size = 0; GenProbesOctree *children[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; ~GenProbesOctree() { for (int i = 0; i < 8; i++) { diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 30fe1ecea8..5315e685a0 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -105,7 +105,6 @@ void BoneAttachment3D::_notification(int p_what) { } BoneAttachment3D::BoneAttachment3D() { - bound = false; } void BoneAttachment3D::_bind_methods() { diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index 0dddaa1028..0c6d5f12b1 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -36,7 +36,7 @@ class BoneAttachment3D : public Node3D { GDCLASS(BoneAttachment3D, Node3D); - bool bound; + bool bound = false; String bone_name; void _check_bind(); diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 53c3204b3e..f0623c625e 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -209,7 +209,7 @@ void Camera3D::set_projection(Camera3D::Projection p_mode) { if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) { mode = p_mode; _update_camera_mode(); - _change_notify(); + notify_property_list_changed(); } } @@ -432,7 +432,7 @@ void Camera3D::set_keep_aspect_mode(KeepAspect p_aspect) { keep_aspect = p_aspect; RenderingServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH); _update_camera_mode(); - _change_notify(); + notify_property_list_changed(); } Camera3D::KeepAspect Camera3D::get_keep_aspect_mode() const { @@ -562,14 +562,12 @@ void Camera3D::set_fov(float p_fov) { ERR_FAIL_COND(p_fov < 1 || p_fov > 179); fov = p_fov; _update_camera_mode(); - _change_notify("fov"); } void Camera3D::set_size(float p_size) { ERR_FAIL_COND(p_size < 0.1 || p_size > 16384); size = p_size; _update_camera_mode(); - _change_notify("size"); } void Camera3D::set_near(float p_near) { @@ -653,24 +651,10 @@ Vector3 Camera3D::get_doppler_tracked_velocity() const { Camera3D::Camera3D() { camera = RenderingServer::get_singleton()->camera_create(); - size = 1; - fov = 0; - frustum_offset = Vector2(); - near = 0; - far = 0; - current = false; - viewport = nullptr; - force_change = false; - mode = PROJECTION_PERSPECTIVE; set_perspective(75.0, 0.05, 4000.0); - keep_aspect = KEEP_HEIGHT; - layers = 0xfffff; - v_offset = 0; - h_offset = 0; RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers); //active=false; velocity_tracker.instance(); - doppler_tracking = DOPPLER_TRACKING_DISABLED; set_notify_transform(true); set_disable_scale(true); } @@ -689,17 +673,17 @@ float ClippedCamera3D::get_margin() const { return margin; } -void ClippedCamera3D::set_process_mode(ProcessMode p_mode) { - if (process_mode == p_mode) { +void ClippedCamera3D::set_process_callback(ClipProcessCallback p_mode) { + if (process_callback == p_mode) { return; } - process_mode = p_mode; - set_process_internal(process_mode == CLIP_PROCESS_IDLE); - set_physics_process_internal(process_mode == CLIP_PROCESS_PHYSICS); + process_callback = p_mode; + set_process_internal(process_callback == CLIP_PROCESS_IDLE); + set_physics_process_internal(process_callback == CLIP_PROCESS_PHYSICS); } -ClippedCamera3D::ProcessMode ClippedCamera3D::get_process_mode() const { - return process_mode; +ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() const { + return process_callback; } Transform ClippedCamera3D::get_camera_transform() const { @@ -844,8 +828,8 @@ void ClippedCamera3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera3D::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera3D::get_margin); - ClassDB::bind_method(D_METHOD("set_process_mode", "process_mode"), &ClippedCamera3D::set_process_mode); - ClassDB::bind_method(D_METHOD("get_process_mode"), &ClippedCamera3D::get_process_mode); + ClassDB::bind_method(D_METHOD("set_process_callback", "process_callback"), &ClippedCamera3D::set_process_callback); + ClassDB::bind_method(D_METHOD("get_process_callback"), &ClippedCamera3D::get_process_callback); ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera3D::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera3D::get_collision_mask); @@ -870,7 +854,7 @@ void ClippedCamera3D::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera3D::clear_exceptions); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_GROUP("Clip To", "clip_to"); @@ -882,16 +866,10 @@ void ClippedCamera3D::_bind_methods() { } ClippedCamera3D::ClippedCamera3D() { - margin = 0; - clip_offset = 0; - process_mode = CLIP_PROCESS_PHYSICS; set_physics_process_internal(true); - collision_mask = 1; set_notify_local_transform(Engine::get_singleton()->is_editor_hint()); points.resize(5); pyramid_shape = PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONVEX_POLYGON); - clip_to_areas = false; - clip_to_bodies = true; } ClippedCamera3D::~ClippedCamera3D() { diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index aa36c8800d..cea61e4db8 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -57,26 +57,27 @@ public: }; private: - bool force_change; - bool current; - Viewport *viewport; + bool force_change = false; + bool current = false; + Viewport *viewport = nullptr; - Projection mode; + Projection mode = PROJECTION_PERSPECTIVE; - float fov; - float size; + float fov = 0.0; + float size = 1.0; Vector2 frustum_offset; - float near, far; - float v_offset; - float h_offset; - KeepAspect keep_aspect; + float near = 0.0; + float far = 0.0; + float v_offset = 0.0; + float h_offset = 0.0; + KeepAspect keep_aspect = KEEP_HEIGHT; RID camera; RID scenario_id; // String camera_group; - uint32_t layers; + uint32_t layers = 0xfffff; Ref<Environment> environment; Ref<CameraEffects> effects; @@ -87,7 +88,7 @@ private: friend class Viewport; void _update_audio_listener_state(); - DopplerTracking doppler_tracking; + DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED; Ref<VelocityTracker3D> velocity_tracker; protected: @@ -185,19 +186,19 @@ class ClippedCamera3D : public Camera3D { GDCLASS(ClippedCamera3D, Camera3D); public: - enum ProcessMode { + enum ClipProcessCallback { CLIP_PROCESS_PHYSICS, CLIP_PROCESS_IDLE, }; private: - ProcessMode process_mode; + ClipProcessCallback process_callback = CLIP_PROCESS_PHYSICS; RID pyramid_shape; - float margin; - float clip_offset; - uint32_t collision_mask; - bool clip_to_areas; - bool clip_to_bodies; + float margin = 0.0; + float clip_offset = 0.0; + uint32_t collision_mask = 1; + bool clip_to_areas = false; + bool clip_to_bodies = true; Set<RID> exclude; @@ -218,8 +219,8 @@ public: void set_margin(float p_margin); float get_margin() const; - void set_process_mode(ProcessMode p_mode); - ProcessMode get_process_mode() const; + void set_process_callback(ClipProcessCallback p_mode); + ClipProcessCallback get_process_callback() const; void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; @@ -239,5 +240,5 @@ public: ~ClippedCamera3D(); }; -VARIANT_ENUM_CAST(ClippedCamera3D::ProcessMode); +VARIANT_ENUM_CAST(ClippedCamera3D::ClipProcessCallback); #endif diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index f1d7ac64b2..849ef7a2bf 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -30,6 +30,7 @@ #include "collision_object_3d.h" +#include "mesh_instance_3d.h" #include "scene/scene_string_names.h" #include "servers/physics_server_3d.h" @@ -110,6 +111,42 @@ void CollisionObject3D::_update_pickable() { } } +void CollisionObject3D::_update_debug_shapes() { + for (Set<uint32_t>::Element *shapedata_idx = debug_shapes_to_update.front(); shapedata_idx; shapedata_idx = shapedata_idx->next()) { + if (shapes.has(shapedata_idx->get())) { + ShapeData &shapedata = shapes[shapedata_idx->get()]; + for (int i = 0; i < shapedata.shapes.size(); i++) { + ShapeData::ShapeBase &s = shapedata.shapes.write[i]; + if (s.debug_shape) { + s.debug_shape->queue_delete(); + s.debug_shape = nullptr; + } + if (s.shape.is_null() || shapedata.disabled) { + continue; + } + + Ref<Mesh> mesh = s.shape->get_debug_mesh(); + MeshInstance3D *mi = memnew(MeshInstance3D); + mi->set_transform(shapedata.xform); + mi->set_mesh(mesh); + add_child(mi); + mi->force_update_transform(); + s.debug_shape = mi; + } + } + } + debug_shapes_to_update.clear(); +} + +void CollisionObject3D::_update_shape_data(uint32_t p_owner) { + if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { + if (debug_shapes_to_update.is_empty()) { + call_deferred("_update_debug_shapes"); + } + debug_shapes_to_update.insert(p_owner); + } +} + void CollisionObject3D::set_ray_pickable(bool p_ray_pickable) { ray_pickable = p_ray_pickable; _update_pickable(); @@ -141,6 +178,8 @@ void CollisionObject3D::_bind_methods() { ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject3D::shape_owner_clear_shapes); ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner); + ClassDB::bind_method(D_METHOD("_update_debug_shapes"), &CollisionObject3D::_update_debug_shapes); + BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx"))); ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx"))); @@ -188,6 +227,7 @@ void CollisionObject3D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl PhysicsServer3D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled); } } + _update_shape_data(p_owner); } bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const { @@ -223,6 +263,8 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf PhysicsServer3D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform); } } + + _update_shape_data(p_owner); } Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const { @@ -245,6 +287,7 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3 ShapeData::ShapeBase s; s.index = total_subshapes; s.shape = p_shape; + if (area) { PhysicsServer3D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } else { @@ -253,6 +296,8 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3 sd.shapes.push_back(s); total_subshapes++; + + _update_shape_data(p_owner); } int CollisionObject3D::shape_owner_get_shape_count(uint32_t p_owner) const { @@ -279,13 +324,19 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) ERR_FAIL_COND(!shapes.has(p_owner)); ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size()); - int index_to_remove = shapes[p_owner].shapes[p_shape].index; + const ShapeData::ShapeBase &s = shapes[p_owner].shapes[p_shape]; + int index_to_remove = s.index; + if (area) { PhysicsServer3D::get_singleton()->area_remove_shape(rid, index_to_remove); } else { PhysicsServer3D::get_singleton()->body_remove_shape(rid, index_to_remove); } + if (s.debug_shape) { + s.debug_shape->queue_delete(); + } + shapes[p_owner].shapes.remove(p_shape); for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { @@ -325,10 +376,7 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) { rid = p_rid; area = p_area; - capture_input_on_drag = false; - ray_pickable = true; set_notify_transform(true); - total_subshapes = 0; if (p_area) { PhysicsServer3D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id()); @@ -360,8 +408,6 @@ String CollisionObject3D::get_configuration_warning() const { } CollisionObject3D::CollisionObject3D() { - capture_input_on_drag = false; - ray_pickable = true; set_notify_transform(true); //owner= diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index da65791b9c..fe20176984 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -37,36 +37,36 @@ class CollisionObject3D : public Node3D { GDCLASS(CollisionObject3D, Node3D); - bool area; + bool area = false; RID rid; struct ShapeData { - Object *owner; + Object *owner = nullptr; Transform xform; struct ShapeBase { + Node *debug_shape = nullptr; Ref<Shape3D> shape; - int index; + int index = 0; }; Vector<ShapeBase> shapes; - bool disabled; - - ShapeData() { - disabled = false; - owner = nullptr; - } + bool disabled = false; }; - int total_subshapes; + int total_subshapes = 0; Map<uint32_t, ShapeData> shapes; - bool capture_input_on_drag; - bool ray_pickable; + bool capture_input_on_drag = false; + bool ray_pickable = true; + + Set<uint32_t> debug_shapes_to_update; void _update_pickable(); + void _update_shape_data(uint32_t p_owner); + protected: CollisionObject3D(RID p_rid, bool p_area); @@ -77,6 +77,8 @@ protected: virtual void _mouse_enter(); virtual void _mouse_exit(); + void _update_debug_shapes(); + public: uint32_t create_shape_owner(Object *p_owner); void remove_shape_owner(uint32_t owner); diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 5e77937533..e3e2eb4669 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -70,6 +70,7 @@ void CollisionPolygon3D::_build_polygon() { } convex->set_points(cp); + convex->set_margin(margin); parent->shape_owner_add_shape(owner_id, convex); parent->shape_owner_set_disabled(owner_id, disabled); } @@ -132,13 +133,13 @@ AABB CollisionPolygon3D::get_item_rect() const { return aabb; } -void CollisionPolygon3D::set_depth(float p_depth) { +void CollisionPolygon3D::set_depth(real_t p_depth) { depth = p_depth; _build_polygon(); update_gizmo(); } -float CollisionPolygon3D::get_depth() const { +real_t CollisionPolygon3D::get_depth() const { return depth; } @@ -155,6 +156,17 @@ bool CollisionPolygon3D::is_disabled() const { return disabled; } +real_t CollisionPolygon3D::get_margin() const { + return margin; +} + +void CollisionPolygon3D::set_margin(real_t p_margin) { + margin = p_margin; + if (parent) { + _build_polygon(); + } +} + String CollisionPolygon3D::get_configuration_warning() const { String warning = Node3D::get_configuration_warning(); @@ -189,18 +201,17 @@ void CollisionPolygon3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionPolygon3D::set_disabled); ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionPolygon3D::is_disabled); + ClassDB::bind_method(D_METHOD("set_margin", "margin"), &CollisionPolygon3D::set_margin); + ClassDB::bind_method(D_METHOD("get_margin"), &CollisionPolygon3D::get_margin); + ClassDB::bind_method(D_METHOD("_is_editable_3d_polygon"), &CollisionPolygon3D::_is_editable_3d_polygon); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth"), "set_depth", "get_depth"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin"); } CollisionPolygon3D::CollisionPolygon3D() { - aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); - depth = 1.0; set_notify_local_transform(true); - parent = nullptr; - owner_id = 0; - disabled = false; } diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h index ec13b9af6d..750751b509 100644 --- a/scene/3d/collision_polygon_3d.h +++ b/scene/3d/collision_polygon_3d.h @@ -37,16 +37,17 @@ class CollisionObject3D; class CollisionPolygon3D : public Node3D { GDCLASS(CollisionPolygon3D, Node3D); + real_t margin = 0.04; protected: - float depth; - AABB aabb; + real_t depth = 1.0; + AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); Vector<Point2> polygon; - uint32_t owner_id; - CollisionObject3D *parent; + uint32_t owner_id = 0; + CollisionObject3D *parent = nullptr; - bool disabled; + bool disabled = false; void _build_polygon(); @@ -59,8 +60,8 @@ protected: static void _bind_methods(); public: - void set_depth(float p_depth); - float get_depth() const; + void set_depth(real_t p_depth); + real_t get_depth() const; void set_polygon(const Vector<Point2> &p_polygon); Vector<Point2> get_polygon() const; @@ -70,6 +71,9 @@ public: virtual AABB get_item_rect() const; + real_t get_margin() const; + void set_margin(real_t p_margin); + String get_configuration_warning() const override; CollisionPolygon3D(); diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 47966c772b..242d82ab4c 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -100,9 +100,6 @@ void CollisionShape3D::_notification(int p_what) { if (parent) { _update_in_shape_owner(); } - if (get_tree()->is_debugging_collisions_hint()) { - _update_debug_shape(); - } } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { if (parent) { @@ -163,13 +160,14 @@ void CollisionShape3D::_bind_methods() { ClassDB::bind_method(D_METHOD("make_convex_from_siblings"), &CollisionShape3D::make_convex_from_siblings); ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_siblings", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); - ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape3D::_update_debug_shape); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); } void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) { + if (p_shape == shape) { + return; + } if (!shape.is_null()) { shape->unregister_owner(this); shape->disconnect("changed", callable_mp(this, &CollisionShape3D::_shape_changed)); @@ -211,10 +209,6 @@ bool CollisionShape3D::is_disabled() const { CollisionShape3D::CollisionShape3D() { //indicator = RenderingServer::get_singleton()->mesh_create(); - disabled = false; - debug_shape = nullptr; - parent = nullptr; - owner_id = 0; set_notify_local_transform(true); } @@ -225,34 +219,9 @@ CollisionShape3D::~CollisionShape3D() { //RenderingServer::get_singleton()->free(indicator); } -void CollisionShape3D::_update_debug_shape() { - debug_shape_dirty = false; - - if (debug_shape) { - debug_shape->queue_delete(); - debug_shape = nullptr; - } - - Ref<Shape3D> s = get_shape(); - if (s.is_null()) { - return; - } - - Ref<Mesh> mesh = s->get_debug_mesh(); - MeshInstance3D *mi = memnew(MeshInstance3D); - mi->set_mesh(mesh); - add_child(mi); - debug_shape = mi; -} - void CollisionShape3D::_shape_changed() { // If this is a heightfield shape our center may have changed if (parent) { _update_in_shape_owner(true); } - - if (is_inside_tree() && get_tree()->is_debugging_collisions_hint() && !debug_shape_dirty) { - debug_shape_dirty = true; - call_deferred("_update_debug_shape"); - } } diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index 5f556b01a9..5512417f75 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -40,17 +40,13 @@ class CollisionShape3D : public Node3D { Ref<Shape3D> shape; - uint32_t owner_id; - CollisionObject3D *parent; - - Node *debug_shape; - bool debug_shape_dirty; + uint32_t owner_id = 0; + CollisionObject3D *parent = nullptr; void resource_changed(RES res); - bool disabled; + bool disabled = false; protected: - void _update_debug_shape(); void _shape_changed(); void _update_in_shape_owner(bool p_xform_only = false); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 3562f7b778..d22d7ff3ab 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -73,7 +73,7 @@ void CPUParticles3D::set_amount(int p_amount) { } particle_data.resize((12 + 4 + 4) * p_amount); - RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true); + RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true); particle_order.resize(p_amount); } @@ -152,6 +152,7 @@ float CPUParticles3D::get_speed_scale() const { } void CPUParticles3D::set_draw_order(DrawOrder p_order) { + ERR_FAIL_INDEX(p_order, DRAW_ORDER_MAX); draw_order = p_order; } @@ -372,7 +373,7 @@ void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_ena ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); particle_flags[p_particle_flag] = p_enable; if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { - _change_notify(); + notify_property_list_changed(); } } @@ -575,7 +576,7 @@ void CPUParticles3D::_particles_process(float p_delta) { cycle++; if (one_shot && cycle > 0) { set_emitting(false); - _change_notify(); + notify_property_list_changed(); } } @@ -646,6 +647,8 @@ void CPUParticles3D::_particles_process(float p_delta) { restart = true; } + float tv = 0.0; + if (restart) { if (!emitting) { p.active = false; @@ -660,12 +663,12 @@ void CPUParticles3D::_particles_process(float p_delta) { float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv); } p.seed = Math::rand(); @@ -676,13 +679,13 @@ void CPUParticles3D::_particles_process(float p_delta) { p.anim_offset_rand = Math::randf(); if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } else { //initiate velocity spread in 3D - float angle1_rad = Math::atan2(direction.x, direction.z) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; - float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); + float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread); Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); @@ -706,8 +709,9 @@ void CPUParticles3D::_particles_process(float p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { - float s = 2.0 * Math::randf() - 1.0, t = 2.0 * Math_PI * Math::randf(); - float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); + real_t s = 2.0 * Math::randf() - 1.0; + real_t t = Math_TAU * Math::randf(); + real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s); } break; case EMISSION_SHAPE_BOX: { @@ -771,61 +775,63 @@ void CPUParticles3D::_particles_process(float p_delta) { continue; } else if (p.time > p.lifetime) { p.active = false; + tv = 1.0; } else { uint32_t alt_seed = p.seed; p.time += local_delta; p.custom[1] = p.time / lifetime; + tv = p.time / p.lifetime; float tex_linear_velocity = 0.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]); + tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv); } float tex_orbit_velocity = 0.0; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]); + tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv); } } float tex_angular_velocity = 0.0; if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { - tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]); + tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv); } float tex_linear_accel = 0.0; if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) { - tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]); + tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv); } float tex_tangential_accel = 0.0; if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { - tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]); + tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv); } float tex_radial_accel = 0.0; if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) { - tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]); + tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv); } float tex_damping = 0.0; if (curve_parameters[PARAM_DAMPING].is_valid()) { - tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]); + tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv); } float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_speed = 0.0; if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) { - tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]); + tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]); + tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv); } Vector3 force = gravity; @@ -855,7 +861,7 @@ void CPUParticles3D::_particles_process(float p_delta) { if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); if (orbit_amount != 0.0) { - float ang = orbit_amount * local_delta * Math_PI * 2.0; + float ang = orbit_amount * local_delta * Math_TAU; // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); @@ -887,15 +893,15 @@ void CPUParticles3D::_particles_process(float p_delta) { float tex_scale = 1.0; if (curve_parameters[PARAM_SCALE].is_valid()) { - tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]); + tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv); } float tex_hue_variation = 0.0; if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) { - tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]); + tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv); } - float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); + float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); float hue_rot_c = Math::cos(hue_rot_angle); float hue_rot_s = Math::sin(hue_rot_angle); @@ -911,7 +917,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } if (color_ramp.is_valid()) { - p.color = color_ramp->get_color_at_offset(p.custom[1]) * color; + p.color = color_ramp->get_color_at_offset(tv) * color; } else { p.color = color; } @@ -1006,6 +1012,7 @@ void CPUParticles3D::_update_particle_data_buffer() { sorter.compare.particles = r; sorter.sort(order, pc); } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { + ERR_FAIL_NULL(get_viewport()); Camera3D *c = get_viewport()->get_camera(); if (c) { Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close @@ -1067,7 +1074,7 @@ void CPUParticles3D::_update_particle_data_buffer() { ptr += 20; } - can_update = true; + can_update.set(); } void CPUParticles3D::_set_redraw(bool p_redraw) { @@ -1096,9 +1103,9 @@ void CPUParticles3D::_set_redraw(bool p_redraw) { void CPUParticles3D::_update_render_thread() { MutexLock lock(update_mutex); - if (can_update) { + if (can_update.is_set()) { RS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); - can_update = false; //wait for next time + can_update.clear(); //wait for next time } } @@ -1160,7 +1167,7 @@ void CPUParticles3D::_notification(int p_what) { ptr += 20; } - can_update = true; + can_update.set(); } } } @@ -1440,13 +1447,6 @@ void CPUParticles3D::_bind_methods() { } CPUParticles3D::CPUParticles3D() { - time = 0; - inactive_time = 0; - frame_remainder = 0; - cycle = 0; - redraw = false; - emitting = false; - set_notify_transform(true); multimesh = RenderingServer::get_singleton()->multimesh_create(); @@ -1454,23 +1454,8 @@ CPUParticles3D::CPUParticles3D() { set_base(multimesh); set_emitting(true); - set_one_shot(false); set_amount(8); - set_lifetime(1); - set_fixed_fps(0); - set_fractional_delta(true); - set_pre_process_time(0); - set_explosiveness_ratio(0); - set_randomness_ratio(0); - set_lifetime_randomness(0); - set_use_local_coordinates(true); - - set_draw_order(DRAW_ORDER_INDEX); - set_speed_scale(1); - - set_direction(Vector3(1, 0, 0)); - set_spread(45); - set_flatness(0); + set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); set_param(PARAM_ANGULAR_VELOCITY, 0); set_param(PARAM_ORBIT_VELOCITY, 0); @@ -1497,8 +1482,6 @@ CPUParticles3D::CPUParticles3D() { particle_flags[i] = false; } - can_update = false; - set_color(Color(1, 1, 1, 1)); } diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 3ee03ff3d8..10ac32622d 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -32,6 +32,7 @@ #define CPU_PARTICLES_H #include "core/templates/rid.h" +#include "core/templates/safe_refcount.h" #include "scene/3d/visual_instance_3d.h" class CPUParticles3D : public GeometryInstance3D { @@ -43,6 +44,7 @@ public: DRAW_ORDER_INDEX, DRAW_ORDER_LIFETIME, DRAW_ORDER_VIEW_DEPTH, + DRAW_ORDER_MAX }; enum Parameter { @@ -78,30 +80,30 @@ public: }; private: - bool emitting; + bool emitting = false; struct Particle { Transform transform; Color color; - float custom[4]; + float custom[4] = {}; Vector3 velocity; - bool active; - float angle_rand; - float scale_rand; - float hue_rot_rand; - float anim_offset_rand; - float time; - float lifetime; + bool active = false; + float angle_rand = 0.0; + float scale_rand = 0.0; + float hue_rot_rand = 0.0; + float anim_offset_rand = 0.0; + float time = 0.0; + float lifetime = 0.0; Color base_color; - uint32_t seed; + uint32_t seed = 0; }; - float time; - float inactive_time; - float frame_remainder; - int cycle; - bool redraw; + float time = 0.0; + float inactive_time = 0.0; + float frame_remainder = 0.0; + int cycle = 0; + bool redraw = false; RID multimesh; @@ -110,7 +112,7 @@ private: Vector<int> particle_order; struct SortLifetime { - const Particle *particles; + const Particle *particles = nullptr; bool operator()(int p_a, int p_b) const { return particles[p_a].time > particles[p_b].time; @@ -118,7 +120,7 @@ private: }; struct SortAxis { - const Particle *particles; + const Particle *particles = nullptr; Vector3 axis; bool operator()(int p_a, int p_b) const { return axis.dot(particles[p_a].transform.origin) < axis.dot(particles[p_b].transform.origin); @@ -127,50 +129,50 @@ private: // - bool one_shot; + bool one_shot = false; - float lifetime; - float pre_process_time; - float explosiveness_ratio; - float randomness_ratio; - float lifetime_randomness; - float speed_scale; - bool local_coords; - int fixed_fps; - bool fractional_delta; + float lifetime = 1.0; + float pre_process_time = 0.0; + float explosiveness_ratio = 0.0; + float randomness_ratio = 0.0; + float lifetime_randomness = 0.0; + float speed_scale = 1.0; + bool local_coords = true; + int fixed_fps = 0; + bool fractional_delta = true; Transform inv_emission_transform; - volatile bool can_update; + SafeFlag can_update; - DrawOrder draw_order; + DrawOrder draw_order = DRAW_ORDER_INDEX; Ref<Mesh> mesh; //////// - Vector3 direction; - float spread; - float flatness; + Vector3 direction = Vector3(1, 0, 0); + float spread = 45.0; + float flatness = 0.0; float parameters[PARAM_MAX]; - float randomness[PARAM_MAX]; + float randomness[PARAM_MAX] = {}; Ref<Curve> curve_parameters[PARAM_MAX]; - Color color; + Color color = Color(1, 1, 1, 1); Ref<Gradient> color_ramp; - bool particle_flags[PARTICLE_FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX] = {}; - EmissionShape emission_shape; - float emission_sphere_radius; - Vector3 emission_box_extents; + EmissionShape emission_shape = EMISSION_SHAPE_POINT; + float emission_sphere_radius = 1.0; + Vector3 emission_box_extents = Vector3(1, 1, 1); Vector<Vector3> emission_points; Vector<Vector3> emission_normals; Vector<Color> emission_colors; - int emission_point_count; + int emission_point_count = 0; - Vector3 gravity; + Vector3 gravity = Vector3(0, -9.8, 0); void _update_internal(); void _particles_process(float p_delta); diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index e67802cfc4..0f10f2b85f 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -34,7 +34,6 @@ void Decal::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->decal_set_extents(decal, p_extents); update_gizmo(); - _change_notify("extents"); } Vector3 Decal::get_extents() const { @@ -220,18 +219,6 @@ void Decal::_bind_methods() { } Decal::Decal() { - extents = Vector3(1, 1, 1); - emission_energy = 1.0; - modulate = Color(1, 1, 1, 1); - albedo_mix = 1.0; - cull_mask = (1 << 20) - 1; - upper_fade = 0.3; - lower_fade = 0.3; - normal_fade = 0; - distance_fade_enabled = false; - distance_fade_begin = 10; - distance_fade_length = 1; - decal = RenderingServer::get_singleton()->decal_create(); RS::get_singleton()->instance_set_base(get_instance(), decal); } diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 500a1425f2..095579d775 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -49,18 +49,18 @@ public: private: RID decal; - Vector3 extents; + Vector3 extents = Vector3(1, 1, 1); Ref<Texture2D> textures[TEXTURE_MAX]; - float emission_energy; - float albedo_mix; - Color modulate; - uint32_t cull_mask; - float normal_fade; - float upper_fade; - float lower_fade; - bool distance_fade_enabled; - float distance_fade_begin; - float distance_fade_length; + float emission_energy = 1.0; + float albedo_mix = 1.0; + Color modulate = Color(1, 1, 1, 1); + uint32_t cull_mask = (1 << 20) - 1; + float normal_fade = 0.0; + float upper_fade = 0.3; + float lower_fade = 0.3; + bool distance_fade_enabled = false; + float distance_fade_begin = 10.0; + float distance_fade_length = 1.0; protected: static void _bind_methods(); diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index b00a0ec30b..43f820e5d4 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -91,7 +91,7 @@ Dictionary GIProbeData::_get_data() const { } void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { - RS::get_singleton()->gi_probe_allocate(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); + RS::get_singleton()->gi_probe_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); bounds = p_aabb; to_cell_xform = p_to_cell_xform; octree_size = p_octree_size; @@ -221,7 +221,7 @@ RID GIProbeData::get_rid() const { void GIProbeData::_validate_property(PropertyInfo &property) const { if (property.name == "anisotropy_strength") { - bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/quality/gi_probes/anisotropic"); + bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/global_illumination/gi_probes/anisotropic"); if (!anisotropy_enabled) { property.usage = PROPERTY_USAGE_NOEDITOR; } @@ -286,17 +286,6 @@ void GIProbeData::_bind_methods() { } GIProbeData::GIProbeData() { - ao = 0.0; - ao_size = 0.5; - dynamic_range = 4; - energy = 1.0; - bias = 1.5; - normal_bias = 0.0; - propagation = 0.7; - anisotropy_strength = 0.5; - interior = false; - use_two_bounces = false; - probe = RS::get_singleton()->gi_probe_create(); } @@ -334,7 +323,6 @@ GIProbe::Subdiv GIProbe::get_subdiv() const { void GIProbe::set_extents(const Vector3 &p_extents) { extents = p_extents; update_gizmo(); - _change_notify("extents"); } Vector3 GIProbe::get_extents() const { @@ -427,13 +415,16 @@ Vector3i GIProbe::get_estimated_cell_size() const { void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; + p_from_node = p_from_node ? p_from_node : get_parent(); + ERR_FAIL_NULL(p_from_node); + Voxelizer baker; baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0)); List<PlotMesh> mesh_list; - _find_meshes(p_from_node ? p_from_node : get_parent(), mesh_list); + _find_meshes(p_from_node, mesh_list); if (bake_begin_function) { bake_begin_function(mesh_list.size() + 1); @@ -497,7 +488,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { bake_end_function(); } - _change_notify(); //bake property may have changed + notify_property_list_changed(); //bake property may have changed } void GIProbe::_debug_bake() { @@ -520,7 +511,10 @@ String GIProbe::get_configuration_warning() const { warning += "\n\n"; } warning += TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead."); + } else if (probe_data.is_null()) { + warning += TTR("No GIProbe data set, so this node is disabled. Bake static objects to enable GI."); } + return warning; } @@ -550,9 +544,6 @@ void GIProbe::_bind_methods() { } GIProbe::GIProbe() { - subdiv = SUBDIV_128; - extents = Vector3(10, 10, 10); - gi_probe = RS::get_singleton()->gi_probe_create(); set_disable_scale(true); } diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index afea94fe12..534b425557 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -46,16 +46,16 @@ class GIProbeData : public Resource { AABB bounds; Vector3 octree_size; - float dynamic_range; - float energy; - float bias; - float normal_bias; - float propagation; - float anisotropy_strength; - float ao; - float ao_size; - bool interior; - bool use_two_bounces; + float dynamic_range = 4.0; + float energy = 1.0; + float bias = 1.5; + float normal_bias = 0.0; + float propagation = 0.7; + float anisotropy_strength = 0.5; + float ao = 0.0; + float ao_size = 0.5; + bool interior = false; + bool use_two_bounces = false; protected: static void _bind_methods(); @@ -129,8 +129,8 @@ private: RID gi_probe; - Subdiv subdiv; - Vector3 extents; + Subdiv subdiv = SUBDIV_128; + Vector3 extents = Vector3(10, 10, 10); struct PlotMesh { Ref<Material> override_material; diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 7d77578b01..17a61b3e4d 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -100,7 +100,6 @@ void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) { visibility_aabb = p_aabb; RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb); update_gizmo(); - _change_notify("visibility_aabb"); } void GPUParticles3D::set_use_local_coordinates(bool p_enable) { @@ -190,7 +189,7 @@ void GPUParticles3D::set_draw_passes(int p_count) { ERR_FAIL_COND(p_count < 1); draw_passes.resize(p_count); RS::get_singleton()->particles_set_draw_passes(particles, p_count); - _change_notify(); + notify_property_list_changed(); } int GPUParticles3D::get_draw_passes() const { @@ -353,7 +352,7 @@ void GPUParticles3D::_notification(int p_what) { // the shot ends the editor can properly update if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (one_shot && !is_emitting()) { - _change_notify(); + notify_property_list_changed(); set_process_internal(false); } } diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 145b5afbd0..97241be60f 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -293,11 +293,11 @@ void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, cons SGN(cb.cross(nor).dot(pb)) + SGN(ac.cross(nor).dot(pc)) < 2.0) ? - MIN(MIN( + MIN(MIN( Vector3_dot2(ba * CLAMP(ba.dot(pa) / Vector3_dot2(ba), 0.0, 1.0) - pa), Vector3_dot2(cb * CLAMP(cb.dot(pb) / Vector3_dot2(cb), 0.0, 1.0) - pb)), Vector3_dot2(ac * CLAMP(ac.dot(pc) / Vector3_dot2(ac), 0.0, 1.0) - pc)) : - nor.dot(pa) * nor.dot(pa) / Vector3_dot2(nor)); + nor.dot(pa) * nor.dot(pa) / Vector3_dot2(nor)); closest_distance = MIN(closest_distance, inside_d); } diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 7d6301ee50..81c33663f3 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -130,16 +130,16 @@ private: LEAF_MASK = LEAF_BIT - 1 }; AABB bounds; - uint32_t children[2]; + uint32_t children[2] = {}; }; struct FacePos { Vector3 center; - uint32_t index; + uint32_t index = 0; }; struct FaceSort { - uint32_t axis; + uint32_t axis = 0; bool operator()(const FacePos &p_left, const FacePos &p_right) const { return p_left.center[axis] < p_right.center[axis]; } @@ -148,13 +148,13 @@ private: uint32_t _create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness); struct ComputeSDFParams { - float *cells; + float *cells = nullptr; Vector3i size; - float cell_size; + float cell_size = 0.0; Vector3 cell_offset; - const BVH *bvh; - const Face3 *triangles; - float thickness; + const BVH *bvh = nullptr; + const Face3 *triangles = nullptr; + float thickness = 0.0; }; void _find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance); diff --git a/scene/3d/immediate_geometry_3d.cpp b/scene/3d/immediate_geometry_3d.cpp index 17410d5870..d64babaa9d 100644 --- a/scene/3d/immediate_geometry_3d.cpp +++ b/scene/3d/immediate_geometry_3d.cpp @@ -87,21 +87,24 @@ Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const { } void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) { + const double lat_step = Math_TAU / p_lats; + const double lon_step = Math_TAU / p_lons; + for (int i = 1; i <= p_lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / p_lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = p_lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / p_lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); @@ -147,7 +150,6 @@ void ImmediateGeometry3D::_bind_methods() { ImmediateGeometry3D::ImmediateGeometry3D() { im = RenderingServer::get_singleton()->immediate_create(); set_base(im); - empty = true; } ImmediateGeometry3D::~ImmediateGeometry3D() { diff --git a/scene/3d/immediate_geometry_3d.h b/scene/3d/immediate_geometry_3d.h index 8e546e27e7..ee4938d9f7 100644 --- a/scene/3d/immediate_geometry_3d.h +++ b/scene/3d/immediate_geometry_3d.h @@ -41,7 +41,7 @@ class ImmediateGeometry3D : public GeometryInstance3D { //a list of textures drawn need to be kept, to avoid references // in RenderingServer from becoming invalid if the texture is no longer used List<Ref<Texture2D>> cached_textures; - bool empty; + bool empty = true; AABB aabb; protected: diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index b9293b364d..b0a10b5547 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -48,11 +48,7 @@ void Light3D::set_param(Param p_param, float p_value) { update_gizmo(); if (p_param == PARAM_SPOT_ANGLE) { - _change_notify("spot_angle"); update_configuration_warning(); - } else if (p_param == PARAM_RANGE) { - _change_notify("omni_range"); - _change_notify("spot_range"); } } } @@ -184,8 +180,6 @@ void Light3D::_update_visibility() { #endif RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree() && editor_ok); - - _change_notify("geometry/visible"); } void Light3D::_notification(int p_what) { @@ -212,6 +206,10 @@ void Light3D::_validate_property(PropertyInfo &property) const { property.usage = 0; } + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_specular") { + property.usage = 0; + } + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { property.usage = 0; } @@ -257,7 +255,7 @@ void Light3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); @@ -320,10 +318,6 @@ Light3D::Light3D(RenderingServer::LightType p_type) { RS::get_singleton()->instance_set_base(get_instance(), light); - reverse_cull = false; - bake_mode = BAKE_DYNAMIC; - - editor_only = false; set_color(Color(1, 1, 1, 1)); set_shadow(false); set_negative(false); @@ -347,13 +341,12 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_BIAS, 0.02); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); - set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 1.0); + set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1); set_param(PARAM_SHADOW_FADE_START, 1); set_disable_scale(true); } Light3D::Light3D() { - type = RenderingServer::LIGHT_DIRECTIONAL; ERR_PRINT("Light3D should not be instanced directly; use the DirectionalLight3D, OmniLight3D or SpotLight3D subtypes instead."); } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 833598c4a1..311db54bce 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -71,16 +71,16 @@ public: private: Color color; - float param[PARAM_MAX]; + float param[PARAM_MAX] = {}; Color shadow_color; - bool shadow; - bool negative; - bool reverse_cull; - uint32_t cull_mask; - RS::LightType type; - bool editor_only; + bool shadow = false; + bool negative = false; + bool reverse_cull = false; + uint32_t cull_mask = 0; + RS::LightType type = RenderingServer::LIGHT_DIRECTIONAL; + bool editor_only = false; void _update_visibility(); - BakeMode bake_mode; + BakeMode bake_mode = BAKE_DYNAMIC; Ref<Texture2D> projector; // bind helpers diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp index 23adb0aa19..9842f152d7 100644 --- a/scene/3d/listener_3d.cpp +++ b/scene/3d/listener_3d.cpp @@ -159,8 +159,6 @@ void Listener3D::_bind_methods() { } Listener3D::Listener3D() { - current = false; - force_change = false; set_notify_transform(true); //active=false; } diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h index 2a78efb2c7..85657a8e53 100644 --- a/scene/3d/listener_3d.h +++ b/scene/3d/listener_3d.h @@ -38,8 +38,8 @@ class Listener3D : public Node3D { GDCLASS(Listener3D, Node3D); private: - bool force_change; - bool current; + bool force_change = false; + bool current = false; RID scenario_id; diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 865510731e..b997c64b29 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -95,7 +95,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { ls.sort(); for (List<String>::Element *E = ls.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "0,1,0.00001")); + p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "-1,1,0.00001")); } if (mesh.is_valid()) { @@ -112,7 +112,6 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) { if (mesh.is_valid()) { mesh->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance3D::_mesh_changed)); - materials.clear(); } mesh = p_mesh; @@ -136,7 +135,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) { update_gizmo(); - _change_notify(); + notify_property_list_changed(); } Ref<Mesh> MeshInstance3D::get_mesh() const { @@ -153,7 +152,7 @@ void MeshInstance3D::_resolve_skeleton_path() { if (skin_internal.is_null()) { //a skin was created for us skin_internal = new_skin_reference->get_skin(); - _change_notify(); + notify_property_list_changed(); } } } @@ -320,6 +319,7 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { } void MeshInstance3D::_mesh_changed() { + ERR_FAIL_COND(mesh.is_null()); materials.resize(mesh->get_surface_count()); } @@ -429,7 +429,6 @@ void MeshInstance3D::_bind_methods() { } MeshInstance3D::MeshInstance3D() { - skeleton_path = NodePath(".."); } MeshInstance3D::~MeshInstance3D() { diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index 822e04e656..eb300784b1 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -44,15 +44,11 @@ protected: Ref<Skin> skin; Ref<Skin> skin_internal; Ref<SkinReference> skin_ref; - NodePath skeleton_path; + NodePath skeleton_path = NodePath(".."); struct BlendShapeTrack { - int idx; - float value; - BlendShapeTrack() { - idx = 0; - value = 0; - } + int idx = 0; + float value = 0.0; }; Map<StringName, BlendShapeTrack> blend_shape_tracks; diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp index 2a7195be1a..eaddec7601 100644 --- a/scene/3d/navigation_3d.cpp +++ b/scene/3d/navigation_3d.cpp @@ -110,8 +110,6 @@ Navigation3D::Navigation3D() { set_cell_size(0.3); set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius - - up = Vector3(0, 1, 0); } Navigation3D::~Navigation3D() { diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h index 3e8adaf5ff..b89725a3f5 100644 --- a/scene/3d/navigation_3d.h +++ b/scene/3d/navigation_3d.h @@ -39,7 +39,7 @@ class Navigation3D : public Node3D { RID map; - Vector3 up; + Vector3 up = Vector3(0, 1, 0); real_t cell_size; real_t edge_connection_margin; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index b7b1415091..19bde94222 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -124,13 +124,13 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes } if (navmesh.is_valid()) { - navmesh->remove_change_receptor(this); + navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } navmesh = p_navmesh; if (navmesh.is_valid()) { - navmesh->add_change_receptor(this); + navmesh->connect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } NavigationServer3D::get_singleton()->region_set_navmesh(region, p_navmesh); @@ -150,7 +150,7 @@ Ref<NavigationMesh> NavigationRegion3D::get_navigation_mesh() const { } struct BakeThreadsArgs { - NavigationRegion3D *nav_region; + NavigationRegion3D *nav_region = nullptr; }; void _bake_navigation_mesh(void *p_user_data) { @@ -170,18 +170,17 @@ void _bake_navigation_mesh(void *p_user_data) { } void NavigationRegion3D::bake_navigation_mesh() { - ERR_FAIL_COND(bake_thread != nullptr); + ERR_FAIL_COND(bake_thread.is_started()); BakeThreadsArgs *args = memnew(BakeThreadsArgs); args->nav_region = this; - bake_thread = Thread::create(_bake_navigation_mesh, args); - ERR_FAIL_COND(bake_thread == nullptr); + bake_thread.start(_bake_navigation_mesh, args); } void NavigationRegion3D::_bake_finished(Ref<NavigationMesh> p_nav_mesh) { set_navigation_mesh(p_nav_mesh); - bake_thread = nullptr; + bake_thread.wait_to_finish(); emit_signal("bake_finished"); } @@ -231,7 +230,7 @@ void NavigationRegion3D::_bind_methods() { ADD_SIGNAL(MethodInfo("bake_finished")); } -void NavigationRegion3D::_changed_callback(Object *p_changed, const char *p_prop) { +void NavigationRegion3D::_navigation_changed() { update_gizmo(); update_configuration_warning(); } @@ -243,7 +242,7 @@ NavigationRegion3D::NavigationRegion3D() { NavigationRegion3D::~NavigationRegion3D() { if (navmesh.is_valid()) { - navmesh->remove_change_receptor(this); + navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } NavigationServer3D::get_singleton()->free(region); } diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index a5b8c2cd5e..6ae15c9360 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -46,12 +46,13 @@ class NavigationRegion3D : public Node3D { Navigation3D *navigation = nullptr; Node *debug_view = nullptr; - Thread *bake_thread = nullptr; + Thread bake_thread; + + void _navigation_changed(); protected: void _notification(int p_what); static void _bind_methods(); - void _changed_callback(Object *p_changed, const char *p_prop) override; public: void set_enabled(bool p_enabled); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 503dd5735b..4575716f7a 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -226,10 +226,6 @@ void Node3D::_notification(int p_what) { void Node3D::set_transform(const Transform &p_transform) { data.local_transform = p_transform; data.dirty |= DIRTY_VECTORS; - _change_notify("translation"); - _change_notify("rotation"); - _change_notify("rotation_degrees"); - _change_notify("scale"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -239,8 +235,8 @@ void Node3D::set_transform(const Transform &p_transform) { void Node3D::set_global_transform(const Transform &p_transform) { Transform xform = (data.parent && !data.top_level_active) ? - data.parent->get_global_transform().affine_inverse() * p_transform : - p_transform; + data.parent->get_global_transform().affine_inverse() * p_transform : + p_transform; set_transform(xform); } @@ -307,7 +303,6 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const { void Node3D::set_translation(const Vector3 &p_translation) { data.local_transform.origin = p_translation; - _change_notify("transform"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -322,7 +317,6 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) { data.rotation = p_euler_rad; data.dirty |= DIRTY_LOCAL; - _change_notify("transform"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -330,7 +324,7 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) { } void Node3D::set_rotation_degrees(const Vector3 &p_euler_deg) { - set_rotation(p_euler_deg * Math_PI / 180.0); + set_rotation(p_euler_deg * (Math_PI / 180.0)); } void Node3D::set_scale(const Vector3 &p_scale) { @@ -341,7 +335,6 @@ void Node3D::set_scale(const Vector3 &p_scale) { data.scale = p_scale; data.dirty |= DIRTY_LOCAL; - _change_notify("transform"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -364,7 +357,7 @@ Vector3 Node3D::get_rotation() const { } Vector3 Node3D::get_rotation_degrees() const { - return get_rotation() * 180.0 / Math_PI; + return get_rotation() * (180.0 / Math_PI); } Vector3 Node3D::get_scale() const { @@ -495,7 +488,6 @@ Ref<World3D> Node3D::get_world_3d() const { void Node3D::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringNames::get_singleton()->visibility_changed); - _change_notify("visible"); #ifdef TOOLS_ENABLED if (data.gizmo.is_valid()) { _update_gizmo(); @@ -755,8 +747,8 @@ void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("orthonormalize"), &Node3D::orthonormalize); ClassDB::bind_method(D_METHOD("set_identity"), &Node3D::set_identity); - ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Node3D::look_at); - ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Node3D::look_at_from_position); + ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Node3D::look_at, DEFVAL(Vector3(0, 1, 0))); + ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Node3D::look_at_from_position, DEFVAL(Vector3(0, 1, 0))); ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local); ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 8610e2c0bd..a62c7b31a8 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -173,8 +173,8 @@ public: void global_scale(const Vector3 &p_scale); void global_translate(const Vector3 &p_offset); - void look_at(const Vector3 &p_target, const Vector3 &p_up); - void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up); + void look_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); Vector3 to_local(Vector3 p_global) const; Vector3 to_global(Vector3 p_local) const; diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 3f048beb71..7e2601902b 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -323,8 +323,6 @@ void PathFollow3D::set_offset(float p_offset) { _update_transform(); } - _change_notify("offset"); - _change_notify("unit_offset"); } void PathFollow3D::set_h_offset(float p_h_offset) { diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 15e38c95e7..17ee47593e 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -66,10 +66,10 @@ public: private: Path3D *path = nullptr; - real_t delta_offset = 0; // Change in offset since last _update_transform. - real_t offset = 0; - real_t h_offset = 0; - real_t v_offset = 0; + real_t delta_offset = 0.0; // Change in offset since last _update_transform. + real_t offset = 0.0; + real_t h_offset = 0.0; + real_t v_offset = 0.0; bool cubic = true; bool loop = true; RotationMode rotation_mode = ROTATION_XYZ; diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 5645923f22..6d135c8283 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -51,7 +51,7 @@ Vector3 PhysicsBody3D::get_angular_velocity() const { return Vector3(); } -float PhysicsBody3D::get_inverse_mass() const { +real_t PhysicsBody3D::get_inverse_mass() const { return 0; } @@ -148,7 +148,8 @@ void PhysicsBody3D::_bind_methods() { } PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : - CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(p_mode), false) { + CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); collision_layer = 1; collision_mask = 1; } @@ -330,8 +331,8 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap struct _RigidBodyInOut { ObjectID id; - int shape; - int local_shape; + int shape = 0; + int local_shape = 0; }; void RigidBody3D::_direct_state_changed(Object *p_state) { @@ -825,24 +826,6 @@ void RigidBody3D::_bind_methods() { RigidBody3D::RigidBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { - mode = MODE_RIGID; - - mass = 1; - max_contacts_reported = 0; - state = nullptr; - - gravity_scale = 1; - linear_damp = -1; - angular_damp = -1; - - //angular_velocity=0; - sleeping = false; - ccd = false; - - custom_integrator = false; - contact_monitor = nullptr; - can_sleep = true; - PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -924,7 +907,7 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_ //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector3 body_velocity = p_linear_velocity; Vector3 body_velocity_normal = body_velocity.normalized(); Vector3 up_direction = p_up_direction.normalized(); @@ -1018,7 +1001,7 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const return body_velocity; } -Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector3 up_direction = p_up_direction.normalized(); bool was_on_floor = on_floor; @@ -1090,7 +1073,7 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision Vector3 recover; int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; - float deepest_depth; + real_t deepest_depth; for (int i = 0; i < hits; i++) { if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) { deepest = i; @@ -1131,12 +1114,12 @@ bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); } -void KinematicBody3D::set_safe_margin(float p_margin) { +void KinematicBody3D::set_safe_margin(real_t p_margin) { margin = p_margin; PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); } -float KinematicBody3D::get_safe_margin() const { +real_t KinematicBody3D::get_safe_margin() const { return margin; } @@ -1180,8 +1163,8 @@ void KinematicBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody3D::_direct_state_changed); ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true)); @@ -1221,11 +1204,6 @@ void KinematicBody3D::_direct_state_changed(Object *p_state) { KinematicBody3D::KinematicBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { - locked_axis = 0; - on_floor = false; - on_ceiling = false; - on_wall = false; - set_safe_margin(0.001); PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -1716,6 +1694,10 @@ bool PhysicalBone3D::SixDOFJointData::_set(const StringName &p_name, const Varia String path = p_name; + if (!path.begins_with("joint_constraints/")) { + return false; + } + Vector3::Axis axis; { const String axis_s = path.get_slicec('/', 1); @@ -1872,6 +1854,10 @@ bool PhysicalBone3D::SixDOFJointData::_get(const StringName &p_name, Variant &r_ String path = p_name; + if (!path.begins_with("joint_constraints/")) { + return false; + } + int axis; { const String axis_s = path.get_slicec('/', 1); @@ -2026,7 +2012,7 @@ void PhysicalBone3D::_notification(int p_what) { update_bone_id(); reset_to_rest_position(); reset_physics_simulation_state(); - if (!joint.is_valid() && joint_data) { + if (joint_data) { _reload_joint(); } break; @@ -2037,10 +2023,7 @@ void PhysicalBone3D::_notification(int p_what) { } } parent_skeleton = nullptr; - if (joint.is_valid()) { - PhysicsServer3D::get_singleton()->free(joint); - joint = RID(); - } + PhysicsServer3D::get_singleton()->joint_clear(joint); break; case NOTIFICATION_TRANSFORM_CHANGED: if (Engine::get_singleton()->is_editor_hint()) { @@ -2190,17 +2173,14 @@ void PhysicalBone3D::_fix_joint_offset() { } void PhysicalBone3D::_reload_joint() { - if (joint.is_valid()) { - PhysicsServer3D::get_singleton()->free(joint); - joint = RID(); - } - if (!parent_skeleton) { + PhysicsServer3D::get_singleton()->joint_clear(joint); return; } PhysicalBone3D *body_a = parent_skeleton->get_physical_bone_parent(bone_id); if (!body_a) { + PhysicsServer3D::get_singleton()->joint_clear(joint); return; } @@ -2210,7 +2190,7 @@ void PhysicalBone3D::_reload_joint() { switch (get_joint_type()) { case JOINT_TYPE_PIN: { - joint = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin); + PhysicsServer3D::get_singleton()->joint_make_pin(joint, body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin); const PinJointData *pjd(static_cast<const PinJointData *>(joint_data)); PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias); PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_DAMPING, pjd->damping); @@ -2218,7 +2198,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_CONE: { - joint = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_cone_twist(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data)); PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span); PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, cjd->twist_span); @@ -2228,7 +2208,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_HINGE: { - joint = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_hinge(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data)); PhysicsServer3D::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled); PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, hjd->angular_limit_upper); @@ -2239,7 +2219,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_SLIDER: { - joint = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_slider(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data)); PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper); PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER, sjd->linear_limit_lower); @@ -2254,7 +2234,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_6DOF: { - joint = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_generic_6dof(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data)); for (int axis = 0; axis < 3; ++axis) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, g6dofjd->axis_data[axis].linear_limit_enabled); @@ -2347,7 +2327,7 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) { _reload_joint(); #ifdef TOOLS_ENABLED - _change_notify(); + notify_property_list_changed(); if (get_gizmo().is_valid()) { get_gizmo()->redraw(); } @@ -2362,7 +2342,6 @@ void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; _update_joint_offset(); - _change_notify("joint_rotation_degrees"); } const Transform &PhysicalBone3D::get_joint_offset() const { @@ -2373,7 +2352,6 @@ void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); _update_joint_offset(); - _change_notify("joint_offset"); } Vector3 PhysicalBone3D::get_joint_rotation() const { @@ -2381,11 +2359,11 @@ Vector3 PhysicalBone3D::get_joint_rotation() const { } void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { - set_joint_rotation(p_euler_deg * Math_PI / 180.0); + set_joint_rotation(p_euler_deg * (Math_PI / 180.0)); } Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { - return get_joint_rotation() * 180.0 / Math_PI; + return get_joint_rotation() * (180.0 / Math_PI); } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2508,6 +2486,7 @@ bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { + joint = PhysicsServer3D::get_singleton()->joint_create(); reset_physics_simulation_state(); } @@ -2515,6 +2494,7 @@ PhysicalBone3D::~PhysicalBone3D() { if (joint_data) { memdelete(joint_data); } + PhysicsServer3D::get_singleton()->free(joint); } void PhysicalBone3D::update_bone_id() { diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index d9b95e6551..1450fce6a6 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -50,7 +50,7 @@ protected: public: virtual Vector3 get_linear_velocity() const; virtual Vector3 get_angular_velocity() const; - virtual float get_inverse_mass() const; + virtual real_t get_inverse_mass() const; void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; @@ -111,31 +111,31 @@ public: }; protected: - bool can_sleep; - PhysicsDirectBodyState3D *state; - Mode mode; + bool can_sleep = true; + PhysicsDirectBodyState3D *state = nullptr; + Mode mode = MODE_RIGID; - real_t mass; + real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; Vector3 linear_velocity; Vector3 angular_velocity; Basis inverse_inertia_tensor; - real_t gravity_scale; - real_t linear_damp; - real_t angular_damp; + real_t gravity_scale = 1.0; + real_t linear_damp = -1.0; + real_t angular_damp = -1.0; - bool sleeping; - bool ccd; + bool sleeping = false; + bool ccd = false; - int max_contacts_reported; + int max_contacts_reported = 0; - bool custom_integrator; + bool custom_integrator = false; struct ShapePair { - int body_shape; - int local_shape; - bool tagged; + int body_shape = 0; + int local_shape = 0; + bool tagged = false; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return local_shape < p_sp.local_shape; @@ -157,16 +157,16 @@ protected: }; struct BodyState { //int rc; - bool in_tree; + bool in_tree = false; VSet<ShapePair> shapes; }; struct ContactMonitor { - bool locked; + bool locked = false; Map<ObjectID, BodyState> body_map; }; - ContactMonitor *contact_monitor; + ContactMonitor *contact_monitor = nullptr; void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); @@ -183,7 +183,7 @@ public: void set_mass(real_t p_mass); real_t get_mass() const; - virtual float get_inverse_mass() const override { return 1.0 / mass; } + virtual real_t get_inverse_mass() const override { return 1.0 / mass; } void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -261,27 +261,27 @@ public: Vector3 collider_vel; ObjectID collider; RID collider_rid; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; Vector3 remainder; Vector3 travel; - int local_shape; + int local_shape = 0; }; private: Vector3 linear_velocity; Vector3 angular_velocity; - uint16_t locked_axis; + uint16_t locked_axis = 0; - float margin; + real_t margin; Vector3 floor_normal; Vector3 floor_velocity; RID on_floor_body; - bool on_floor; - bool on_ceiling; - bool on_wall; + bool on_floor = false; + bool on_ceiling = false; + bool on_wall = false; Vector<Collision> colliders; Vector<Ref<KinematicCollision3D>> slide_colliders; Ref<KinematicCollision3D> motion_cache; @@ -309,11 +309,11 @@ public: void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; - void set_safe_margin(float p_margin); - float get_safe_margin() const; + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); + Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; @@ -385,10 +385,8 @@ public: virtual void _get_property_list(List<PropertyInfo> *p_list) const; real_t bias = 0.3; - real_t damping = 1.; - real_t impulse_clamp = 0; - - PinJointData() {} + real_t damping = 1.0; + real_t impulse_clamp = 0.0; }; struct ConeJointData : public JointData { @@ -398,14 +396,11 @@ public: virtual bool _get(const StringName &p_name, Variant &r_ret) const; virtual void _get_property_list(List<PropertyInfo> *p_list) const; - real_t swing_span; + real_t swing_span = Math_PI * 0.25; real_t twist_span = Math_PI; real_t bias = 0.3; real_t softness = 0.8; real_t relaxation = 1.; - - ConeJointData() : - swing_span(Math_PI * 0.25) {} }; struct HingeJointData : public JointData { @@ -416,16 +411,11 @@ public: virtual void _get_property_list(List<PropertyInfo> *p_list) const; bool angular_limit_enabled = false; - real_t angular_limit_upper; - real_t angular_limit_lower; + real_t angular_limit_upper = Math_PI * 0.5; + real_t angular_limit_lower = -Math_PI * 0.5; real_t angular_limit_bias = 0.3; real_t angular_limit_softness = 0.9; real_t angular_limit_relaxation = 1.; - - HingeJointData() : - - angular_limit_upper(Math_PI * 0.5), - angular_limit_lower(-Math_PI * 0.5) {} }; struct SliderJointData : public JointData { @@ -435,45 +425,41 @@ public: virtual bool _get(const StringName &p_name, Variant &r_ret) const; virtual void _get_property_list(List<PropertyInfo> *p_list) const; - real_t linear_limit_upper = 1.; - real_t linear_limit_lower = -1.; - real_t linear_limit_softness = 1.; + real_t linear_limit_upper = 1.0; + real_t linear_limit_lower = -1.0; + real_t linear_limit_softness = 1.0; real_t linear_limit_restitution = 0.7; - real_t linear_limit_damping = 1.; - real_t angular_limit_upper = 0; - real_t angular_limit_lower = 0; - real_t angular_limit_softness = 1.; + real_t linear_limit_damping = 1.0; + real_t angular_limit_upper = 0.0; + real_t angular_limit_lower = 0.0; + real_t angular_limit_softness = 1.0; real_t angular_limit_restitution = 0.7; - real_t angular_limit_damping = 1.; - - SliderJointData() {} + real_t angular_limit_damping = 1.0; }; struct SixDOFJointData : public JointData { struct SixDOFAxisData { bool linear_limit_enabled = true; - real_t linear_limit_upper = 0; - real_t linear_limit_lower = 0; + real_t linear_limit_upper = 0.0; + real_t linear_limit_lower = 0.0; real_t linear_limit_softness = 0.7; real_t linear_restitution = 0.5; - real_t linear_damping = 1.; + real_t linear_damping = 1.0; bool linear_spring_enabled = false; - real_t linear_spring_stiffness = 0; - real_t linear_spring_damping = 0; - real_t linear_equilibrium_point = 0; + real_t linear_spring_stiffness = 0.0; + real_t linear_spring_damping = 0.0; + real_t linear_equilibrium_point = 0.0; bool angular_limit_enabled = true; - real_t angular_limit_upper = 0; - real_t angular_limit_lower = 0; + real_t angular_limit_upper = 0.0; + real_t angular_limit_lower = 0.0; real_t angular_limit_softness = 0.5; - real_t angular_restitution = 0; - real_t angular_damping = 1.; + real_t angular_restitution = 0.0; + real_t angular_damping = 1.0; real_t erp = 0.5; bool angular_spring_enabled = false; - real_t angular_spring_stiffness = 0; - real_t angular_spring_damping = 0.; - real_t angular_equilibrium_point = 0; - - SixDOFAxisData() {} + real_t angular_spring_stiffness = 0.0; + real_t angular_spring_damping = 0.0; + real_t angular_equilibrium_point = 0.0; }; virtual JointType get_joint_type() { return JOINT_TYPE_6DOF; } @@ -505,12 +491,12 @@ private: int bone_id = -1; String bone_name; - real_t bounce = 0; - real_t mass = 1; - real_t friction = 1; - real_t gravity_scale = 1; - real_t linear_damp = -1; - real_t angular_damp = -1; + real_t bounce = 0.0; + real_t mass = 1.0; + real_t friction = 1.0; + real_t gravity_scale = 1.0; + real_t linear_damp = -1.0; + real_t angular_damp = -1.0; bool can_sleep = true; protected: diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 0a2af6b0cd..ebc57ed477 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -62,18 +62,18 @@ void Joint3D::_body_exit_tree(const ObjectID &p_body_id) { } void Joint3D::_update_joint(bool p_only_free) { - if (joint.is_valid()) { - if (ba.is_valid() && bb.is_valid()) { - PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb); - } - - PhysicsServer3D::get_singleton()->free(joint); - joint = RID(); - ba = RID(); - bb = RID(); + if (ba.is_valid() && bb.is_valid()) { + PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb); + PhysicsServer3D::get_singleton()->body_remove_collision_exception(bb, ba); } + ba = RID(); + bb = RID(); + + configured = false; + if (p_only_free || !is_inside_tree()) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = String(); return; } @@ -85,50 +85,57 @@ void Joint3D::_update_joint(bool p_only_free) { PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b); if (node_a && !body_a && node_b && !body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be PhysicsBody3Ds"); update_configuration_warning(); return; } if (node_a && !body_a) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node A must be a PhysicsBody3D"); update_configuration_warning(); return; } if (node_b && !body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node B must be a PhysicsBody3D"); update_configuration_warning(); return; } if (!body_a && !body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Joint is not connected to any PhysicsBody3Ds"); update_configuration_warning(); return; } if (body_a == body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be different PhysicsBody3Ds"); update_configuration_warning(); return; } - if (!body_a) { - SWAP(body_a, body_b); - } - warning = String(); update_configuration_warning(); - joint = _configure_joint(body_a, body_b); + configured = true; - ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); + if (body_a) { + _configure_joint(joint, body_a, body_b); + } else if (body_b) { + _configure_joint(joint, body_b, nullptr); + } PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority); - ba = body_a->get_rid(); - body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree), make_binds(body_a->get_instance_id())); + if (body_a) { + ba = body_a->get_rid(); + body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree), make_binds(body_a->get_instance_id())); + } if (body_b) { bb = body_b->get_rid(); @@ -243,9 +250,12 @@ void Joint3D::_bind_methods() { } Joint3D::Joint3D() { - exclude_from_collision = true; - solver_priority = 1; set_notify_transform(true); + joint = PhysicsServer3D::get_singleton()->joint_create(); +} + +Joint3D::~Joint3D() { + PhysicsServer3D::get_singleton()->free(joint); } /////////////////////////////////// @@ -263,20 +273,20 @@ void PinJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_IMPULSE_CLAMP); } -void PinJoint3D::set_param(Param p_param, float p_value) { +void PinJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, 3); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer3D::PinJointParam(p_param), p_value); } } -float PinJoint3D::get_param(Param p_param) const { +real_t PinJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, 3, 0); return params[p_param]; } -RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void PinJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Vector3 pinpos = get_global_transform().origin; Vector3 local_a = body_a->get_global_transform().affine_inverse().xform(pinpos); Vector3 local_b; @@ -287,11 +297,10 @@ RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { local_b = pinpos; } - RID j = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_pin(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < 3; i++) { - PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PinJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer3D::PinJointParam(i), params[i]); } - return j; } PinJoint3D::PinJoint3D() { @@ -304,19 +313,19 @@ PinJoint3D::PinJoint3D() { /////////////////////////////////// -void HingeJoint3D::_set_upper_limit(float p_limit) { +void HingeJoint3D::_set_upper_limit(real_t p_limit) { set_param(PARAM_LIMIT_UPPER, Math::deg2rad(p_limit)); } -float HingeJoint3D::_get_upper_limit() const { +real_t HingeJoint3D::_get_upper_limit() const { return Math::rad2deg(get_param(PARAM_LIMIT_UPPER)); } -void HingeJoint3D::_set_lower_limit(float p_limit) { +void HingeJoint3D::_set_lower_limit(real_t p_limit) { set_param(PARAM_LIMIT_LOWER, Math::deg2rad(p_limit)); } -float HingeJoint3D::_get_lower_limit() const { +real_t HingeJoint3D::_get_lower_limit() const { return Math::rad2deg(get_param(PARAM_LIMIT_LOWER)); } @@ -361,17 +370,17 @@ void HingeJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_MAX); } -void HingeJoint3D::set_param(Param p_param, float p_value) { +void HingeJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value); } update_gizmo(); } -float HingeJoint3D::get_param(Param p_param) const { +real_t HingeJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params[p_param]; } @@ -379,7 +388,7 @@ float HingeJoint3D::get_param(Param p_param) const { void HingeJoint3D::set_flag(Flag p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags[p_flag] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value); } @@ -391,7 +400,7 @@ bool HingeJoint3D::get_flag(Flag p_flag) const { return flags[p_flag]; } -RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); Transform ainv = body_a->get_global_transform().affine_inverse(); @@ -406,15 +415,14 @@ RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_hinge(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HingeJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->hinge_joint_set_param(p_joint, PhysicsServer3D::HingeJointParam(i), params[i]); } for (int i = 0; i < FLAG_MAX; i++) { set_flag(Flag(i), flags[i]); - PhysicsServer3D::get_singleton()->hinge_joint_set_flag(j, PhysicsServer3D::HingeJointFlag(i), flags[i]); + PhysicsServer3D::get_singleton()->hinge_joint_set_flag(p_joint, PhysicsServer3D::HingeJointFlag(i), flags[i]); } - return j; } HingeJoint3D::HingeJoint3D() { @@ -435,19 +443,19 @@ HingeJoint3D::HingeJoint3D() { ////////////////////////////////// -void SliderJoint3D::_set_upper_limit_angular(float p_limit_angular) { +void SliderJoint3D::_set_upper_limit_angular(real_t p_limit_angular) { set_param(PARAM_ANGULAR_LIMIT_UPPER, Math::deg2rad(p_limit_angular)); } -float SliderJoint3D::_get_upper_limit_angular() const { +real_t SliderJoint3D::_get_upper_limit_angular() const { return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_UPPER)); } -void SliderJoint3D::_set_lower_limit_angular(float p_limit_angular) { +void SliderJoint3D::_set_lower_limit_angular(real_t p_limit_angular) { set_param(PARAM_ANGULAR_LIMIT_LOWER, Math::deg2rad(p_limit_angular)); } -float SliderJoint3D::_get_lower_limit_angular() const { +real_t SliderJoint3D::_get_lower_limit_angular() const { return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_LOWER)); } @@ -512,21 +520,21 @@ void SliderJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_MAX); } -void SliderJoint3D::set_param(Param p_param, float p_value) { +void SliderJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value); } update_gizmo(); } -float SliderJoint3D::get_param(Param p_param) const { +real_t SliderJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params[p_param]; } -RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); Transform ainv = body_a->get_global_transform().affine_inverse(); @@ -541,12 +549,10 @@ RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_slider(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SliderJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->slider_joint_set_param(p_joint, PhysicsServer3D::SliderJointParam(i), params[i]); } - - return j; } SliderJoint3D::SliderJoint3D() { @@ -577,19 +583,19 @@ SliderJoint3D::SliderJoint3D() { ////////////////////////////////// -void ConeTwistJoint3D::_set_swing_span(float p_limit_angular) { +void ConeTwistJoint3D::_set_swing_span(real_t p_limit_angular) { set_param(PARAM_SWING_SPAN, Math::deg2rad(p_limit_angular)); } -float ConeTwistJoint3D::_get_swing_span() const { +real_t ConeTwistJoint3D::_get_swing_span() const { return Math::rad2deg(get_param(PARAM_SWING_SPAN)); } -void ConeTwistJoint3D::_set_twist_span(float p_limit_angular) { +void ConeTwistJoint3D::_set_twist_span(real_t p_limit_angular) { set_param(PARAM_TWIST_SPAN, Math::deg2rad(p_limit_angular)); } -float ConeTwistJoint3D::_get_twist_span() const { +real_t ConeTwistJoint3D::_get_twist_span() const { return Math::rad2deg(get_param(PARAM_TWIST_SPAN)); } @@ -618,22 +624,22 @@ void ConeTwistJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_MAX); } -void ConeTwistJoint3D::set_param(Param p_param, float p_value) { +void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value); } update_gizmo(); } -float ConeTwistJoint3D::get_param(Param p_param) const { +real_t ConeTwistJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params[p_param]; } -RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); @@ -651,12 +657,10 @@ RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *bod local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_cone_twist(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::ConeTwistJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(p_joint, PhysicsServer3D::ConeTwistJointParam(i), params[i]); } - - return j; } ConeTwistJoint3D::ConeTwistJoint3D() { @@ -669,51 +673,51 @@ ConeTwistJoint3D::ConeTwistJoint3D() { ///////////////////////////////////////////////////////////////////// -void Generic6DOFJoint3D::_set_angular_hi_limit_x(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_hi_limit_x(real_t p_limit_angular) { set_param_x(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_hi_limit_x() const { +real_t Generic6DOFJoint3D::_get_angular_hi_limit_x() const { return Math::rad2deg(get_param_x(PARAM_ANGULAR_UPPER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_lo_limit_x(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_lo_limit_x(real_t p_limit_angular) { set_param_x(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_lo_limit_x() const { +real_t Generic6DOFJoint3D::_get_angular_lo_limit_x() const { return Math::rad2deg(get_param_x(PARAM_ANGULAR_LOWER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_hi_limit_y(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_hi_limit_y(real_t p_limit_angular) { set_param_y(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_hi_limit_y() const { +real_t Generic6DOFJoint3D::_get_angular_hi_limit_y() const { return Math::rad2deg(get_param_y(PARAM_ANGULAR_UPPER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_lo_limit_y(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_lo_limit_y(real_t p_limit_angular) { set_param_y(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_lo_limit_y() const { +real_t Generic6DOFJoint3D::_get_angular_lo_limit_y() const { return Math::rad2deg(get_param_y(PARAM_ANGULAR_LOWER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_hi_limit_z(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_hi_limit_z(real_t p_limit_angular) { set_param_z(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_hi_limit_z() const { +real_t Generic6DOFJoint3D::_get_angular_hi_limit_z() const { return Math::rad2deg(get_param_z(PARAM_ANGULAR_UPPER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_lo_limit_z(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_lo_limit_z(real_t p_limit_angular) { set_param_z(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_lo_limit_z() const { +real_t Generic6DOFJoint3D::_get_angular_lo_limit_z() const { return Math::rad2deg(get_param_z(PARAM_ANGULAR_LOWER_LIMIT)); } @@ -875,45 +879,45 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_MAX); } -void Generic6DOFJoint3D::set_param_x(Param p_param, float p_value) { +void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_x[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } update_gizmo(); } -float Generic6DOFJoint3D::get_param_x(Param p_param) const { +real_t Generic6DOFJoint3D::get_param_x(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_x[p_param]; } -void Generic6DOFJoint3D::set_param_y(Param p_param, float p_value) { +void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_y[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } update_gizmo(); } -float Generic6DOFJoint3D::get_param_y(Param p_param) const { +real_t Generic6DOFJoint3D::get_param_y(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_y[p_param]; } -void Generic6DOFJoint3D::set_param_z(Param p_param, float p_value) { +void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_z[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } update_gizmo(); } -float Generic6DOFJoint3D::get_param_z(Param p_param) const { +real_t Generic6DOFJoint3D::get_param_z(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_z[p_param]; } @@ -921,7 +925,7 @@ float Generic6DOFJoint3D::get_param_z(Param p_param) const { void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags_x[p_flag] = p_enabled; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } update_gizmo(); @@ -935,7 +939,7 @@ bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const { void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags_y[p_flag] = p_enabled; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } update_gizmo(); @@ -949,7 +953,7 @@ bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const { void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags_z[p_flag] = p_enabled; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } update_gizmo(); @@ -960,7 +964,7 @@ bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const { return flags_z[p_flag]; } -RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); @@ -978,19 +982,17 @@ RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *b local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_generic_6dof(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]); } for (int i = 0; i < FLAG_MAX; i++) { - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]); } - - return j; } Generic6DOFJoint3D::Generic6DOFJoint3D() { diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h index 9702076318..8d0a16e432 100644 --- a/scene/3d/physics_joint_3d.h +++ b/scene/3d/physics_joint_3d.h @@ -44,9 +44,10 @@ class Joint3D : public Node3D { NodePath a; NodePath b; - int solver_priority; - bool exclude_from_collision; + int solver_priority = 1; + bool exclude_from_collision = true; String warning; + bool configured = false; protected: void _disconnect_signals(); @@ -55,10 +56,12 @@ protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0; static void _bind_methods(); + _FORCE_INLINE_ bool is_configured() const { return configured; } + public: virtual String get_configuration_warning() const override; @@ -76,6 +79,7 @@ public: RID get_joint() const { return joint; } Joint3D(); + ~Joint3D(); }; /////////////////////////////////////////// @@ -91,13 +95,13 @@ public: }; protected: - float params[3]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + real_t params[3]; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; PinJoint3D(); }; @@ -127,20 +131,20 @@ public: }; protected: - float params[PARAM_MAX]; + real_t params[PARAM_MAX]; bool flags[FLAG_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); - void _set_upper_limit(float p_limit); - float _get_upper_limit() const; + void _set_upper_limit(real_t p_limit); + real_t _get_upper_limit() const; - void _set_lower_limit(float p_limit); - float _get_lower_limit() const; + void _set_lower_limit(real_t p_limit); + real_t _get_lower_limit() const; public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; void set_flag(Flag p_flag, bool p_value); bool get_flag(Flag p_flag) const; @@ -184,19 +188,19 @@ public: }; protected: - void _set_upper_limit_angular(float p_limit_angular); - float _get_upper_limit_angular() const; + void _set_upper_limit_angular(real_t p_limit_angular); + real_t _get_upper_limit_angular() const; - void _set_lower_limit_angular(float p_limit_angular); - float _get_lower_limit_angular() const; + void _set_lower_limit_angular(real_t p_limit_angular); + real_t _get_lower_limit_angular() const; - float params[PARAM_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + real_t params[PARAM_MAX]; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; SliderJoint3D(); }; @@ -217,19 +221,19 @@ public: }; protected: - void _set_swing_span(float p_limit_angular); - float _get_swing_span() const; + void _set_swing_span(real_t p_limit_angular); + real_t _get_swing_span() const; - void _set_twist_span(float p_limit_angular); - float _get_twist_span() const; + void _set_twist_span(real_t p_limit_angular); + real_t _get_twist_span() const; - float params[PARAM_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + real_t params[PARAM_MAX]; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; ConeTwistJoint3D(); }; @@ -277,43 +281,43 @@ public: }; protected: - void _set_angular_hi_limit_x(float p_limit_angular); - float _get_angular_hi_limit_x() const; + void _set_angular_hi_limit_x(real_t p_limit_angular); + real_t _get_angular_hi_limit_x() const; - void _set_angular_hi_limit_y(float p_limit_angular); - float _get_angular_hi_limit_y() const; + void _set_angular_hi_limit_y(real_t p_limit_angular); + real_t _get_angular_hi_limit_y() const; - void _set_angular_hi_limit_z(float p_limit_angular); - float _get_angular_hi_limit_z() const; + void _set_angular_hi_limit_z(real_t p_limit_angular); + real_t _get_angular_hi_limit_z() const; - void _set_angular_lo_limit_x(float p_limit_angular); - float _get_angular_lo_limit_x() const; + void _set_angular_lo_limit_x(real_t p_limit_angular); + real_t _get_angular_lo_limit_x() const; - void _set_angular_lo_limit_y(float p_limit_angular); - float _get_angular_lo_limit_y() const; + void _set_angular_lo_limit_y(real_t p_limit_angular); + real_t _get_angular_lo_limit_y() const; - void _set_angular_lo_limit_z(float p_limit_angular); - float _get_angular_lo_limit_z() const; + void _set_angular_lo_limit_z(real_t p_limit_angular); + real_t _get_angular_lo_limit_z() const; - float params_x[PARAM_MAX]; + real_t params_x[PARAM_MAX]; bool flags_x[FLAG_MAX]; - float params_y[PARAM_MAX]; + real_t params_y[PARAM_MAX]; bool flags_y[FLAG_MAX]; - float params_z[PARAM_MAX]; + real_t params_z[PARAM_MAX]; bool flags_z[FLAG_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param_x(Param p_param, float p_value); - float get_param_x(Param p_param) const; + void set_param_x(Param p_param, real_t p_value); + real_t get_param_x(Param p_param) const; - void set_param_y(Param p_param, float p_value); - float get_param_y(Param p_param) const; + void set_param_y(Param p_param, real_t p_value); + real_t get_param_y(Param p_param) const; - void set_param_z(Param p_param, float p_value); - float get_param_z(Param p_param) const; + void set_param_z(Param p_param, real_t p_value); + real_t get_param_z(Param p_param) const; void set_flag_x(Flag p_flag, bool p_enabled); bool get_flag_x(Flag p_flag) const; diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 59b59c7163..bfe79f15f5 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -148,14 +148,14 @@ void RayCast3D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (enabled && !Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(true); - - if (get_tree()->is_debugging_collisions_hint()) { - _update_debug_shape(); - } } else { set_physics_process_internal(false); } + if (get_tree()->is_debugging_collisions_hint()) { + _update_debug_shape(); + } + if (Object::cast_to<CollisionObject3D>(get_parent())) { if (exclude_parent_body) { exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); @@ -348,23 +348,32 @@ void RayCast3D::_update_debug_shape() { } MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape); - if (!mi->get_mesh().is_valid()) { + Ref<ArrayMesh> mesh = mi->get_mesh(); + if (!mesh.is_valid()) { return; } - Ref<ArrayMesh> mesh = mi->get_mesh(); - mesh->clear_surfaces(); - - Array a; - a.resize(Mesh::ARRAY_MAX); - Vector<Vector3> verts; verts.push_back(Vector3()); verts.push_back(target_position); - a[Mesh::ARRAY_VERTEX] = verts; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a); - mesh->surface_set_material(0, debug_material); + if (mesh->get_surface_count() == 0) { + Array a; + a.resize(Mesh::ARRAY_MAX); + a[Mesh::ARRAY_VERTEX] = verts; + + uint32_t flags = Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); + mesh->surface_set_material(0, debug_material); + } else { + Vector<uint8_t> byte_array; + int array_size = sizeof(Vector3) * verts.size(); + byte_array.resize(array_size); + copymem(byte_array.ptrw(), verts.ptr(), array_size); + + RS::get_singleton()->mesh_surface_update_region(mesh->get_rid(), 0, 0, byte_array); + } } void RayCast3D::_clear_debug_shape() { @@ -383,13 +392,4 @@ void RayCast3D::_clear_debug_shape() { } RayCast3D::RayCast3D() { - enabled = true; - collided = false; - against_shape = 0; - collision_mask = 1; - target_position = Vector3(0, -1, 0); - debug_shape = nullptr; - exclude_parent_body = true; - collide_with_areas = false; - collide_with_bodies = true; } diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h index 4109853280..ae92189527 100644 --- a/scene/3d/ray_cast_3d.h +++ b/scene/3d/ray_cast_3d.h @@ -36,28 +36,28 @@ class RayCast3D : public Node3D { GDCLASS(RayCast3D, Node3D); - bool enabled; - bool collided; + bool enabled = true; + bool collided = false; ObjectID against; - int against_shape; + int against_shape = 0; Vector3 collision_point; Vector3 collision_normal; - Vector3 target_position; + Vector3 target_position = Vector3(0, -1, 0); Set<RID> exclude; - uint32_t collision_mask; - bool exclude_parent_body; + uint32_t collision_mask = 1; + bool exclude_parent_body = true; - Node *debug_shape; + Node *debug_shape = nullptr; Ref<Material> debug_material; void _create_debug_shape(); void _update_debug_shape(); void _clear_debug_shape(); - bool collide_with_areas; - bool collide_with_bodies; + bool collide_with_areas = false; + bool collide_with_bodies = true; protected: void _notification(int p_what); diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 63fa0c06c3..ad24f39bce 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -42,7 +42,7 @@ float ReflectionProbe::get_intensity() const { void ReflectionProbe::set_ambient_mode(AmbientMode p_mode) { ambient_mode = p_mode; RS::get_singleton()->reflection_probe_set_ambient_mode(probe, RS::ReflectionProbeAmbientMode(p_mode)); - _change_notify(); + notify_property_list_changed(); } ReflectionProbe::AmbientMode ReflectionProbe::get_ambient_mode() const { @@ -95,13 +95,12 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) { if (extents[i] - 0.01 < ABS(origin_offset[i])) { origin_offset[i] = SGN(origin_offset[i]) * (extents[i] - 0.01); - _change_notify("origin_offset"); } } RS::get_singleton()->reflection_probe_set_extents(probe, extents); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); - _change_notify("extents"); + update_gizmo(); } @@ -120,7 +119,6 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) { RS::get_singleton()->reflection_probe_set_extents(probe, extents); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); - _change_notify("origin_offset"); update_gizmo(); } @@ -257,20 +255,6 @@ void ReflectionProbe::_bind_methods() { } ReflectionProbe::ReflectionProbe() { - intensity = 1.0; - ambient_mode = AMBIENT_ENVIRONMENT; - ambient_color = Color(0, 0, 0); - ambient_color_energy = 1.0; - max_distance = 0; - extents = Vector3(1, 1, 1); - origin_offset = Vector3(0, 0, 0); - box_projection = false; - interior = false; - enable_shadows = false; - cull_mask = (1 << 20) - 1; - update_mode = UPDATE_ONCE; - lod_threshold = 1.0; - probe = RenderingServer::get_singleton()->reflection_probe_create(); RS::get_singleton()->instance_set_base(get_instance(), probe); set_disable_scale(true); diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index a43d4e2422..15c2da3ae0 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -53,20 +53,20 @@ public: private: RID probe; - float intensity; - float max_distance; - Vector3 extents; - Vector3 origin_offset; - bool box_projection; - bool enable_shadows; - bool interior; - AmbientMode ambient_mode; - Color ambient_color; - float ambient_color_energy; - float lod_threshold; - - uint32_t cull_mask; - UpdateMode update_mode; + float intensity = 1.0; + float max_distance = 0.0; + Vector3 extents = Vector3(1, 1, 1); + Vector3 origin_offset = Vector3(0, 0, 0); + bool box_projection = false; + bool enable_shadows = false; + bool interior = false; + AmbientMode ambient_mode = AMBIENT_ENVIRONMENT; + Color ambient_color = Color(0, 0, 0); + float ambient_color_energy = 1.0; + float lod_threshold = 1.0; + + uint32_t cull_mask = (1 << 20) - 1; + UpdateMode update_mode = UPDATE_ONCE; protected: static void _bind_methods(); diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp index 4afbb80779..83ac813c53 100644 --- a/scene/3d/remote_transform_3d.cpp +++ b/scene/3d/remote_transform_3d.cpp @@ -217,10 +217,5 @@ void RemoteTransform3D::_bind_methods() { } RemoteTransform3D::RemoteTransform3D() { - use_global_coordinates = true; - update_remote_position = true; - update_remote_rotation = true; - update_remote_scale = true; - set_notify_transform(true); } diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h index 3b30c835be..21005d92d1 100644 --- a/scene/3d/remote_transform_3d.h +++ b/scene/3d/remote_transform_3d.h @@ -40,10 +40,10 @@ class RemoteTransform3D : public Node3D { ObjectID cache; - bool use_global_coordinates; - bool update_remote_position; - bool update_remote_rotation; - bool update_remote_scale; + bool use_global_coordinates = true; + bool update_remote_position = true; + bool update_remote_rotation = true; + bool update_remote_scale = true; void _update_remote(); void _update_cache(); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 5e09a15b80..be62fe801f 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -304,7 +304,7 @@ void Skeleton3D::_notification(int p_what) { uint32_t bind_count = skin->get_bind_count(); if (E->get()->bind_count != bind_count) { - RS::get_singleton()->skeleton_allocate(skeleton, bind_count); + RS::get_singleton()->skeleton_allocate_data(skeleton, bind_count); E->get()->bind_count = bind_count; E->get()->skin_bone_indices.resize(bind_count); E->get()->skin_bone_indices_ptrs = E->get()->skin_bone_indices.ptrw(); @@ -927,10 +927,6 @@ void Skeleton3D::_bind_methods() { } Skeleton3D::Skeleton3D() { - animate_physical_bones = true; - dirty = false; - version = 1; - process_order_dirty = true; } Skeleton3D::~Skeleton3D() { diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 73417dce21..9772bfcc95 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -74,57 +74,44 @@ private: struct Bone { String name; - bool enabled; - int parent; - int sort_index; //used for re-sorting process order + bool enabled = true; + int parent = -1; + int sort_index = 0; //used for re-sorting process order - bool disable_rest; + bool disable_rest = false; Transform rest; Transform pose; Transform pose_global; - bool custom_pose_enable; + bool custom_pose_enable = false; Transform custom_pose; - float global_pose_override_amount; - bool global_pose_override_reset; + float global_pose_override_amount = 0.0; + bool global_pose_override_reset = false; Transform global_pose_override; #ifndef _3D_DISABLED - PhysicalBone3D *physical_bone; - PhysicalBone3D *cache_parent_physical_bone; + PhysicalBone3D *physical_bone = nullptr; + PhysicalBone3D *cache_parent_physical_bone = nullptr; #endif // _3D_DISABLED List<ObjectID> nodes_bound; - - Bone() { - parent = -1; - enabled = true; - disable_rest = false; - custom_pose_enable = false; - global_pose_override_amount = 0; - global_pose_override_reset = false; -#ifndef _3D_DISABLED - physical_bone = nullptr; - cache_parent_physical_bone = nullptr; -#endif // _3D_DISABLED - } }; Set<SkinReference *> skin_bindings; void _skin_changed(); - bool animate_physical_bones; + bool animate_physical_bones = true; Vector<Bone> bones; Vector<int> process_order; - bool process_order_dirty; + bool process_order_dirty = true; void _make_dirty(); - bool dirty; + bool dirty = false; - uint64_t version; + uint64_t version = 1; // bind helpers Array _get_bound_child_nodes_to_bone(int p_bone) const { diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 557647aa62..eefecf68bb 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -54,15 +54,13 @@ class FabrikInverseKinematic { BoneId bone = -1; PhysicalBone3D *pb = nullptr; - real_t length = 0; + real_t length = 0.0; /// Positions relative to root bone Transform initial_transform; Vector3 current_pos; // Direction from this bone to child Vector3 current_ori; - ChainItem() {} - ChainItem *find_child(const BoneId p_bone_id); ChainItem *add_child(const BoneId p_bone_id); }; @@ -80,7 +78,7 @@ class FabrikInverseKinematic { struct Chain { ChainItem chain_root; - ChainItem *middle_chain_item; + ChainItem *middle_chain_item = nullptr; Vector<ChainTip> tips; Vector3 magnet_position; }; @@ -130,7 +128,7 @@ class SkeletonIK3D : public Node { StringName root_bone; StringName tip_bone; - real_t interpolation = 1; + real_t interpolation = 1.0; Transform target; NodePath target_node_path_override; bool override_tip_basis = true; diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 785465f28e..2d8f22ab37 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -245,13 +245,11 @@ bool SoftBody3D::_get_property_pinned_points(int p_item, const String &p_what, V return true; } -void SoftBody3D::_changed_callback(Object *p_changed, const char *p_prop) { +void SoftBody3D::_softbody_changed() { prepare_physics_server(); _reset_points_offsets(); #ifdef TOOLS_ENABLED - if (p_changed == this) { - update_configuration_warning(); - } + update_configuration_warning(); #endif } @@ -259,7 +257,9 @@ void SoftBody3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { if (Engine::get_singleton()->is_editor_hint()) { - add_change_receptor(this); + // I have no idea what this is supposed to do, it's really weird + // leaving for upcoming PK work on physics + //add_change_receptor(this); } RID space = get_world_3d()->get_space(); @@ -337,8 +337,8 @@ void SoftBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness); ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness); - ClassDB::bind_method(D_METHOD("set_areaAngular_stiffness", "areaAngular_stiffness"), &SoftBody3D::set_areaAngular_stiffness); - ClassDB::bind_method(D_METHOD("get_areaAngular_stiffness"), &SoftBody3D::get_areaAngular_stiffness); + ClassDB::bind_method(D_METHOD("set_angular_stiffness", "angular_stiffness"), &SoftBody3D::set_angular_stiffness); + ClassDB::bind_method(D_METHOD("get_angular_stiffness"), &SoftBody3D::get_angular_stiffness); ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness); ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness); @@ -366,7 +366,7 @@ void SoftBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_angular_stiffness", "get_angular_stiffness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); @@ -612,12 +612,12 @@ real_t SoftBody3D::get_linear_stiffness() { return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid); } -void SoftBody3D::set_areaAngular_stiffness(real_t p_areaAngular_stiffness) { - PhysicsServer3D::get_singleton()->soft_body_set_areaAngular_stiffness(physics_rid, p_areaAngular_stiffness); +void SoftBody3D::set_angular_stiffness(real_t p_angular_stiffness) { + PhysicsServer3D::get_singleton()->soft_body_set_angular_stiffness(physics_rid, p_angular_stiffness); } -real_t SoftBody3D::get_areaAngular_stiffness() { - return PhysicsServer3D::get_singleton()->soft_body_get_areaAngular_stiffness(physics_rid); +real_t SoftBody3D::get_angular_stiffness() { + return PhysicsServer3D::get_singleton()->soft_body_get_angular_stiffness(physics_rid); } void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) { diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h index d3c5dc022f..6e24a530bd 100644 --- a/scene/3d/soft_body_3d.h +++ b/scene/3d/soft_body_3d.h @@ -39,13 +39,13 @@ class SoftBodyRenderingServerHandler { friend class SoftBody3D; RID mesh; - int surface; + int surface = 0; Vector<uint8_t> buffer; - uint32_t stride; - uint32_t offset_vertices; - uint32_t offset_normal; + uint32_t stride = 0; + uint32_t offset_vertices = 0; + uint32_t offset_normal = 0; - uint8_t *write_buffer; + uint8_t *write_buffer = nullptr; private: SoftBodyRenderingServerHandler(); @@ -91,13 +91,15 @@ private: bool pinned_points_cache_dirty = true; Ref<ArrayMesh> debug_mesh_cache; - class MeshInstance3D *debug_mesh; + class MeshInstance3D *debug_mesh = nullptr; - bool capture_input_on_drag; + bool capture_input_on_drag = false; bool ray_pickable = true; void _update_pickable(); + void _softbody_changed(); + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -107,8 +109,6 @@ protected: bool _set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value); bool _get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; - void _notification(int p_what); static void _bind_methods(); @@ -149,8 +149,8 @@ public: void set_linear_stiffness(real_t p_linear_stiffness); real_t get_linear_stiffness(); - void set_areaAngular_stiffness(real_t p_areaAngular_stiffness); - real_t get_areaAngular_stiffness(); + void set_angular_stiffness(real_t p_angular_stiffness); + real_t get_angular_stiffness(); void set_volume_stiffness(real_t p_volume_stiffness); real_t get_volume_stiffness(); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 6812282844..9518b47696 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -78,11 +78,11 @@ void SpringArm3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); } -float SpringArm3D::get_length() const { +real_t SpringArm3D::get_length() const { return spring_length; } -void SpringArm3D::set_length(float p_length) { +void SpringArm3D::set_length(real_t p_length) { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) { update_gizmo(); } @@ -106,11 +106,11 @@ uint32_t SpringArm3D::get_mask() { return mask; } -float SpringArm3D::get_margin() { +real_t SpringArm3D::get_margin() { return margin; } -void SpringArm3D::set_margin(float p_margin) { +void SpringArm3D::set_margin(real_t p_margin) { margin = p_margin; } @@ -126,7 +126,7 @@ void SpringArm3D::clear_excluded_objects() { excluded_objects.clear(); } -float SpringArm3D::get_hit_length() { +real_t SpringArm3D::get_hit_length() { return current_spring_length; } @@ -143,7 +143,7 @@ void SpringArm3D::process_spring() { PhysicsDirectSpaceState3D::RayResult r; bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask); if (intersected) { - float dist = get_global_transform().origin.distance_to(r.position); + real_t dist = get_global_transform().origin.distance_to(r.position); dist -= margin; motion_delta = dist / (spring_length); } diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h index 4c2d2a54ff..63505ab9d3 100644 --- a/scene/3d/spring_arm_3d.h +++ b/scene/3d/spring_arm_3d.h @@ -38,19 +38,19 @@ class SpringArm3D : public Node3D { Ref<Shape3D> shape; Set<RID> excluded_objects; - float spring_length = 1; - float current_spring_length = 0; + real_t spring_length = 1.0; + real_t current_spring_length = 0.0; bool keep_child_basis = false; uint32_t mask = 1; - float margin = 0.01; + real_t margin = 0.01; protected: void _notification(int p_what); static void _bind_methods(); public: - void set_length(float p_length); - float get_length() const; + void set_length(real_t p_length); + real_t get_length() const; void set_shape(Ref<Shape3D> p_shape); Ref<Shape3D> get_shape() const; void set_mask(uint32_t p_mask); @@ -58,9 +58,9 @@ public: void add_excluded_object(RID p_rid); bool remove_excluded_object(RID p_rid); void clear_excluded_objects(); - float get_hit_length(); - void set_margin(float p_margin); - float get_margin(); + real_t get_hit_length(); + void set_margin(real_t p_margin); + real_t get_margin(); SpringArm3D() {} diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 3e49750366..cb2df9130f 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -339,24 +339,10 @@ void SpriteBase3D::_bind_methods() { } SpriteBase3D::SpriteBase3D() { - color_dirty = true; - centered = true; - hflip = false; - vflip = false; - parent_sprite = nullptr; - pI = nullptr; - for (int i = 0; i < FLAG_MAX; i++) { flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED; } - alpha_cut = ALPHA_CUT_DISABLED; - billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; - axis = Vector3::AXIS_Z; - pixel_size = 0.01; - modulate = Color(1, 1, 1, 1); - pending_update = false; - opacity = 1.0; immediate = RenderingServer::get_singleton()->immediate_create(); set_base(immediate); } @@ -557,8 +543,6 @@ void Sprite3D::set_frame(int p_frame) { _queue_update(); - _change_notify("frame"); - _change_notify("frame_coords"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -581,7 +565,7 @@ void Sprite3D::set_vframes(int p_amount) { ERR_FAIL_COND(p_amount < 1); vframes = p_amount; _queue_update(); - _change_notify(); + notify_property_list_changed(); } int Sprite3D::get_vframes() const { @@ -592,7 +576,7 @@ void Sprite3D::set_hframes(int p_amount) { ERR_FAIL_COND(p_amount < 1); hframes = p_amount; _queue_update(); - _change_notify(); + notify_property_list_changed(); } int Sprite3D::get_hframes() const { @@ -904,12 +888,13 @@ void AnimatedSprite3D::_notification(int p_what) { } else { frame = fc - 1; } + emit_signal(SceneStringNames::get_singleton()->animation_finished); } else { frame++; } _queue_update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } float to_process = MIN(timeout, remaining); @@ -935,7 +920,7 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { set_frame(frame); } - _change_notify(); + notify_property_list_changed(); _reset_timeout(); _queue_update(); update_configuration_warning(); @@ -968,7 +953,7 @@ void AnimatedSprite3D::set_frame(int p_frame) { frame = p_frame; _reset_timeout(); _queue_update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -1004,8 +989,6 @@ Rect2 AnimatedSprite3D::get_item_rect() const { void AnimatedSprite3D::_res_changed() { set_frame(frame); - _change_notify("frame"); - _change_notify("animation"); _queue_update(); } @@ -1062,7 +1045,7 @@ void AnimatedSprite3D::set_animation(const StringName &p_animation) { animation = p_animation; _reset_timeout(); set_frame(0); - _change_notify(); + notify_property_list_changed(); _queue_update(); } @@ -1101,6 +1084,7 @@ void AnimatedSprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame); ADD_SIGNAL(MethodInfo("frame_changed")); + ADD_SIGNAL(MethodInfo("animation_finished")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); @@ -1109,8 +1093,4 @@ void AnimatedSprite3D::_bind_methods() { } AnimatedSprite3D::AnimatedSprite3D() { - frame = 0; - playing = false; - animation = "default"; - timeout = 0; } diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 3e38d4581e..a9ce2d8eee 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -55,32 +55,32 @@ public: }; private: - bool color_dirty; + bool color_dirty = true; Color color_accum; - SpriteBase3D *parent_sprite; + SpriteBase3D *parent_sprite = nullptr; List<SpriteBase3D *> children; - List<SpriteBase3D *>::Element *pI; + List<SpriteBase3D *>::Element *pI = nullptr; - bool centered; + bool centered = true; Point2 offset; - bool hflip; - bool vflip; + bool hflip = false; + bool vflip = false; - Color modulate; - float opacity; + Color modulate = Color(1, 1, 1, 1); + float opacity = 1.0; - Vector3::Axis axis; - float pixel_size; + Vector3::Axis axis = Vector3::AXIS_Z; + float pixel_size = 0.01; AABB aabb; RID immediate; bool flags[FLAG_MAX]; - AlphaCutMode alpha_cut; - StandardMaterial3D::BillboardMode billboard_mode; - bool pending_update; + AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; + StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; + bool pending_update = false; void _im_update(); void _propagate_color_changed(); @@ -195,16 +195,16 @@ class AnimatedSprite3D : public SpriteBase3D { GDCLASS(AnimatedSprite3D, SpriteBase3D); Ref<SpriteFrames> frames; - bool playing; - StringName animation; - int frame; + bool playing = false; + StringName animation = "default"; + int frame = 0; - bool centered; + bool centered = true; - float timeout; + float timeout = 0.0; - bool hflip; - bool vflip; + bool hflip = 1; + bool vflip = 1; Color modulate; diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 120bbbae43..0d25e2f21f 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -147,77 +147,77 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) { } } -void VehicleWheel3D::set_radius(float p_radius) { +void VehicleWheel3D::set_radius(real_t p_radius) { m_wheelRadius = p_radius; update_gizmo(); } -float VehicleWheel3D::get_radius() const { +real_t VehicleWheel3D::get_radius() const { return m_wheelRadius; } -void VehicleWheel3D::set_suspension_rest_length(float p_length) { +void VehicleWheel3D::set_suspension_rest_length(real_t p_length) { m_suspensionRestLength = p_length; update_gizmo(); } -float VehicleWheel3D::get_suspension_rest_length() const { +real_t VehicleWheel3D::get_suspension_rest_length() const { return m_suspensionRestLength; } -void VehicleWheel3D::set_suspension_travel(float p_length) { +void VehicleWheel3D::set_suspension_travel(real_t p_length) { m_maxSuspensionTravelCm = p_length / 0.01; } -float VehicleWheel3D::get_suspension_travel() const { +real_t VehicleWheel3D::get_suspension_travel() const { return m_maxSuspensionTravelCm * 0.01; } -void VehicleWheel3D::set_suspension_stiffness(float p_value) { +void VehicleWheel3D::set_suspension_stiffness(real_t p_value) { m_suspensionStiffness = p_value; } -float VehicleWheel3D::get_suspension_stiffness() const { +real_t VehicleWheel3D::get_suspension_stiffness() const { return m_suspensionStiffness; } -void VehicleWheel3D::set_suspension_max_force(float p_value) { +void VehicleWheel3D::set_suspension_max_force(real_t p_value) { m_maxSuspensionForce = p_value; } -float VehicleWheel3D::get_suspension_max_force() const { +real_t VehicleWheel3D::get_suspension_max_force() const { return m_maxSuspensionForce; } -void VehicleWheel3D::set_damping_compression(float p_value) { +void VehicleWheel3D::set_damping_compression(real_t p_value) { m_wheelsDampingCompression = p_value; } -float VehicleWheel3D::get_damping_compression() const { +real_t VehicleWheel3D::get_damping_compression() const { return m_wheelsDampingCompression; } -void VehicleWheel3D::set_damping_relaxation(float p_value) { +void VehicleWheel3D::set_damping_relaxation(real_t p_value) { m_wheelsDampingRelaxation = p_value; } -float VehicleWheel3D::get_damping_relaxation() const { +real_t VehicleWheel3D::get_damping_relaxation() const { return m_wheelsDampingRelaxation; } -void VehicleWheel3D::set_friction_slip(float p_value) { +void VehicleWheel3D::set_friction_slip(real_t p_value) { m_frictionSlip = p_value; } -float VehicleWheel3D::get_friction_slip() const { +real_t VehicleWheel3D::get_friction_slip() const { return m_frictionSlip; } -void VehicleWheel3D::set_roll_influence(float p_value) { +void VehicleWheel3D::set_roll_influence(real_t p_value) { m_rollInfluence = p_value; } -float VehicleWheel3D::get_roll_influence() const { +real_t VehicleWheel3D::get_roll_influence() const { return m_rollInfluence; } @@ -295,27 +295,27 @@ void VehicleWheel3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation"); } -void VehicleWheel3D::set_engine_force(float p_engine_force) { +void VehicleWheel3D::set_engine_force(real_t p_engine_force) { m_engineForce = p_engine_force; } -float VehicleWheel3D::get_engine_force() const { +real_t VehicleWheel3D::get_engine_force() const { return m_engineForce; } -void VehicleWheel3D::set_brake(float p_brake) { +void VehicleWheel3D::set_brake(real_t p_brake) { m_brake = p_brake; } -float VehicleWheel3D::get_brake() const { +real_t VehicleWheel3D::get_brake() const { return m_brake; } -void VehicleWheel3D::set_steering(float p_steering) { +void VehicleWheel3D::set_steering(real_t p_steering) { m_steering = p_steering; } -float VehicleWheel3D::get_steering() const { +real_t VehicleWheel3D::get_steering() const { return m_steering; } @@ -335,39 +335,15 @@ bool VehicleWheel3D::is_used_as_steering() const { return steers; } -float VehicleWheel3D::get_skidinfo() const { +real_t VehicleWheel3D::get_skidinfo() const { return m_skidInfo; } -float VehicleWheel3D::get_rpm() const { +real_t VehicleWheel3D::get_rpm() const { return m_rpm; } VehicleWheel3D::VehicleWheel3D() { - steers = false; - engine_traction = false; - m_steering = real_t(0.); - m_engineForce = real_t(0.); - m_rotation = real_t(0.); - m_deltaRotation = real_t(0.); - m_brake = real_t(0.); - m_rollInfluence = real_t(0.1); - - m_suspensionRestLength = 0.15; - m_wheelRadius = 0.5; //0.28; - m_suspensionStiffness = 5.88; - m_wheelsDampingCompression = 0.83; - m_wheelsDampingRelaxation = 0.88; - m_frictionSlip = 10.5; - m_bIsFrontWheel = false; - m_maxSuspensionTravelCm = 500; - m_maxSuspensionForce = 6000; - - m_suspensionRelativeVelocity = 0; - m_clippedInvContactDotSuspension = 1.0; - m_raycastInfo.m_isInContact = false; - - body = nullptr; } void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) { @@ -564,7 +540,7 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const Vector3 vel = vel1 - vel2; Basis b2trans; - float b2invmass = 0; + real_t b2invmass = 0; Vector3 b2lv; Vector3 b2av; Vector3 b2invinertia; //todo @@ -622,8 +598,8 @@ VehicleBody3D::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDir m_frictionPositionWorld(frictionPosWorld), m_frictionDirectionWorld(frictionDirectionWorld), m_maxImpulse(maxImpulse) { - float denom0 = 0; - float denom1 = 0; + real_t denom0 = 0; + real_t denom1 = 0; { Vector3 r0 = frictionPosWorld - s->get_transform().origin; @@ -831,7 +807,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) { state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); - float step = state->get_step(); + real_t step = state->get_step(); for (int i = 0; i < wheels.size(); i++) { _update_wheel(i, state); @@ -891,7 +867,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) { state = nullptr; } -void VehicleBody3D::set_engine_force(float p_engine_force) { +void VehicleBody3D::set_engine_force(real_t p_engine_force) { engine_force = p_engine_force; for (int i = 0; i < wheels.size(); i++) { VehicleWheel3D &wheelInfo = *wheels[i]; @@ -901,11 +877,11 @@ void VehicleBody3D::set_engine_force(float p_engine_force) { } } -float VehicleBody3D::get_engine_force() const { +real_t VehicleBody3D::get_engine_force() const { return engine_force; } -void VehicleBody3D::set_brake(float p_brake) { +void VehicleBody3D::set_brake(real_t p_brake) { brake = p_brake; for (int i = 0; i < wheels.size(); i++) { VehicleWheel3D &wheelInfo = *wheels[i]; @@ -913,11 +889,11 @@ void VehicleBody3D::set_brake(float p_brake) { } } -float VehicleBody3D::get_brake() const { +real_t VehicleBody3D::get_brake() const { return brake; } -void VehicleBody3D::set_steering(float p_steering) { +void VehicleBody3D::set_steering(real_t p_steering) { m_steeringValue = p_steering; for (int i = 0; i < wheels.size(); i++) { VehicleWheel3D &wheelInfo = *wheels[i]; @@ -927,7 +903,7 @@ void VehicleBody3D::set_steering(float p_steering) { } } -float VehicleBody3D::get_steering() const { +real_t VehicleBody3D::get_steering() const { return m_steeringValue; } @@ -948,16 +924,6 @@ void VehicleBody3D::_bind_methods() { } VehicleBody3D::VehicleBody3D() { - m_pitchControl = 0; - m_currentVehicleSpeedKmHour = real_t(0.); - m_steeringValue = real_t(0.); - - engine_force = 0; - brake = 0; - - state = nullptr; - ccd = false; - exclude.insert(get_rid()); //PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index ca7ea6574d..860fa7e3b7 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -42,52 +42,52 @@ class VehicleWheel3D : public Node3D { Transform m_worldTransform; Transform local_xform; - bool engine_traction; - bool steers; + bool engine_traction = false; + bool steers = false; Vector3 m_chassisConnectionPointCS; //const Vector3 m_wheelDirectionCS; //const Vector3 m_wheelAxleCS; // const or modified by steering - real_t m_suspensionRestLength; - real_t m_maxSuspensionTravelCm; - real_t m_wheelRadius; + real_t m_suspensionRestLength = 0.15; + real_t m_maxSuspensionTravelCm = 500.0; + real_t m_wheelRadius = 0.5; - real_t m_suspensionStiffness; - real_t m_wheelsDampingCompression; - real_t m_wheelsDampingRelaxation; - real_t m_frictionSlip; - real_t m_maxSuspensionForce; - bool m_bIsFrontWheel; + real_t m_suspensionStiffness = 5.88; + real_t m_wheelsDampingCompression = 0.83; + real_t m_wheelsDampingRelaxation = 0.88; + real_t m_frictionSlip = 10.5; + real_t m_maxSuspensionForce = 6000.0; + bool m_bIsFrontWheel = false; - VehicleBody3D *body; + VehicleBody3D *body = nullptr; //btVector3 m_wheelAxleCS; // const or modified by steering ? - real_t m_steering; - real_t m_rotation; - real_t m_deltaRotation; - real_t m_rpm; - real_t m_rollInfluence; - real_t m_engineForce; - real_t m_brake; + real_t m_steering = 0.0; + real_t m_rotation = 0.0; + real_t m_deltaRotation = 0.0; + real_t m_rpm = 0.0; + real_t m_rollInfluence = 0.1; + real_t m_engineForce = 0.0; + real_t m_brake = 0.0; - real_t m_clippedInvContactDotSuspension; - real_t m_suspensionRelativeVelocity; + real_t m_clippedInvContactDotSuspension = 1.0; + real_t m_suspensionRelativeVelocity = 0.0; //calculated by suspension - real_t m_wheelsSuspensionForce; - real_t m_skidInfo; + real_t m_wheelsSuspensionForce = 0.0; + real_t m_skidInfo = 0.0; struct RaycastInfo { //set by raycaster Vector3 m_contactNormalWS; //contactnormal Vector3 m_contactPointWS; //raycast hitpoint - real_t m_suspensionLength; + real_t m_suspensionLength = 0.0; Vector3 m_hardPointWS; //raycast starting point Vector3 m_wheelDirectionWS; //direction in worldspace Vector3 m_wheelAxleWS; // axle in worldspace - bool m_isInContact; - PhysicsBody3D *m_groundObject; //could be general void* ptr + bool m_isInContact = false; + PhysicsBody3D *m_groundObject = nullptr; //could be general void* ptr } m_raycastInfo; void _update(PhysicsDirectBodyState3D *s); @@ -97,29 +97,29 @@ protected: static void _bind_methods(); public: - void set_radius(float p_radius); - float get_radius() const; + void set_radius(real_t p_radius); + real_t get_radius() const; - void set_suspension_rest_length(float p_length); - float get_suspension_rest_length() const; + void set_suspension_rest_length(real_t p_length); + real_t get_suspension_rest_length() const; - void set_suspension_travel(float p_length); - float get_suspension_travel() const; + void set_suspension_travel(real_t p_length); + real_t get_suspension_travel() const; - void set_suspension_stiffness(float p_value); - float get_suspension_stiffness() const; + void set_suspension_stiffness(real_t p_value); + real_t get_suspension_stiffness() const; - void set_suspension_max_force(float p_value); - float get_suspension_max_force() const; + void set_suspension_max_force(real_t p_value); + real_t get_suspension_max_force() const; - void set_damping_compression(float p_value); - float get_damping_compression() const; + void set_damping_compression(real_t p_value); + real_t get_damping_compression() const; - void set_damping_relaxation(float p_value); - float get_damping_relaxation() const; + void set_damping_relaxation(real_t p_value); + real_t get_damping_relaxation() const; - void set_friction_slip(float p_value); - float get_friction_slip() const; + void set_friction_slip(real_t p_value); + real_t get_friction_slip() const; void set_use_as_traction(bool p_enable); bool is_used_as_traction() const; @@ -129,21 +129,21 @@ public: bool is_in_contact() const; - void set_roll_influence(float p_value); - float get_roll_influence() const; + void set_roll_influence(real_t p_value); + real_t get_roll_influence() const; - float get_skidinfo() const; + real_t get_skidinfo() const; - float get_rpm() const; + real_t get_rpm() const; - void set_engine_force(float p_engine_force); - float get_engine_force() const; + void set_engine_force(real_t p_engine_force); + real_t get_engine_force() const; - void set_brake(float p_brake); - float get_brake() const; + void set_brake(real_t p_brake); + real_t get_brake() const; - void set_steering(float p_steering); - float get_steering() const; + void set_steering(real_t p_steering); + real_t get_steering() const; String get_configuration_warning() const override; @@ -153,12 +153,12 @@ public: class VehicleBody3D : public RigidBody3D { GDCLASS(VehicleBody3D, RigidBody3D); - float engine_force; - float brake; + real_t engine_force = 0.0; + real_t brake = 0.0; - real_t m_pitchControl; - real_t m_steeringValue; - real_t m_currentVehicleSpeedKmHour; + real_t m_pitchControl = 0.0; + real_t m_steeringValue = 0.0; + real_t m_currentVehicleSpeedKmHour = 0.0; Set<RID> exclude; @@ -168,12 +168,12 @@ class VehicleBody3D : public RigidBody3D { Vector<real_t> m_sideImpulse; struct btVehicleWheelContactPoint { - PhysicsDirectBodyState3D *m_s; - PhysicsBody3D *m_body1; + PhysicsDirectBodyState3D *m_s = nullptr; + PhysicsBody3D *m_body1 = nullptr; Vector3 m_frictionPositionWorld; Vector3 m_frictionDirectionWorld; - real_t m_jacDiagABInv; - real_t m_maxImpulse; + real_t m_jacDiagABInv = 0.0; + real_t m_maxImpulse = 0.0; btVehicleWheelContactPoint(PhysicsDirectBodyState3D *s, PhysicsBody3D *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse); }; @@ -195,14 +195,14 @@ class VehicleBody3D : public RigidBody3D { void _direct_state_changed(Object *p_state) override; public: - void set_engine_force(float p_engine_force); - float get_engine_force() const; + void set_engine_force(real_t p_engine_force); + real_t get_engine_force() const; - void set_brake(float p_brake); - float get_brake() const; + void set_brake(real_t p_brake); + real_t get_brake() const; - void set_steering(float p_steering); - float get_steering() const; + void set_steering(real_t p_steering); + real_t get_steering() const; VehicleBody3D(); }; diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp index 35d00f3639..5b5cc06456 100644 --- a/scene/3d/velocity_tracker_3d.cpp +++ b/scene/3d/velocity_tracker_3d.cpp @@ -128,6 +128,4 @@ void VelocityTracker3D::_bind_methods() { VelocityTracker3D::VelocityTracker3D() { position_history.resize(4); // should be configurable - position_history_len = 0; - physics_step = false; } diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h index 3fc89cc7fb..e971f4755a 100644 --- a/scene/3d/velocity_tracker_3d.h +++ b/scene/3d/velocity_tracker_3d.h @@ -37,13 +37,13 @@ class VelocityTracker3D : public Reference { GDCLASS(VelocityTracker3D, Reference); struct PositionHistory { - uint64_t frame; + uint64_t frame = 0; Vector3 position; }; - bool physics_step; + bool physics_step = false; Vector<PositionHistory> position_history; - int position_history_len; + int position_history_len = 0; protected: static void _bind_methods(); diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp index 494709fe84..471838b9d1 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -69,7 +69,6 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) { get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb)); } - _change_notify("aabb"); update_gizmo(); } @@ -80,13 +79,16 @@ AABB VisibilityNotifier3D::get_aabb() const { void VisibilityNotifier3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - get_world_3d()->_register_notifier(this, get_global_transform().xform(aabb)); + world = get_world_3d(); + ERR_FAIL_COND(!world.is_valid()); + world->_register_notifier(this, get_global_transform().xform(aabb)); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb)); + world->_update_notifier(this, get_global_transform().xform(aabb)); } break; case NOTIFICATION_EXIT_WORLD: { - get_world_3d()->_remove_notifier(this); + ERR_FAIL_COND(!world.is_valid()); + world->_remove_notifier(this); } break; } } @@ -109,7 +111,6 @@ void VisibilityNotifier3D::_bind_methods() { } VisibilityNotifier3D::VisibilityNotifier3D() { - aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); set_notify_transform(true); } @@ -249,6 +250,4 @@ VisibilityEnabler3D::VisibilityEnabler3D() { for (int i = 0; i < ENABLER_MAX; i++) { enabler[i] = true; } - - visible = false; } diff --git a/scene/3d/visibility_notifier_3d.h b/scene/3d/visibility_notifier_3d.h index 29552510b7..9f7705067f 100644 --- a/scene/3d/visibility_notifier_3d.h +++ b/scene/3d/visibility_notifier_3d.h @@ -33,13 +33,15 @@ #include "scene/3d/node_3d.h" +class World3D; class Camera3D; class VisibilityNotifier3D : public Node3D { GDCLASS(VisibilityNotifier3D, Node3D); + Ref<World3D> world; Set<Camera3D *> cameras; - AABB aabb; + AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); protected: virtual void _screen_enter() {} @@ -74,7 +76,7 @@ protected: virtual void _screen_enter() override; virtual void _screen_exit() override; - bool visible; + bool visible = false; void _find_nodes(Node *p_node); diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 1d0a830383..394c67e873 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -43,7 +43,6 @@ void VisualInstance3D::_update_visibility() { return; } - _change_notify("visible"); RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree()); } @@ -135,7 +134,6 @@ RID VisualInstance3D::get_base() const { VisualInstance3D::VisualInstance3D() { instance = RenderingServer::get_singleton()->instance_create(); RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id()); - layers = 1; set_notify_transform(true); } @@ -371,7 +369,7 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode); ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode); - ClassDB::bind_method(D_METHOD("set_lod_bias", "p_bias"), &GeometryInstance3D::set_lod_bias); + ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias); ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias); ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &GeometryInstance3D::set_custom_aabb); @@ -412,17 +410,5 @@ void GeometryInstance3D::_bind_methods() { } GeometryInstance3D::GeometryInstance3D() { - lod_min_distance = 0; - lod_max_distance = 0; - lod_min_hysteresis = 0; - lod_max_hysteresis = 0; - - lod_bias = 1.0; - - gi_mode = GI_MODE_DISABLED; - lightmap_scale = LIGHTMAP_SCALE_1X; - - shadow_casting_setting = SHADOW_CASTING_SETTING_ON; - extra_cull_margin = 0; //RS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0); } diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index f370f29cb0..7fed8095ef 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -42,7 +42,7 @@ class VisualInstance3D : public Node3D { RID base; RID instance; - uint32_t layers; + uint32_t layers = 1; RID _get_visual_instance_rid() const; @@ -105,21 +105,21 @@ public: }; private: - ShadowCastingSetting shadow_casting_setting; + ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON; Ref<Material> material_override; - float lod_min_distance; - float lod_max_distance; - float lod_min_hysteresis; - float lod_max_hysteresis; + float lod_min_distance = 0.0; + float lod_max_distance = 0.0; + float lod_min_hysteresis = 0.0; + float lod_max_hysteresis = 0.0; - float lod_bias; + float lod_bias = 1.0; mutable HashMap<StringName, Variant> instance_uniforms; mutable HashMap<StringName, StringName> instance_uniform_property_remap; - float extra_cull_margin; - LightmapScale lightmap_scale; - GIMode gi_mode; + float extra_cull_margin = 0.0; + LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X; + GIMode gi_mode = GI_MODE_DISABLED; const StringName *_instance_uniform_get_remap(const StringName p_name) const; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index b99d753dde..17c8596e8f 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -1007,7 +1007,4 @@ Transform Voxelizer::get_to_cell_space_xform() const { } Voxelizer::Voxelizer() { - sorted = false; - color_scan_cell_width = 4; - bake_texture_size = 128; } diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index a0b581d625..87f949e7db 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -44,35 +44,25 @@ private: struct Cell { uint32_t children[8]; - float albedo[3]; //albedo in RGB24 - float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) - float normal[3]; - uint32_t used_sides; - float alpha; //used for upsampling - uint16_t x; - uint16_t y; - uint16_t z; - uint16_t level; + float albedo[3] = {}; //albedo in RGB24 + float emission[3] = {}; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) + float normal[3] = {}; + uint32_t used_sides = 0; + float alpha = 0.0; //used for upsampling + uint16_t x = 0; + uint16_t y = 0; + uint16_t z = 0; + uint16_t level = 0; Cell() { for (int i = 0; i < 8; i++) { children[i] = CHILD_EMPTY; } - - for (int i = 0; i < 3; i++) { - emission[i] = 0; - albedo[i] = 0; - normal[i] = 0; - } - alpha = 0; - used_sides = 0; - x = y = z = 0; - level = 0; } }; Vector<Cell> bake_cells; - int cell_subdiv; + int cell_subdiv = 0; struct CellSort { union { @@ -82,10 +72,10 @@ private: uint64_t x : 16; uint64_t level : 16; }; - uint64_t key; + uint64_t key = 0; }; - int32_t index; + int32_t index = 0; _FORCE_INLINE_ bool operator<(const CellSort &p_cell_sort) const { return key < p_cell_sort.key; @@ -101,16 +91,16 @@ private: Map<Ref<Material>, MaterialCache> material_cache; AABB original_bounds; AABB po2_bounds; - int axis_cell_size[3]; + int axis_cell_size[3] = {}; Transform to_cell_space; - int color_scan_cell_width; - int bake_texture_size; - float cell_size; + int color_scan_cell_width = 4; + int bake_texture_size = 128; + float cell_size = 0.0; - int max_original_cells; - int leaf_voxel_count; + int max_original_cells = 0; + int leaf_voxel_count = 0; Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add); MaterialCache _get_material_cache(Ref<Material> p_material); @@ -119,7 +109,7 @@ private: void _fixup_plot(int p_idx, int p_level); void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx); - bool sorted; + bool sorted = false; void _sort(); public: diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index cf1c319acc..214ffd6bd5 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -35,51 +35,69 @@ void WorldEnvironment::_notification(int p_what) { if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) { if (environment.is_valid()) { - if (get_viewport()->find_world_3d()->get_environment().is_valid()) { - WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_environment(environment); add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_environment(); } if (camera_effects.is_valid()) { - if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) { - WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_camera_effects(camera_effects); add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_camera_effects(); } } else if (p_what == Node3D::NOTIFICATION_EXIT_WORLD || p_what == Node3D::NOTIFICATION_EXIT_TREE) { - if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) { - get_viewport()->find_world_3d()->set_environment(Ref<Environment>()); + if (environment.is_valid()) { remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_environment(); } - if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) { - get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); + if (camera_effects.is_valid()) { remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_camera_effects(); } } } -void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) { - if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) { +void WorldEnvironment::_update_current_environment() { + WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()))); + + if (first) { + get_viewport()->find_world_3d()->set_environment(first->environment); + } else { get_viewport()->find_world_3d()->set_environment(Ref<Environment>()); + } + get_tree()->call_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning"); +} + +void WorldEnvironment::_update_current_camera_effects() { + WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()))); + if (first) { + get_viewport()->find_world_3d()->set_camera_effects(first->camera_effects); + } else { + get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); + } + + get_tree()->call_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning"); +} + +void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) { + if (environment == p_environment) { + return; + } + if (is_inside_tree() && environment.is_valid()) { remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - //clean up } environment = p_environment; + if (is_inside_tree() && environment.is_valid()) { - if (get_viewport()->find_world_3d()->get_environment().is_valid()) { - WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_environment(environment); add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } - update_configuration_warning(); + if (is_inside_tree()) { + _update_current_environment(); + } else { + update_configuration_warning(); + } } Ref<Environment> WorldEnvironment::get_environment() const { @@ -87,22 +105,24 @@ Ref<Environment> WorldEnvironment::get_environment() const { } void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) { + if (camera_effects == p_camera_effects) { + return; + } + if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) { - get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - //clean up } camera_effects = p_camera_effects; if (is_inside_tree() && camera_effects.is_valid()) { - if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) { - WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_camera_effects(camera_effects); add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } - update_configuration_warning(); + if (is_inside_tree()) { + _update_current_camera_effects(); + } else { + update_configuration_warning(); + } } Ref<CameraEffects> WorldEnvironment::get_camera_effects() const { @@ -123,14 +143,18 @@ String WorldEnvironment::get_configuration_warning() const { return warning; } - List<Node *> nodes; - get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), &nodes); + if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() != environment) { + if (!warning.is_empty()) { + warning += "\n\n"; + } + warning += TTR("Only the first Environment has an effect in a scene (or set of instantiated scenes)."); + } - if (nodes.size() > 1) { + if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() != camera_effects) { if (!warning.is_empty()) { warning += "\n\n"; } - warning += TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); + warning += TTR("Only the first CameraEffects has an effect in a scene (or set of instantiated scenes)."); } return warning; diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 3dfba20bf0..e3f28d6d6b 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -41,6 +41,9 @@ class WorldEnvironment : public Node { Ref<Environment> environment; Ref<CameraEffects> camera_effects; + void _update_current_environment(); + void _update_current_camera_effects(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 41e1318b1f..15f562242f 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -311,14 +311,6 @@ AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() { for (int i = 0; i < MAX_BLEND_POINTS; i++) { blend_points[i].name = itos(i); } - blend_points_used = 0; - max_space = 1; - min_space = -1; - - snap = 0.1; - value_label = "value"; - - blend_position = "blend_position"; } AnimationNodeBlendSpace1D::~AnimationNodeBlendSpace1D() { diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index 6edbc4e319..8886e6c679 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -43,24 +43,24 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode { struct BlendPoint { StringName name; Ref<AnimationRootNode> node; - float position; + float position = 0.0; }; BlendPoint blend_points[MAX_BLEND_POINTS]; - int blend_points_used; + int blend_points_used = 0; - float max_space; - float min_space; + float max_space = 1.0; + float min_space = -1.0; - float snap; + float snap = 0.1; - String value_label; + String value_label = "value"; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _tree_changed(); - StringName blend_position; + StringName blend_position = "blend_position"; protected: virtual void _validate_property(PropertyInfo &property) const override; diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index c32cc82bd8..9c4bc107dd 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -437,7 +437,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { Vector2 blend_pos = get_parameter(blend_position); int closest = get_parameter(this->closest); float length_internal = get_parameter(this->length_internal); - float mind = 0; //time of min distance point + float mind = 0.0; //time of min distance point if (blend_mode == BLEND_MODE_INTERPOLATED) { if (triangles.size() == 0) { @@ -529,7 +529,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { } if (new_closest != closest && new_closest != -1) { - float from = 0; + float from = 0.0; if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) { //see how much animation remains from = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, true, 0.0, FILTER_IGNORE, false) - length_internal; @@ -665,18 +665,6 @@ AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() { for (int i = 0; i < MAX_BLEND_POINTS; i++) { blend_points[i].name = itos(i); } - auto_triangles = true; - blend_points_used = 0; - max_space = Vector2(1, 1); - min_space = Vector2(-1, -1); - snap = Vector2(0.1, 0.1); - x_label = "x"; - y_label = "y"; - trianges_dirty = false; - blend_position = "blend_position"; - closest = "closest"; - length_internal = "length_internal"; - blend_mode = BLEND_MODE_INTERPOLATED; } AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() { diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h index c74afcb8ce..65d09a550d 100644 --- a/scene/animation/animation_blend_space_2d.h +++ b/scene/animation/animation_blend_space_2d.h @@ -55,23 +55,23 @@ protected: }; BlendPoint blend_points[MAX_BLEND_POINTS]; - int blend_points_used; + int blend_points_used = 0; struct BlendTriangle { - int points[3]; + int points[3] = {}; }; Vector<BlendTriangle> triangles; - StringName blend_position; - StringName closest; - StringName length_internal; - Vector2 max_space; - Vector2 min_space; - Vector2 snap; - String x_label; - String y_label; - BlendMode blend_mode; + StringName blend_position = "blend_position"; + StringName closest = "closest"; + StringName length_internal = "length_internal"; + Vector2 max_space = Vector2(1, 1); + Vector2 min_space = Vector2(-1, -1); + Vector2 snap = Vector2(0.1, 0.1); + String x_label = "x"; + String y_label = "y"; + BlendMode blend_mode = BLEND_MODE_INTERPOLATED; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _set_triangles(const Vector<int> &p_triangles); @@ -79,8 +79,8 @@ protected: void _blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights); - bool auto_triangles; - bool trianges_dirty; + bool auto_triangles = true; + bool trianges_dirty = false; void _update_triangles(); void _queue_auto_triangles(); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 24ae01e9d8..79a1dc1ac0 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -34,7 +34,6 @@ void AnimationNodeAnimation::set_animation(const StringName &p_name) { animation = p_name; - _change_notify("animation"); } StringName AnimationNodeAnimation::get_animation() const { @@ -125,9 +124,6 @@ void AnimationNodeAnimation::_bind_methods() { } AnimationNodeAnimation::AnimationNodeAnimation() { - last_version = 0; - skip = false; - time = "time"; } //////////////////////////////////////////////////////// @@ -346,21 +342,6 @@ void AnimationNodeOneShot::_bind_methods() { AnimationNodeOneShot::AnimationNodeOneShot() { add_input("in"); add_input("shot"); - - fade_in = 0.1; - fade_out = 0.1; - autorestart = false; - autorestart_delay = 1; - autorestart_random_delay = 0; - - mix = MIX_MODE_BLEND; - sync = false; - - active = "active"; - prev_active = "prev_active"; - time = "time"; - remaining = "remaining"; - time_to_restart = "time_to_restart"; } //////////////////////////////////////////////// @@ -405,10 +386,8 @@ void AnimationNodeAdd2::_bind_methods() { } AnimationNodeAdd2::AnimationNodeAdd2() { - add_amount = "add_amount"; add_input("in"); add_input("add"); - sync = false; } //////////////////////////////////////////////// @@ -454,11 +433,9 @@ void AnimationNodeAdd3::_bind_methods() { } AnimationNodeAdd3::AnimationNodeAdd3() { - add_amount = "add_amount"; add_input("-add"); add_input("in"); add_input("+add"); - sync = false; } ///////////////////////////////////////////// @@ -504,10 +481,8 @@ void AnimationNodeBlend2::_bind_methods() { } AnimationNodeBlend2::AnimationNodeBlend2() { - blend_amount = "blend_amount"; add_input("in"); add_input("blend"); - sync = false; } ////////////////////////////////////// @@ -583,7 +558,6 @@ void AnimationNodeTimeScale::_bind_methods() { } AnimationNodeTimeScale::AnimationNodeTimeScale() { - scale = "scale"; add_input("in"); } @@ -608,7 +582,6 @@ float AnimationNodeTimeSeek::process(float p_time, bool p_seek) { } else if (seek_pos >= 0) { float ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false); set_parameter(this->seek_pos, -1.0); //reset - _change_notify("seek_pos"); return ret; } else { return blend_input(0, p_time, false, 1.0, FILTER_IGNORE, false); @@ -620,7 +593,6 @@ void AnimationNodeTimeSeek::_bind_methods() { AnimationNodeTimeSeek::AnimationNodeTimeSeek() { add_input("in"); - seek_pos = "seek_position"; } ///////////////////////////////////////////////// @@ -728,7 +700,7 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) { return 0; } - float rem = 0; + float rem = 0.0; if (prev < 0) { // process current animation, check for transition @@ -811,16 +783,7 @@ void AnimationNodeTransition::_bind_methods() { } AnimationNodeTransition::AnimationNodeTransition() { - prev_xfading = "prev_xfading"; - prev = "prev"; - time = "time"; - current = "current"; - prev_current = "prev_current"; - xfade = 0.0; - - enabled_inputs = 0; for (int i = 0; i < MAX_INPUTS; i++) { - inputs[i].auto_advance = false; inputs[i].name = "state " + itos(i); } } @@ -1158,6 +1121,13 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } +void AnimationNodeBlendTree::reset_state() { + graph_offset = Vector2(); + nodes.clear(); + emit_changed(); + emit_signal("tree_changed"); +} + void AnimationNodeBlendTree::_tree_changed() { emit_signal("tree_changed"); } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 45a9f2e7e1..d82658c8c2 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -37,10 +37,10 @@ class AnimationNodeAnimation : public AnimationRootNode { GDCLASS(AnimationNodeAnimation, AnimationRootNode); StringName animation; - StringName time; + StringName time = "time"; - uint64_t last_version; - bool skip; + uint64_t last_version = 0; + bool skip = false; protected: void _validate_property(PropertyInfo &property) const override; @@ -71,26 +71,26 @@ public: }; private: - float fade_in; - float fade_out; + float fade_in = 0.1; + float fade_out = 0.1; - bool autorestart; - float autorestart_delay; - float autorestart_random_delay; - MixMode mix; + bool autorestart = false; + float autorestart_delay = 1.0; + float autorestart_random_delay = 0.0; + MixMode mix = MIX_MODE_BLEND; - bool sync; + bool sync = false; /* bool active; bool do_start; float time; float remaining;*/ - StringName active; - StringName prev_active; - StringName time; - StringName remaining; - StringName time_to_restart; + StringName active = "active"; + StringName prev_active = "prev_active"; + StringName time = "time"; + StringName remaining = "remaining"; + StringName time_to_restart = "time_to_restart"; protected: static void _bind_methods(); @@ -132,8 +132,8 @@ VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode) class AnimationNodeAdd2 : public AnimationNode { GDCLASS(AnimationNodeAdd2, AnimationNode); - StringName add_amount; - bool sync; + StringName add_amount = "add_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -156,8 +156,8 @@ public: class AnimationNodeAdd3 : public AnimationNode { GDCLASS(AnimationNodeAdd3, AnimationNode); - StringName add_amount; - bool sync; + StringName add_amount = "add_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -180,8 +180,8 @@ public: class AnimationNodeBlend2 : public AnimationNode { GDCLASS(AnimationNodeBlend2, AnimationNode); - StringName blend_amount; - bool sync; + StringName blend_amount = "blend_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -225,7 +225,7 @@ public: class AnimationNodeTimeScale : public AnimationNode { GDCLASS(AnimationNodeTimeScale, AnimationNode); - StringName scale; + StringName scale = "scale"; protected: static void _bind_methods(); @@ -244,7 +244,7 @@ public: class AnimationNodeTimeSeek : public AnimationNode { GDCLASS(AnimationNodeTimeSeek, AnimationNode); - StringName seek_pos; + StringName seek_pos = "seek_position"; protected: static void _bind_methods(); @@ -268,12 +268,11 @@ class AnimationNodeTransition : public AnimationNode { }; struct InputData { String name; - bool auto_advance; - InputData() { auto_advance = false; } + bool auto_advance = false; }; InputData inputs[MAX_INPUTS]; - int enabled_inputs; + int enabled_inputs = 0; /* float prev_xfading; @@ -282,13 +281,13 @@ class AnimationNodeTransition : public AnimationNode { int current; int prev_current; */ - StringName prev_xfading; - StringName prev; - StringName time; - StringName current; - StringName prev_current; + StringName prev_xfading = "prev_xfading"; + StringName prev = "prev"; + StringName time = "time"; + StringName current = "current"; + StringName prev_current = "prev_current"; - float xfade; + float xfade = 0.0; void _update_inputs(); @@ -352,6 +351,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: enum ConnectionError { CONNECTION_OK, @@ -381,7 +382,7 @@ public: struct NodeConnection { StringName input_node; - int input_index; + int input_index = 0; StringName output_node; }; diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index 6ef2da6977..689acdd57b 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -308,7 +308,4 @@ void AnimationCache::set_root(Node *p_root) { } AnimationCache::AnimationCache() { - root = nullptr; - cache_dirty = true; - cache_valid = false; } diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h index 484b710b06..07c9d09ae0 100644 --- a/scene/animation/animation_cache.h +++ b/scene/animation/animation_cache.h @@ -39,31 +39,23 @@ class AnimationCache : public Object { struct Path { RES resource; - Object *object; - Skeleton3D *skeleton; // haxor - Node *node; - Node3D *spatial; + Object *object = nullptr; + Skeleton3D *skeleton = nullptr; // haxor + Node *node = nullptr; + Node3D *spatial = nullptr; - int bone_idx; + int bone_idx = -1; Vector<StringName> subpath; - bool valid; - Path() { - object = nullptr; - skeleton = nullptr; - node = nullptr; - bone_idx = -1; - valid = false; - spatial = nullptr; - } + bool valid = false; }; Set<Node *> connected_nodes; Vector<Path> path_cache; - Node *root; + Node *root = nullptr; Ref<Animation> animation; - bool cache_dirty; - bool cache_valid; + bool cache_dirty = true; + bool cache_valid = false; void _node_exit_tree(Node *p_node); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index ef9f531f04..d46f24752e 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -130,11 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() { } AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() { - switch_mode = SWITCH_MODE_IMMEDIATE; - auto_advance = false; - xfade = 0; - disabled = false; - priority = 1; } //////////////////////////////////////////////////////// @@ -322,7 +317,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st // stopped, invalid state String node_name = start_request; start_request = StringName(); //clear start request - ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing."); + ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing. Maybe you need to enable Autoplay on Load for one of the nodes in your state machine or call .start() first?"); } } else { if (!_travel(p_state_machine, start_request)) { @@ -398,7 +393,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st //find next StringName next; - float next_xfade = 0; + float next_xfade = 0.0; AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE; if (path.size()) { @@ -502,16 +497,6 @@ void AnimationNodeStateMachinePlayback::_bind_methods() { AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() { set_local_to_scene(true); //only one per instanced scene - - playing = false; - len_current = 0; - fading_time = 0; - stop_request = false; - len_total = 0.0; - pos_current = 0.0; - loops_current = 0; - fading_pos = 0.0; - start_request_travel = false; } /////////////////////////////////////////////////////// @@ -929,6 +914,18 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } +void AnimationNodeStateMachine::reset_state() { + states.clear(); + transitions.clear(); + playback = "playback"; + start_node = StringName(); + end_node = StringName(); + graph_offset = Vector2(); + + emit_changed(); + emit_signal("tree_changed"); +} + void AnimationNodeStateMachine::set_node_position(const StringName &p_name, const Vector2 &p_position) { ERR_FAIL_COND(!states.has(p_name)); states[p_name].position = p_position; @@ -975,5 +972,4 @@ void AnimationNodeStateMachine::_bind_methods() { } AnimationNodeStateMachine::AnimationNodeStateMachine() { - playback = "playback"; } diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index daeb2fabaa..9c1bca63c3 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -44,13 +44,13 @@ public: }; private: - SwitchMode switch_mode; - bool auto_advance; + SwitchMode switch_mode = SWITCH_MODE_IMMEDIATE; + bool auto_advance = false; StringName advance_condition; StringName advance_condition_name; - float xfade; - bool disabled; - int priority; + float xfade = 0.0; + bool disabled = false; + int priority = 1; protected: static void _bind_methods(); @@ -89,28 +89,28 @@ class AnimationNodeStateMachinePlayback : public Resource { friend class AnimationNodeStateMachine; struct AStarCost { - float distance; + float distance = 0.0; StringName prev; }; - float len_total; + float len_total = 0.0; - float len_current; - float pos_current; - int loops_current; + float len_current = 0.0; + float pos_current = 0.0; + int loops_current = 0; StringName current; StringName fading_from; - float fading_time; - float fading_pos; + float fading_time = 0.0; + float fading_pos = 0.0; Vector<StringName> path; - bool playing; + bool playing = false; StringName start_request; - bool start_request_travel; - bool stop_request; + bool start_request_travel = false; + bool stop_request = false; bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel); @@ -154,7 +154,7 @@ private: Vector<Transition> transitions; - StringName playback; + StringName playback = "playback"; StringName start_node; StringName end_node; @@ -171,6 +171,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: virtual void get_parameter_list(List<PropertyInfo> *r_list) const override; virtual Variant get_parameter_default_value(const StringName &p_parameter) const override; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 8e50c733ae..2c19307c52 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -206,7 +206,7 @@ void AnimationPlayer::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PROCESS: { - if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) { + if (process_callback == ANIMATION_PROCESS_PHYSICS) { break; } @@ -215,7 +215,7 @@ void AnimationPlayer::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - if (animation_process_mode == ANIMATION_PROCESS_IDLE) { + if (process_callback == ANIMATION_PROCESS_IDLE) { break; } @@ -229,13 +229,13 @@ void AnimationPlayer::_notification(int p_what) { } } -void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { +void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_override) { // Already cached? if (p_anim->node_cache.size() == p_anim->animation->get_track_count()) { return; } - Node *parent = get_node(root); + Node *parent = p_root_override ? p_root_override : get_node(root); ERR_FAIL_COND(!parent); @@ -969,7 +969,7 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati } _ref_anim(p_animation); - _change_notify(); + notify_property_list_changed(); return OK; } @@ -981,7 +981,7 @@ void AnimationPlayer::remove_animation(const StringName &p_name) { animation_set.erase(p_name); clear_caches(); - _change_notify(); + notify_property_list_changed(); } void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { @@ -1039,7 +1039,7 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam } clear_caches(); - _change_notify(); + notify_property_list_changed(); } bool AnimationPlayer::has_animation(const StringName &p_name) const { @@ -1132,7 +1132,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float Playback &c = playback; if (c.current.from) { - float blend_time = 0; + float blend_time = 0.0; // find if it can blend BlendKey bk; bk.from = c.current.from->name; @@ -1403,8 +1403,8 @@ bool AnimationPlayer::is_reset_on_save_enabled() const { return reset_on_save; } -void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) { - if (animation_process_mode == p_mode) { +void AnimationPlayer::set_process_callback(AnimationProcessCallback p_mode) { + if (process_callback == p_mode) { return; } @@ -1412,14 +1412,14 @@ void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) { if (pr) { _set_process(false); } - animation_process_mode = p_mode; + process_callback = p_mode; if (pr) { _set_process(true); } } -AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mode() const { - return animation_process_mode; +AnimationPlayer::AnimationProcessCallback AnimationPlayer::get_process_callback() const { + return process_callback; } void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) { @@ -1435,7 +1435,7 @@ void AnimationPlayer::_set_process(bool p_process, bool p_force) { return; } - switch (animation_process_mode) { + switch (process_callback) { case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break; @@ -1497,13 +1497,13 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i } #ifdef TOOLS_ENABLED -Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values() { +Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_override) { Ref<AnimatedValuesBackup> backup; if (!playback.current.from) { return backup; } - _ensure_node_caches(playback.current.from); + _ensure_node_caches(playback.current.from, p_root_override); backup.instance(); for (int i = 0; i < playback.current.from->node_cache.size(); i++) { @@ -1560,10 +1560,11 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { AnimationPlayer *aux_player = memnew(AnimationPlayer); EditorNode::get_singleton()->add_child(aux_player); - aux_player->set_root(aux_player->get_path_to(root_node)); aux_player->add_animation("RESET", reset_anim); aux_player->set_assigned_animation("RESET"); - Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(); + // Forcing the use of the original root because the scene where original player belongs may be not the active one + Node *root = get_node(get_root()); + Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root); aux_player->seek(0.0f, true); aux_player->queue_delete(); @@ -1636,8 +1637,8 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_caches"), &AnimationPlayer::clear_caches); - ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationPlayer::set_animation_process_mode); - ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationPlayer::get_animation_process_mode); + ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationPlayer::set_process_callback); + ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationPlayer::get_process_callback); ClassDB::bind_method(D_METHOD("set_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode); ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode); @@ -1657,7 +1658,7 @@ void AnimationPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position"); ADD_GROUP("Playback Options", "playback_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_animation_process_mode", "get_animation_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); @@ -1677,23 +1678,7 @@ void AnimationPlayer::_bind_methods() { } AnimationPlayer::AnimationPlayer() { - accum_pass = 1; - cache_update_size = 0; - cache_update_prop_size = 0; - cache_update_bezier_size = 0; - speed_scale = 1; - end_reached = false; - end_notify = false; - reset_on_save = true; - animation_process_mode = ANIMATION_PROCESS_IDLE; - method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; - processing = false; - default_blend_time = 0; root = SceneStringNames::get_singleton()->path_pp; - playing = false; - active = true; - playback.seeked = false; - playback.started = false; } AnimationPlayer::~AnimationPlayer() { diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 4532825f5a..2a1821c215 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -41,9 +41,9 @@ class AnimatedValuesBackup : public Reference { GDCLASS(AnimatedValuesBackup, Reference); struct Entry { - Object *object; + Object *object = nullptr; Vector<StringName> subpath; // Unused if bone - int bone_idx; // -1 if not a bone + int bone_idx = -1; // -1 if not a bone Variant value; }; Vector<Entry> entries; @@ -64,7 +64,7 @@ class AnimationPlayer : public Node { OBJ_CATEGORY("Animation Nodes"); public: - enum AnimationProcessMode { + enum AnimationProcessCallback { ANIMATION_PROCESS_PHYSICS, ANIMATION_PROCESS_IDLE, ANIMATION_PROCESS_MANUAL, @@ -118,8 +118,6 @@ private: Variant value_accum; uint64_t accum_pass = 0; Variant capture; - - PropertyAnim() {} }; Map<StringName, PropertyAnim> property_anim; @@ -130,8 +128,6 @@ private: float bezier_accum = 0.0; Object *object = nullptr; uint64_t accum_pass = 0; - - BezierAnim() {} }; Map<StringName, BezierAnim> bezier_anim; @@ -141,7 +137,7 @@ private: struct TrackNodeCacheKey { ObjectID id; - int bone_idx; + int bone_idx = -1; inline bool operator<(const TrackNodeCacheKey &p_right) const { if (id == p_right.id) { @@ -155,16 +151,16 @@ private: Map<TrackNodeCacheKey, TrackNodeCache> node_cache_map; TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX]; - int cache_update_size; + int cache_update_size = 0; TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX]; - int cache_update_prop_size; + int cache_update_prop_size = 0; TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX]; - int cache_update_bezier_size; + int cache_update_bezier_size = 0; Set<TrackNodeCache *> playing_caches; - uint64_t accum_pass; - float speed_scale; - float default_blend_time; + uint64_t accum_pass = 1; + float speed_scale = 1.0; + float default_blend_time = 0.0; struct AnimationData { String name; @@ -183,54 +179,43 @@ private: Map<BlendKey, float> blend_times; struct PlaybackData { - AnimationData *from; - float pos; - float speed_scale; - - PlaybackData() { - pos = 0; - speed_scale = 1.0; - from = nullptr; - } + AnimationData *from = nullptr; + float pos = 0.0; + float speed_scale = 1.0; }; struct Blend { PlaybackData data; - float blend_time; - float blend_left; - - Blend() { - blend_left = 0; - blend_time = 0; - } + float blend_time = 0.0; + float blend_left = 0.0; }; struct Playback { List<Blend> blend; PlaybackData current; StringName assigned; - bool seeked; - bool started; + bool seeked = false; + bool started = false; } playback; List<StringName> queued; - bool end_reached; - bool end_notify; + bool end_reached = false; + bool end_notify = false; String autoplay; - bool reset_on_save; - AnimationProcessMode animation_process_mode; - AnimationMethodCallMode method_call_mode; - bool processing; - bool active; + bool reset_on_save = true; + AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; + AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool processing = false; + bool active = true; NodePath root; void _animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false); - void _ensure_node_caches(AnimationData *p_anim); + void _ensure_node_caches(AnimationData *p_anim, Node *p_root_override = nullptr); void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started); void _animation_process2(float p_delta, bool p_started); void _animation_update_transforms(); @@ -257,7 +242,7 @@ private: void _set_process(bool p_process, bool p_force = false); - bool playing; + bool playing = false; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -313,8 +298,8 @@ public: void set_reset_on_save_enabled(bool p_enabled); bool is_reset_on_save_enabled() const; - void set_animation_process_mode(AnimationProcessMode p_mode); - AnimationProcessMode get_animation_process_mode() const; + void set_process_callback(AnimationProcessCallback p_mode); + AnimationProcessCallback get_process_callback() const; void set_method_call_mode(AnimationMethodCallMode p_mode); AnimationMethodCallMode get_method_call_mode() const; @@ -334,7 +319,7 @@ public: void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; #ifdef TOOLS_ENABLED - Ref<AnimatedValuesBackup> backup_animated_values(); + Ref<AnimatedValuesBackup> backup_animated_values(Node *p_root_override = nullptr); Ref<AnimatedValuesBackup> apply_reset(bool p_user_initiated = false); bool can_apply_reset() const; #endif @@ -343,7 +328,7 @@ public: ~AnimationPlayer(); }; -VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessMode); +VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessCallback); VARIANT_ENUM_CAST(AnimationPlayer::AnimationMethodCallMode); #endif diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index e6abbc0c7a..26a13f33c9 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -158,7 +158,7 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p Ref<AnimationNode> node = blend_tree->get_node(node_name); //inputs.write[p_input].last_pass = state->last_pass; - float activity = 0; + float activity = 0.0; float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity); Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path); @@ -441,9 +441,6 @@ void AnimationNode::_bind_methods() { } AnimationNode::AnimationNode() { - state = nullptr; - parent = nullptr; - filter_enabled = false; } //////////////////// @@ -476,7 +473,7 @@ void AnimationTree::set_active(bool p_active) { active = p_active; started = active; - if (process_mode == ANIMATION_PROCESS_IDLE) { + if (process_callback == ANIMATION_PROCESS_IDLE) { set_process_internal(active); } else { set_physics_process_internal(active); @@ -497,8 +494,8 @@ bool AnimationTree::is_active() const { return active; } -void AnimationTree::set_process_mode(AnimationProcessMode p_mode) { - if (process_mode == p_mode) { +void AnimationTree::set_process_callback(AnimationProcessCallback p_mode) { + if (process_callback == p_mode) { return; } @@ -507,15 +504,15 @@ void AnimationTree::set_process_mode(AnimationProcessMode p_mode) { set_active(false); } - process_mode = p_mode; + process_callback = p_mode; if (was_active) { set_active(true); } } -AnimationTree::AnimationProcessMode AnimationTree::get_process_mode() const { - return process_mode; +AnimationTree::AnimationProcessCallback AnimationTree::get_process_callback() const { + return process_callback; } void AnimationTree::_node_removed(Node *p_node) { @@ -820,6 +817,7 @@ void AnimationTree::_process_graph(float p_delta) { Ref<Animation> a = as.animation; float time = as.time; float delta = as.delta; + float weight = as.blend; bool seeked = as.seeked; for (int i = 0; i < a->get_track_count(); i++) { @@ -839,7 +837,7 @@ void AnimationTree::_process_graph(float p_delta) { ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count); - float blend = (*as.track_blends)[blend_idx]; + float blend = (*as.track_blends)[blend_idx] * weight; if (blend < CMP_EPSILON) { continue; //nothing to blend @@ -1236,11 +1234,11 @@ void AnimationTree::advance(float p_time) { } void AnimationTree::_notification(int p_what) { - if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) { + if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_callback == ANIMATION_PROCESS_PHYSICS) { _process_graph(get_physics_process_delta_time()); } - if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) { + if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_callback == ANIMATION_PROCESS_IDLE) { _process_graph(get_process_delta_time()); } @@ -1396,7 +1394,7 @@ void AnimationTree::_update_properties() { properties_dirty = false; - _change_notify(); + notify_property_list_changed(); } bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) { @@ -1406,9 +1404,6 @@ bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) { if (property_map.has(p_name)) { property_map[p_name] = p_value; -#ifdef TOOLS_ENABLED - _change_notify(p_name.operator String().utf8().get_data()); -#endif return true; } @@ -1476,8 +1471,8 @@ void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root); ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root); - ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationTree::set_process_mode); - ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationTree::get_process_mode); + ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationTree::set_process_callback); + ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationTree::get_process_callback); ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player); ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player); @@ -1496,7 +1491,7 @@ void AnimationTree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback"); ADD_GROUP("Root Motion", "root_motion_"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track"); @@ -1506,13 +1501,6 @@ void AnimationTree::_bind_methods() { } AnimationTree::AnimationTree() { - process_mode = ANIMATION_PROCESS_IDLE; - active = false; - cache_valid = false; - setup_pass = 1; - process_pass = 1; - started = true; - properties_dirty = true; } AnimationTree::~AnimationTree() { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index a0171e617b..1c5aec26ab 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -63,26 +63,26 @@ public: struct AnimationState { Ref<Animation> animation; - float time; - float delta; - const Vector<float> *track_blends; - float blend; - bool seeked; + float time = 0.0; + float delta = 0.0; + const Vector<float> *track_blends = nullptr; + float blend = 0.0; + bool seeked = false; }; struct State { - int track_count; + int track_count = 0; HashMap<NodePath, int> track_map; List<AnimationState> animation_states; - bool valid; - AnimationPlayer *player; - AnimationTree *tree; + bool valid = false; + AnimationPlayer *player = nullptr; + AnimationTree *tree = nullptr; String invalid_reasons; - uint64_t last_pass; + uint64_t last_pass = 0; }; Vector<float> blends; - State *state; + State *state = nullptr; float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections); void _pre_update_animations(HashMap<NodePath, int> *track_map); @@ -90,10 +90,10 @@ public: //all this is temporary StringName base_path; Vector<StringName> connections; - AnimationNode *parent; + AnimationNode *parent = nullptr; HashMap<NodePath, bool> filter; - bool filter_enabled; + bool filter_enabled = false; Array _get_filters() const; void _set_filters(const Array &p_filters); @@ -163,7 +163,7 @@ class AnimationTree : public Node { GDCLASS(AnimationTree, Node); public: - enum AnimationProcessMode { + enum AnimationProcessCallback { ANIMATION_PROCESS_PHYSICS, ANIMATION_PROCESS_IDLE, ANIMATION_PROCESS_MANUAL, @@ -171,36 +171,29 @@ public: private: struct TrackCache { - bool root_motion; - uint64_t setup_pass; - uint64_t process_pass; - Animation::TrackType type; - Object *object; + bool root_motion = false; + uint64_t setup_pass = 0; + uint64_t process_pass = 0; + Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION; + Object *object = nullptr; ObjectID object_id; TrackCache() { - root_motion = false; - setup_pass = 0; - process_pass = 0; - object = nullptr; } virtual ~TrackCache() {} }; struct TrackCacheTransform : public TrackCache { - Node3D *spatial; - Skeleton3D *skeleton; - int bone_idx; + Node3D *spatial = nullptr; + Skeleton3D *skeleton = nullptr; + int bone_idx = -1; Vector3 loc; Quat rot; - float rot_blend_accum; + float rot_blend_accum = 0.0; Vector3 scale; TrackCacheTransform() { type = Animation::TYPE_TRANSFORM; - spatial = nullptr; - bone_idx = -1; - skeleton = nullptr; } }; @@ -215,33 +208,28 @@ private: }; struct TrackCacheBezier : public TrackCache { - float value; + float value = 0.0; Vector<StringName> subpath; TrackCacheBezier() { type = Animation::TYPE_BEZIER; - value = 0; } }; struct TrackCacheAudio : public TrackCache { - bool playing; - float start; - float len; + bool playing = false; + float start = 0.0; + float len = 0.0; TrackCacheAudio() { type = Animation::TYPE_AUDIO; - playing = false; - start = 0; - len = 0; } }; struct TrackCacheAnimation : public TrackCache { - bool playing; + bool playing = false; TrackCacheAnimation() { type = Animation::TYPE_ANIMATION; - playing = false; } }; @@ -250,12 +238,12 @@ private: Ref<AnimationNode> root; - AnimationProcessMode process_mode; - bool active; + AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; + bool active = false; NodePath animation_player; AnimationNode::State state; - bool cache_valid; + bool cache_valid = false; void _node_removed(Node *p_node); void _caches_cleared(); @@ -263,16 +251,16 @@ private: bool _update_caches(AnimationPlayer *player); void _process_graph(float p_delta); - uint64_t setup_pass; - uint64_t process_pass; + uint64_t setup_pass = 1; + uint64_t process_pass = 1; - bool started; + bool started = true; NodePath root_motion_track; Transform root_motion_transform; friend class AnimationNode; - bool properties_dirty; + bool properties_dirty = true; void _tree_changed(); void _update_properties(); List<PropertyInfo> properties; @@ -280,8 +268,8 @@ private: HashMap<StringName, Variant> property_map; struct Activity { - uint64_t last_pass; - float activity; + uint64_t last_pass = 0; + float activity = 0.0; }; HashMap<StringName, Vector<Activity>> input_activity_map; @@ -306,8 +294,8 @@ public: void set_active(bool p_active); bool is_active() const; - void set_process_mode(AnimationProcessMode p_mode); - AnimationProcessMode get_process_mode() const; + void set_process_callback(AnimationProcessCallback p_mode); + AnimationProcessCallback get_process_callback() const; void set_animation_player(const NodePath &p_player); NodePath get_animation_player() const; @@ -332,6 +320,6 @@ public: ~AnimationTree(); }; -VARIANT_ENUM_CAST(AnimationTree::AnimationProcessMode) +VARIANT_ENUM_CAST(AnimationTree::AnimationProcessCallback) #endif // ANIMATION_GRAPH_PLAYER_H diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 5fd936df8e..9ee1f32581 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -89,12 +89,12 @@ void RootMotionView::_notification(int p_what) { AnimationTree *tree = Object::cast_to<AnimationTree>(node); if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) { - if (is_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { + if (is_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { set_process_internal(false); set_physics_process_internal(true); } - if (is_physics_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_IDLE) { + if (is_physics_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_IDLE) { set_process_internal(true); set_physics_process_internal(false); } @@ -188,13 +188,9 @@ void RootMotionView::_bind_methods() { } RootMotionView::RootMotionView() { - zero_y = true; - radius = 10; - cell_size = 1; set_process_internal(true); immediate = RenderingServer::get_singleton()->immediate_create(); set_base(immediate); - color = Color(0.5, 0.5, 1.0); } RootMotionView::~RootMotionView() { diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index 063fb8feda..afcff6137f 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -39,12 +39,12 @@ class RootMotionView : public VisualInstance3D { public: RID immediate; NodePath path; - float cell_size; - float radius; - bool use_in_game; - Color color; - bool first; - bool zero_y; + float cell_size = 1.0; + float radius = 10.0; + bool use_in_game = false; + Color color = Color(0.5, 0.5, 1.0); + bool first = true; + bool zero_y = true; Transform accumulated; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 8bdb5c7447..9b98f3d031 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -1098,7 +1098,7 @@ void Tween::seek(real_t p_time) { real_t Tween::tell() const { // We want to grab the position of the furthest along tween pending_update++; - real_t pos = 0; + real_t pos = 0.0; // For each interpolation... for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { @@ -1122,7 +1122,7 @@ real_t Tween::get_runtime() const { pending_update++; // For each interpolation... - real_t runtime = 0; + real_t runtime = 0.0; for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { // Get the tween data and see if it's runtime is greater than the previous tweens const InterpolateData &data = E->get(); @@ -1350,6 +1350,9 @@ void Tween::interpolate_property(Object *p_object, NodePath p_property, Variant return; } + // Check that the target object is valid + ERR_FAIL_COND_MSG(p_object == nullptr, vformat("The Tween \"%s\"'s target node is `null`. Is the node reference correct?", get_name())); + // Get the property from the node path p_property = p_property.get_as_property_path(); @@ -1378,6 +1381,9 @@ void Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_ return; } + // Check that the target object is valid + ERR_FAIL_COND_MSG(p_object == nullptr, vformat("The Tween \"%s\"'s target node is `null`. Is the node reference correct?", get_name())); + // Convert any integers into REALs as they are better for interpolation if (p_initial_val.get_type() == Variant::INT) { p_initial_val = p_initial_val.operator real_t(); @@ -1789,12 +1795,6 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in } Tween::Tween() { - // Initialize tween attributes - tween_process_mode = TWEEN_PROCESS_IDLE; - repeat = false; - speed_scale = 1; - pending_update = 0; - uid = 0; } Tween::~Tween() { diff --git a/scene/animation/tween.h b/scene/animation/tween.h index c65a6f850f..88c02be0bc 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -79,11 +79,11 @@ private: }; struct InterpolateData { - bool active; - InterpolateType type; - bool finish; - bool call_deferred; - real_t elapsed; + bool active = false; + InterpolateType type = INTER_CALLBACK; + bool finish = false; + bool call_deferred = false; + real_t elapsed = 0.0; ObjectID id; Vector<StringName> key; StringName concatenated_key; @@ -92,33 +92,27 @@ private: Variant final_val; ObjectID target_id; Vector<StringName> target_key; - real_t duration; - TransitionType trans_type; - EaseType ease_type; - real_t delay; - int args; + real_t duration = 0.0; + TransitionType trans_type = TransitionType::TRANS_BACK; + EaseType ease_type = EaseType::EASE_COUNT; + real_t delay = 0.0; + int args = 0; Variant arg[5]; - int uid; - InterpolateData() { - active = false; - finish = false; - call_deferred = false; - uid = 0; - } + int uid = 0; }; String autoplay; - TweenProcessMode tween_process_mode; - bool repeat; - float speed_scale; - mutable int pending_update; - int uid; + TweenProcessMode tween_process_mode = TWEEN_PROCESS_IDLE; + bool repeat = false; + float speed_scale = 1.0; + mutable int pending_update = 0; + int uid = 0; List<InterpolateData> interpolates; struct PendingCommand { StringName key; - int args; + int args = 0; Variant arg[10]; }; List<PendingCommand> pending_commands; diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 4a9e146696..2853a8b9d9 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -99,37 +99,37 @@ void AudioStreamPlayer::_mix_audio() { use_fadeout = false; } - if (!stream_playback.is_valid() || !active || + if (!stream_playback.is_valid() || !active.is_set() || (stream_paused && !stream_paused_fade)) { return; } if (stream_paused) { - if (stream_paused_fade) { + if (stream_paused_fade && stream_playback->is_playing()) { _mix_internal(true); stream_paused_fade = false; } return; } - if (setstop) { + if (setstop.is_set()) { _mix_internal(true); stream_playback->stop(); - setstop = false; + setstop.clear(); } - if (setseek >= 0.0 && !stop_has_priority) { + if (setseek.get() >= 0.0 && !stop_has_priority.is_set()) { if (stream_playback->is_playing()) { //fade out to avoid pops _mix_internal(true); } - stream_playback->start(setseek); - setseek = -1.0; //reset seek + stream_playback->start(setseek.get()); + setseek.set(-1.0); //reset seek mix_volume_db = volume_db; //reset ramp } - stop_has_priority = false; + stop_has_priority.clear(); _mix_internal(false); } @@ -143,8 +143,8 @@ void AudioStreamPlayer::_notification(int p_what) { } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (!active || (setseek < 0 && !stream_playback->is_playing())) { - active = false; + if (!active.is_set() || (setseek.get() < 0 && !stream_playback->is_playing())) { + active.clear(); set_process_internal(false); emit_signal("finished"); } @@ -169,7 +169,7 @@ void AudioStreamPlayer::_notification(int p_what) { void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) { AudioServer::get_singleton()->lock(); - if (active && stream_playback.is_valid() && !stream_paused) { + if (active.is_set() && stream_playback.is_valid() && !stream_paused) { //changing streams out of the blue is not a great idea, but at least //lets try to somehow avoid a click @@ -196,9 +196,9 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) { if (stream_playback.is_valid()) { stream_playback.unref(); stream.unref(); - active = false; - setseek = -1; - setstop = false; + active.clear(); + setseek.set(-1); + setstop.clear(); } if (p_stream.is_valid()) { @@ -237,29 +237,29 @@ float AudioStreamPlayer::get_pitch_scale() const { void AudioStreamPlayer::play(float p_from_pos) { if (stream_playback.is_valid()) { //mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks - setseek = p_from_pos; - stop_has_priority = false; - active = true; + setseek.set(p_from_pos); + stop_has_priority.clear(); + active.set(); set_process_internal(true); } } void AudioStreamPlayer::seek(float p_seconds) { if (stream_playback.is_valid()) { - setseek = p_seconds; + setseek.set(p_seconds); } } void AudioStreamPlayer::stop() { - if (stream_playback.is_valid() && active) { - setstop = true; - stop_has_priority = true; + if (stream_playback.is_valid() && active.is_set()) { + setstop.set(); + stop_has_priority.set(); } } bool AudioStreamPlayer::is_playing() const { if (stream_playback.is_valid()) { - return active && !setstop; //&& stream_playback->is_playing(); + return active.is_set() && !setstop.is_set(); //&& stream_playback->is_playing(); } return false; @@ -267,6 +267,10 @@ bool AudioStreamPlayer::is_playing() const { float AudioStreamPlayer::get_playback_position() { if (stream_playback.is_valid()) { + float ss = setseek.get(); + if (ss >= 0.0) { + return ss; + } return stream_playback->get_playback_position(); } @@ -314,7 +318,7 @@ void AudioStreamPlayer::_set_playing(bool p_enable) { } bool AudioStreamPlayer::_is_active() const { - return active; + return active.is_set(); } void AudioStreamPlayer::set_stream_paused(bool p_pause) { @@ -344,7 +348,7 @@ void AudioStreamPlayer::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer::_bus_layout_changed() { - _change_notify(); + notify_property_list_changed(); } Ref<AudioStreamPlayback> AudioStreamPlayer::get_stream_playback() { @@ -402,18 +406,7 @@ void AudioStreamPlayer::_bind_methods() { } AudioStreamPlayer::AudioStreamPlayer() { - mix_volume_db = 0; - pitch_scale = 1.0; - volume_db = 0; - autoplay = false; - setseek = -1; - active = false; - stream_paused = false; - stream_paused_fade = false; - mix_target = MIX_TARGET_STEREO; fadeout_buffer.resize(512); - setstop = false; - use_fadeout = false; AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer::_bus_layout_changed)); } diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h index fa45a39682..aa8d088be5 100644 --- a/scene/audio/audio_stream_player.h +++ b/scene/audio/audio_stream_player.h @@ -31,6 +31,7 @@ #ifndef AUDIO_STREAM_PLAYER_H #define AUDIO_STREAM_PLAYER_H +#include "core/templates/safe_refcount.h" #include "scene/main/node.h" #include "servers/audio/audio_stream.h" @@ -49,22 +50,22 @@ private: Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; Vector<AudioFrame> fadeout_buffer; - bool use_fadeout; - - volatile float setseek; - volatile bool active; - volatile bool setstop; - volatile bool stop_has_priority; - - float mix_volume_db; - float pitch_scale; - float volume_db; - bool autoplay; - bool stream_paused; - bool stream_paused_fade; + bool use_fadeout = false; + + SafeNumeric<float> setseek{ -1.0 }; + SafeFlag active; + SafeFlag setstop; + SafeFlag stop_has_priority; + + float mix_volume_db = 0.0; + float pitch_scale = 1.0; + float volume_db = 0.0; + bool autoplay = false; + bool stream_paused = false; + bool stream_paused_fade = false; StringName bus; - MixTarget mix_target; + MixTarget mix_target = MIX_TARGET_STEREO; void _mix_internal(bool p_fadeout); void _mix_audio(); diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index 51632446f8..9d54556187 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -77,7 +77,7 @@ public: class SceneDebuggerTree { public: struct RemoteNode { - int child_count; + int child_count = 0; String name; String type_name; ObjectID id; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 27e33be9d7..db13b9b11f 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -199,7 +199,6 @@ void BaseButton::set_disabled(bool p_disabled) { status.pressing_inside = false; } update(); - _change_notify("disabled"); } bool BaseButton::is_disabled() const { @@ -213,7 +212,6 @@ void BaseButton::set_pressed(bool p_pressed) { if (status.pressed == p_pressed) { return; } - _change_notify("pressed"); status.pressed = p_pressed; if (p_pressed) { @@ -448,18 +446,7 @@ void BaseButton::_bind_methods() { } BaseButton::BaseButton() { - toggle_mode = false; - shortcut_in_tooltip = true; - keep_pressed_outside = false; - status.pressed = false; - status.press_attempt = false; - status.hovering = false; - status.pressing_inside = false; - status.disabled = false; set_focus_mode(FOCUS_ALL); - action_mode = ACTION_MODE_BUTTON_RELEASE; - button_mask = BUTTON_MASK_LEFT; - shortcut_context = ObjectID(); } BaseButton::~BaseButton() { diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index b349b75761..d54d63cc39 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -45,21 +45,21 @@ public: }; private: - int button_mask; - bool toggle_mode; - bool shortcut_in_tooltip; - bool keep_pressed_outside; + int button_mask = BUTTON_MASK_LEFT; + bool toggle_mode = false; + bool shortcut_in_tooltip = true; + bool keep_pressed_outside = false; Ref<Shortcut> shortcut; ObjectID shortcut_context; - ActionMode action_mode; + ActionMode action_mode = ACTION_MODE_BUTTON_RELEASE; struct Status { - bool pressed; - bool hovering; - bool press_attempt; - bool pressing_inside; + bool pressed = false; + bool hovering = false; + bool press_attempt = false; + bool pressing_inside = false; - bool disabled; + bool disabled = false; } status; diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index a00d755c9c..c570438b6a 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -33,9 +33,9 @@ #include "margin_container.h" struct _MinSizeCache { - int min_size; - bool will_stretch; - int final_size; + int min_size = 0; + bool will_stretch = false; + int final_size = 0; }; void BoxContainer::_resort() { @@ -50,7 +50,7 @@ void BoxContainer::_resort() { int children_count = 0; int stretch_min = 0; int stretch_avail = 0; - float stretch_ratio_total = 0; + float stretch_ratio_total = 0.0; Map<Control *, _MinSizeCache> min_size_cache; for (int i = 0; i < get_child_count(); i++) { @@ -105,7 +105,7 @@ void BoxContainer::_resort() { has_stretched = true; bool refit_successful = true; //assume refit-test will go well - float error = 0; // Keep track of accumulated error in pixels + float error = 0.0; // Keep track of accumulated error in pixels for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -331,7 +331,6 @@ void BoxContainer::add_spacer(bool p_begin) { BoxContainer::BoxContainer(bool p_vertical) { vertical = p_vertical; - align = ALIGN_BEGIN; } void BoxContainer::_bind_methods() { diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index 8285c2b9a2..31050d1feb 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -44,8 +44,8 @@ public: }; private: - bool vertical; - AlignMode align; + bool vertical = false; + AlignMode align = ALIGN_BEGIN; void _resort(); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 119f3539e1..b0bcde8865 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -56,6 +56,11 @@ Size2 Button::get_minimum_size() const { } } + Ref<Font> font = get_theme_font("font"); + float font_height = font->get_height(get_theme_font_size("font_size")); + + minsize.height = MAX(font_height, minsize.height); + return get_theme_stylebox("normal")->get_minimum_size() + minsize; } @@ -102,8 +107,8 @@ void Button::_notification(int p_what) { style->draw(ci, Rect2(Point2(0, 0), size)); } color = get_theme_color("font_color"); - if (has_theme_color("icon_color_normal")) { - color_icon = get_theme_color("icon_color_normal"); + if (has_theme_color("icon_normal_color")) { + color_icon = get_theme_color("icon_normal_color"); } } break; case DRAW_HOVER_PRESSED: { @@ -117,13 +122,13 @@ void Button::_notification(int p_what) { if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } - if (has_theme_color("font_color_hover_pressed")) { - color = get_theme_color("font_color_hover_pressed"); + if (has_theme_color("font_hover_pressed_color")) { + color = get_theme_color("font_hover_pressed_color"); } else { color = get_theme_color("font_color"); } - if (has_theme_color("icon_color_hover_pressed")) { - color_icon = get_theme_color("icon_color_hover_pressed"); + if (has_theme_color("icon_hover_pressed_color")) { + color_icon = get_theme_color("icon_hover_pressed_color"); } break; @@ -140,13 +145,13 @@ void Button::_notification(int p_what) { if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } - if (has_theme_color("font_color_pressed")) { - color = get_theme_color("font_color_pressed"); + if (has_theme_color("font_pressed_color")) { + color = get_theme_color("font_pressed_color"); } else { color = get_theme_color("font_color"); } - if (has_theme_color("icon_color_pressed")) { - color_icon = get_theme_color("icon_color_pressed"); + if (has_theme_color("icon_pressed_color")) { + color_icon = get_theme_color("icon_pressed_color"); } } break; @@ -160,9 +165,9 @@ void Button::_notification(int p_what) { if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } - color = get_theme_color("font_color_hover"); - if (has_theme_color("icon_color_hover")) { - color_icon = get_theme_color("icon_color_hover"); + color = get_theme_color("font_hover_color"); + if (has_theme_color("icon_hover_color")) { + color_icon = get_theme_color("icon_hover_color"); } } break; @@ -176,9 +181,9 @@ void Button::_notification(int p_what) { if (!flat) { style->draw(ci, Rect2(Point2(0, 0), size)); } - color = get_theme_color("font_color_disabled"); - if (has_theme_color("icon_color_disabled")) { - color_icon = get_theme_color("icon_color_disabled"); + color = get_theme_color("font_disabled_color"); + if (has_theme_color("icon_disabled_color")) { + color_icon = get_theme_color("icon_disabled_color"); } } break; @@ -203,7 +208,7 @@ void Button::_notification(int p_what) { color_icon.a = 0.4; } - float icon_ofs_region = 0; + float icon_ofs_region = 0.0; if (rtl) { if (_internal_margin[SIDE_RIGHT] > 0) { icon_ofs_region = _internal_margin[SIDE_RIGHT] + get_theme_constant("hseparation"); @@ -303,13 +308,13 @@ void Button::_notification(int p_what) { text_ofs.x -= icon_ofs.x; } - Color font_outline_modulate = get_theme_color("font_outline_modulate"); + Color font_outline_color = get_theme_color("font_outline_color"); int outline_size = get_theme_constant("outline_size"); - if (outline_size > 0 && font_outline_modulate.a > 0) { - text_buf->draw_outline(ci, text_ofs.floor(), outline_size, font_outline_modulate); + if (outline_size > 0 && font_outline_color.a > 0) { + text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color); } - text_buf->draw(ci, text_ofs.floor(), color); + text_buf->draw(ci, text_ofs, color); if (!_icon.is_null() && icon_region.size.width > 0) { draw_texture_rect_region(_icon, icon_region, Rect2(Point2(), _icon->get_size()), color_icon); @@ -338,7 +343,6 @@ void Button::set_text(const String &p_text) { _shape(); update(); - _change_notify("text"); minimum_size_changed(); } } @@ -399,7 +403,6 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) { if (icon != p_icon) { icon = p_icon; update(); - _change_notify("icon"); minimum_size_changed(); } } @@ -424,7 +427,6 @@ void Button::set_flat(bool p_flat) { if (flat != p_flat) { flat = p_flat; update(); - _change_notify("flat"); } } @@ -474,7 +476,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -544,16 +546,8 @@ Button::Button(const String &p_text) { text_buf.instance(); text_buf->set_flags(TextServer::BREAK_MANDATORY); - flat = false; - clip_text = false; - expand_icon = false; set_mouse_filter(MOUSE_FILTER_STOP); set_text(p_text); - align = ALIGN_CENTER; - - for (int i = 0; i < 4; i++) { - _internal_margin[i] = 0; - } } Button::~Button() { diff --git a/scene/gui/button.h b/scene/gui/button.h index d633fddc8a..d968f63f51 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -45,7 +45,7 @@ public: }; private: - bool flat; + bool flat = false; String text; String xl_text; Ref<TextParagraph> text_buf; @@ -55,10 +55,10 @@ private: TextDirection text_direction = TEXT_DIRECTION_AUTO; Ref<Texture2D> icon; - bool expand_icon; - bool clip_text; - TextAlign align; - float _internal_margin[4]; + bool expand_icon = false; + bool clip_text = false; + TextAlign align = ALIGN_CENTER; + float _internal_margin[4] = {}; void _shape(); diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index f2d1dee0fc..909516e7ef 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -95,6 +95,4 @@ void CenterContainer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_top_left"), "set_use_top_left", "is_using_top_left"); } -CenterContainer::CenterContainer() { - use_top_left = false; -} +CenterContainer::CenterContainer() {} diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h index ee8b2e0e48..0944f200fc 100644 --- a/scene/gui/center_container.h +++ b/scene/gui/center_container.h @@ -36,7 +36,7 @@ class CenterContainer : public Container { GDCLASS(CenterContainer, Container); - bool use_top_left; + bool use_top_left = false; protected: void _notification(int p_what); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 6c81ef0998..e8586b72e9 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -52,6 +52,7 @@ void ColorPicker::_notification(int p_what) { btn_pick->set_icon(get_theme_icon("screen_picker", "ColorPicker")); bt_add_preset->set_icon(get_theme_icon("add_preset")); + _update_controls(); _update_color(); #ifdef TOOLS_ENABLED @@ -165,10 +166,13 @@ void ColorPicker::_value_changed(double) { } if (hsv_mode_enabled) { - color.set_hsv(scroll[0]->get_value() / 360.0, - scroll[1]->get_value() / 100.0, - scroll[2]->get_value() / 100.0, - scroll[3]->get_value() / 255.0); + h = scroll[0]->get_value() / 360.0; + s = scroll[1]->get_value() / 100.0; + v = scroll[2]->get_value() / 100.0; + color.set_hsv(h, s, v, scroll[3]->get_value() / 255.0); + + last_hsv = color; + } else { for (int i = 0; i < 4; i++) { color.components[i] = scroll[i]->get_value() / (raw_mode_enabled ? 1.0 : 255.0); @@ -577,6 +581,10 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { } void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) { + if (!is_inside_tree()) { + return; + } + Ref<InputEventMouseButton> bev = p_event; if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) { emit_signal("color_changed", color); @@ -606,6 +614,10 @@ void ColorPicker::_add_preset_pressed() { } void ColorPicker::_screen_pick_pressed() { + if (!is_inside_tree()) { + return; + } + Viewport *r = get_tree()->get_root(); if (!screen) { screen = memnew(Control); @@ -718,17 +730,6 @@ void ColorPicker::_bind_methods() { ColorPicker::ColorPicker() : BoxContainer(true) { - updating = true; - edit_alpha = true; - text_is_constructor = false; - hsv_mode_enabled = false; - raw_mode_enabled = false; - deferred_mode_enabled = false; - changing_color = false; - presets_enabled = true; - presets_visible = true; - screen = nullptr; - HBoxContainer *hb_edit = memnew(HBoxContainer); add_child(hb_edit); hb_edit->set_v_size_flags(SIZE_EXPAND_FILL); @@ -1001,12 +1002,5 @@ void ColorPickerButton::_bind_methods() { } ColorPickerButton::ColorPickerButton() { - // Initialization is now done deferred, - // this improves performance in the inspector as the color picker - // can be expensive to initialize. - picker = nullptr; - popup = nullptr; - edit_alpha = true; - set_toggle_mode(true); } diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 3695820a79..7915527bc0 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -46,7 +46,7 @@ class ColorPicker : public BoxContainer { GDCLASS(ColorPicker, BoxContainer); private: - Control *screen; + Control *screen = nullptr; Control *uv_edit; Control *w_edit; TextureRect *sample; @@ -64,20 +64,22 @@ private: Label *labels[4]; Button *text_type; LineEdit *c_text; - bool edit_alpha; + bool edit_alpha = true; Size2i ms; - bool text_is_constructor; - int presets_per_row; + bool text_is_constructor = false; + int presets_per_row = 0; Color color; - bool raw_mode_enabled; - bool hsv_mode_enabled; - bool deferred_mode_enabled; - bool updating; - bool changing_color; - bool presets_enabled; - bool presets_visible; - float h, s, v; + bool raw_mode_enabled = false; + bool hsv_mode_enabled = false; + bool deferred_mode_enabled = false; + bool updating = true; + bool changing_color = false; + bool presets_enabled = true; + bool presets_visible = true; + float h = 0.0; + float s = 0.0; + float v = 0.0; Color last_hsv; void _html_entered(const String &p_html); @@ -139,10 +141,14 @@ public: class ColorPickerButton : public Button { GDCLASS(ColorPickerButton, Button); - PopupPanel *popup; - ColorPicker *picker; + // Initialization is now done deferred, + // this improves performance in the inspector as the color picker + // can be expensive to initialize. + + PopupPanel *popup = nullptr; + ColorPicker *picker = nullptr; Color color; - bool edit_alpha; + bool edit_alpha = true; void _color_changed(const Color &p_color); void _modal_closed(); diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 03bade6702..2e6b798eea 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -180,7 +180,6 @@ void Container::_bind_methods() { } Container::Container() { - pending_sort = false; // All containers should let mouse events pass by default. set_mouse_filter(MOUSE_FILTER_PASS); } diff --git a/scene/gui/container.h b/scene/gui/container.h index 5e60ca04dc..a4f392a3ae 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -36,7 +36,7 @@ class Container : public Control { GDCLASS(Container, Control); - bool pending_sort; + bool pending_sort = false; void _sort_children(); void _child_minsize_changed(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 10f1d33e56..bff3024e38 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -439,14 +439,14 @@ bool Control::is_layout_rtl() const { } else if (parent_window) { return parent_window->is_layout_rtl(); } else { - if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) { + if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) { return true; } String locale = TranslationServer::get_singleton()->get_tool_locale(); return TS->is_locale_right_to_left(locale); } } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { - if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) { + if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) { return true; } String locale = TranslationServer::get_singleton()->get_tool_locale(); @@ -456,6 +456,10 @@ bool Control::is_layout_rtl() const { } } +void Control::_clear_size_warning() { + data.size_warning = false; +} + //moved theme configuration here, so controls can set up even if still not inside active scene void Control::add_child_notify(Node *p_child) { @@ -503,7 +507,9 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_EXIT_TREE: { get_viewport()->_gui_remove_control(this); - + } break; + case NOTIFICATION_READY: { + connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT); } break; case NOTIFICATION_ENTER_CANVAS: { @@ -709,7 +715,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const } } - return Variant(); + return false; } void Control::drop_data(const Point2 &p_point, const Variant &p_data) { @@ -1275,7 +1281,6 @@ void Control::_size_changed() { } if (pos_changed || size_changed) { item_rect_changed(size_changed); - _change_notify_offsets(); _notify_transform(); } @@ -1315,10 +1320,6 @@ void Control::set_anchor(Side p_side, float p_anchor, bool p_keep_offset, bool p } update(); - _change_notify("anchor_left"); - _change_notify("anchor_right"); - _change_notify("anchor_top"); - _change_notify("anchor_bottom"); } void Control::_set_anchor(Side p_side, float p_anchor) { @@ -1592,16 +1593,6 @@ float Control::get_anchor(Side p_side) const { return data.anchor[p_side]; } -void Control::_change_notify_offsets() { - // this avoids sending the whole object data again on a change - _change_notify("offset_left"); - _change_notify("offset_top"); - _change_notify("offset_right"); - _change_notify("offset_bottom"); - _change_notify("rect_position"); - _change_notify("rect_size"); -} - void Control::set_offset(Side p_side, float p_value) { ERR_FAIL_INDEX((int)p_side, 4); @@ -1699,10 +1690,6 @@ void Control::_set_position(const Size2 &p_point) { void Control::set_position(const Size2 &p_point, bool p_keep_offsets) { if (p_keep_offsets) { _compute_anchors(Rect2(p_point, data.size_cache), data.offset, data.anchor); - _change_notify("anchor_left"); - _change_notify("anchor_right"); - _change_notify("anchor_top"); - _change_notify("anchor_bottom"); } else { _compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset); } @@ -1721,6 +1708,11 @@ void Control::set_rect(const Rect2 &p_rect) { } void Control::_set_size(const Size2 &p_size) { +#ifdef DEBUG_ENABLED + if (data.size_warning) { + WARN_PRINT("Adjusting the size of Control nodes before they are fully initialized is unreliable. Consider deferring it with set_deferred()."); + } +#endif set_size(p_size); } @@ -1736,10 +1728,6 @@ void Control::set_size(const Size2 &p_size, bool p_keep_offsets) { if (p_keep_offsets) { _compute_anchors(Rect2(data.pos_cache, new_size), data.offset, data.anchor); - _change_notify("anchor_left"); - _change_notify("anchor_right"); - _change_notify("anchor_top"); - _change_notify("anchor_bottom"); } else { _compute_offsets(Rect2(data.pos_cache, new_size), data.anchor, data.offset); } @@ -2577,7 +2565,6 @@ void Control::set_rotation(float p_radians) { data.rotation = p_radians; update(); _notify_transform(); - _change_notify("rect_rotation"); } float Control::get_rotation() const { @@ -2602,7 +2589,6 @@ void Control::set_pivot_offset(const Vector2 &p_pivot) { data.pivot_offset = p_pivot; update(); _notify_transform(); - _change_notify("rect_pivot_offset"); } Vector2 Control::get_pivot_offset() const { @@ -2785,6 +2771,8 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("has_focus"), &Control::has_focus); ClassDB::bind_method(D_METHOD("grab_focus"), &Control::grab_focus); ClassDB::bind_method(D_METHOD("release_focus"), &Control::release_focus); + ClassDB::bind_method(D_METHOD("find_prev_valid_focus"), &Control::find_prev_valid_focus); + ClassDB::bind_method(D_METHOD("find_next_valid_focus"), &Control::find_next_valid_focus); ClassDB::bind_method(D_METHOD("get_focus_owner"), &Control::get_focus_owner); ClassDB::bind_method(D_METHOD("set_h_size_flags", "flags"), &Control::set_h_size_flags); diff --git a/scene/gui/control.h b/scene/gui/control.h index ac2a1b35de..8981e05872 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -179,13 +179,14 @@ private: LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; - float rotation = 0; + float rotation = 0.0; Vector2 scale = Vector2(1, 1); Vector2 pivot_offset; + bool size_warning = true; int h_size_flags = SIZE_FILL; int v_size_flags = SIZE_FILL; - float expand = 1; + float expand = 1.0; Point2 custom_minimum_size; MouseFilter mouse_filter = MOUSE_FILTER_STOP; @@ -233,9 +234,9 @@ private: void _theme_changed(); - void _change_notify_offsets(); void _update_minimum_size(); + void _clear_size_warning(); void _update_scroll(); void _compute_offsets(Rect2 p_rect, const float p_anchors[4], float (&r_offsets)[4]); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 773c609a70..fdfbf9eafc 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -292,8 +292,6 @@ void AcceptDialog::set_swap_cancel_ok(bool p_swap) { } AcceptDialog::AcceptDialog() { - parent_visible = nullptr; - set_wrap_controls(true); set_visible(false); set_transient(true); @@ -325,7 +323,6 @@ AcceptDialog::AcceptDialog() { ok->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed)); - hide_on_ok = true; set_title(RTR("Alert!")); connect("window_input", callable_mp(this, &AcceptDialog::_input_from_window)); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index e450a3c30a..b072055d49 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -44,12 +44,12 @@ class LineEdit; class AcceptDialog : public Window { GDCLASS(AcceptDialog, Window); - Window *parent_visible; + Window *parent_visible = nullptr; Panel *bg; HBoxContainer *hbc; Label *label; Button *ok; - bool hide_on_ok; + bool hide_on_ok = true; void _custom_action(const String &p_action); void _update_child_rects(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 5765d6b932..7453324505 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -50,20 +50,20 @@ VBoxContainer *FileDialog::get_vbox() { void FileDialog::_theme_changed() { Color font_color = vbox->get_theme_color("font_color", "Button"); - Color font_color_hover = vbox->get_theme_color("font_color_hover", "Button"); - Color font_color_pressed = vbox->get_theme_color("font_color_pressed", "Button"); + Color font_hover_color = vbox->get_theme_color("font_hover_color", "Button"); + Color font_pressed_color = vbox->get_theme_color("font_pressed_color", "Button"); - dir_up->add_theme_color_override("icon_color_normal", font_color); - dir_up->add_theme_color_override("icon_color_hover", font_color_hover); - dir_up->add_theme_color_override("icon_color_pressed", font_color_pressed); + dir_up->add_theme_color_override("icon_normal_color", font_color); + dir_up->add_theme_color_override("icon_hover_color", font_hover_color); + dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color); - refresh->add_theme_color_override("icon_color_normal", font_color); - refresh->add_theme_color_override("icon_color_hover", font_color_hover); - refresh->add_theme_color_override("icon_color_pressed", font_color_pressed); + refresh->add_theme_color_override("icon_normal_color", font_color); + refresh->add_theme_color_override("icon_hover_color", font_hover_color); + refresh->add_theme_color_override("icon_pressed_color", font_pressed_color); - show_hidden->add_theme_color_override("icon_color_normal", font_color); - show_hidden->add_theme_color_override("icon_color_hover", font_color_hover); - show_hidden->add_theme_color_override("icon_color_pressed", font_color_pressed); + show_hidden->add_theme_color_override("icon_normal_color", font_color); + show_hidden->add_theme_color_override("icon_hover_color", font_hover_color); + show_hidden->add_theme_color_override("icon_pressed_color", font_pressed_color); } void FileDialog::_notification(int p_what) { @@ -852,8 +852,6 @@ void FileDialog::set_default_show_hidden_files(bool p_show) { FileDialog::FileDialog() { show_hidden_files = default_show_hidden_files; - mode_overrides_title = true; - vbox = memnew(VBoxContainer); add_child(vbox); vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed)); @@ -925,7 +923,6 @@ FileDialog::FileDialog() { vbox->add_child(file_box); dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); - access = ACCESS_RESOURCES; _update_drives(); connect("confirmed", callable_mp(this, &FileDialog::_action_pressed)); @@ -967,7 +964,6 @@ FileDialog::FileDialog() { set_hide_on_ok(false); - invalidated = true; if (register_func) { register_func(this); } diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 626bb78d42..25b742c234 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -69,7 +69,7 @@ private: LineEdit *makedirname; Button *makedir; - Access access; + Access access = ACCESS_RESOURCES; //Button *action; VBoxContainer *vbox; FileMode mode; @@ -93,12 +93,12 @@ private: Vector<String> filters; - bool mode_overrides_title; + bool mode_overrides_title = true; static bool default_show_hidden_files; - bool show_hidden_files; + bool show_hidden_files = false; - bool invalidated; + bool invalidated = true; void update_dir(); void update_file_name(); diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index d18fff887d..36b383f16c 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -42,8 +42,6 @@ #endif GradientEdit::GradientEdit() { - grabbed = -1; - grabbing = false; set_focus_mode(FOCUS_ALL); popup = memnew(PopupPanel); diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index 189b33f563..eb7367d598 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -44,8 +44,8 @@ class GradientEdit : public Control { Ref<ImageTexture> checker; - bool grabbing; - int grabbed; + bool grabbing = false; + int grabbed = -1; Vector<Gradient::Point> points; void _draw_checker(int x, int y, int w, int h); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index d5b12b6bb6..9c8669fff0 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -154,6 +154,10 @@ Vector2 GraphEditMinimap::_convert_to_graph_position(const Vector2 &p_position) } void GraphEditMinimap::_gui_input(const Ref<InputEvent> &p_ev) { + if (!ge->is_minimap_enabled()) { + return; + } + Ref<InputEventMouseButton> mb = p_ev; Ref<InputEventMouseMotion> mm = p_ev; @@ -381,6 +385,15 @@ void GraphEdit::_graph_node_moved(Node *p_gn) { connections_layer->update(); } +void GraphEdit::_graph_node_slot_updated(int p_index, Node *p_gn) { + GraphNode *gn = Object::cast_to<GraphNode>(p_gn); + ERR_FAIL_COND(!gn); + top_layer->update(); + minimap->update(); + update(); + connections_layer->update(); +} + void GraphEdit::add_child_notify(Node *p_child) { Control::add_child_notify(p_child); @@ -390,6 +403,7 @@ void GraphEdit::add_child_notify(Node *p_child) { if (gn) { gn->set_scale(Vector2(zoom, zoom)); gn->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved), varray(gn)); + gn->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated), varray(gn)); gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised), varray(gn)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update)); @@ -401,16 +415,30 @@ void GraphEdit::add_child_notify(Node *p_child) { void GraphEdit::remove_child_notify(Node *p_child) { Control::remove_child_notify(p_child); - if (is_inside_tree()) { + if (p_child == top_layer) { + top_layer = nullptr; + minimap = nullptr; + } else if (p_child == connections_layer) { + connections_layer = nullptr; + } + + if (top_layer != nullptr && is_inside_tree()) { top_layer->call_deferred("raise"); // Top layer always on top! } GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved)); + gn->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated)); gn->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised)); - gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update)); - gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update)); + + // In case of the whole GraphEdit being destroyed these references can already be freed. + if (connections_layer != nullptr && connections_layer->is_inside_tree()) { + gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update)); + } + if (minimap != nullptr && minimap->is_inside_tree()) { + gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update)); + } } } @@ -502,14 +530,14 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, p_point)) { + if (is_in_hot_zone(pos / zoom, p_point / zoom)) { return true; } } for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, p_point)) { + if (is_in_hot_zone(pos / zoom, p_point / zoom)) { return true; } } @@ -523,7 +551,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { connecting_valid = false; Ref<Texture2D> port = get_theme_icon("port", "GraphNode"); - click_pos = mb->get_position(); + click_pos = mb->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) { @@ -532,7 +560,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, click_pos)) { + if (is_in_hot_zone(pos / zoom, click_pos)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { @@ -574,7 +602,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); - if (is_in_hot_zone(pos, click_pos)) { + if (is_in_hot_zone(pos / zoom, click_pos)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { @@ -623,11 +651,11 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; top_layer->update(); minimap->update(); - connecting_valid = just_disconnected || click_pos.distance_to(connecting_to) > 20.0 * zoom; + connecting_valid = just_disconnected || click_pos.distance_to(connecting_to / zoom) > 20.0 * zoom; if (connecting_valid) { Ref<Texture2D> port = get_theme_icon("port", "GraphNode"); - Vector2 mpos = mm->get_position(); + Vector2 mpos = mm->get_position() / zoom; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) { @@ -638,7 +666,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_output_count(); j++) { Vector2 pos = gn->get_connection_output_position(j) + gn->get_position(); int type = gn->get_connection_output_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -650,7 +678,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { for (int j = 0; j < gn->get_connection_input_count(); j++) { Vector2 pos = gn->get_connection_input_position(j) + gn->get_position(); int type = gn->get_connection_input_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) { + if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos)) { connecting_target = true; connecting_to = pos; connecting_target_to = gn->get_name(); @@ -732,6 +760,11 @@ bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) { continue; } Rect2 rect = child->get_rect(); + + // To prevent intersections with other nodes. + rect.position *= zoom; + rect.size *= zoom; + if (rect.has_point(p_mouse_pos)) { //check sub-controls Vector2 subpos = p_mouse_pos - rect.position; @@ -1181,7 +1214,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { continue; } - if (gn_selected->has_point(b->get_position() - gn_selected->get_position())) { + if (gn_selected->has_point((b->get_position() - gn_selected->get_position()) / zoom)) { gn = gn_selected; break; } @@ -1302,25 +1335,17 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } } - Ref<InputEventKey> k = p_ev; - - if (k.is_valid()) { - if (k->get_keycode() == KEY_D && k->is_pressed() && k->get_command()) { + if (p_ev->is_pressed()) { + if (p_ev->is_action("ui_graph_duplicate")) { emit_signal("duplicate_nodes_request"); accept_event(); - } - - if (k->get_keycode() == KEY_C && k->is_pressed() && k->get_command()) { + } else if (p_ev->is_action("ui_copy")) { emit_signal("copy_nodes_request"); accept_event(); - } - - if (k->get_keycode() == KEY_V && k->is_pressed() && k->get_command()) { + } else if (p_ev->is_action("ui_paste")) { emit_signal("paste_nodes_request"); accept_event(); - } - - if (k->get_keycode() == KEY_DELETE && k->is_pressed()) { + } else if (p_ev->is_action("ui_graph_delete")) { emit_signal("delete_nodes_request"); accept_event(); } @@ -1576,7 +1601,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_valid_connection_type", "from_type", "to_type"), &GraphEdit::remove_valid_connection_type); ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type); - ClassDB::bind_method(D_METHOD("set_zoom", "p_zoom"), &GraphEdit::set_zoom); + ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom); ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom); ClassDB::bind_method(D_METHOD("set_snap", "pixels"), &GraphEdit::set_snap); @@ -1591,9 +1616,9 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_connection_lines_antialiased", "pixels"), &GraphEdit::set_connection_lines_antialiased); ClassDB::bind_method(D_METHOD("is_connection_lines_antialiased"), &GraphEdit::is_connection_lines_antialiased); - ClassDB::bind_method(D_METHOD("set_minimap_size", "p_size"), &GraphEdit::set_minimap_size); + ClassDB::bind_method(D_METHOD("set_minimap_size", "size"), &GraphEdit::set_minimap_size); ClassDB::bind_method(D_METHOD("get_minimap_size"), &GraphEdit::get_minimap_size); - ClassDB::bind_method(D_METHOD("set_minimap_opacity", "p_opacity"), &GraphEdit::set_minimap_opacity); + ClassDB::bind_method(D_METHOD("set_minimap_opacity", "opacity"), &GraphEdit::set_minimap_opacity); ClassDB::bind_method(D_METHOD("get_minimap_opacity"), &GraphEdit::get_minimap_opacity); ClassDB::bind_method(D_METHOD("set_minimap_enabled", "enable"), &GraphEdit::set_minimap_enabled); @@ -1640,8 +1665,6 @@ void GraphEdit::_bind_methods() { GraphEdit::GraphEdit() { set_focus_mode(FOCUS_ALL); - awaiting_scroll_offset_update = false; - top_layer = nullptr; top_layer = memnew(GraphEditFilter(this)); add_child(top_layer); top_layer->set_mouse_filter(MOUSE_FILTER_PASS); @@ -1664,13 +1687,6 @@ GraphEdit::GraphEdit() { v_scroll->set_name("_v_scroll"); top_layer->add_child(v_scroll); - updating = false; - connecting = false; - right_disconnects = false; - - box_selecting = false; - dragging = false; - //set large minmax so it can scroll even if not resized yet h_scroll->set_min(-10000); h_scroll->set_max(10000); @@ -1681,8 +1697,6 @@ GraphEdit::GraphEdit() { h_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved)); v_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved)); - zoom = 1; - zoom_hb = memnew(HBoxContainer); top_layer->add_child(zoom_hb); zoom_hb->set_position(Vector2(10, 10)); @@ -1741,7 +1755,7 @@ GraphEdit::GraphEdit() { top_layer->add_child(minimap); minimap->set_name("_minimap"); minimap->set_modulate(Color(1, 1, 1, minimap_opacity)); - minimap->set_mouse_filter(MOUSE_FILTER_STOP); + minimap->set_mouse_filter(MOUSE_FILTER_PASS); minimap->set_custom_minimum_size(Vector2(50, 50)); minimap->set_size(minimap_size); minimap->set_anchors_preset(Control::PRESET_BOTTOM_RIGHT); @@ -1751,7 +1765,5 @@ GraphEdit::GraphEdit() { minimap->set_offset(Side::SIDE_BOTTOM, -MINIMAP_OFFSET); minimap->connect("draw", callable_mp(this, &GraphEdit::_minimap_draw)); - setting_scroll_ofs = false; - just_disconnected = false; set_clip_contents(true); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 4525152bd5..8fdf975319 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -99,9 +99,9 @@ public: struct Connection { StringName from; StringName to; - int from_port; - int to_port; - float activity; + int from_port = 0; + int to_port = 0; + float activity = 0.0; }; private: @@ -121,41 +121,41 @@ private: HScrollBar *h_scroll; VScrollBar *v_scroll; - float port_grab_distance_horizontal; + float port_grab_distance_horizontal = 0.0; float port_grab_distance_vertical; - bool connecting; + bool connecting = false; String connecting_from; - bool connecting_out; - int connecting_index; - int connecting_type; + bool connecting_out = false; + int connecting_index = 0; + int connecting_type = 0; Color connecting_color; - bool connecting_target; + bool connecting_target = false; Vector2 connecting_to; String connecting_target_to; int connecting_target_index; - bool just_disconnected; - bool connecting_valid; + bool just_disconnected = false; + bool connecting_valid = false; Vector2 click_pos; - bool dragging; - bool just_selected; - bool moving_selection; + bool dragging = false; + bool just_selected = false; + bool moving_selection = false; Vector2 drag_accum; - float zoom; + float zoom = 1.0; - bool box_selecting; - bool box_selection_mode_additive; + bool box_selecting = false; + bool box_selection_mode_additive = false; Point2 box_selecting_from; Point2 box_selecting_to; Rect2 box_selecting_rect; List<GraphNode *> previus_selected; - bool setting_scroll_ofs; - bool right_disconnects; - bool updating; - bool awaiting_scroll_offset_update; + bool setting_scroll_ofs = false; + bool right_disconnects = false; + bool updating = false; + bool awaiting_scroll_offset_update = false; List<Connection> connections; float lines_thickness = 2.0f; @@ -167,6 +167,7 @@ private: void _graph_node_raised(Node *p_gn); void _graph_node_moved(Node *p_gn); + void _graph_node_slot_updated(int p_index, Node *p_gn); void _update_scroll(); void _scroll_moved(double); @@ -194,7 +195,7 @@ private: uint32_t type_a; uint32_t type_b; }; - uint64_t key; + uint64_t key = 0; }; bool operator<(const ConnType &p_type) const { diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 9f5c87377f..b615cdb266 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -51,7 +51,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -71,6 +71,8 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { si.enable_left = p_value; } else if (what == "left_type") { si.type_left = p_value; + } else if (what == "left_icon") { + si.custom_slot_left = p_value; } else if (what == "left_color") { si.color_left = p_value; } else if (what == "right_enabled") { @@ -79,11 +81,13 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { si.type_right = p_value; } else if (what == "right_color") { si.color_right = p_value; + } else if (what == "right_icon") { + si.custom_slot_right = p_value; } else { return false; } - set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right); + set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right, si.custom_slot_left, si.custom_slot_right); update(); return true; } @@ -120,12 +124,16 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const { r_ret = si.type_left; } else if (what == "left_color") { r_ret = si.color_left; + } else if (what == "left_icon") { + r_ret = si.custom_slot_left; } else if (what == "right_enabled") { r_ret = si.enable_right; } else if (what == "right_type") { r_ret = si.type_right; } else if (what == "right_color") { r_ret = si.color_right; + } else if (what == "right_icon") { + r_ret = si.custom_slot_right; } else { return false; } @@ -152,9 +160,11 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::BOOL, base + "left_enabled")); p_list->push_back(PropertyInfo(Variant::INT, base + "left_type")); p_list->push_back(PropertyInfo(Variant::COLOR, base + "left_color")); + p_list->push_back(PropertyInfo(Variant::OBJECT, base + "left_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); p_list->push_back(PropertyInfo(Variant::BOOL, base + "right_enabled")); p_list->push_back(PropertyInfo(Variant::INT, base + "right_type")); p_list->push_back(PropertyInfo(Variant::COLOR, base + "right_color")); + p_list->push_back(PropertyInfo(Variant::OBJECT, base + "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); idx++; } @@ -355,7 +365,9 @@ void GraphNode::_shape() { void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) { ERR_FAIL_COND(p_idx < 0); - if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1)) { + if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && + !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1) && + !p_custom_left.is_valid() && !p_custom_right.is_valid()) { slot_info.erase(p_idx); return; } @@ -372,6 +384,8 @@ void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const C slot_info[p_idx] = s; update(); connpos_dirty = true; + + emit_signal("slot_updated", p_idx); } void GraphNode::clear_slot(int p_idx) { @@ -472,7 +486,6 @@ void GraphNode::set_title(const String &p_title) { _shape(); update(); - _change_notify("title"); minimum_size_changed(); } @@ -826,6 +839,7 @@ void GraphNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay"); ADD_SIGNAL(MethodInfo("position_offset_changed")); + ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx"))); ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to"))); ADD_SIGNAL(MethodInfo("raise_request")); ADD_SIGNAL(MethodInfo("close_request")); @@ -838,12 +852,5 @@ void GraphNode::_bind_methods() { GraphNode::GraphNode() { title_buf.instance(); - overlay = OVERLAY_DISABLED; - show_close = false; - connpos_dirty = true; set_mouse_filter(MOUSE_FILTER_STOP); - comment = false; - resizable = false; - resizing = false; - selected = false; } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index cf66586e6b..1bc54dddb7 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -46,23 +46,14 @@ public: private: struct Slot { - bool enable_left; - int type_left; - Color color_left; - bool enable_right; - int type_right; - Color color_right; + bool enable_left = false; + int type_left = 0; + Color color_left = Color(1, 1, 1, 1); + bool enable_right = false; + int type_right = 0; + Color color_right = Color(1, 1, 1, 1); Ref<Texture2D> custom_slot_left; Ref<Texture2D> custom_slot_right; - - Slot() { - enable_left = false; - type_left = 0; - color_left = Color(1, 1, 1, 1); - enable_right = false; - type_right = 0; - color_right = Color(1, 1, 1, 1); - } }; String title; @@ -72,12 +63,12 @@ private: String language; TextDirection text_direction = TEXT_DIRECTION_AUTO; - bool show_close; + bool show_close = false; Vector2 position_offset; - bool comment; - bool resizable; + bool comment = false; + bool resizable = false; - bool resizing; + bool resizing = false; Vector2 resizing_from; Vector2 resizing_from_size; @@ -87,7 +78,7 @@ private: struct ConnCache { Vector2 pos; - int type; + int type = 0; Color color; }; @@ -96,16 +87,16 @@ private: Map<int, Slot> slot_info; - bool connpos_dirty; + bool connpos_dirty = true; void _connpos_update(); void _resort(); void _shape(); Vector2 drag_from; - bool selected; + bool selected = false; - Overlay overlay; + Overlay overlay = OVERLAY_DISABLED; protected: void _gui_input(const Ref<InputEvent> &p_ev); diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 11335db54a..541925a802 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -261,6 +261,4 @@ Size2 GridContainer::get_minimum_size() const { return ms; } -GridContainer::GridContainer() { - columns = 1; -} +GridContainer::GridContainer() {} diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index 8045c94b9a..9b43a5bc7e 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -36,7 +36,7 @@ class GridContainer : public Container { GDCLASS(GridContainer, Container); - int columns; + int columns = 1; protected: void _notification(int p_what); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 69ca96b28e..7afc04c51c 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -50,7 +50,7 @@ void ItemList::_shape(int p_idx) { } } -void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) { +int ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) { Item item; item.icon = p_texture; item.icon_transposed = false; @@ -64,14 +64,16 @@ void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, b item.tooltip_enabled = true; item.custom_bg = Color(0, 0, 0, 0); items.push_back(item); + int item_id = items.size() - 1; _shape(items.size() - 1); update(); shape_changed = true; + return item_id; } -void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) { +int ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) { Item item; item.icon = p_item; item.icon_transposed = false; @@ -85,9 +87,11 @@ void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) { item.tooltip_enabled = true; item.custom_bg = Color(0, 0, 0, 0); items.push_back(item); + int item_id = items.size() - 1; update(); shape_changed = true; + return item_id; } void ItemList::set_item_text(int p_idx, const String &p_text) { @@ -879,6 +883,8 @@ void ItemList::_notification(int p_what) { int vseparation = get_theme_constant("vseparation"); int icon_margin = get_theme_constant("icon_margin"); int line_separation = get_theme_constant("line_separation"); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); Ref<StyleBox> sbsel = has_focus() ? get_theme_stylebox("selected_focus") : get_theme_stylebox("selected"); Ref<StyleBox> cursor = has_focus() ? get_theme_stylebox("cursor") : get_theme_stylebox("cursor_unfocused"); @@ -886,7 +892,7 @@ void ItemList::_notification(int p_what) { Color guide_color = get_theme_color("guide_color"); Color font_color = get_theme_color("font_color"); - Color font_color_selected = get_theme_color("font_color_selected"); + Color font_selected_color = get_theme_color("font_selected_color"); if (has_focus()) { RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), true); @@ -895,7 +901,7 @@ void ItemList::_notification(int p_what) { } if (shape_changed) { - float max_column_width = 0; + float max_column_width = 0.0; //1- compute item minimum sizes for (int i = 0; i < items.size(); i++) { @@ -1184,13 +1190,12 @@ void ItemList::_notification(int p_what) { max_len = size2.x; } - Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); + Color modulate = items[i].selected ? font_selected_color : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); if (items[i].disabled) { modulate.a *= 0.5; } if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) { - text_ofs = text_ofs.floor(); text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; @@ -1201,6 +1206,10 @@ void ItemList::_notification(int p_what) { items.write[i].text_buf->set_width(max_len); items.write[i].text_buf->set_align(HALIGN_CENTER); + if (outline_size > 0 && font_outline_color.a > 0) { + items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color); + } + items[i].text_buf->draw(get_canvas_item(), text_ofs, modulate); } else { if (fixed_column_width > 0) { @@ -1213,7 +1222,6 @@ void ItemList::_notification(int p_what) { text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2; } - text_ofs = text_ofs.floor(); text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; @@ -1228,6 +1236,11 @@ void ItemList::_notification(int p_what) { } else { items.write[i].text_buf->set_align(HALIGN_LEFT); } + + if (outline_size > 0 && font_outline_color.a > 0) { + items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color); + } + items[i].text_buf->draw(get_canvas_item(), text_ofs, modulate); } } @@ -1613,34 +1626,12 @@ void ItemList::_bind_methods() { } ItemList::ItemList() { - current = -1; - - select_mode = SELECT_SINGLE; - icon_mode = ICON_MODE_LEFT; - - fixed_column_width = 0; - same_column_width = false; - max_text_lines = 1; - max_columns = 1; - auto_height = false; - auto_height_value = 0.0f; - scroll_bar = memnew(VScrollBar); add_child(scroll_bar); - shape_changed = true; scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed)); set_focus_mode(FOCUS_ALL); - current_columns = 1; - search_time_msec = 0; - ensure_selected_visible = false; - defer_select_single = -1; - allow_rmb_select = false; - allow_reselect = false; - do_autoscroll_to_bottom = false; - - icon_scale = 1.0f; set_clip_contents(true); } diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index d08823c398..86a0174a20 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -52,7 +52,7 @@ public: private: struct Item { Ref<Texture2D> icon; - bool icon_transposed; + bool icon_transposed = false; Rect2i icon_region; Color icon_modulate; Ref<Texture2D> tag_icon; @@ -62,10 +62,10 @@ private: String language; TextDirection text_direction = TEXT_DIRECTION_AUTO; - bool selectable; - bool selected; - bool disabled; - bool tooltip_enabled; + bool selectable = false; + bool selected = false; + bool disabled = false; + bool tooltip_enabled = false; Variant metadata; String tooltip; Color custom_fg; @@ -79,44 +79,44 @@ private: bool operator<(const Item &p_another) const { return text < p_another.text; } }; - int current; + int current = -1; - bool shape_changed; + bool shape_changed = true; - bool ensure_selected_visible; - bool same_column_width; + bool ensure_selected_visible = false; + bool same_column_width = false; - bool auto_height; - float auto_height_value; + bool auto_height = false; + float auto_height_value = 0.0; Vector<Item> items; Vector<int> separators; - SelectMode select_mode; - IconMode icon_mode; + SelectMode select_mode = SELECT_SINGLE; + IconMode icon_mode = ICON_MODE_LEFT; VScrollBar *scroll_bar; - uint64_t search_time_msec; + uint64_t search_time_msec = 0; String search_string; - int current_columns; - int fixed_column_width; - int max_text_lines; - int max_columns; + int current_columns = 1; + int fixed_column_width = 0; + int max_text_lines = 1; + int max_columns = 1; Size2 fixed_icon_size; Size2 max_item_size_cache; - int defer_select_single; + int defer_select_single = -1; - bool allow_rmb_select; + bool allow_rmb_select = false; - bool allow_reselect; + bool allow_reselect = false; - real_t icon_scale; + real_t icon_scale = 1.0; - bool do_autoscroll_to_bottom; + bool do_autoscroll_to_bottom = false; Array _get_items() const; void _set_items(const Array &p_items); @@ -130,8 +130,8 @@ protected: static void _bind_methods(); public: - void add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true); - void add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true); + int add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true); + int add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true); void set_item_text(int p_idx, const String &p_text); String get_item_text(int p_idx) const; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index bd89fe441c..b98caf3562 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -184,17 +184,17 @@ void Label::_notification(int p_what) { Ref<StyleBox> style = get_theme_stylebox("normal"); Ref<Font> font = get_theme_font("font"); Color font_color = get_theme_color("font_color"); - Color font_color_shadow = get_theme_color("font_color_shadow"); + Color font_shadow_color = get_theme_color("font_shadow_color"); Point2 shadow_ofs(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y")); int line_spacing = get_theme_constant("line_spacing"); - Color font_outline_modulate = get_theme_color("font_outline_modulate"); + Color font_outline_color = get_theme_color("font_outline_color"); int outline_size = get_theme_constant("outline_size"); int shadow_outline_size = get_theme_constant("shadow_outline_size"); bool rtl = is_layout_rtl(); style->draw(ci, Rect2(Point2(0, 0), get_size())); - float total_h = 0; + float total_h = 0.0; int lines_visible = 0; // Get number of lines to fit to the height. @@ -298,17 +298,17 @@ void Label::_notification(int p_what) { for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { if (glyphs[j].font_rid != RID()) { - if (font_color_shadow.a > 0) { - TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + shadow_ofs, glyphs[j].index, font_color_shadow); + if (font_shadow_color.a > 0) { + TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + shadow_ofs, glyphs[j].index, font_shadow_color); if (shadow_outline_size > 0) { //draw shadow - TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, shadow_ofs.y), glyphs[j].index, font_color_shadow); - TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_color_shadow); - TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_color_shadow); + TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, shadow_ofs.y), glyphs[j].index, font_shadow_color); + TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_shadow_color); + TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_shadow_color); } } - if (font_outline_modulate.a != 0.0 && outline_size > 0) { - TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off), glyphs[j].index, font_outline_modulate); + if (font_outline_color.a != 0.0 && outline_size > 0) { + TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off), glyphs[j].index, font_outline_color); } } ofs.x += glyphs[j].advance; @@ -357,21 +357,25 @@ void Label::_notification(int p_what) { } Size2 Label::get_minimum_size() const { - Size2 min_style = get_theme_stylebox("normal")->get_minimum_size(); - // don't want to mutable everything if (dirty || lines_dirty) { const_cast<Label *>(this)->_shape(); } + Size2 min_size = minsize; + + Ref<Font> font = get_theme_font("font"); + min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size("font_size")) + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM)); + + Size2 min_style = get_theme_stylebox("normal")->get_minimum_size(); if (autowrap) { - return Size2(1, clip ? 1 : minsize.height) + min_style; + return Size2(1, clip ? 1 : min_size.height) + min_style; } else { - Size2 ms = minsize; if (clip) { - ms.width = 1; + min_size.width = 1; } - return ms + min_style; + + return min_size + min_style; } } @@ -391,7 +395,7 @@ int Label::get_visible_line_count() const { Ref<StyleBox> style = get_theme_stylebox("normal"); int line_spacing = get_theme_constant("line_spacing"); int lines_visible = 0; - float total_h = 0; + float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing; if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { @@ -538,7 +542,6 @@ void Label::set_visible_characters(int p_amount) { if (get_total_character_count() > 0) { percent_visible = (float)p_amount / (float)get_total_character_count(); } - _change_notify("percent_visible"); update(); } @@ -555,7 +558,6 @@ void Label::set_percent_visible(float p_percent) { visible_chars = get_total_character_count() * p_percent; percent_visible = p_percent; } - _change_notify("visible_chars"); update(); } @@ -564,6 +566,7 @@ float Label::get_percent_visible() const { } void Label::set_lines_skipped(int p_lines) { + ERR_FAIL_COND(p_lines < 0); lines_skipped = p_lines; _update_visible(); update(); @@ -610,7 +613,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } diff --git a/scene/gui/label.h b/scene/gui/label.h index 219c6af39e..032b4112e1 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -72,7 +72,7 @@ private: Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT; Array st_args; - float percent_visible = 1; + float percent_visible = 1.0; int visible_chars = -1; int lines_skipped = 0; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 5f0bb453f3..ba08aae8e3 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -30,6 +30,7 @@ #include "line_edit.h" +#include "core/input/input_map.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -44,6 +45,175 @@ #endif #include "scene/main/window.h" +void LineEdit::_swap_current_input_direction() { + if (input_direction == TEXT_DIRECTION_LTR) { + input_direction = TEXT_DIRECTION_RTL; + } else { + input_direction = TEXT_DIRECTION_LTR; + } + set_cursor_position(get_cursor_position()); + update(); +} + +void LineEdit::_move_cursor_left(bool p_select, bool p_move_by_word) { + if (selection.enabled && !p_select) { + set_cursor_position(selection.begin); + deselect(); + return; + } + + shift_selection_check_pre(p_select); + + if (p_move_by_word) { + int cc = cursor_pos; + + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = words.size() - 1; i >= 0; i--) { + if (words[i].x < cc) { + cc = words[i].x; + break; + } + } + + set_cursor_position(cc); + } else { + if (mid_grapheme_caret_enabled) { + set_cursor_position(get_cursor_position() - 1); + } else { + set_cursor_position(TS->shaped_text_prev_grapheme_pos(text_rid, get_cursor_position())); + } + } + + shift_selection_check_post(p_select); +} + +void LineEdit::_move_cursor_right(bool p_select, bool p_move_by_word) { + if (selection.enabled && !p_select) { + set_cursor_position(selection.end); + deselect(); + return; + } + + shift_selection_check_pre(p_select); + + if (p_move_by_word) { + int cc = cursor_pos; + + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 0; i < words.size(); i++) { + if (words[i].y > cc) { + cc = words[i].y; + break; + } + } + + set_cursor_position(cc); + } else { + if (mid_grapheme_caret_enabled) { + set_cursor_position(get_cursor_position() + 1); + } else { + set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, get_cursor_position())); + } + } + + shift_selection_check_post(p_select); +} + +void LineEdit::_move_cursor_start(bool p_select) { + shift_selection_check_pre(p_select); + set_cursor_position(0); + shift_selection_check_post(p_select); +} + +void LineEdit::_move_cursor_end(bool p_select) { + shift_selection_check_pre(p_select); + set_cursor_position(text.length()); + shift_selection_check_post(p_select); +} + +void LineEdit::_backspace(bool p_word, bool p_all_to_left) { + if (!editable) { + return; + } + + if (p_all_to_left) { + deselect(); + text = text.substr(0, cursor_pos); + _text_changed(); + return; + } + + if (selection.enabled) { + selection_delete(); + return; + } + + if (p_word) { + int cc = cursor_pos; + + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = words.size() - 1; i >= 0; i--) { + if (words[i].x < cc) { + cc = words[i].x; + } + } + + delete_text(cc, cursor_pos); + + set_cursor_position(cc); + } else { + delete_char(); + } +} + +void LineEdit::_delete(bool p_word, bool p_all_to_right) { + if (!editable) { + return; + } + + if (p_all_to_right) { + deselect(); + text = text.substr(cursor_pos, text.length() - cursor_pos); + _shape(); + set_cursor_position(0); + _text_changed(); + return; + } + + if (selection.enabled) { + selection_delete(); + return; + } + + int text_len = text.length(); + + if (cursor_pos == text_len) { + return; // Nothing to do. + } + + if (p_word) { + int cc = cursor_pos; + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 0; i < words.size(); i++) { + if (words[i].y > cc) { + cc = words[i].y; + break; + } + } + + delete_text(cursor_pos, cc); + } else { + if (mid_grapheme_caret_enabled) { + set_cursor_position(cursor_pos + 1); + delete_char(); + } else { + int cc = cursor_pos; + set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, cursor_pos)); + delete_text(cc, cursor_pos); + } + } +} + void LineEdit::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventMouseButton> b = p_event; @@ -55,7 +225,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && context_menu_enabled) { menu->set_position(get_screen_transform().xform(get_local_mouse_position())); menu->set_size(Vector2(1, 1)); - //menu->set_scale(get_global_transform().get_scale()); + _generate_context_menu(); menu->popup(); grab_focus(); accept_event(); @@ -121,13 +291,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { selection.creating = false; selection.doubleclick = false; - if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) { - if (selection.enabled) { - DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end); - } else { - DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos); - } - } + show_virtual_keyboard(); } update(); @@ -159,453 +323,163 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { return; } -#ifdef APPLE_STYLE_KEYS - if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) { - uint32_t remap_key = KEY_UNKNOWN; - switch (k->get_keycode()) { - case KEY_F: { - remap_key = KEY_RIGHT; - } break; - case KEY_B: { - remap_key = KEY_LEFT; - } break; - case KEY_P: { - remap_key = KEY_UP; - } break; - case KEY_N: { - remap_key = KEY_DOWN; - } break; - case KEY_D: { - remap_key = KEY_DELETE; - } break; - case KEY_H: { - remap_key = KEY_BACKSPACE; - } break; - case KEY_A: { - remap_key = KEY_HOME; - } break; - case KEY_E: { - remap_key = KEY_END; - } break; + if (context_menu_enabled) { + if (k->is_action("ui_menu", true)) { + Point2 pos = Point2(get_cursor_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2); + menu->set_position(get_global_transform().xform(pos)); + menu->set_size(Vector2(1, 1)); + _generate_context_menu(); + menu->popup(); + menu->grab_focus(); } + } - if (remap_key != KEY_UNKNOWN) { - k->set_keycode(remap_key); - k->set_control(false); + // Default is ENTER, KP_ENTER. Cannot use ui_accept as default includes SPACE + if (k->is_action("ui_text_newline", true)) { + emit_signal("text_entered", text); + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) { + DisplayServer::get_singleton()->virtual_keyboard_hide(); } } -#endif - - unsigned int code = k->get_keycode(); - - if (k->get_command() && is_shortcut_keys_enabled()) { - bool handled = true; - - switch (code) { - case (KEY_QUOTELEFT): { // Swap current input direction (primary cursor) - - if (input_direction == TEXT_DIRECTION_LTR) { - input_direction = TEXT_DIRECTION_RTL; - } else { - input_direction = TEXT_DIRECTION_LTR; - } - set_cursor_position(get_cursor_position()); - update(); - - } break; - - case (KEY_X): { // CUT. - - if (editable) { - cut_text(); - } - - } break; - case (KEY_C): { // COPY. - - copy_text(); - - } break; - - case (KEY_Y): // PASTE (Yank for unix users). - case (KEY_V): { // PASTE. - - if (editable) { - paste_text(); - } - - } break; - - case (KEY_Z): { // Undo/redo. - if (editable) { - if (k->get_shift()) { - redo(); - } else { - undo(); - } - } - } break; - - case (KEY_U): { // Delete from start to cursor. - - if (editable) { - deselect(); - text = text.substr(cursor_pos, text.length() - cursor_pos); - _shape(); - set_cursor_position(0); - _text_changed(); - } - - } break; - - case (KEY_K): { // Delete from cursor_pos to end. - - if (editable) { - deselect(); - text = text.substr(0, cursor_pos); - _text_changed(); - } + if (is_shortcut_keys_enabled()) { + if (k->is_action("ui_copy", true)) { + copy_text(); + accept_event(); + return; + } - } break; - case (KEY_A): { // Select all. - select(); + if (k->is_action("ui_text_select_all", true)) { + select(); + accept_event(); + return; + } - } break; -#ifdef APPLE_STYLE_KEYS - case (KEY_LEFT): { // Go to start of text - like HOME key. - shift_selection_check_pre(k->get_shift()); - set_cursor_position(0); - shift_selection_check_post(k->get_shift()); - } break; - case (KEY_RIGHT): { // Go to end of text - like END key. - shift_selection_check_pre(k->get_shift()); - set_cursor_position(text.length()); - shift_selection_check_post(k->get_shift()); - } break; - case (KEY_BACKSPACE): { - if (!editable) - break; + // Cut / Paste + if (k->is_action("ui_cut", true)) { + cut_text(); + accept_event(); + return; + } - // If selected, delete the selection - if (selection.enabled) { - selection_delete(); - break; - } + if (k->is_action("ui_paste", true)) { + paste_text(); + accept_event(); + return; + } - // Otherwise delete from cursor to beginning of text edit - int current_pos = get_cursor_position(); - if (current_pos != 0) { - delete_text(0, current_pos); - } - } break; -#endif - default: { - handled = false; - } + // Undo / Redo + if (k->is_action("ui_undo", true)) { + undo(); + accept_event(); + return; } - if (handled) { + if (k->is_action("ui_redo", true)) { + redo(); accept_event(); return; } } - _reset_caret_blink_timer(); - if (!k->get_metakey()) { - bool handled = true; - switch (code) { - case KEY_KP_ENTER: - case KEY_ENTER: { - emit_signal("text_entered", text); - if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) { - DisplayServer::get_singleton()->virtual_keyboard_hide(); - } - - } break; - - case KEY_BACKSPACE: { - if (!editable) { - break; - } - - if (selection.enabled) { - selection_delete(); - break; - } - -#ifdef APPLE_STYLE_KEYS - if (k->get_alt()) { -#else - if (k->get_alt()) { - handled = false; - break; - } else if (k->get_command()) { -#endif - int cc = cursor_pos; - - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; - break; - } - } - - delete_text(cc, cursor_pos); - - set_cursor_position(cc); - - } else { - delete_char(); - } - - } break; - case KEY_KP_4: { - if (k->get_unicode() != 0) { - handled = false; - break; - } - [[fallthrough]]; - } - case KEY_LEFT: { -#ifndef APPLE_STYLE_KEYS - if (!k->get_alt()) { -#endif - if (selection.enabled && !k->get_shift()) { - set_cursor_position(selection.begin); - deselect(); - handled = true; - break; - } - - shift_selection_check_pre(k->get_shift()); -#ifndef APPLE_STYLE_KEYS - } -#endif - -#ifdef APPLE_STYLE_KEYS - if (k->get_command()) { - set_cursor_position(0); - } else if (k->get_alt()) { -#else - if (k->get_alt()) { - handled = false; - break; - } else if (k->get_command()) { -#endif - int cc = cursor_pos; - - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; - break; - } - } - - set_cursor_position(cc); - - } else { - if (mid_grapheme_caret_enabled) { - set_cursor_position(get_cursor_position() - 1); - } else { - set_cursor_position(TS->shaped_text_prev_grapheme_pos(text_rid, get_cursor_position())); - } - } - - shift_selection_check_post(k->get_shift()); - - } break; - case KEY_KP_6: { - if (k->get_unicode() != 0) { - handled = false; - break; - } - [[fallthrough]]; - } - case KEY_RIGHT: { -#ifndef APPLE_STYLE_KEYS - if (!k->get_alt()) { -#endif - if (selection.enabled && !k->get_shift()) { - set_cursor_position(selection.end); - deselect(); - handled = true; - break; - } - - shift_selection_check_pre(k->get_shift()); -#ifndef APPLE_STYLE_KEYS - } -#endif - -#ifdef APPLE_STYLE_KEYS - if (k->get_command()) { - set_cursor_position(text.length()); - } else if (k->get_alt()) { -#else - if (k->get_alt()) { - handled = false; - break; - } else if (k->get_command()) { -#endif - int cc = cursor_pos; - - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; - break; - } - } - - set_cursor_position(cc); - - } else { - if (mid_grapheme_caret_enabled) { - set_cursor_position(get_cursor_position() + 1); - } else { - set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, get_cursor_position())); - } - } - - shift_selection_check_post(k->get_shift()); - - } break; - case KEY_UP: { - shift_selection_check_pre(k->get_shift()); - if (get_cursor_position() == 0) { - handled = false; - } - set_cursor_position(0); - shift_selection_check_post(k->get_shift()); - } break; - case KEY_DOWN: { - shift_selection_check_pre(k->get_shift()); - if (get_cursor_position() == text.length()) { - handled = false; - } - set_cursor_position(text.length()); - shift_selection_check_post(k->get_shift()); - } break; - case KEY_DELETE: { - if (!editable) { - break; - } - - if (k->get_shift() && !k->get_command() && !k->get_alt()) { - cut_text(); - break; - } - - if (selection.enabled) { - selection_delete(); - break; - } - - int text_len = text.length(); + // BACKSPACE + if (k->is_action("ui_text_backspace_all_to_left", true)) { + _backspace(false, true); + accept_event(); + return; + } + if (k->is_action("ui_text_backspace_word", true)) { + _backspace(true); + accept_event(); + return; + } + if (k->is_action("ui_text_backspace", true)) { + _backspace(); + accept_event(); + return; + } - if (cursor_pos == text_len) { - break; // Nothing to do. - } + // DELETE + if (k->is_action("ui_text_delete_all_to_right", true)) { + _delete(false, true); + accept_event(); + return; + } + if (k->is_action("ui_text_delete_word", true)) { + _delete(true); + accept_event(); + return; + } + if (k->is_action("ui_text_delete", true)) { + _delete(); + accept_event(); + return; + } -#ifdef APPLE_STYLE_KEYS - if (k->get_alt()) { -#else - if (k->get_alt()) { - handled = false; - break; - } else if (k->get_command()) { -#endif - int cc = cursor_pos; + // Cursor Movement - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; - break; - } - } + k = k->duplicate(); + bool shift_pressed = k->get_shift(); + // Remove shift or else actions will not match. Use above variable for selection. + k->set_shift(false); - delete_text(cursor_pos, cc); + if (k->is_action("ui_text_caret_word_left", true)) { + _move_cursor_left(shift_pressed, true); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_left", true)) { + _move_cursor_left(shift_pressed); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_word_right", true)) { + _move_cursor_right(shift_pressed, true); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_right", true)) { + _move_cursor_right(shift_pressed, false); + accept_event(); + return; + } - } else { - if (mid_grapheme_caret_enabled) { - set_cursor_position(cursor_pos + 1); - delete_char(); - } else { - int cc = cursor_pos; - set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, cursor_pos)); - delete_text(cc, cursor_pos); - } - } + // Up = Home, Down = End + if (k->is_action("ui_text_caret_up", true) || k->is_action("ui_text_caret_line_start", true) || k->is_action("ui_text_caret_page_up", true)) { + _move_cursor_start(shift_pressed); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_down", true) || k->is_action("ui_text_caret_line_end", true) || k->is_action("ui_text_caret_page_down", true)) { + _move_cursor_end(shift_pressed); + accept_event(); + return; + } - } break; - case KEY_KP_7: { - if (k->get_unicode() != 0) { - handled = false; - break; - } - [[fallthrough]]; - } - case KEY_HOME: { - shift_selection_check_pre(k->get_shift()); - set_cursor_position(0); - shift_selection_check_post(k->get_shift()); - } break; - case KEY_KP_1: { - if (k->get_unicode() != 0) { - handled = false; - break; - } - [[fallthrough]]; - } - case KEY_END: { - shift_selection_check_pre(k->get_shift()); - set_cursor_position(text.length()); - shift_selection_check_post(k->get_shift()); - } break; - case KEY_MENU: { - if (context_menu_enabled) { - Point2 pos = Point2(get_cursor_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2); - menu->set_position(get_global_transform().xform(pos)); - menu->set_size(Vector2(1, 1)); - //menu->set_scale(get_global_transform().get_scale()); - menu->popup(); - menu->grab_focus(); - } - } break; + // Misc + if (k->is_action("ui_swap_input_direction", true)) { + _swap_current_input_direction(); + accept_event(); + return; + } - default: { - handled = false; - } break; - } + _reset_caret_blink_timer(); - if (handled) { - accept_event(); - } else if (!k->get_command()) { - if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) { - if (editable) { - selection_delete(); - char32_t ucodestr[2] = { (char32_t)k->get_unicode(), 0 }; - int prev_len = text.length(); - append_at_cursor(ucodestr); - if (text.length() != prev_len) { - _text_changed(); - } - accept_event(); - } + // Allow unicode handling if: + // * No Modifiers are pressed (except shift) + bool allow_unicode_handling = !(k->get_command() || k->get_control() || k->get_alt() || k->get_metakey()); - } else { - return; - } + if (allow_unicode_handling && editable && k->get_unicode() >= 32) { + // Handle Unicode (if no modifiers active) + selection_delete(); + char32_t ucodestr[2] = { (char32_t)k->get_unicode(), 0 }; + int prev_len = text.length(); + append_at_cursor(ucodestr); + if (text.length() != prev_len) { + _text_changed(); } - - update(); + accept_event(); } - - return; } } @@ -635,10 +509,17 @@ Variant LineEdit::get_drag_data(const Point2 &p_point) { } bool LineEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const { + bool drop_override = Control::can_drop_data(p_point, p_data); // In case user wants to drop custom data. + if (drop_override) { + return drop_override; + } + return p_data.get_type() == Variant::STRING; } void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) { + Control::drop_data(p_point, p_data); + if (p_data.get_type() == Variant::STRING) { set_cursor_at_pixel_pos(p_point.x); int selected = selection.end - selection.begin; @@ -770,8 +651,8 @@ void LineEdit::_notification(int p_what) { int y_ofs = style->get_offset().y + (y_area - text_height) / 2; Color selection_color = get_theme_color("selection_color"); - Color font_color = is_editable() ? get_theme_color("font_color") : get_theme_color("font_color_uneditable"); - Color font_color_selected = get_theme_color("font_color_selected"); + Color font_color = is_editable() ? get_theme_color("font_color") : get_theme_color("font_uneditable_color"); + Color font_selected_color = get_theme_color("font_selected_color"); Color cursor_color = get_theme_color("cursor_color"); // Draw placeholder color. @@ -834,14 +715,32 @@ void LineEdit::_notification(int p_what) { // Draw text. ofs.y += TS->shaped_text_get_ascent(text_rid); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); + if (outline_size > 0 && font_outline_color.a > 0) { + Vector2 oofs = ofs; + for (int i = 0; i < gl_size; i++) { + for (int j = 0; j < glyphs[i].repeat; j++) { + if (ceil(oofs.x) >= x_ofs && (oofs.x + glyphs[i].advance) <= ofs_max) { + if (glyphs[i].font_rid != RID()) { + TS->font_draw_glyph_outline(glyphs[i].font_rid, ci, glyphs[i].font_size, outline_size, oofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, font_outline_color); + } + } + oofs.x += glyphs[i].advance; + } + if (oofs.x >= ofs_max) { + break; + } + } + } for (int i = 0; i < gl_size; i++) { bool selected = selection.enabled && glyphs[i].start >= selection.begin && glyphs[i].end <= selection.end; for (int j = 0; j < glyphs[i].repeat; j++) { if (ceil(ofs.x) >= x_ofs && (ofs.x + glyphs[i].advance) <= ofs_max) { if (glyphs[i].font_rid != RID()) { - TS->font_draw_glyph(glyphs[i].font_rid, ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_color_selected : font_color); + TS->font_draw_glyph(glyphs[i].font_rid, ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_selected_color : font_color); } else if ((glyphs[i].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - TS->draw_hex_code_box(ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_color_selected : font_color); + TS->draw_hex_code_box(ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_selected_color : font_color); } } ofs.x += glyphs[i].advance; @@ -953,14 +852,7 @@ void LineEdit::_notification(int p_what) { DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id()); } - if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) { - if (selection.enabled) { - DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end); - } else { - DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos); - } - } - + show_virtual_keyboard(); } break; case NOTIFICATION_FOCUS_EXIT: { if (caret_blink_enabled && !caret_force_displayed) { @@ -1001,13 +893,17 @@ void LineEdit::copy_text() { } void LineEdit::cut_text() { - if (selection.enabled && !pass) { + if (editable && selection.enabled && !pass) { DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin)); selection_delete(); } } void LineEdit::paste_text() { + if (!editable) { + return; + } + // Strip escape characters like \n and \t as they can't be displayed on LineEdit. String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes(); @@ -1028,6 +924,10 @@ void LineEdit::paste_text() { } void LineEdit::undo() { + if (!editable) { + return; + } + if (undo_stack_pos == nullptr) { if (undo_stack.size() <= 1) { return; @@ -1047,6 +947,10 @@ void LineEdit::undo() { } void LineEdit::redo() { + if (!editable) { + return; + } + if (undo_stack_pos == nullptr) { return; } @@ -1407,6 +1311,21 @@ Array LineEdit::get_structured_text_bidi_override_options() const { void LineEdit::clear() { clear_internal(); _text_changed(); + + // This should reset virtual keyboard state if needed. + if (has_focus()) { + show_virtual_keyboard(); + } +} + +void LineEdit::show_virtual_keyboard() { + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) { + if (selection.enabled) { + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end); + } else { + DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos); + } + } } String LineEdit::get_text() const { @@ -1559,12 +1478,12 @@ Size2 LineEdit::get_minimum_size() const { Size2 min_size; // Minimum size of text. - int space_size = font->get_char_size('m', 0, font_size).x; - min_size.width = get_theme_constant("minimum_spaces") * space_size; + int em_space_size = font->get_char_size('M', 0, font_size).x; + min_size.width = get_theme_constant("minimum_character_width") * em_space_size; if (expand_to_text_length) { // Add a space because some fonts are too exact, and because cursor needs a bit more when at the end. - min_size.width = MAX(min_size.width, full_width + space_size); + min_size.width = MAX(min_size.width, full_width + em_space_size); } min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM), font->get_height(font_size)); @@ -1949,7 +1868,6 @@ void LineEdit::_text_changed() { void LineEdit::_emit_text_change() { emit_signal("text_changed", text); - _change_notify("text"); text_changed_dirty = false; } @@ -2034,25 +1952,50 @@ void LineEdit::_create_undo_state() { undo_stack.push_back(op); } +int LineEdit::_get_menu_action_accelerator(const String &p_action) { + const List<Ref<InputEvent>> *events = InputMap::get_singleton()->action_get_events(p_action); + if (!events) { + return 0; + } + + // Use first event in the list for the accelerator. + const List<Ref<InputEvent>>::Element *first_event = events->front(); + if (!first_event) { + return 0; + } + + const Ref<InputEventKey> event = first_event->get(); + if (event.is_null()) { + return 0; + } + + // Use physical keycode if non-zero + if (event->get_physical_keycode() != 0) { + return event->get_physical_keycode_with_modifiers(); + } else { + return event->get_keycode_with_modifiers(); + } +} + void LineEdit::_generate_context_menu() { // Reorganize context menu. menu->clear(); if (editable) { - menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0); + menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_cut") : 0); } - menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0); + menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_copy") : 0); if (editable) { - menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0); + menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_paste") : 0); } menu->add_separator(); if (is_selecting_enabled()) { - menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0); + menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_text_select_all") : 0); } if (editable) { menu->add_item(RTR("Clear"), MENU_CLEAR); menu->add_separator(); - menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0); - menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0); + menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_undo") : 0); + menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0); } menu->add_separator(); menu->add_submenu_item(RTR("Text writing direction"), "DirMenu"); @@ -2082,7 +2025,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -2255,9 +2198,6 @@ LineEdit::LineEdit() { text_rid = TS->create_shaped_text(); _create_undo_state(); - clear_button_status.press_attempt = false; - clear_button_status.pressing_inside = false; - deselect(); set_focus_mode(FOCUS_ALL); set_default_cursor_shape(CURSOR_IBEAM); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 1e7495e734..cbadf818cd 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -94,7 +94,7 @@ private: Point2 ime_selection; RID text_rid; - float full_width = 0; + float full_width = 0.0; bool selecting_enabled = true; @@ -129,19 +129,19 @@ private: Ref<Texture2D> right_icon; struct Selection { - int begin; - int end; - int cursor_start; - bool enabled; - bool creating; - bool doubleclick; - bool drag_attempt; + int begin = 0; + int end = 0; + int cursor_start = 0; + bool enabled = false; + bool creating = false; + bool doubleclick = false; + bool drag_attempt = false; } selection; struct TextOperation { - int cursor_pos; - int scroll_offset; - int cached_width; + int cursor_pos = 0; + int scroll_offset = 0; + int cached_width = 0; String text; }; List<TextOperation> undo_stack; @@ -163,6 +163,7 @@ private: void _clear_redo(); void _create_undo_state(); + int _get_menu_action_accelerator(const String &p_action); void _generate_context_menu(); void _shape(); @@ -188,6 +189,14 @@ private: void _editor_settings_changed(); + void _swap_current_input_direction(); + void _move_cursor_left(bool p_select, bool p_move_by_word = false); + void _move_cursor_right(bool p_select, bool p_move_by_word = false); + void _move_cursor_start(bool p_select); + void _move_cursor_end(bool p_select); + void _backspace(bool p_word = false, bool p_all_to_left = false); + void _delete(bool p_word = false, bool p_all_to_right = false); + void _gui_input(Ref<InputEvent> p_event); void _notification(int p_what); @@ -306,6 +315,9 @@ public: Ref<Texture2D> get_right_icon(); virtual bool is_text_field() const override; + + void show_virtual_keyboard(); + LineEdit(); ~LineEdit(); }; diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 495529017a..1f7b61e3d1 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -163,8 +163,8 @@ void LinkButton::_notification(int p_what) { } break; case DRAW_HOVER_PRESSED: case DRAW_PRESSED: { - if (has_theme_color("font_color_pressed")) { - color = get_theme_color("font_color_pressed"); + if (has_theme_color("font_pressed_color")) { + color = get_theme_color("font_pressed_color"); } else { color = get_theme_color("font_color"); } @@ -173,12 +173,12 @@ void LinkButton::_notification(int p_what) { } break; case DRAW_HOVER: { - color = get_theme_color("font_color_hover"); + color = get_theme_color("font_hover_color"); do_underline = underline_mode != UNDERLINE_MODE_NEVER; } break; case DRAW_DISABLED: { - color = get_theme_color("font_color_disabled"); + color = get_theme_color("font_disabled_color"); do_underline = underline_mode == UNDERLINE_MODE_ALWAYS; } break; @@ -191,9 +191,17 @@ void LinkButton::_notification(int p_what) { int width = text_buf->get_line_width(); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); if (is_layout_rtl()) { + if (outline_size > 0 && font_outline_color.a > 0) { + text_buf->draw_outline(get_canvas_item(), Vector2(size.width - width, 0), outline_size, font_outline_color); + } text_buf->draw(get_canvas_item(), Vector2(size.width - width, 0), color); } else { + if (outline_size > 0 && font_outline_color.a > 0) { + text_buf->draw_outline(get_canvas_item(), Vector2(0, 0), outline_size, font_outline_color); + } text_buf->draw(get_canvas_item(), Vector2(0, 0), color); } @@ -231,7 +239,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -294,7 +302,6 @@ void LinkButton::_bind_methods() { LinkButton::LinkButton() { text_buf.instance(); - underline_mode = UNDERLINE_MODE_ALWAYS; set_focus_mode(FOCUS_NONE); set_default_cursor_shape(CURSOR_POINTING_HAND); } diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 5ab6aba122..7eaa9f88b6 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -48,7 +48,7 @@ public: private: String text; Ref<TextLine> text_buf; - UnderlineMode underline_mode; + UnderlineMode underline_mode = UNDERLINE_MODE_ALWAYS; Dictionary opentype_features; String language; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 94cb5ef0f4..5acc7e808a 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -118,7 +118,6 @@ void MenuButton::set_disable_shortcuts(bool p_disabled) { } MenuButton::MenuButton() { - switch_on_hover = false; set_flat(true); set_toggle_mode(true); set_disable_shortcuts(false); diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index cd4ed5bcb2..fd9ae6021e 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -37,9 +37,9 @@ class MenuButton : public Button { GDCLASS(MenuButton, Button); - bool clicked; - bool switch_on_hover; - bool disable_shortcuts; + bool clicked = false; + bool switch_on_hover = false; + bool disable_shortcuts = false; PopupMenu *popup; Array _get_items() const; diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index c274eb5c10..29a38ad5e3 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -98,7 +98,6 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { */ minimum_size_changed(); emit_signal("texture_changed"); - _change_notify("texture"); } Ref<Texture2D> NinePatchRect::get_texture() const { @@ -110,20 +109,6 @@ void NinePatchRect::set_patch_margin(Side p_side, int p_size) { margin[p_side] = p_size; update(); minimum_size_changed(); - switch (p_side) { - case SIDE_LEFT: - _change_notify("patch_margin_left"); - break; - case SIDE_TOP: - _change_notify("patch_margin_top"); - break; - case SIDE_RIGHT: - _change_notify("patch_margin_right"); - break; - case SIDE_BOTTOM: - _change_notify("patch_margin_bottom"); - break; - } } int NinePatchRect::get_patch_margin(Side p_side) const { @@ -139,7 +124,6 @@ void NinePatchRect::set_region_rect(const Rect2 &p_region_rect) { region_rect = p_region_rect; item_rect_changed(); - _change_notify("region_rect"); } Rect2 NinePatchRect::get_region_rect() const { @@ -174,16 +158,7 @@ NinePatchRect::AxisStretchMode NinePatchRect::get_v_axis_stretch_mode() const { } NinePatchRect::NinePatchRect() { - margin[SIDE_LEFT] = 0; - margin[SIDE_RIGHT] = 0; - margin[SIDE_BOTTOM] = 0; - margin[SIDE_TOP] = 0; - set_mouse_filter(MOUSE_FILTER_IGNORE); - draw_center = true; - - axis_h = AXIS_STRETCH_MODE_STRETCH; - axis_v = AXIS_STRETCH_MODE_STRETCH; } NinePatchRect::~NinePatchRect() { diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h index fcf25018aa..f9a3f31fe5 100644 --- a/scene/gui/nine_patch_rect.h +++ b/scene/gui/nine_patch_rect.h @@ -43,12 +43,13 @@ public: AXIS_STRETCH_MODE_TILE_FIT, }; - bool draw_center; - int margin[4]; + bool draw_center = true; + int margin[4] = {}; Rect2 region_rect; Ref<Texture2D> texture; - AxisStretchMode axis_h, axis_v; + AxisStretchMode axis_h = AXIS_STRETCH_MODE_STRETCH; + AxisStretchMode axis_v = AXIS_STRETCH_MODE_STRETCH; protected: void _notification(int p_what); diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 4f274595a2..e52b6917be 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -62,13 +62,13 @@ void OptionButton::_notification(int p_what) { if (get_theme_constant("modulate_arrow")) { switch (get_draw_mode()) { case DRAW_PRESSED: - clr = get_theme_color("font_color_pressed"); + clr = get_theme_color("font_pressed_color"); break; case DRAW_HOVER: - clr = get_theme_color("font_color_hover"); + clr = get_theme_color("font_hover_color"); break; case DRAW_DISABLED: - clr = get_theme_color("font_color_disabled"); + clr = get_theme_color("font_disabled_color"); break; default: clr = get_theme_color("font_color"); @@ -336,7 +336,6 @@ void OptionButton::_bind_methods() { } OptionButton::OptionButton() { - current = -1; set_toggle_mode(true); set_text_align(ALIGN_LEFT); if (is_layout_rtl()) { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 9cb296baa9..d846e395ad 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -38,7 +38,7 @@ class OptionButton : public Button { GDCLASS(OptionButton, Button); PopupMenu *popup; - int current; + int current = -1; void _focused(int p_which); void _selected(int p_which); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index e777e6c26b..f237f79be1 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -52,8 +52,8 @@ Size2 PopupMenu::_get_contents_minimum_size() const { Size2 minsize = get_theme_stylebox("panel")->get_minimum_size(); // Accounts for margin in the margin container minsize.x += scroll_container->get_v_scrollbar()->get_size().width * 2; // Adds a buffer so that the scrollbar does not render over the top of content - float max_w = 0; - float icon_w = 0; + float max_w = 0.0; + float icon_w = 0.0; int check_w = MAX(get_theme_icon("checked")->get_width(), get_theme_icon("radio_checked")->get_width()) + hseparation; int accel_max_w = 0; bool has_check = false; @@ -62,7 +62,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const { Size2 size; Size2 icon_size = items[i].get_icon_size(); - size.height = MAX(icon_size.height, items[i].text_buf->get_size().y); + size.height = _get_item_height(i); icon_w = MAX(icon_size.width, icon_w); size.width += items[i].h_ofs; @@ -89,7 +89,9 @@ Size2 PopupMenu::_get_contents_minimum_size() const { minsize.height += size.height; } - minsize.width += max_w + icon_w + accel_max_w; + int item_side_padding = get_theme_constant("item_start_padding") + get_theme_constant("item_end_padding"); + minsize.width += max_w + icon_w + accel_max_w + item_side_padding; + if (has_check) { minsize.width += check_w; } @@ -104,13 +106,35 @@ Size2 PopupMenu::_get_contents_minimum_size() const { return minsize; } +int PopupMenu::_get_item_height(int p_item) const { + ERR_FAIL_INDEX_V(p_item, items.size(), 0); + ERR_FAIL_COND_V(p_item < 0, 0); + + int icon_height = items[p_item].get_icon_size().height; + if (items[p_item].checkable_type) { + icon_height = MAX(icon_height, MAX(get_theme_icon("checked")->get_height(), get_theme_icon("radio_checked")->get_height())); + } + + int text_height = items[p_item].text_buf->get_size().height; + if (text_height == 0 && !items[p_item].separator) { + text_height = get_theme_font("font")->get_height(get_theme_font_size("font_size")); + } + + int separator_height = 0; + if (items[p_item].separator) { + separator_height = MAX(get_theme_stylebox("separator")->get_minimum_size().height, MAX(get_theme_stylebox("labeled_separator_left")->get_minimum_size().height, get_theme_stylebox("labeled_separator_right")->get_minimum_size().height)); + } + + return MAX(separator_height, MAX(text_height, icon_height)); +} + int PopupMenu::_get_items_total_height() const { int vsep = get_theme_constant("vseparation"); // Get total height of all items by taking max of icon height and font height int items_total_height = 0; for (int i = 0; i < items.size(); i++) { - items_total_height += MAX(items[i].get_icon_size().height, items[i].text_buf->get_size().y) + vsep; + items_total_height += _get_item_height(i) + vsep; } // Subtract a separator which is not needed for the last item. @@ -152,7 +176,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { for (int i = 0; i < items.size(); i++) { ofs.y += i > 0 ? vseparation : (float)vseparation / 2; - ofs.y += MAX(items[i].get_icon_size().height, items[i].text_buf->get_size().y); + ofs.y += _get_item_height(i); if (p_over.y - control->get_position().y < ofs.y) { return i; @@ -451,6 +475,10 @@ void PopupMenu::_draw_items() { margin_size.width = margin_container->get_theme_constant("margin_right") + margin_container->get_theme_constant("margin_left"); margin_size.height = margin_container->get_theme_constant("margin_top") + margin_container->get_theme_constant("margin_bottom"); + // Space between the item content and the sides of popup menu. + int item_start_padding = get_theme_constant("item_start_padding"); + int item_end_padding = get_theme_constant("item_end_padding"); + bool rtl = control->is_layout_rtl(); Ref<StyleBox> style = get_theme_stylebox("panel"); Ref<StyleBox> hover = get_theme_stylebox("hover"); @@ -471,10 +499,10 @@ void PopupMenu::_draw_items() { int vseparation = get_theme_constant("vseparation"); int hseparation = get_theme_constant("hseparation"); Color font_color = get_theme_color("font_color"); - Color font_color_disabled = get_theme_color("font_color_disabled"); - Color font_color_accel = get_theme_color("font_color_accel"); - Color font_color_hover = get_theme_color("font_color_hover"); - Color font_color_separator = get_theme_color("font_color_separator"); + Color font_disabled_color = get_theme_color("font_disabled_color"); + Color font_accelerator_color = get_theme_color("font_accelerator_color"); + Color font_hover_color = get_theme_color("font_hover_color"); + Color font_separator_color = get_theme_color("font_separator_color"); float scroll_width = scroll_container->get_v_scrollbar()->is_visible_in_tree() ? scroll_container->get_v_scrollbar()->get_size().width : 0; float display_width = control->get_size().width - scroll_width; @@ -509,7 +537,7 @@ void PopupMenu::_draw_items() { Point2 item_ofs = ofs; Size2 icon_size = items[i].get_icon_size(); - float h = MAX(icon_size.height, items[i].text_buf->get_size().y); + float h = _get_item_height(i); if (i == mouse_over) { if (rtl) { @@ -525,24 +553,28 @@ void PopupMenu::_draw_items() { item_ofs.x += items[i].h_ofs; if (items[i].separator) { int sep_h = separator->get_center_size().height + separator->get_minimum_size().height; + int sep_ofs = Math::floor((h - sep_h) / 2.0); if (text != String()) { int text_size = items[i].text_buf->get_size().width; int text_center = display_width / 2; int text_left = text_center - text_size / 2; int text_right = text_center + text_size / 2; if (text_left > item_ofs.x) { - labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, text_left - item_ofs.x), sep_h))); + labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(MAX(0, text_left - item_ofs.x), sep_h))); } if (text_right < display_width) { - labeled_separator_right->draw(ci, Rect2(Point2(text_right, item_ofs.y + Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, display_width - text_right), sep_h))); + labeled_separator_right->draw(ci, Rect2(Point2(text_right, item_ofs.y + sep_ofs), Size2(MAX(0, display_width - text_right), sep_h))); } } else { - separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(display_width, sep_h))); + separator->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(display_width, sep_h))); } } Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1); + // For non-separator items, add some padding for the content. + item_ofs.x += item_start_padding; + // Checkboxes if (items[i].checkable_type) { Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr(); @@ -565,35 +597,53 @@ void PopupMenu::_draw_items() { // Submenu arrow on right hand side if (items[i].submenu != "") { if (rtl) { - submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT), item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); + submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); } else { - submenu->draw(ci, Point2(display_width - style->get_margin(SIDE_RIGHT) - submenu->get_width(), item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); + submenu->draw(ci, Point2(display_width - style->get_margin(SIDE_RIGHT) - submenu->get_width() - item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color); } } // Text + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); if (items[i].separator) { if (text != String()) { int center = (display_width - items[i].text_buf->get_size().width) / 2; - items[i].text_buf->draw(ci, Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), font_color_separator); + Vector2 text_pos = Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); + if (outline_size > 0 && font_outline_color.a > 0) { + items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + items[i].text_buf->draw(ci, text_pos, font_separator_color); } } else { item_ofs.x += icon_ofs + check_ofs; if (rtl) { - items[i].text_buf->draw(ci, Size2(control->get_size().width - items[i].text_buf->get_size().width - item_ofs.x, item_ofs.y) + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color)); + Vector2 text_pos = Size2(control->get_size().width - items[i].text_buf->get_size().width - item_ofs.x, item_ofs.y) + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); + if (outline_size > 0 && font_outline_color.a > 0) { + items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + items[i].text_buf->draw(ci, text_pos, items[i].disabled ? font_disabled_color : (i == mouse_over ? font_hover_color : font_color)); } else { - items[i].text_buf->draw(ci, item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color)); + Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); + if (outline_size > 0 && font_outline_color.a > 0) { + items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + items[i].text_buf->draw(ci, text_pos, items[i].disabled ? font_disabled_color : (i == mouse_over ? font_hover_color : font_color)); } } // Accelerator / Shortcut if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { if (rtl) { - item_ofs.x = scroll_width + style->get_margin(SIDE_LEFT); + item_ofs.x = scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding; } else { - item_ofs.x = display_width - style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x; + item_ofs.x = display_width - style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x - item_end_padding; + } + Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); + if (outline_size > 0 && font_outline_color.a > 0) { + items[i].accel_text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); } - items[i].accel_text_buf->draw(ci, item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), i == mouse_over ? font_color_hover : font_color_accel); + items[i].accel_text_buf->draw(ci, text_pos, i == mouse_over ? font_hover_color : font_accelerator_color); } // Cache the item vertical offset from the first item and the height @@ -1656,19 +1706,6 @@ PopupMenu::PopupMenu() { connect("window_input", callable_mp(this, &PopupMenu::_gui_input)); - mouse_over = -1; - submenu_over = -1; - initial_button_mask = 0; - during_grabbed_click = false; - - allow_search = true; - search_time_msec = 0; - search_string = ""; - - set_hide_on_item_selection(true); - set_hide_on_checkable_item_selection(true); - set_hide_on_multistate_item_selection(false); - submenu_timer = memnew(Timer); submenu_timer->set_wait_time(0.3); submenu_timer->set_one_shot(true); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index c050e61d50..e4cbe984c9 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -51,28 +51,28 @@ class PopupMenu : public Popup { String language; Control::TextDirection text_direction = Control::TEXT_DIRECTION_AUTO; - bool checked; + bool checked = false; enum { CHECKABLE_TYPE_NONE, CHECKABLE_TYPE_CHECK_BOX, CHECKABLE_TYPE_RADIO_BUTTON, } checkable_type; - int max_states; - int state; - bool separator; - bool disabled; - bool dirty; - int id; + int max_states = 0; + int state = 0; + bool separator = false; + bool disabled = false; + bool dirty = true; + int id = 0; Variant metadata; String submenu; String tooltip; - uint32_t accel; - int _ofs_cache; - int _height_cache; - int h_ofs; + uint32_t accel = 0; + int _ofs_cache = 0; + int _height_cache = 0; + int h_ofs = 0; Ref<Shortcut> shortcut; - bool shortcut_is_global; - bool shortcut_is_disabled; + bool shortcut_is_global = false; + bool shortcut_is_disabled = false; // Returns (0,0) if icon is null. Size2 get_icon_size() const { @@ -82,19 +82,7 @@ class PopupMenu : public Popup { Item() { text_buf.instance(); accel_text_buf.instance(); - dirty = true; - checked = false; checkable_type = CHECKABLE_TYPE_NONE; - separator = false; - max_states = 0; - state = 0; - accel = 0; - disabled = false; - _ofs_cache = 0; - _height_cache = 0; - h_ofs = 0; - shortcut_is_global = false; - shortcut_is_disabled = false; } }; @@ -104,15 +92,16 @@ class PopupMenu : public Popup { Timer *submenu_timer; List<Rect2> autohide_areas; Vector<Item> items; - int initial_button_mask; - bool during_grabbed_click; - int mouse_over; - int submenu_over; + int initial_button_mask = 0; + bool during_grabbed_click = false; + int mouse_over = -1; + int submenu_over = -1; Rect2 parent_rect; String _get_accel_text(const Item &p_item) const; int _get_mouse_over(const Point2 &p_over) const; virtual Size2 _get_contents_minimum_size() const override; + int _get_item_height(int p_item) const; int _get_items_total_height() const; void _scroll_to_item(int p_item); @@ -123,9 +112,9 @@ class PopupMenu : public Popup { void _submenu_timeout(); uint64_t popup_time_msec = 0; - bool hide_on_item_selection; - bool hide_on_checkable_item_selection; - bool hide_on_multistate_item_selection; + bool hide_on_item_selection = true; + bool hide_on_checkable_item_selection = true; + bool hide_on_multistate_item_selection = false; Vector2 moved; Array _get_items() const; @@ -136,9 +125,9 @@ class PopupMenu : public Popup { void _ref_shortcut(Ref<Shortcut> p_sc); void _unref_shortcut(Ref<Shortcut> p_sc); - bool allow_search; - uint64_t search_time_msec; - String search_string; + bool allow_search = true; + uint64_t search_time_msec = 0; + String search_string = ""; MarginContainer *margin_container; ScrollContainer *scroll_container; diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index 1b33cc6ffb..6e8dfd5994 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -74,7 +74,13 @@ void ProgressBar::_notification(int p_what) { if (percent_visible) { String txt = TS->format_number(itos(int(get_as_ratio() * 100))) + TS->percent_sign(); TextLine tl = TextLine(txt, font, font_size); - tl.draw(get_canvas_item(), (Point2(get_size().width - tl.get_size().x, get_size().height - tl.get_size().y) / 2).round(), font_color); + Vector2 text_pos = (Point2(get_size().width - tl.get_size().x, get_size().height - tl.get_size().y) / 2).round(); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); + if (outline_size > 0 && font_outline_color.a > 0) { + tl.draw_outline(get_canvas_item(), text_pos, outline_size, font_outline_color); + } + tl.draw(get_canvas_item(), text_pos, font_color); } } } @@ -98,5 +104,4 @@ void ProgressBar::_bind_methods() { ProgressBar::ProgressBar() { set_v_size_flags(0); set_step(0.01); - percent_visible = true; } diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index 3317846108..fb6060d932 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -36,7 +36,7 @@ class ProgressBar : public Range { GDCLASS(ProgressBar, Range); - bool percent_visible; + bool percent_visible = true; protected: void _notification(int p_what); diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index b9ac6d7505..86b775e795 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -47,7 +47,6 @@ void Range::_value_changed_notify() { _value_changed(shared->val); emit_signal("value_changed", shared->val); update(); - _change_notify("value"); } void Range::Shared::emit_value_changed() { @@ -63,7 +62,6 @@ void Range::Shared::emit_value_changed() { void Range::_changed_notify(const char *p_what) { emit_signal("changed"); update(); - _change_notify(p_what); } void Range::Shared::emit_changed(const char *p_what) { @@ -171,7 +169,10 @@ void Range::set_as_ratio(double p_value) { } double Range::get_as_ratio() const { - ERR_FAIL_COND_V_MSG(Math::is_equal_approx(get_max(), get_min()), 0.0, "Cannot get ratio when minimum and maximum value are equal."); + if (Math::is_equal_approx(get_max(), get_min())) { + // Avoid division by zero. + return 1.0; + } if (shared->exp_ratio && get_min() >= 0) { double exp_min = get_min() == 0 ? 0.0 : Math::log(get_min()) / Math::log((double)2); @@ -311,17 +312,7 @@ bool Range::is_lesser_allowed() const { Range::Range() { shared = memnew(Shared); - shared->min = 0; - shared->max = 100; - shared->val = 0; - shared->step = 1; - shared->page = 0; shared->owners.insert(this); - shared->exp_ratio = false; - shared->allow_greater = false; - shared->allow_lesser = false; - - _rounded_values = false; } Range::~Range() { diff --git a/scene/gui/range.h b/scene/gui/range.h index 68ff46bd74..1072a109c6 100644 --- a/scene/gui/range.h +++ b/scene/gui/range.h @@ -37,11 +37,14 @@ class Range : public Control { GDCLASS(Range, Control); struct Shared { - double val, min, max; - double step, page; - bool exp_ratio; - bool allow_greater; - bool allow_lesser; + double val = 0.0; + double min = 0.0; + double max = 100.0; + double step = 1.0; + double page = 0.0; + bool exp_ratio = false; + bool allow_greater = false; + bool allow_lesser = false; Set<Range *> owners; void emit_value_changed(); void emit_changed(const char *p_what = ""); @@ -62,7 +65,7 @@ protected: static void _bind_methods(); - bool _rounded_values; + bool _rounded_values = false; public: void set_value(double p_val); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4f4d5ece4a..682584d73f 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -45,7 +45,7 @@ #include "editor/editor_scale.h" #endif -RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) { +RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) const { if (p_free) { if (p_item->subitems.size()) { return p_item->subitems.front()->get(); @@ -90,7 +90,7 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) { return nullptr; } -RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) { +RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) const { if (p_free) { if (p_item->subitems.size()) { return p_item->subitems.back()->get(); @@ -147,7 +147,7 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item case ITEM_TEXT: { ItemText *t = (ItemText *)it; offset += t->text.length(); - if (offset > p_position) { + if (offset >= p_position) { return it; } } break; @@ -220,7 +220,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (tab_size > 0) { // Align inline tabs. Vector<float> tabs; - tabs.push_back(tab_size * p_base_font->get_char_size('m', 0, p_base_font_size).width); + tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width); l.text_buf->tab_align(tabs); } @@ -314,7 +314,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->rows.clear(); Vector2 offset; - float row_height = 0; + float row_height = 0.0; for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. @@ -392,7 +392,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (tab_size > 0) { // Align inline tabs. Vector<float> tabs; - tabs.push_back(tab_size * p_base_font->get_char_size('m', 0, p_base_font_size).width); + tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width); l.text_buf->tab_align(tabs); } @@ -454,6 +454,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> ItemImage *img = (ItemImage *)it; l.text_buf->add_object((uint64_t)it, img->image->get_size(), img->inline_align, 1); text += String::chr(0xfffc); + l.char_count += 1; } break; case ITEM_TABLE: { ItemTable *table = static_cast<ItemTable *>(it); @@ -553,7 +554,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->rows.clear(); Vector2 offset; - float row_height = 0; + float row_height = 0.0; for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. @@ -618,11 +619,11 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } } -void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &p_shadow_ofs) { +int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, bool p_shadow_as_outline, const Point2 &p_shadow_ofs) { Vector2 off; - ERR_FAIL_COND(p_frame == nullptr); - ERR_FAIL_COND(p_line < 0 || p_line >= p_frame->lines.size()); + ERR_FAIL_COND_V(p_frame == nullptr, 0); + ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), 0); Line &l = p_frame->lines.write[p_line]; @@ -631,7 +632,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ Variant meta; if (it_from == nullptr) { - return; + return 0; } RID ci = get_canvas_item(); @@ -699,14 +700,24 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ } l.text_buf->draw_dropcap(ci, p_ofs + ((rtl) ? Vector2() : Vector2(l.offset.x, 0)), l.dc_color); + int line_count = 0; + Size2 ctrl_size = get_size(); // Draw text. for (int line = 0; line < l.text_buf->get_line_count(); line++) { RID rid = l.text_buf->get_line_rid(line); + if (p_ofs.y + off.y >= ctrl_size.height) { + break; + } + if (p_ofs.y + off.y + TS->shaped_text_get_size(rid).y <= 0) { + off.y += TS->shaped_text_get_size(rid).y; + continue; + } float width = l.text_buf->get_width(); float length = TS->shaped_text_get_width(rid); // Draw line. + line_count++; if (rtl) { off.x = p_width - l.offset.x - width; @@ -766,6 +777,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ Color odd_row_bg = get_theme_color("table_odd_row_bg"); Color even_row_bg = get_theme_color("table_even_row_bg"); Color border = get_theme_color("table_border"); + int hseparation = get_theme_constant("table_hseparation"); int col_count = table->columns.size(); int row_count = table->rows.size(); @@ -782,15 +794,15 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ coff.x = rect.size.width - table->columns[col].width - coff.x; } if (row % 2 == 0) { - draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width, table->rows[row])), (frame->odd_row_bg != Color(0, 0, 0, 0) ? frame->odd_row_bg : odd_row_bg), true); + draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width + hseparation + frame->padding.position.x + frame->padding.size.x, table->rows[row])), (frame->odd_row_bg != Color(0, 0, 0, 0) ? frame->odd_row_bg : odd_row_bg), true); } else { - draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width, table->rows[row])), (frame->even_row_bg != Color(0, 0, 0, 0) ? frame->even_row_bg : even_row_bg), true); + draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width + hseparation + frame->padding.position.x + frame->padding.size.x, table->rows[row])), (frame->even_row_bg != Color(0, 0, 0, 0) ? frame->even_row_bg : even_row_bg), true); } - draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width, table->rows[row])), (frame->border != Color(0, 0, 0, 0) ? frame->border : border), false); + draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width + hseparation + frame->padding.position.x + frame->padding.size.x, table->rows[row])), (frame->border != Color(0, 0, 0, 0) ? frame->border : border), false); } for (int j = 0; j < frame->lines.size(); j++) { - _draw_line(frame, j, p_ofs + rect.position + off + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_base_color, p_outline_size, p_outline_color, p_font_color_shadow, p_shadow_as_outline, p_shadow_ofs); + _draw_line(frame, j, p_ofs + rect.position + off + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_base_color, p_outline_size, p_outline_color, p_font_shadow_color, p_shadow_as_outline, p_shadow_ofs); } idx++; } @@ -809,8 +821,8 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ // Draw oulines and shadow. for (int i = 0; i < gl_size; i++) { Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start); - int size = _find_outline_size(it); - Color font_color = _find_outline_color(it, Color(0, 0, 0, 0)); + int size = _find_outline_size(it, p_outline_size); + Color font_color = _find_outline_color(it, p_outline_color); if (size <= 0) { gloff.x += glyphs[i].advance; continue; @@ -910,9 +922,9 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ if (visible) { if (frid != RID()) { if (p_shadow_as_outline) { - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, shadow_ofs.y), gl, p_font_color_shadow); - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(shadow_ofs.x, -shadow_ofs.y), gl, p_font_color_shadow); - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, -shadow_ofs.y), gl, p_font_color_shadow); + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, shadow_ofs.y), gl, p_font_shadow_color); + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(shadow_ofs.x, -shadow_ofs.y), gl, p_font_shadow_color); + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, -shadow_ofs.y), gl, p_font_shadow_color); } TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, font_color); } @@ -922,7 +934,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ } // Draw main text. - Color selection_fg = get_theme_color("font_color_selected"); + Color selection_fg = get_theme_color("font_selected_color"); Color selection_bg = get_theme_color("selection_color"); int sel_start = -1; @@ -1068,6 +1080,8 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ } off.y += TS->shaped_text_get_descent(rid); } + + return line_count; } void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside) { @@ -1386,19 +1400,20 @@ void RichTextLabel::_notification(int p_what) { } Ref<Font> base_font = get_theme_font("normal_font"); Color base_color = get_theme_color("default_color"); - Color outline_color = get_theme_color("outline_color"); + Color outline_color = get_theme_color("font_outline_color"); int outline_size = get_theme_constant("outline_size"); - Color font_color_shadow = get_theme_color("font_color_shadow"); + Color font_shadow_color = get_theme_color("font_shadow_color"); bool use_outline = get_theme_constant("shadow_as_outline"); Point2 shadow_ofs(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y")); + visible_paragraph_count = 0; visible_line_count = 0; // New cache draw. Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs); while (ofs.y < size.height && from_line < main->lines.size()) { - visible_line_count++; - _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_color_shadow, use_outline, shadow_ofs); + visible_paragraph_count++; + visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_shadow_color, use_outline, shadow_ofs); ofs.y += main->lines[from_line].text_buf->get_size().y; from_line++; } @@ -1560,53 +1575,36 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventKey> k = p_event; if (k.is_valid()) { - if (k->is_pressed() && !k->get_alt() && !k->get_shift()) { + if (k->is_pressed()) { bool handled = false; - switch (k->get_keycode()) { - case KEY_PAGEUP: { - if (vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() - vscroll->get_page()); - handled = true; - } - } break; - case KEY_PAGEDOWN: { - if (vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() + vscroll->get_page()); - handled = true; - } - } break; - case KEY_UP: { - if (vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() - get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size"))); - handled = true; - } - } break; - case KEY_DOWN: { - if (vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() + get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size"))); - handled = true; - } - } break; - case KEY_HOME: { - if (vscroll->is_visible_in_tree()) { - vscroll->set_value(0); - handled = true; - } - } break; - case KEY_END: { - if (vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_max()); - handled = true; - } - } break; - case KEY_INSERT: - case KEY_C: { - if (k->get_command()) { - selection_copy(); - handled = true; - } - } break; + if (k->is_action("ui_page_up") && vscroll->is_visible_in_tree()) { + vscroll->set_value(vscroll->get_value() - vscroll->get_page()); + handled = true; + } + if (k->is_action("ui_page_down") && vscroll->is_visible_in_tree()) { + vscroll->set_value(vscroll->get_value() + vscroll->get_page()); + handled = true; + } + if (k->is_action("ui_up") && vscroll->is_visible_in_tree()) { + vscroll->set_value(vscroll->get_value() - get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size"))); + handled = true; + } + if (k->is_action("ui_down") && vscroll->is_visible_in_tree()) { + vscroll->set_value(vscroll->get_value() + get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size"))); + handled = true; + } + if (k->is_action("ui_home") && vscroll->is_visible_in_tree()) { + vscroll->set_value(0); + handled = true; + } + if (k->is_action("ui_end") && vscroll->is_visible_in_tree()) { + vscroll->set_value(vscroll->get_max()); + handled = true; + } + if (k->is_action("ui_copy")) { + selection_copy(); + handled = true; } if (handled) { @@ -1740,7 +1738,7 @@ int RichTextLabel::_find_font_size(Item *p_item) { return -1; } -int RichTextLabel::_find_outline_size(Item *p_item) { +int RichTextLabel::_find_outline_size(Item *p_item, int p_default) { Item *sizeitem = p_item; while (sizeitem) { @@ -1752,7 +1750,7 @@ int RichTextLabel::_find_outline_size(Item *p_item) { sizeitem = sizeitem->parent; } - return 0; + return p_default; } Dictionary RichTextLabel::_find_font_features(Item *p_item) { @@ -1834,7 +1832,7 @@ int RichTextLabel::_find_list(Item *p_item, Vector<int> &r_index, Vector<ItemLis int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size) { Item *item = p_item; - float margin = 0; + float margin = 0.0; while (item) { if (item->type == ITEM_INDENT) { @@ -1846,7 +1844,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int if (font_size == -1) { font_size = p_base_font_size; } - margin += tab_size * font->get_char_size('m', 0, font_size).width; + margin += tab_size * font->get_char_size(' ', 0, font_size).width; } else if (item->type == ITEM_LIST) { Ref<Font> font = _find_font(item); @@ -1857,7 +1855,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int if (font_size == -1) { font_size = p_base_font_size; } - margin += tab_size * font->get_char_size('m', 0, font_size).width; + margin += tab_size * font->get_char_size(' ', 0, font_size).width; } item = item->parent; @@ -2001,46 +1999,6 @@ void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack } } -Color RichTextLabel::_get_color_from_string(const String &p_color_str, const Color &p_default_color) { - if (p_color_str.begins_with("#")) { - return Color::html(p_color_str); - } else if (p_color_str == "aqua") { - return Color(0, 1, 1); - } else if (p_color_str == "black") { - return Color(0, 0, 0); - } else if (p_color_str == "blue") { - return Color(0, 0, 1); - } else if (p_color_str == "fuchsia") { - return Color(1, 0, 1); - } else if (p_color_str == "gray" || p_color_str == "grey") { - return Color(0.5, 0.5, 0.5); - } else if (p_color_str == "green") { - return Color(0, 0.5, 0); - } else if (p_color_str == "lime") { - return Color(0, 1, 0); - } else if (p_color_str == "maroon") { - return Color(0.5, 0, 0); - } else if (p_color_str == "navy") { - return Color(0, 0, 0.5); - } else if (p_color_str == "olive") { - return Color(0.5, 0.5, 0); - } else if (p_color_str == "purple") { - return Color(0.5, 0, 0.5); - } else if (p_color_str == "red") { - return Color(1, 0, 0); - } else if (p_color_str == "silver") { - return Color(0.75, 0.75, 0.75); - } else if (p_color_str == "teal") { - return Color(0, 0.5, 0.5); - } else if (p_color_str == "white") { - return Color(1, 1, 1); - } else if (p_color_str == "yellow") { - return Color(1, 1, 0); - } else { - return p_default_color; - } -} - bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) { Item *item = p_item; @@ -2279,6 +2237,8 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, } ERR_FAIL_COND(p_image.is_null()); + ERR_FAIL_COND(p_image->get_width() == 0); + ERR_FAIL_COND(p_image->get_height() == 0); ItemImage *item = memnew(ItemImage); item->image = p_image; @@ -2905,17 +2865,18 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { } } push_cell(); + const Color fallback_color = Color(0, 0, 0, 0); for (int i = 0; i < subtag.size(); i++) { Vector<String> subtag_a = subtag[i].split("="); if (subtag_a.size() == 2) { if (subtag_a[0] == "border") { - Color color = _get_color_from_string(subtag_a[1], Color(0, 0, 0, 0)); + Color color = Color::from_string(subtag_a[1], fallback_color); set_cell_border_color(color); } else if (subtag_a[0] == "bg") { Vector<String> subtag_b = subtag_a[1].split(","); if (subtag_b.size() == 2) { - Color color1 = _get_color_from_string(subtag_b[0], Color(0, 0, 0, 0)); - Color color2 = _get_color_from_string(subtag_b[1], Color(0, 0, 0, 0)); + Color color1 = Color::from_string(subtag_b[0], fallback_color); + Color color2 = Color::from_string(subtag_b[1], fallback_color); set_cell_row_background_color(color1, color2); } } @@ -3131,9 +3092,9 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { } else if (subtag_a[0] == "outline_size") { outline_size = subtag_a[1].to_int(); } else if (subtag_a[0] == "color") { - color = _get_color_from_string(subtag_a[1], color); + color = Color::from_string(subtag_a[1], color); } else if (subtag_a[0] == "outline_color") { - outline_color = _get_color_from_string(subtag_a[1], outline_color); + outline_color = Color::from_string(subtag_a[1], outline_color); } } } @@ -3173,7 +3134,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { Color color = Color(1.0, 1.0, 1.0); OptionMap::Element *color_option = bbcode_options.find("color"); if (color_option) { - color = _get_color_from_string(color_option->value(), color); + color = Color::from_string(color_option->value(), color); } int width = 0; @@ -3205,14 +3166,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { tag_stack.push_front(bbcode_name); } else if (tag.begins_with("color=")) { String color_str = tag.substr(6, tag.length()); - Color color = _get_color_from_string(color_str, base_color); + Color color = Color::from_string(color_str, base_color); push_color(color); pos = brk_end + 1; tag_stack.push_front("color"); } else if (tag.begins_with("outline_color=")) { String color_str = tag.substr(14, tag.length()); - Color color = _get_color_from_string(color_str, base_color); + Color color = Color::from_string(color_str, base_color); push_outline_color(color); pos = brk_end + 1; tag_stack.push_front("outline_color"); @@ -3406,14 +3367,46 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { return OK; } +void RichTextLabel::scroll_to_paragraph(int p_paragraph) { + ERR_FAIL_INDEX(p_paragraph, main->lines.size()); + _validate_line_caches(main); + vscroll->set_value(main->lines[p_paragraph].offset.y); +} + +int RichTextLabel::get_paragraph_count() const { + return current_frame->lines.size(); +} + +int RichTextLabel::get_visible_paragraph_count() const { + if (!is_visible()) { + return 0; + } + return visible_paragraph_count; +} + void RichTextLabel::scroll_to_line(int p_line) { - ERR_FAIL_INDEX(p_line, main->lines.size()); _validate_line_caches(main); - vscroll->set_value(main->lines[p_line].offset.y); + + int line_count = 0; + for (int i = 0; i < main->lines.size(); i++) { + if ((line_count <= p_line) && (line_count + main->lines[i].text_buf->get_line_count() >= p_line)) { + float line_offset = 0.f; + for (int j = 0; j < p_line - line_count; j++) { + line_offset += main->lines[i].text_buf->get_line_size(j).y; + } + vscroll->set_value(main->lines[i].offset.y + line_offset); + return; + } + line_count += main->lines[i].text_buf->get_line_count(); + } } int RichTextLabel::get_line_count() const { - return current_frame->lines.size(); + int line_count = 0; + for (int i = 0; i < main->lines.size(); i++) { + line_count += main->lines[i].text_buf->get_line_count(); + } + return line_count; } int RichTextLabel::get_visible_line_count() const { @@ -3514,7 +3507,7 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p return false; } -String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) { +String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) const { String text; ERR_FAIL_COND_V(p_frame == nullptr, text); ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), text); @@ -3581,7 +3574,7 @@ String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p return text; } -String RichTextLabel::get_selected_text() { +String RichTextLabel::get_selected_text() const { if (!selection.active || !selection.enabled) { return ""; } @@ -3605,6 +3598,22 @@ bool RichTextLabel::is_selection_enabled() const { return selection.enabled; } +int RichTextLabel::get_selection_from() const { + if (!selection.active || !selection.enabled) { + return -1; + } + + return selection.from_frame->lines[selection.from_line].char_offset + selection.from_char; +} + +int RichTextLabel::get_selection_to() const { + if (!selection.active || !selection.enabled) { + return -1; + } + + return selection.to_frame->lines[selection.to_line].char_offset + selection.to_char - 1; +} + void RichTextLabel::set_bbcode(const String &p_bbcode) { bbcode = p_bbcode; if (is_inside_tree() && use_bbcode) { @@ -3640,6 +3649,8 @@ String RichTextLabel::get_text() { text += t->text; } else if (it->type == ITEM_NEWLINE) { text += "\n"; + } else if (it->type == ITEM_IMAGE) { + text += " "; } else if (it->type == ITEM_INDENT || it->type == ITEM_LIST) { text += "\t"; } @@ -3821,6 +3832,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll); ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line); + ClassDB::bind_method(D_METHOD("scroll_to_paragraph", "paragraph"), &RichTextLabel::scroll_to_paragraph); ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size); ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size); @@ -3831,6 +3843,11 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled); ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled); + ClassDB::bind_method(D_METHOD("get_selection_from"), &RichTextLabel::get_selection_from); + ClassDB::bind_method(D_METHOD("get_selection_to"), &RichTextLabel::get_selection_to); + + ClassDB::bind_method(D_METHOD("get_selected_text"), &RichTextLabel::get_selected_text); + ClassDB::bind_method(D_METHOD("parse_bbcode", "bbcode"), &RichTextLabel::parse_bbcode); ClassDB::bind_method(D_METHOD("append_bbcode", "bbcode"), &RichTextLabel::append_bbcode); @@ -3851,6 +3868,9 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line_count"), &RichTextLabel::get_line_count); ClassDB::bind_method(D_METHOD("get_visible_line_count"), &RichTextLabel::get_visible_line_count); + ClassDB::bind_method(D_METHOD("get_paragraph_count"), &RichTextLabel::get_paragraph_count); + ClassDB::bind_method(D_METHOD("get_visible_paragraph_count"), &RichTextLabel::get_visible_paragraph_count); + ClassDB::bind_method(D_METHOD("get_content_height"), &RichTextLabel::get_content_height); ClassDB::bind_method(D_METHOD("parse_expressions_for_values", "expressions"), &RichTextLabel::parse_expressions_for_values); @@ -3929,6 +3949,14 @@ void RichTextLabel::_bind_methods() { void RichTextLabel::set_visible_characters(int p_visible) { visible_characters = p_visible; + if (p_visible == -1) { + percent_visible = 1; + } else { + int total_char_count = get_total_character_count(); + if (total_char_count > 0) { + percent_visible = (float)p_visible / (float)total_char_count; + } + } update(); } @@ -4046,19 +4074,6 @@ RichTextLabel::RichTextLabel() { main->first_invalid_line = 0; main->first_resized_line = 0; current_frame = main; - tab_size = 4; - default_align = ALIGN_LEFT; - underline_meta = true; - meta_hovering = nullptr; - override_selected_font_color = false; - - scroll_visible = false; - scroll_follow = false; - scroll_following = false; - updating_scroll = false; - scroll_active = true; - scroll_w = 0; - scroll_updated = false; vscroll = memnew(VScrollBar); add_child(vscroll); @@ -4070,19 +4085,6 @@ RichTextLabel::RichTextLabel() { vscroll->connect("value_changed", callable_mp(this, &RichTextLabel::_scroll_changed)); vscroll->set_step(1); vscroll->hide(); - use_bbcode = false; - - selection.click_frame = nullptr; - selection.click_item = nullptr; - selection.active = false; - selection.enabled = false; - - visible_characters = -1; - percent_visible = 1; - visible_line_count = 0; - - fixed_width = -1; - fit_content_height = false; set_clip_contents(true); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index f828a8cd1a..2351aff0a4 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -147,9 +147,9 @@ private: struct ItemDropcap : public Item { String text; Ref<Font> font; - int font_size; + int font_size = 0; Color color; - int ol_size; + int ol_size = 0; Color ol_color; Rect2 dropcap_margins; ItemDropcap() { type = ITEM_DROPCAP; } @@ -232,11 +232,11 @@ private: struct ItemTable : public Item { struct Column { - bool expand; - int expand_ratio; - int min_width; - int max_width; - int width; + bool expand = false; + int expand_ratio = 0; + int min_width = 0; + int max_width = 0; + int width = 0; }; Vector<Column> columns; @@ -322,30 +322,31 @@ private: } }; - ItemFrame *main; - Item *current; - ItemFrame *current_frame; + ItemFrame *main = nullptr; + Item *current = nullptr; + ItemFrame *current_frame = nullptr; - VScrollBar *vscroll; + VScrollBar *vscroll = nullptr; - bool scroll_visible; - bool scroll_follow; - bool scroll_following; - bool scroll_active; - int scroll_w; - bool scroll_updated; - bool updating_scroll; + bool scroll_visible = false; + bool scroll_follow = false; + bool scroll_following = false; + bool scroll_active = true; + int scroll_w = 0; + bool scroll_updated = false; + bool updating_scroll = false; int current_idx = 1; int current_char_ofs = 0; - int visible_line_count; + int visible_paragraph_count = 0; + int visible_line_count = 0; - int tab_size; - bool underline_meta; - bool override_selected_font_color; + int tab_size = 4; + bool underline_meta = true; + bool override_selected_font_color = false; - Align default_align; + Align default_align = ALIGN_LEFT; - ItemMeta *meta_hovering; + ItemMeta *meta_hovering = nullptr; Variant current_meta; Vector<Ref<RichTextEffect>> custom_effects; @@ -362,38 +363,38 @@ private: Array st_args; struct Selection { - ItemFrame *click_frame; - int click_line; - Item *click_item; - int click_char; - - ItemFrame *from_frame; - int from_line; - Item *from_item; - int from_char; - - ItemFrame *to_frame; - int to_line; - Item *to_item; - int to_char; - - bool active; // anything selected? i.e. from, to, etc. valid? - bool enabled; // allow selections? + ItemFrame *click_frame = nullptr; + int click_line = 0; + Item *click_item = nullptr; + int click_char = 0; + + ItemFrame *from_frame = nullptr; + int from_line = 0; + Item *from_item = nullptr; + int from_char = 0; + + ItemFrame *to_frame = nullptr; + int to_line = 0; + Item *to_item = nullptr; + int to_char = 0; + + bool active = false; // anything selected? i.e. from, to, etc. valid? + bool enabled = false; // allow selections? }; Selection selection; - int visible_characters; - float percent_visible; + int visible_characters = -1; + float percent_visible = 1.0; void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr); - String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel); + String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const; bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, Item *p_from, Item *p_to); void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset); void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width); - void _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs); + int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, bool p_shadow_as_outline, const Point2 &shadow_ofs); float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr); String _roman(int p_num, bool p_capitalize) const; @@ -404,7 +405,7 @@ private: Ref<Font> _find_font(Item *p_item); int _find_font_size(Item *p_item); Dictionary _find_font_features(Item *p_item); - int _find_outline_size(Item *p_item); + int _find_outline_size(Item *p_item, int p_default); ItemList *_find_list_item(Item *p_item); ItemDropcap *_find_dc_item(Item *p_item); int _find_list(Item *p_item, Vector<int> &r_index, Vector<ItemList *> &r_list); @@ -421,26 +422,24 @@ private: bool _find_layout_subitem(Item *from, Item *to); void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack); - static Color _get_color_from_string(const String &p_color_str, const Color &p_default_color); - void _update_scroll(); void _update_fx(ItemFrame *p_frame, float p_delta_time); void _scroll_changed(double); void _gui_input(Ref<InputEvent> p_event); - Item *_get_next_item(Item *p_item, bool p_free = false); - Item *_get_prev_item(Item *p_item, bool p_free = false); + Item *_get_next_item(Item *p_item, bool p_free = false) const; + Item *_get_prev_item(Item *p_item, bool p_free = false) const; Rect2 _get_text_rect(); Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier); virtual Dictionary parse_expressions_for_values(Vector<String> p_expressions); - bool use_bbcode; + bool use_bbcode = false; String bbcode; - int fixed_width; + int fixed_width = -1; - bool fit_content_height; + bool fit_content_height = false; protected: void _notification(int p_what); @@ -509,6 +508,10 @@ public: bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false); + void scroll_to_paragraph(int p_paragraph); + int get_paragraph_count() const; + int get_visible_paragraph_count() const; + void scroll_to_line(int p_line); int get_line_count() const; int get_visible_line_count() const; @@ -521,7 +524,9 @@ public: void set_selection_enabled(bool p_enabled); bool is_selection_enabled() const; - String get_selected_text(); + int get_selection_from() const; + int get_selection_to() const; + String get_selected_text() const; void selection_copy(); Error parse_bbcode(const String &p_bbcode); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 79a0de35fc..f2516e76a5 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -434,7 +434,7 @@ double ScrollBar::get_area_size() const { } double ScrollBar::get_area_offset() const { - double ofs = 0; + double ofs = 0.0; if (orientation == VERTICAL) { ofs += get_theme_stylebox("hscroll")->get_margin(SIDE_TOP); diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 7dd71cc269..24b3b33e82 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -47,14 +47,14 @@ class ScrollBar : public Range { Orientation orientation; Size2 size; - float custom_step = -1; + float custom_step = -1.0; HighlightStatus highlight = HIGHLIGHT_NONE; struct Drag { bool active = false; - float pos_at_click = 0; - float value_at_click = 0; + float pos_at_click = 0.0; + float value_at_click = 0.0; } drag; double get_grabber_size() const; @@ -73,14 +73,14 @@ class ScrollBar : public Range { Vector2 drag_node_accum; Vector2 drag_node_from; Vector2 last_drag_node_accum; - float last_drag_node_time; - float time_since_motion; + float last_drag_node_time = 0.0; + float time_since_motion = 0.0; bool drag_node_touching = false; bool drag_node_touching_deaccel = false; - bool click_handled; + bool click_handled = false; bool scrolling = false; - double target_scroll = 0; + double target_scroll = 0.0; bool smooth_scroll_enabled = false; void _drag_node_exit(); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 52feb2ab23..411891ece8 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -244,11 +244,11 @@ void ScrollContainer::_ensure_focused_visible(Control *p_control) { if (is_a_parent_of(p_control)) { Rect2 global_rect = get_global_rect(); Rect2 other_rect = p_control->get_global_rect(); - float right_margin = 0; + float right_margin = 0.0; if (v_scroll->is_visible()) { right_margin += v_scroll->get_size().x; } - float bottom_margin = 0; + float bottom_margin = 0.0; if (h_scroll->is_visible()) { bottom_margin += h_scroll->get_size().y; } @@ -624,15 +624,7 @@ ScrollContainer::ScrollContainer() { add_child(v_scroll); v_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved)); - drag_speed = Vector2(); - drag_touching = false; - drag_touching_deaccel = false; - beyond_deadzone = false; - scroll_h = true; - scroll_v = true; - deadzone = GLOBAL_GET("gui/common/default_scroll_deadzone"); - follow_focus = false; set_clip_contents(true); }; diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index 7e32cbed1c..9d3ce39345 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -50,18 +50,18 @@ class ScrollContainer : public Container { Vector2 drag_accum; Vector2 drag_from; Vector2 last_drag_accum; - float last_drag_time; - float time_since_motion; - bool drag_touching; - bool drag_touching_deaccel; - bool click_handled; - bool beyond_deadzone; - - bool scroll_h; - bool scroll_v; - - int deadzone; - bool follow_focus; + float last_drag_time = 0.0; + float time_since_motion = 0.0; + bool drag_touching = false; + bool drag_touching_deaccel = false; + bool click_handled = false; + bool beyond_deadzone = false; + + bool scroll_h = true; + bool scroll_v = true; + + int deadzone = 0; + bool follow_focus = false; void _cancel_drag(); diff --git a/scene/gui/separator.h b/scene/gui/separator.h index 1ac0f2c503..77162c68fa 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -36,7 +36,7 @@ class Separator : public Control { GDCLASS(Separator, Control); protected: - Orientation orientation; + Orientation orientation = Orientation::HORIZONTAL; void _notification(int p_what); public: diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 0edf1856de..2239226c78 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -73,8 +73,10 @@ void Slider::_gui_input(Ref<InputEvent> p_event) { } } else if (scrollable) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) { + grab_focus(); set_value(get_value() + get_step()); } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) { + grab_focus(); set_value(get_value() - get_step()); } } @@ -269,12 +271,5 @@ void Slider::_bind_methods() { Slider::Slider(Orientation p_orientation) { orientation = p_orientation; - mouse_inside = false; - grab.active = false; - ticks = 0; - ticks_on_borders = false; - custom_step = -1; - editable = true; - scrollable = true; set_focus_mode(FOCUS_ALL); } diff --git a/scene/gui/slider.h b/scene/gui/slider.h index 292931b7b5..65a4036cd1 100644 --- a/scene/gui/slider.h +++ b/scene/gui/slider.h @@ -37,23 +37,23 @@ class Slider : public Range { GDCLASS(Slider, Range); struct Grab { - int pos; - float uvalue; - bool active; + int pos = 0; + float uvalue = 0.0; + bool active = false; } grab; - int ticks; - bool mouse_inside; + int ticks = 0; + bool mouse_inside = false; Orientation orientation; - float custom_step; - bool editable; - bool scrollable; + float custom_step = -1.0; + bool editable = true; + bool scrollable = true; protected: void _gui_input(Ref<InputEvent> p_event); void _notification(int p_what); static void _bind_methods(); - bool ticks_on_borders; + bool ticks_on_borders = false; public: virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 037a60810e..2c9720e4b6 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -268,7 +268,6 @@ void SpinBox::_bind_methods() { } SpinBox::SpinBox() { - last_w = 0; line_edit = memnew(LineEdit); add_child(line_edit); @@ -280,7 +279,6 @@ SpinBox::SpinBox() { line_edit->connect("text_entered", callable_mp(this, &SpinBox::_text_entered), Vector<Variant>(), CONNECT_DEFERRED); line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED); line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input)); - drag.enabled = false; range_click_timer = memnew(Timer); range_click_timer->connect("timeout", callable_mp(this, &SpinBox::_range_click_timeout)); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 0647ec005b..4c3adf30e8 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -39,7 +39,7 @@ class SpinBox : public Range { GDCLASS(SpinBox, Range); LineEdit *line_edit; - int last_w; + int last_w = 0; Timer *range_click_timer; void _range_click_timeout(); @@ -52,11 +52,11 @@ class SpinBox : public Range { void _line_edit_input(const Ref<InputEvent> &p_event); struct Drag { - float base_val; - bool allowed; - bool enabled; + float base_val = 0.0; + bool allowed = false; + bool enabled = false; Vector2 capture_pos; - float diff_y; + float diff_y = 0.0; } drag; void _line_edit_focus_exit(); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index d6f2df1d8c..d43e195df1 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -102,7 +102,7 @@ void SplitContainer::_resort() { middle_sep += clamped_split_offset; if (should_clamp_split_offset) { split_offset = clamped_split_offset; - _change_notify("split_offset"); + should_clamp_split_offset = false; } } @@ -359,12 +359,5 @@ void SplitContainer::_bind_methods() { } SplitContainer::SplitContainer(bool p_vertical) { - mouse_inside = false; - split_offset = 0; - should_clamp_split_offset = false; - middle_sep = 0; vertical = p_vertical; - dragging = false; - collapsed = false; - dragger_visibility = DRAGGER_VISIBLE; } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 46a6792206..6cb94d6ecf 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -44,16 +44,16 @@ public: }; private: - bool should_clamp_split_offset; - int split_offset; - int middle_sep; - bool vertical; - bool dragging; - int drag_from; - int drag_ofs; - bool collapsed; - DraggerVisibility dragger_visibility; - bool mouse_inside; + bool should_clamp_split_offset = false; + int split_offset = 0; + int middle_sep = 0; + bool vertical = false; + bool dragging = false; + int drag_from = 0; + int drag_ofs = 0; + bool collapsed = false; + DraggerVisibility dragger_visibility = DRAGGER_VISIBLE; + bool mouse_inside = false; Control *_getch(int p_idx) const; diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 68eef0f96b..8ffdd269a4 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -203,8 +203,6 @@ void SubViewportContainer::_bind_methods() { } SubViewportContainer::SubViewportContainer() { - stretch = false; - shrink = 1; set_process_input(true); set_process_unhandled_input(true); } diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h index 91fc29d377..77cf4c16b3 100644 --- a/scene/gui/subviewport_container.h +++ b/scene/gui/subviewport_container.h @@ -36,8 +36,8 @@ class SubViewportContainer : public Container { GDCLASS(SubViewportContainer, Container); - bool stretch; - int shrink; + bool stretch = false; + int shrink = 1; protected: void _notification(int p_what); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 7f0d7b6e7b..e3e3f549de 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -43,11 +43,11 @@ int TabContainer::_get_top_margin() const { } // Respect the minimum tab height. - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); - int tab_height = MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height); + int tab_height = MAX(MAX(tab_unselected->get_minimum_size().height, tab_selected->get_minimum_size().height), tab_disabled->get_minimum_size().height); // Font height or higher icon wins. int content_height = 0; @@ -337,8 +337,8 @@ void TabContainer::_notification(int p_what) { } Vector<Control *> tabs = _get_tabs(); - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); Ref<Texture2D> increment = get_theme_icon("increment"); Ref<Texture2D> increment_hl = get_theme_icon("increment_highlight"); @@ -346,9 +346,9 @@ void TabContainer::_notification(int p_what) { Ref<Texture2D> decrement_hl = get_theme_icon("decrement_highlight"); Ref<Texture2D> menu = get_theme_icon("menu"); Ref<Texture2D> menu_hl = get_theme_icon("menu_highlight"); - Color font_color_fg = get_theme_color("font_color_fg"); - Color font_color_bg = get_theme_color("font_color_bg"); - Color font_color_disabled = get_theme_color("font_color_disabled"); + Color font_selected_color = get_theme_color("font_selected_color"); + Color font_unselected_color = get_theme_color("font_unselected_color"); + Color font_disabled_color = get_theme_color("font_disabled_color"); int side_margin = get_theme_constant("side_margin"); // Find out start and width of the header area. @@ -433,17 +433,17 @@ void TabContainer::_notification(int p_what) { int tab_width = tab_widths[i]; if (get_tab_disabled(index)) { if (rtl) { - _draw_tab(tab_disabled, font_color_disabled, index, size.width - (tabs_ofs_cache + x) - tab_width); + _draw_tab(tab_disabled, font_disabled_color, index, size.width - (tabs_ofs_cache + x) - tab_width); } else { - _draw_tab(tab_disabled, font_color_disabled, index, tabs_ofs_cache + x); + _draw_tab(tab_disabled, font_disabled_color, index, tabs_ofs_cache + x); } } else if (index == current) { x_current = x; } else { if (rtl) { - _draw_tab(tab_bg, font_color_bg, index, size.width - (tabs_ofs_cache + x) - tab_width); + _draw_tab(tab_unselected, font_unselected_color, index, size.width - (tabs_ofs_cache + x) - tab_width); } else { - _draw_tab(tab_bg, font_color_bg, index, tabs_ofs_cache + x); + _draw_tab(tab_unselected, font_unselected_color, index, tabs_ofs_cache + x); } } @@ -459,9 +459,9 @@ void TabContainer::_notification(int p_what) { // Draw selected tab in front. only draw selected tab when it's in visible range. if (tabs.size() > 0 && current - first_tab_cache < tab_widths.size() && current >= first_tab_cache) { if (rtl) { - _draw_tab(tab_fg, font_color_fg, current, size.width - (tabs_ofs_cache + x_current) - tab_widths[current]); + _draw_tab(tab_selected, font_selected_color, current, size.width - (tabs_ofs_cache + x_current) - tab_widths[current]); } else { - _draw_tab(tab_fg, font_color_fg, current, tabs_ofs_cache + x_current); + _draw_tab(tab_selected, font_selected_color, current, tabs_ofs_cache + x_current); } } @@ -535,6 +535,8 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in Vector<Control *> tabs = _get_tabs(); RID canvas = get_canvas_item(); Ref<Font> font = get_theme_font("font"); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); int icon_text_distance = get_theme_constant("icon_separation"); int tab_width = _get_tab_width(p_index); int header_height = _get_top_margin(); @@ -565,6 +567,9 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in // Draw the tab text. Point2i text_pos(x_content, y_center - text_buf[p_index]->get_size().y / 2); + if (outline_size > 0 && font_outline_color.a > 0) { + text_buf[p_index]->draw_outline(canvas, text_pos, outline_size, font_outline_color); + } text_buf[p_index]->draw(canvas, text_pos, p_font_color); } @@ -655,15 +660,15 @@ int TabContainer::_get_tab_width(int p_index) const { } // Respect a minimum size. - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); if (get_tab_disabled(p_index)) { width += tab_disabled->get_minimum_size().width; } else if (p_index == current) { - width += tab_fg->get_minimum_size().width; + width += tab_selected->get_minimum_size().width; } else { - width += tab_bg->get_minimum_size().width; + width += tab_unselected->get_minimum_size().width; } return width; @@ -747,8 +752,6 @@ void TabContainer::set_current_tab(int p_current) { _repaint(); - _change_notify("current_tab"); - if (pending_previous == current) { emit_signal("tab_selected", current); } else { @@ -789,6 +792,10 @@ Control *TabContainer::get_current_tab_control() const { void TabContainer::remove_child_notify(Node *p_child) { Container::remove_child_notify(p_child); + if (!Object::cast_to<Control>(p_child)) { + return; + } + call_deferred("_update_current_tab"); p_child->disconnect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback)); @@ -963,8 +970,6 @@ void TabContainer::set_tab_align(TabAlign p_align) { ERR_FAIL_INDEX(p_align, 3); align = p_align; update(); - - _change_notify("tab_align"); } TabContainer::TabAlign TabContainer::get_tab_align() const { @@ -1127,13 +1132,13 @@ Size2 TabContainer::get_minimum_size() const { ms.y = MAX(ms.y, cms.y); } - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); Ref<Font> font = get_theme_font("font"); if (tabs_visible) { - ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y); + ms.y += MAX(MAX(tab_unselected->get_minimum_size().y, tab_selected->get_minimum_size().y), tab_disabled->get_minimum_size().y); ms.y += _get_top_margin(); } @@ -1239,20 +1244,5 @@ void TabContainer::_bind_methods() { } TabContainer::TabContainer() { - first_tab_cache = 0; - last_tab_cache = 0; - buttons_visible_cache = false; - menu_hovered = false; - highlight_arrow = -1; - tabs_ofs_cache = 0; - current = 0; - previous = 0; - align = ALIGN_CENTER; - tabs_visible = true; - all_tabs_in_front = false; - drag_to_rearrange_enabled = false; - tabs_rearrange_group = -1; - use_hidden_tabs_for_min_size = false; - connect("mouse_exited", callable_mp(this, &TabContainer::_on_mouse_exited)); } diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 58742c5be8..4ed5255729 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -46,23 +46,23 @@ public: }; private: - int first_tab_cache; - int tabs_ofs_cache; - int last_tab_cache; - int current; - int previous; - bool tabs_visible; - bool all_tabs_in_front; - bool buttons_visible_cache; - bool menu_hovered; - int highlight_arrow; - TabAlign align; + int first_tab_cache = 0; + int tabs_ofs_cache = 0; + int last_tab_cache = 0; + int current = 0; + int previous = 0; + bool tabs_visible = true; + bool all_tabs_in_front = false; + bool buttons_visible_cache = false; + bool menu_hovered = false; + int highlight_arrow = -1; + TabAlign align = ALIGN_CENTER; Control *_get_tab(int p_idx) const; int _get_top_margin() const; mutable ObjectID popup_obj_id; - bool drag_to_rearrange_enabled; - bool use_hidden_tabs_for_min_size; - int tabs_rearrange_group; + bool drag_to_rearrange_enabled = false; + bool use_hidden_tabs_for_min_size = false; + int tabs_rearrange_group = -1; Vector<Ref<TextLine>> text_buf; Vector<Control *> _get_tabs() const; diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 3bf71d6c01..da1a9698d0 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -38,11 +38,11 @@ #include "scene/gui/texture_rect.h" Size2 Tabs::get_minimum_size() const { - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); - int y_margin = MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height); + int y_margin = MAX(MAX(tab_unselected->get_minimum_size().height, tab_selected->get_minimum_size().height), tab_disabled->get_minimum_size().height); Size2 ms(0, 0); @@ -61,9 +61,9 @@ Size2 Tabs::get_minimum_size() const { if (tabs[i].disabled) { ms.width += tab_disabled->get_minimum_size().width; } else if (current == i) { - ms.width += tab_fg->get_minimum_size().width; + ms.width += tab_selected->get_minimum_size().width; } else { - ms.width += tab_bg->get_minimum_size().width; + ms.width += tab_unselected->get_minimum_size().width; } if (tabs[i].right_button.is_valid()) { @@ -71,7 +71,7 @@ Size2 Tabs::get_minimum_size() const { Size2 bms = rb->get_size(); bms.width += get_theme_constant("hseparation"); ms.width += bms.width; - ms.height = MAX(bms.height + tab_bg->get_minimum_size().height, ms.height); + ms.height = MAX(bms.height + tab_unselected->get_minimum_size().height, ms.height); } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { @@ -79,7 +79,7 @@ Size2 Tabs::get_minimum_size() const { Size2 bms = cb->get_size(); bms.width += get_theme_constant("hseparation"); ms.width += bms.width; - ms.height = MAX(bms.height + tab_bg->get_minimum_size().height, ms.height); + ms.height = MAX(bms.height + tab_unselected->get_minimum_size().height, ms.height); } } @@ -268,13 +268,16 @@ void Tabs::_notification(int p_what) { _update_cache(); RID ci = get_canvas_item(); - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); - Color color_fg = get_theme_color("font_color_fg"); - Color color_bg = get_theme_color("font_color_bg"); - Color color_disabled = get_theme_color("font_color_disabled"); + Color font_selected_color = get_theme_color("font_selected_color"); + Color font_unselected_color = get_theme_color("font_unselected_color"); + Color font_disabled_color = get_theme_color("font_disabled_color"); Ref<Texture2D> close = get_theme_icon("close"); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); + Vector2 size = get_size(); bool rtl = is_layout_rtl(); @@ -316,13 +319,13 @@ void Tabs::_notification(int p_what) { if (tabs[i].disabled) { sb = tab_disabled; - col = color_disabled; + col = font_disabled_color; } else if (i == current) { - sb = tab_fg; - col = color_fg; + sb = tab_selected; + col = font_selected_color; } else { - sb = tab_bg; - col = color_bg; + sb = tab_unselected; + col = font_unselected_color; } if (w + lsize > limit) { @@ -357,9 +360,17 @@ void Tabs::_notification(int p_what) { } if (rtl) { - tabs[i].text_buf->draw(ci, Point2i(size.width - w - tabs[i].text_buf->get_size().x, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2), col); + Vector2 text_pos = Point2i(size.width - w - tabs[i].text_buf->get_size().x, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2); + if (outline_size > 0 && font_outline_color.a > 0) { + tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + tabs[i].text_buf->draw(ci, text_pos, col); } else { - tabs[i].text_buf->draw(ci, Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2), col); + Vector2 text_pos = Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2); + if (outline_size > 0 && font_outline_color.a > 0) { + tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + tabs[i].text_buf->draw(ci, text_pos, col); } w += tabs[i].size_text; @@ -481,7 +492,6 @@ void Tabs::set_current_tab(int p_current) { previous = current; current = p_current; - _change_notify("current_tab"); _update_cache(); update(); @@ -652,8 +662,8 @@ void Tabs::_update_hover() { void Tabs::_update_cache() { Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<Texture2D> incr = get_theme_icon("increment"); Ref<Texture2D> decr = get_theme_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); @@ -683,9 +693,9 @@ void Tabs::_update_cache() { if (tabs[i].disabled) { sb = tab_disabled; } else if (i == current) { - sb = tab_fg; + sb = tab_selected; } else { - sb = tab_bg; + sb = tab_unselected; } int lsize = tabs[i].size_cache; int slen = tabs[i].size_text; @@ -918,8 +928,8 @@ void Tabs::move_tab(int from, int to) { int Tabs::get_tab_width(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, tabs.size(), 0); - Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg"); + Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected"); + Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected"); Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled"); int x = 0; @@ -937,9 +947,9 @@ int Tabs::get_tab_width(int p_idx) const { if (tabs[p_idx].disabled) { x += tab_disabled->get_minimum_size().width; } else if (current == p_idx) { - x += tab_fg->get_minimum_size().width; + x += tab_selected->get_minimum_size().width; } else { - x += tab_bg->get_minimum_size().width; + x += tab_unselected->get_minimum_size().width; } if (tabs[p_idx].right_button.is_valid()) { @@ -1137,27 +1147,5 @@ void Tabs::_bind_methods() { } Tabs::Tabs() { - current = 0; - previous = 0; - tab_align = ALIGN_CENTER; - rb_hover = -1; - rb_pressing = false; - highlight_arrow = -1; - - cb_hover = -1; - cb_pressing = false; - cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER; - offset = 0; - max_drawn_tab = 0; - - select_with_rmb = false; - - min_width = 0; - scrolling_enabled = true; - buttons_visible = false; - hover = -1; - drag_to_rearrange_enabled = false; - tabs_rearrange_group = -1; - connect("mouse_exited", callable_mp(this, &Tabs::_on_mouse_exited)); } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 4396981004..86877f4d80 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -63,42 +63,42 @@ private: Ref<TextLine> text_buf; Ref<Texture2D> icon; - int ofs_cache; - bool disabled; - int size_cache; - int size_text; - int x_cache; - int x_size_cache; + int ofs_cache = 0; + bool disabled = false; + int size_cache = 0; + int size_text = 0; + int x_cache = 0; + int x_size_cache = 0; Ref<Texture2D> right_button; Rect2 rb_rect; Rect2 cb_rect; }; - int offset; - int max_drawn_tab; - int highlight_arrow; - bool buttons_visible; - bool missing_right; + int offset = 0; + int max_drawn_tab = 0; + int highlight_arrow = -1; + bool buttons_visible = false; + bool missing_right = false; Vector<Tab> tabs; - int current; - int previous; + int current = 0; + int previous = 0; int _get_top_margin() const; - TabAlign tab_align; - int rb_hover; - bool rb_pressing; + TabAlign tab_align = ALIGN_CENTER; + int rb_hover = -1; + bool rb_pressing = false; - bool select_with_rmb; + bool select_with_rmb = false; - int cb_hover; - bool cb_pressing; - CloseButtonDisplayPolicy cb_displaypolicy; + int cb_hover = -1; + bool cb_pressing = false; + CloseButtonDisplayPolicy cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER; - int hover; // Hovered tab. - int min_width; - bool scrolling_enabled; - bool drag_to_rearrange_enabled; - int tabs_rearrange_group; + int hover = -1; // Hovered tab. + int min_width = 0; + bool scrolling_enabled = true; + bool drag_to_rearrange_enabled = false; + int tabs_rearrange_group = -1; int get_tab_width(int p_idx) const; void _ensure_no_over_offset(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 7557d36298..36aa18417d 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/input/input.h" +#include "core/input/input_map.h" #include "core/object/message_queue.h" #include "core/object/script_language.h" #include "core/os/keyboard.h" @@ -202,7 +203,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ // Apply tab align. if (indent_size > 0) { Vector<float> tabs; - tabs.push_back(font->get_char_size('m', 0, font_size).width * indent_size); + tabs.push_back(font->get_char_size(' ', 0, font_size).width * indent_size); text.write[p_line].data_buf->tab_align(tabs); } } @@ -212,7 +213,7 @@ void TextEdit::Text::invalidate_all_lines() { text.write[i].data_buf->set_width(width); if (indent_size > 0) { Vector<float> tabs; - tabs.push_back(font->get_char_size('m', 0, font_size).width * indent_size); + tabs.push_back(font->get_char_size(' ', 0, font_size).width * indent_size); text.write[i].data_buf->tab_align(tabs); } } @@ -500,7 +501,7 @@ void TextEdit::_update_minimap_click() { int row; _get_minimap_mouse_row(Point2i(mp.x, mp.y), row); - if (row >= get_first_visible_line() && (row < get_last_visible_line() || row >= (text.size() - 1))) { + if (row >= get_first_visible_line() && (row < get_last_full_visible_line() || row >= (text.size() - 1))) { minimap_scroll_ratio = v_scroll->get_as_ratio(); minimap_scroll_click_pos = mp.y; can_drag_minimap = true; @@ -637,7 +638,7 @@ void TextEdit::_notification(int p_what) { int visible_rows = get_visible_rows() + 1; - Color color = readonly ? cache.font_color_readonly : cache.font_color; + Color color = readonly ? cache.font_readonly_color : cache.font_color; if (cache.background_color.a > 0.01) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), cache.background_color); @@ -810,8 +811,8 @@ void TextEdit::_notification(int p_what) { } } + bool is_cursor_line_visible = false; Point2 cursor_pos; - int cursor_insert_offset_y = 0; // Get the highlighted words. String highlighted_text = get_selection_text(); @@ -877,7 +878,7 @@ void TextEdit::_notification(int p_what) { Color current_color = cache.font_color; if (readonly) { - current_color = cache.font_color_readonly; + current_color = cache.font_readonly_color; } Vector<String> wrap_rows = get_wrap_rows_text(minimap_line); @@ -918,7 +919,7 @@ void TextEdit::_notification(int p_what) { if (color_map.has(last_wrap_column + j)) { current_color = color_map[last_wrap_column + j].get("color"); if (readonly) { - current_color.a = cache.font_color_readonly.a; + current_color.a = cache.font_readonly_color.a; } } color = current_color; @@ -977,6 +978,16 @@ void TextEdit::_notification(int p_what) { } } + int top_limit_y = 0; + int bottom_limit_y = get_size().height; + if (readonly) { + top_limit_y += cache.style_readonly->get_margin(SIDE_TOP); + bottom_limit_y -= cache.style_readonly->get_margin(SIDE_BOTTOM); + } else { + top_limit_y += cache.style_normal->get_margin(SIDE_TOP); + bottom_limit_y -= cache.style_normal->get_margin(SIDE_BOTTOM); + } + // draw main text int row_height = get_row_height(); int line = first_visible_line; @@ -1001,7 +1012,7 @@ void TextEdit::_notification(int p_what) { Dictionary color_map = _get_line_syntax_highlighting(line); // Ensure we at least use the font color. - Color current_color = readonly ? cache.font_color_readonly : cache.font_color; + Color current_color = readonly ? cache.font_readonly_color : cache.font_color; const Ref<TextParagraph> ldata = text.get_line_data(line); @@ -1019,17 +1030,33 @@ void TextEdit::_notification(int p_what) { const String &str = wrap_rows[line_wrap_index]; int char_margin = xmargin_beg - cursor.x_ofs; - int ofs_readonly = 0; int ofs_x = 0; + int ofs_y = 0; if (readonly) { - ofs_readonly = cache.style_readonly->get_offset().y / 2; ofs_x = cache.style_readonly->get_offset().x / 2; + ofs_x -= cache.style_normal->get_offset().x / 2; + ofs_y = cache.style_readonly->get_offset().y / 2; + } else { + ofs_y = cache.style_normal->get_offset().y / 2; } - int ofs_y = (i * row_height + cache.line_spacing / 2) + ofs_readonly; + ofs_y += i * row_height + cache.line_spacing / 2; ofs_y -= cursor.wrap_ofs * row_height; ofs_y -= get_v_scroll_offset() * row_height; + bool clipped = false; + if (ofs_y + row_height < top_limit_y) { + // Line is outside the top margin, clip current line. + // Still need to go through the process to prepare color changes for next lines. + clipped = true; + } + + if (ofs_y > bottom_limit_y) { + // Line is outside the bottom margin, clip any remaining text. + i = draw_amount; + break; + } + if (text.is_marked(line)) { if (rtl) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color); @@ -1050,7 +1077,7 @@ void TextEdit::_notification(int p_what) { // Give visual indication of empty selected line. if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) { - int char_w = cache.font->get_char_size('m', 0, cache.font_size).width; + int char_w = cache.font->get_char_size(' ', 0, cache.font_size).width; if (rtl) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - xmargin_beg - ofs_x - char_w, ofs_y, char_w, row_height), cache.selection_color); } else { @@ -1091,6 +1118,9 @@ void TextEdit::_notification(int p_what) { tl->add_string(text, cache.font, cache.font_size); int yofs = ofs_y + (row_height - tl->get_size().y) / 2; + if (cache.outline_size > 0 && cache.outline_color.a > 0) { + tl->draw_outline(ci, Point2(gutter_offset + ofs_x, yofs), cache.outline_size, cache.outline_color); + } tl->draw(ci, Point2(gutter_offset + ofs_x, yofs), get_line_gutter_item_color(line, g)); } break; case GUTTER_TPYE_ICON: { @@ -1147,7 +1177,7 @@ void TextEdit::_notification(int p_what) { char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x; } - if (selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection + if (!clipped && selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column; int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column; Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to); @@ -1167,7 +1197,7 @@ void TextEdit::_notification(int p_what) { } int start = TS->shaped_text_get_range(rid).x; - if (!search_text.is_empty()) { // Search highhlight + if (!clipped && !search_text.is_empty()) { // Search highhlight int search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0); while (search_text_col != -1) { Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text.length() + start); @@ -1190,7 +1220,7 @@ void TextEdit::_notification(int p_what) { } } - if (highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight + if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); while (highlighted_text_col != -1) { Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start); @@ -1212,7 +1242,7 @@ void TextEdit::_notification(int p_what) { } } - if (select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word + if (!clipped && select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word if (_is_char(highlighted_word[0]) || highlighted_word[0] == '.') { int highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); while (highlighted_word_col != -1) { @@ -1230,7 +1260,7 @@ void TextEdit::_notification(int p_what) { } rect.position.y = TS->shaped_text_get_ascent(rid) + cache.font->get_underline_position(cache.font_size); rect.size.y = cache.font->get_underline_thickness(cache.font_size); - draw_rect(rect, cache.font_color_selected); + draw_rect(rect, cache.font_selected_color); } highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_word_col + 1); @@ -1238,6 +1268,7 @@ void TextEdit::_notification(int p_what) { } } + const int line_top_offset_y = ofs_y; ofs_y += (row_height - text_height) / 2; const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid); @@ -1246,11 +1277,27 @@ void TextEdit::_notification(int p_what) { ofs_y += ldata->get_line_ascent(line_wrap_index); int char_ofs = 0; + if (cache.outline_size > 0 && cache.outline_color.a > 0) { + for (int j = 0; j < gl_size; j++) { + for (int k = 0; k < glyphs[j].repeat; k++) { + if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { + if (glyphs[j].font_rid != RID()) { + TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, cache.outline_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, cache.outline_color); + } + } + char_ofs += glyphs[j].advance; + } + if ((char_ofs + char_margin) >= xmargin_end) { + break; + } + } + char_ofs = 0; + } for (int j = 0; j < gl_size; j++) { if (color_map.has(glyphs[j].start)) { current_color = color_map[glyphs[j].start].get("color"); - if (readonly && current_color.a > cache.font_color_readonly.a) { - current_color.a = cache.font_color_readonly.a; + if (readonly && current_color.a > cache.font_readonly_color.a) { + current_color.a = cache.font_readonly_color.a; } } @@ -1259,39 +1306,44 @@ void TextEdit::_notification(int p_what) { int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column; if (glyphs[j].start >= sel_from && glyphs[j].end <= sel_to && override_selected_font_color) { - current_color = cache.font_color_selected; + current_color = cache.font_selected_color; } } - if (brace_matching_enabled) { - if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) || - (cursor.column == glyphs[j].start && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) { - if (brace_open_mismatch) { - current_color = cache.brace_mismatch_color; + int char_pos = char_ofs + char_margin + ofs_x; + if (char_pos >= xmargin_beg) { + if (brace_matching_enabled) { + if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) || + (cursor.column == glyphs[j].start && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) { + if (brace_open_mismatch) { + current_color = cache.brace_mismatch_color; + } + Rect2 rect = Rect2(char_pos, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size)); + draw_rect(rect, current_color); } - Rect2 rect = Rect2(char_ofs + char_margin + ofs_x, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size)); - draw_rect(rect, current_color); - } - if ((brace_close_match_line == line && brace_close_match_column == glyphs[j].start) || - (cursor.column == glyphs[j].start + 1 && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) { - if (brace_close_mismatch) { - current_color = cache.brace_mismatch_color; + if ((brace_close_match_line == line && brace_close_match_column == glyphs[j].start) || + (cursor.column == glyphs[j].start + 1 && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) { + if (brace_close_mismatch) { + current_color = cache.brace_mismatch_color; + } + Rect2 rect = Rect2(char_pos, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size)); + draw_rect(rect, current_color); } - Rect2 rect = Rect2(char_ofs + char_margin + ofs_x, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size)); - draw_rect(rect, current_color); + } + + if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) { + int yofs = (text_height - cache.tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); + cache.tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), current_color); + } else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE)) { + int yofs = (text_height - cache.space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); + int xofs = (glyphs[j].advance * glyphs[j].repeat - cache.space_icon->get_width()) / 2; + cache.space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), current_color); } } - if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) { - int yofs = (text_height - cache.tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); - cache.tab_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), current_color); - } else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE)) { - int yofs = (text_height - cache.space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); - int xofs = (glyphs[j].advance * glyphs[j].repeat - cache.space_icon->get_width()) / 2; - cache.space_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x + xofs, ofs_y + yofs), current_color); - } + for (int k = 0; k < glyphs[j].repeat; k++) { - if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { + if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { if (glyphs[j].font_rid != RID()) { TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color); } else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { @@ -1306,11 +1358,13 @@ void TextEdit::_notification(int p_what) { } if (line_wrap_index == line_wrap_amount && is_folded(line)) { - int yofs = (text_height - cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); - int xofs = cache.folded_eol_icon->get_width() / 2; - Color eol_color = cache.code_folding_color; - eol_color.a = 1; - cache.folded_eol_icon->draw(ci, Point2(char_ofs + char_margin + xofs + ofs_x, ofs_y + yofs), eol_color); + int xofs = char_ofs + char_margin + ofs_x + (cache.folded_eol_icon->get_width() / 2); + if (xofs >= xmargin_beg && xofs < xmargin_end) { + int yofs = (text_height - cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); + Color eol_color = cache.code_folding_color; + eol_color.a = 1; + cache.folded_eol_icon->draw(ci, Point2(xofs, ofs_y + yofs), eol_color); + } } // Carets @@ -1319,8 +1373,10 @@ void TextEdit::_notification(int p_what) { #else int caret_width = 1; #endif - if (cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) { - cursor_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); + if (!clipped && cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) { + is_cursor_line_visible = true; + cursor_pos.y = line_top_offset_y; + if (ime_text.length() == 0) { Rect2 l_caret, t_caret; TextServer::Direction l_dir, t_dir; @@ -1345,7 +1401,7 @@ void TextEdit::_notification(int p_what) { cursor_pos.x = char_margin + ofs_x + t_caret.position.x; } - if (draw_caret) { + if (draw_caret && cursor_pos.x >= xmargin_beg && cursor_pos.x < xmargin_end) { if (block_caret || insert_mode) { //Block or underline caret, draw trailing carets at full height. int h = cache.font->get_height(cache.font_size); @@ -1370,7 +1426,7 @@ void TextEdit::_notification(int p_what) { l_caret.size.y = h; } l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = cache.font->get_char_size('m', 0, cache.font_size).x; + l_caret.size.x = cache.font->get_char_size('M', 0, cache.font_size).x; draw_rect(l_caret, cache.caret_color, false); } @@ -1434,83 +1490,101 @@ void TextEdit::_notification(int p_what) { } } } - ofs_y += ldata->get_line_descent(line_wrap_index); } } bool completion_below = false; - if (completion_active && completion_options.size() > 0) { - // Code completion box. - Ref<StyleBox> csb = get_theme_stylebox("completion"); - int maxlines = get_theme_constant("completion_lines"); - int cmax_width = get_theme_constant("completion_max_width") * cache.font->get_char_size('x', 0, cache.font_size).x; - int scrollw = get_theme_constant("completion_scroll_width"); - Color scrollc = get_theme_color("completion_scroll_color"); + if (completion_active && is_cursor_line_visible && completion_options.size() > 0) { + // Completion panel + + const Ref<StyleBox> csb = get_theme_stylebox("completion"); + const int maxlines = get_theme_constant("completion_lines"); + const int cmax_width = get_theme_constant("completion_max_width") * cache.font->get_char_size('x', 0, cache.font_size).x; + const Color scrollc = get_theme_color("completion_scroll_color"); const int completion_options_size = completion_options.size(); - int lines = MIN(completion_options_size, maxlines); - int w = 0; - int h = lines * row_height; - int nofs = cache.font->get_string_size(completion_base, cache.font_size).width; + const int row_count = MIN(completion_options_size, maxlines); + const int completion_rows_height = row_count * row_height; + const int completion_base_width = cache.font->get_string_size(completion_base, cache.font_size).width; + int scroll_rectangle_width = get_theme_constant("completion_scroll_width"); + int width = 0; + + // Compute max width of the panel based on the longest completion option if (completion_options_size < 50) { for (int i = 0; i < completion_options_size; i++) { - int w2 = MIN(cache.font->get_string_size(completion_options[i].display, cache.font_size).x, cmax_width); - if (w2 > w) { - w = w2; + int line_width = MIN(cache.font->get_string_size(completion_options[i].display, cache.font_size).x, cmax_width); + if (line_width > width) { + width = line_width; } } } else { - w = cmax_width; + width = cmax_width; } // Add space for completion icons. const int icon_hsep = get_theme_constant("hseparation", "ItemList"); - Size2 icon_area_size(row_height, row_height); - w += icon_area_size.width + icon_hsep; + const Size2 icon_area_size(row_height, row_height); + const int icon_area_width = icon_area_size.width + icon_hsep; + width += icon_area_width; - int line_from = CLAMP(completion_index - lines / 2, 0, completion_options_size - lines); + const int line_from = CLAMP(completion_index - row_count / 2, 0, completion_options_size - row_count); - for (int i = 0; i < lines; i++) { + for (int i = 0; i < row_count; i++) { int l = line_from + i; ERR_CONTINUE(l < 0 || l >= completion_options_size); if (completion_options[l].default_value.get_type() == Variant::COLOR) { - w += icon_area_size.width; + width += icon_area_size.width; break; } } - int th = h + csb->get_minimum_size().y; + // Position completion panel + completion_rect.size.width = width + 2; + completion_rect.size.height = completion_rows_height; - if (cursor_pos.y + row_height + th > get_size().height) { - completion_rect.position.y = cursor_pos.y - th - (cache.line_spacing / 2.0f) - cursor_insert_offset_y; - } else { - completion_rect.position.y = cursor_pos.y + cache.font->get_height(cache.font_size) + (cache.line_spacing / 2.0f) + csb->get_offset().y - cursor_insert_offset_y; - completion_below = true; + if (completion_options_size <= maxlines) { + scroll_rectangle_width = 0; } - if (cursor_pos.x - nofs + w + scrollw > get_size().width) { - completion_rect.position.x = get_size().width - w - scrollw; + const Point2 csb_offset = csb->get_offset(); + + const int total_width = completion_rect.size.width + csb->get_minimum_size().x + scroll_rectangle_width; + const int total_height = completion_rect.size.height + csb->get_minimum_size().y; + + const int rect_left_border_x = cursor_pos.x - completion_base_width - icon_area_width - csb_offset.x; + const int rect_right_border_x = rect_left_border_x + total_width; + + if (rect_left_border_x < 0) { + // Anchor the completion panel to the left + completion_rect.position.x = 0; + } else if (rect_right_border_x > get_size().width) { + // Anchor the completion panel to the right + completion_rect.position.x = get_size().width - total_width; } else { - completion_rect.position.x = cursor_pos.x - nofs; + // Let the completion panel float with the cursor + completion_rect.position.x = rect_left_border_x; } - completion_rect.size.width = w + 2; - completion_rect.size.height = h; - if (completion_options_size <= maxlines) { - scrollw = 0; + if (cursor_pos.y + row_height + total_height > get_size().height) { + // Completion panel above the cursor line + completion_rect.position.y = cursor_pos.y - total_height; + } else { + // Completion panel below the cursor line + completion_rect.position.y = cursor_pos.y + row_height; + completion_below = true; } - draw_style_box(csb, Rect2(completion_rect.position - csb->get_offset(), completion_rect.size + csb->get_minimum_size() + Size2(scrollw, 0))); + draw_style_box(csb, Rect2(completion_rect.position - csb_offset, completion_rect.size + csb->get_minimum_size() + Size2(scroll_rectangle_width, 0))); if (cache.completion_background_color.a > 0.01) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scrollw, 0)), cache.completion_background_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scroll_rectangle_width, 0)), cache.completion_background_color); } RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.position.x, completion_rect.position.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color); - draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(nofs, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color); + draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(completion_base_width, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color); - for (int i = 0; i < lines; i++) { + for (int i = 0; i < row_count; i++) { int l = line_from + i; ERR_CONTINUE(l < 0 || l >= completion_options_size); @@ -1547,14 +1621,17 @@ void TextEdit::_notification(int p_what) { } tl->set_align(HALIGN_LEFT); } + if (cache.outline_size > 0 && cache.outline_color.a > 0) { + tl->draw_outline(ci, title_pos, cache.outline_size, cache.outline_color); + } tl->draw(ci, title_pos, completion_options[l].font_color); } - if (scrollw) { + if (scroll_rectangle_width) { // Draw a small scroll rectangle to show a position in the options. float r = (float)maxlines / completion_options_size; float o = (float)line_from / completion_options_size; - draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc); + draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scroll_rectangle_width, completion_rect.size.y * r), scrollc); } completion_line_ofs = line_from; @@ -1562,7 +1639,7 @@ void TextEdit::_notification(int p_what) { // Check to see if the hint should be drawn. bool show_hint = false; - if (completion_hint != "") { + if (is_cursor_line_visible && completion_hint != "") { if (completion_active) { if (completion_below && !callhint_below) { show_hint = true; @@ -1909,7 +1986,7 @@ void TextEdit::backspace_at_cursor() { cursor_set_column(prev_column); } -void TextEdit::indent_right() { +void TextEdit::indent_selected_lines_right() { int start_line; int end_line; @@ -1961,7 +2038,7 @@ void TextEdit::indent_right() { update(); } -void TextEdit::indent_left() { +void TextEdit::indent_selected_lines_left() { int start_line; int end_line; @@ -2032,6 +2109,618 @@ int TextEdit::_calculate_spaces_till_next_right_indent(int column) { return indent_size - column % indent_size; } +void TextEdit::_swap_current_input_direction() { + if (input_direction == TEXT_DIRECTION_LTR) { + input_direction = TEXT_DIRECTION_RTL; + } else { + input_direction = TEXT_DIRECTION_LTR; + } + cursor_set_column(cursor.column); + update(); +} + +void TextEdit::_new_line(bool p_split_current_line, bool p_above) { + if (readonly) { + return; + } + + String ins = "\n"; + + // Keep indentation. + int space_count = 0; + for (int i = 0; i < cursor.column; i++) { + if (text[cursor.line][i] == '\t') { + if (indent_using_spaces) { + ins += space_indent; + } else { + ins += "\t"; + } + space_count = 0; + } else if (text[cursor.line][i] == ' ') { + space_count++; + + if (space_count == indent_size) { + if (indent_using_spaces) { + ins += space_indent; + } else { + ins += "\t"; + } + space_count = 0; + } + } else { + break; + } + } + + if (is_folded(cursor.line)) { + unfold_line(cursor.line); + } + + bool brace_indent = false; + + // No need to indent if we are going upwards. + if (auto_indent && !p_above) { + // Indent once again if previous line will end with ':','{','[','(' and the line is not a comment + // (i.e. colon/brace precedes current cursor position). + if (cursor.column > 0) { + bool indent_char_found = false; + bool should_indent = false; + char indent_char = ':'; + char c = text[cursor.line][cursor.column]; + + for (int i = 0; i < cursor.column; i++) { + c = text[cursor.line][i]; + switch (c) { + case ':': + case '{': + case '[': + case '(': + indent_char_found = true; + should_indent = true; + indent_char = c; + continue; + } + + if (indent_char_found && is_line_comment(cursor.line)) { + should_indent = true; + break; + } else if (indent_char_found && !_is_whitespace(c)) { + should_indent = false; + indent_char_found = false; + } + } + + if (!is_line_comment(cursor.line) && should_indent) { + if (indent_using_spaces) { + ins += space_indent; + } else { + ins += "\t"; + } + + // No need to move the brace below if we are not taking the text with us. + char32_t closing_char = _get_right_pair_symbol(indent_char); + if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !p_split_current_line) { + brace_indent = true; + ins += "\n" + ins.substr(1, ins.length() - 2); + } + } + } + } + begin_complex_operation(); + bool first_line = false; + if (!p_split_current_line) { + if (p_above) { + if (cursor.line > 0) { + cursor_set_line(cursor.line - 1); + cursor_set_column(text[cursor.line].length()); + } else { + cursor_set_column(0); + first_line = true; + } + } else { + cursor_set_column(text[cursor.line].length()); + } + } + + insert_text_at_cursor(ins); + + if (first_line) { + cursor_set_line(0); + } else if (brace_indent) { + cursor_set_line(cursor.line - 1); + cursor_set_column(text[cursor.line].length()); + } + end_complex_operation(); +} + +void TextEdit::_indent_right() { + if (readonly) { + return; + } + + if (is_selection_active()) { + indent_selected_lines_right(); + } else { + // Simple indent. + if (indent_using_spaces) { + // Insert only as much spaces as needed till next indentation level. + int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column); + String indent_to_insert = String(); + for (int i = 0; i < spaces_to_add; i++) { + indent_to_insert = ' ' + indent_to_insert; + } + _insert_text_at_cursor(indent_to_insert); + } else { + _insert_text_at_cursor("\t"); + } + } +} + +void TextEdit::_indent_left() { + if (readonly) { + return; + } + + if (is_selection_active()) { + indent_selected_lines_left(); + } else { + // Simple unindent. + int cc = cursor.column; + const String &line = text[cursor.line]; + + int left = _find_first_non_whitespace_column_of_line(line); + cc = MIN(cc, left); + + while (cc < indent_size && cc < left && line[cc] == ' ') { + cc++; + } + + if (cc > 0 && cc <= text[cursor.line].length()) { + if (text[cursor.line][cc - 1] == '\t') { + // Tabs unindentation. + _remove_text(cursor.line, cc - 1, cursor.line, cc); + if (cursor.column >= left) { + cursor_set_column(MAX(0, cursor.column - 1)); + } + update(); + } else { + // Spaces unindentation. + int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc); + if (spaces_to_remove > 0) { + _remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc); + if (cursor.column > left - spaces_to_remove) { // Inside text? + cursor_set_column(MAX(0, cursor.column - spaces_to_remove)); + } + update(); + } + } + } else if (cc == 0 && line.length() > 0 && line[0] == '\t') { + _remove_text(cursor.line, 0, cursor.line, 1); + update(); + } + } +} + +void TextEdit::_move_cursor_left(bool p_select, bool p_move_by_word) { + // Handle selection + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + if (p_move_by_word) { + int cc = cursor.column; + + if (cc == 0 && cursor.line > 0) { + cursor_set_line(cursor.line - 1); + cursor_set_column(text[cursor.line].length()); + } else { + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid()); + for (int i = words.size() - 1; i >= 0; i--) { + if (words[i].x < cc) { + cc = words[i].x; + break; + } + } + cursor_set_column(cc); + } + } else { + // If the cursor is at the start of the line, and not on the first line, move it up to the end of the previous line. + if (cursor.column == 0) { + if (cursor.line > 0) { + cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1)); + cursor_set_column(text[cursor.line].length()); + } + } else { + if (mid_grapheme_caret_enabled) { + cursor_set_column(cursor_get_column() - 1); + } else { + cursor_set_column(TS->shaped_text_prev_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column())); + } + } + } + + if (p_select) { + _post_shift_selection(); + } +} + +void TextEdit::_move_cursor_right(bool p_select, bool p_move_by_word) { + // Handle selection + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + if (p_move_by_word) { + int cc = cursor.column; + + if (cc == text[cursor.line].length() && cursor.line < text.size() - 1) { + cursor_set_line(cursor.line + 1); + cursor_set_column(0); + } else { + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid()); + for (int i = 0; i < words.size(); i++) { + if (words[i].y > cc) { + cc = words[i].y; + break; + } + } + cursor_set_column(cc); + } + } else { + // If we are at the end of the line, move the caret to the next line down. + if (cursor.column == text[cursor.line].length()) { + if (cursor.line < text.size() - 1) { + cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false); + cursor_set_column(0); + } + } else { + if (mid_grapheme_caret_enabled) { + cursor_set_column(cursor_get_column() + 1); + } else { + cursor_set_column(TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column())); + } + } + } + + if (p_select) { + _post_shift_selection(); + } +} + +void TextEdit::_move_cursor_up(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + int cur_wrap_index = get_cursor_wrap_index(); + if (cur_wrap_index > 0) { + cursor_set_line(cursor.line, true, false, cur_wrap_index - 1); + } else if (cursor.line == 0) { + cursor_set_column(0); + } else { + int new_line = cursor.line - num_lines_from(cursor.line - 1, -1); + if (line_wraps(new_line)) { + cursor_set_line(new_line, true, false, times_line_wraps(new_line)); + } else { + cursor_set_line(new_line, true, false); + } + } + + if (p_select) { + _post_shift_selection(); + } + + _cancel_code_hint(); +} + +void TextEdit::_move_cursor_down(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + int cur_wrap_index = get_cursor_wrap_index(); + if (cur_wrap_index < times_line_wraps(cursor.line)) { + cursor_set_line(cursor.line, true, false, cur_wrap_index + 1); + } else if (cursor.line == get_last_unhidden_line()) { + cursor_set_column(text[cursor.line].length()); + } else { + int new_line = cursor.line + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1); + cursor_set_line(new_line, true, false, 0); + } + + if (p_select) { + _post_shift_selection(); + } + + _cancel_code_hint(); +} + +void TextEdit::_move_cursor_to_line_start(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + // Move cursor column to start of wrapped row and then to start of text. + Vector<String> rows = get_wrap_rows_text(cursor.line); + int wi = get_cursor_wrap_index(); + int row_start_col = 0; + for (int i = 0; i < wi; i++) { + row_start_col += rows[i].length(); + } + if (cursor.column == row_start_col || wi == 0) { + // Compute whitespace symbols seq length. + int current_line_whitespace_len = 0; + while (current_line_whitespace_len < text[cursor.line].length()) { + char32_t c = text[cursor.line][current_line_whitespace_len]; + if (c != '\t' && c != ' ') { + break; + } + current_line_whitespace_len++; + } + + if (cursor_get_column() == current_line_whitespace_len) { + cursor_set_column(0); + } else { + cursor_set_column(current_line_whitespace_len); + } + } else { + cursor_set_column(row_start_col); + } + + if (p_select) { + _post_shift_selection(); + } + + _cancel_completion(); + completion_hint = ""; +} + +void TextEdit::_move_cursor_to_line_end(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + // Move cursor column to end of wrapped row and then to end of text. + Vector<String> rows = get_wrap_rows_text(cursor.line); + int wi = get_cursor_wrap_index(); + int row_end_col = -1; + for (int i = 0; i < wi + 1; i++) { + row_end_col += rows[i].length(); + } + if (wi == rows.size() - 1 || cursor.column == row_end_col) { + cursor_set_column(text[cursor.line].length()); + } else { + cursor_set_column(row_end_col); + } + + if (p_select) { + _post_shift_selection(); + } + _cancel_completion(); + completion_hint = ""; +} + +void TextEdit::_move_cursor_page_up(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + int wi; + int n_line = cursor.line - num_lines_from_rows(cursor.line, get_cursor_wrap_index(), -get_visible_rows(), wi) + 1; + cursor_set_line(n_line, true, false, wi); + + if (p_select) { + _post_shift_selection(); + } + + _cancel_completion(); + completion_hint = ""; +} + +void TextEdit::_move_cursor_page_down(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + int wi; + int n_line = cursor.line + num_lines_from_rows(cursor.line, get_cursor_wrap_index(), get_visible_rows(), wi) - 1; + cursor_set_line(n_line, true, false, wi); + + if (p_select) { + _post_shift_selection(); + } + + _cancel_completion(); + completion_hint = ""; +} + +void TextEdit::_backspace(bool p_word, bool p_all_to_left) { + if (readonly) { + return; + } + + if (is_selection_active()) { + _delete_selection(); + return; + } + if (p_all_to_left) { + int cursor_current_column = cursor.column; + cursor.column = 0; + _remove_text(cursor.line, 0, cursor.line, cursor_current_column); + } else if (p_word) { + int line = cursor.line; + int column = cursor.column; + + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = words.size() - 1; i >= 0; i--) { + if (words[i].x < column) { + column = words[i].x; + break; + } + } + + _remove_text(line, column, cursor.line, cursor.column); + + cursor_set_line(line); + cursor_set_column(column); + } else { + // One character. + if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) { + unfold_line(cursor.line - 1); + } + backspace_at_cursor(); + } +} + +void TextEdit::_delete(bool p_word, bool p_all_to_right) { + if (readonly) { + return; + } + + if (is_selection_active()) { + _delete_selection(); + return; + } + int curline_len = text[cursor.line].length(); + + if (cursor.line == text.size() - 1 && cursor.column == curline_len) { + return; // Last line, last column: Nothing to do. + } + + int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1; + int next_column; + + if (p_all_to_right) { + // Delete everything to right of cursor + next_column = curline_len; + next_line = cursor.line; + } else if (p_word && cursor.column < curline_len - 1) { + // Delete next word to right of cursor + int line = cursor.line; + int column = cursor.column; + + Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = 0; i < words.size(); i++) { + if (words[i].y > column) { + column = words[i].y; + break; + } + } + + next_line = line; + next_column = column; + } else { + // Delete one character + next_column = cursor.column < curline_len ? (cursor.column + 1) : 0; + if (mid_grapheme_caret_enabled) { + next_column = cursor.column < curline_len ? (cursor.column + 1) : 0; + } else { + next_column = cursor.column < curline_len ? TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), (cursor.column)) : 0; + } + } + + _remove_text(cursor.line, cursor.column, next_line, next_column); + update(); +} + +void TextEdit::_delete_selection() { + if (is_selection_active()) { + selection.active = false; + update(); + _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); + cursor_set_line(selection.from_line, true, false); + cursor_set_column(selection.from_column); + update(); + } +} + +void TextEdit::_move_cursor_document_start(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + cursor_set_line(0); + cursor_set_column(0); + + if (p_select) { + _post_shift_selection(); + } +} + +void TextEdit::_move_cursor_document_end(bool p_select) { + if (p_select) { + _pre_shift_selection(); + } else { + deselect(); + } + + cursor_set_line(get_last_unhidden_line(), true, false, 9999); + cursor_set_column(text[cursor.line].length()); + + if (p_select) { + _post_shift_selection(); + } +} + +void TextEdit::_handle_unicode_character(uint32_t unicode, bool p_had_selection, bool p_update_auto_complete) { + if (p_update_auto_complete) { + _reset_caret_blink_timer(); + } + + if (p_had_selection) { + _delete_selection(); + } + + // Remove the old character if in insert mode and no selection. + if (insert_mode && !p_had_selection) { + begin_complex_operation(); + + // Make sure we don't try and remove empty space. + if (cursor.column < get_line(cursor.line).length()) { + _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); + } + } + + const char32_t chr[2] = { (char32_t)unicode, 0 }; + + // Clear completion hint when function closed + if (completion_hint != "" && unicode == ')') { + completion_hint = ""; + } + + if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { + _consume_pair_symbol(chr[0]); + } else { + _insert_text_at_cursor(chr); + } + + if ((insert_mode && !p_had_selection) || (selection.active != p_had_selection)) { + end_complex_operation(); + } + + if (p_update_auto_complete) { + _update_completion_candidates(); + } +} + void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const { float rows = p_mouse.y; rows -= cache.style_normal->get_margin(SIDE_TOP); @@ -2062,6 +2751,18 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co } else { int colx = p_mouse.x - (cache.style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding); colx += cursor.x_ofs; + col = get_char_pos_for_line(colx, row, wrap_index); + if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) { + // Move back one if we are at the end of the row. + Vector<String> rows2 = get_wrap_rows_text(row); + int row_end_col = 0; + for (int i = 0; i < wrap_index + 1; i++) { + row_end_col += rows2[i].length(); + } + if (col >= row_end_col) { + col -= 1; + } + } RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index); if (is_layout_rtl()) { @@ -2267,7 +2968,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { int prev_col = cursor.column; int prev_line = cursor.line; - cursor_set_line(row, true, false); + cursor_set_line(row, false, false); cursor_set_column(col); if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) { @@ -2314,7 +3015,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { update(); } - } else { selection.active = false; selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER; @@ -2363,7 +3063,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { menu->set_position(get_screen_transform().xform(mpos)); menu->set_size(Vector2(1, 1)); - // menu->set_scale(get_global_transform().get_scale()); + _generate_context_menu(); menu->popup(); grab_focus(); } @@ -2457,13 +3157,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { Ref<InputEventKey> k = p_gui_input; if (k.is_valid()) { - k = k->duplicate(); // It will be modified later on. - + // Ctrl + Hover symbols #ifdef OSX_ENABLED if (k->get_keycode() == KEY_META) { #else if (k->get_keycode() == KEY_CONTROL) { - #endif if (select_identifiers_enabled) { if (k->is_pressed() && !dragging_minimap && !dragging_selection) { @@ -2473,1191 +3171,347 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { set_highlighted_word(String()); } } + return; } if (!k->is_pressed()) { return; } - if (completion_active) { - if (readonly) { - return; - } - - bool valid = true; - if (k->get_command() || k->get_metakey()) { - valid = false; - } - - if (valid) { - if (!k->get_alt()) { - if (k->get_keycode() == KEY_UP) { - if (completion_index > 0) { - completion_index--; - } else { - completion_index = completion_options.size() - 1; - } - completion_current = completion_options[completion_index]; - update(); - - accept_event(); - return; - } - - if (k->get_keycode() == KEY_DOWN) { - if (completion_index < completion_options.size() - 1) { - completion_index++; - } else { - completion_index = 0; - } - completion_current = completion_options[completion_index]; - update(); - - accept_event(); - return; - } - - if (k->get_keycode() == KEY_PAGEUP) { - completion_index -= get_theme_constant("completion_lines"); - if (completion_index < 0) { - completion_index = 0; - } - completion_current = completion_options[completion_index]; - update(); - accept_event(); - return; - } - - if (k->get_keycode() == KEY_PAGEDOWN) { - completion_index += get_theme_constant("completion_lines"); - if (completion_index >= completion_options.size()) { - completion_index = completion_options.size() - 1; - } - completion_current = completion_options[completion_index]; - update(); - accept_event(); - return; - } - - if (k->get_keycode() == KEY_HOME && completion_index > 0) { - completion_index = 0; - completion_current = completion_options[completion_index]; - update(); - accept_event(); - return; - } - - if (k->get_keycode() == KEY_END && completion_index < completion_options.size() - 1) { - completion_index = completion_options.size() - 1; - completion_current = completion_options[completion_index]; - update(); - accept_event(); - return; - } - - if (k->get_keycode() == KEY_KP_ENTER || k->get_keycode() == KEY_ENTER || k->get_keycode() == KEY_TAB) { - _confirm_completion(); - accept_event(); - return; - } - - if (k->get_keycode() == KEY_BACKSPACE) { - _reset_caret_blink_timer(); - - backspace_at_cursor(); - _update_completion_candidates(); - accept_event(); - return; - } - - if (k->get_keycode() == KEY_SHIFT) { - accept_event(); - return; - } - } - - if (k->get_unicode() > 32) { - _reset_caret_blink_timer(); - - const char32_t chr[2] = { (char32_t)k->get_unicode(), 0 }; - if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { - _consume_pair_symbol(chr[0]); - } else { - // Remove the old character if in insert mode. - if (insert_mode) { - begin_complex_operation(); - - // Make sure we don't try and remove empty space. - if (cursor.column < get_line(cursor.line).length()) { - _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); - } - } - - _insert_text_at_cursor(chr); - - if (insert_mode) { - end_complex_operation(); - } - } - _update_completion_candidates(); - accept_event(); - - return; - } - } - - _cancel_completion(); - } - - /* TEST CONTROL FIRST! */ - - // Some remaps for duplicate functions. - if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) { - k->set_keycode(KEY_C); - } - if (!k->get_command() && k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) { - k->set_keycode(KEY_V); - k->set_command(true); - k->set_shift(false); - } -#ifdef APPLE_STYLE_KEYS - if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) { - uint32_t remap_key = KEY_UNKNOWN; - switch (k->get_keycode()) { - case KEY_F: { - remap_key = KEY_RIGHT; - } break; - case KEY_B: { - remap_key = KEY_LEFT; - } break; - case KEY_P: { - remap_key = KEY_UP; - } break; - case KEY_N: { - remap_key = KEY_DOWN; - } break; - case KEY_D: { - remap_key = KEY_DELETE; - } break; - case KEY_H: { - remap_key = KEY_BACKSPACE; - } break; - } - - if (remap_key != KEY_UNKNOWN) { - k->set_keycode(remap_key); - k->set_control(false); - } + // If a modifier has been pressed, and nothing else, return. + if (k->get_keycode() == KEY_CONTROL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT || k->get_keycode() == KEY_META) { + return; } -#endif _reset_caret_blink_timer(); + // Allow unicode handling if: + // * No Modifiers are pressed (except shift) + bool allow_unicode_handling = !(k->get_command() || k->get_control() || k->get_alt() || k->get_metakey()); + // Save here for insert mode, just in case it is cleared in the following section. bool had_selection = selection.active; - // Stuff to do when selection is active. - if (!readonly && selection.active) { - bool clear = false; - bool unselect = false; - bool dobreak = false; - - switch (k->get_keycode()) { - case KEY_TAB: { - if (k->get_shift()) { - indent_left(); - } else { - indent_right(); - } - dobreak = true; - accept_event(); - } break; - case KEY_X: - case KEY_C: - // Special keys often used with control, wait. - clear = (!k->get_command() || k->get_shift() || k->get_alt()); - break; - case KEY_DELETE: - if (!k->get_shift()) { - accept_event(); - clear = true; - dobreak = true; - } else if (k->get_command() || k->get_alt()) { - dobreak = true; - } - break; - case KEY_BACKSPACE: - accept_event(); - clear = true; - dobreak = true; - break; - case KEY_LEFT: - case KEY_RIGHT: - case KEY_UP: - case KEY_DOWN: - case KEY_PAGEUP: - case KEY_PAGEDOWN: - case KEY_HOME: - case KEY_END: - // Ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys). - if (k->get_command() || k->get_shift() || k->get_alt()) { - break; - } - unselect = true; - break; - - default: - if (k->get_unicode() >= 32 && !k->get_command() && !k->get_alt() && !k->get_metakey()) { - clear = true; - } - if (auto_brace_completion_enabled && _is_pair_left_symbol(k->get_unicode())) { - clear = false; - } - } - - if (unselect) { - selection.active = false; - selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE; - update(); - } - if (clear) { - if (!dobreak) { - begin_complex_operation(); - } - selection.active = false; - update(); - _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); - cursor_set_line(selection.from_line, true, false); - cursor_set_column(selection.from_column); - update(); - } - if (dobreak) { - return; - } - } - selection.selecting_text = false; - bool keycode_handled = true; - - // Special keycode test. - - switch (k->get_keycode()) { - case KEY_KP_ENTER: - case KEY_ENTER: { - if (readonly) { - break; - } - - String ins = "\n"; - - // Keep indentation. - int space_count = 0; - for (int i = 0; i < cursor.column; i++) { - if (text[cursor.line][i] == '\t') { - if (indent_using_spaces) { - ins += space_indent; - } else { - ins += "\t"; - } - space_count = 0; - } else if (text[cursor.line][i] == ' ') { - space_count++; - - if (space_count == indent_size) { - if (indent_using_spaces) { - ins += space_indent; - } else { - ins += "\t"; - } - space_count = 0; - } - } else { - break; - } - } - - if (is_folded(cursor.line)) { - unfold_line(cursor.line); - } - - bool brace_indent = false; - - // No need to indent if we are going upwards. - if (auto_indent && !(k->get_command() && k->get_shift())) { - // Indent once again if previous line will end with ':','{','[','(' and the line is not a comment - // (i.e. colon/brace precedes current cursor position). - if (cursor.column > 0) { - bool indent_char_found = false; - bool should_indent = false; - char indent_char = ':'; - char c = text[cursor.line][cursor.column]; - - for (int i = 0; i < cursor.column; i++) { - c = text[cursor.line][i]; - switch (c) { - case ':': - case '{': - case '[': - case '(': - indent_char_found = true; - should_indent = true; - indent_char = c; - continue; - } - - if (indent_char_found && is_line_comment(cursor.line)) { - should_indent = true; - break; - } else if (indent_char_found && !_is_whitespace(c)) { - should_indent = false; - indent_char_found = false; - } - } + // Check and handle all built in shortcuts. - if (!is_line_comment(cursor.line) && should_indent) { - if (indent_using_spaces) { - ins += space_indent; - } else { - ins += "\t"; - } - - // No need to move the brace below if we are not taking the text with us. - char32_t closing_char = _get_right_pair_symbol(indent_char); - if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) { - brace_indent = true; - ins += "\n" + ins.substr(1, ins.length() - 2); - } - } - } - } - begin_complex_operation(); - bool first_line = false; - if (k->get_command()) { - if (k->get_shift()) { - if (cursor.line > 0) { - cursor_set_line(cursor.line - 1); - cursor_set_column(text[cursor.line].length()); - } else { - cursor_set_column(0); - first_line = true; - } - } else { - cursor_set_column(text[cursor.line].length()); - } - } - - insert_text_at_cursor(ins); - - if (first_line) { - cursor_set_line(0); - } else if (brace_indent) { - cursor_set_line(cursor.line - 1); - cursor_set_column(text[cursor.line].length()); - } - end_complex_operation(); - } break; - case KEY_ESCAPE: { - if (completion_hint != "") { - completion_hint = ""; - update(); - } else { - keycode_handled = false; - } - } break; - case KEY_TAB: { - if (k->get_command()) { - break; // Avoid tab when command. - } - - if (readonly) { - break; - } - - if (is_selection_active()) { - if (k->get_shift()) { - indent_left(); - } else { - indent_right(); - } - } else { - if (k->get_shift()) { - // Simple unindent. - int cc = cursor.column; - const String &line = text[cursor.line]; - - int left = _find_first_non_whitespace_column_of_line(line); - cc = MIN(cc, left); - - while (cc < indent_size && cc < left && line[cc] == ' ') { - cc++; - } + // AUTO-COMPLETE - if (cc > 0 && cc <= text[cursor.line].length()) { - if (text[cursor.line][cc - 1] == '\t') { - // Tabs unindentation. - _remove_text(cursor.line, cc - 1, cursor.line, cc); - if (cursor.column >= left) { - cursor_set_column(MAX(0, cursor.column - 1)); - } - update(); - } else { - // Spaces unindentation. - int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc); - if (spaces_to_remove > 0) { - _remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc); - if (cursor.column > left - spaces_to_remove) { // Inside text? - cursor_set_column(MAX(0, cursor.column - spaces_to_remove)); - } - update(); - } - } - } else if (cc == 0 && line.length() > 0 && line[0] == '\t') { - _remove_text(cursor.line, 0, cursor.line, 1); - update(); - } - } else { - // Simple indent. - if (indent_using_spaces) { - // Insert only as much spaces as needed till next indentation level. - int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column); - String indent_to_insert = String(); - for (int i = 0; i < spaces_to_add; i++) { - indent_to_insert = ' ' + indent_to_insert; - } - _insert_text_at_cursor(indent_to_insert); - } else { - _insert_text_at_cursor("\t"); - } - } - } - - } break; - case KEY_BACKSPACE: { - if (readonly) { - break; - } - -#ifdef APPLE_STYLE_KEYS - if (k->get_alt() && cursor.column > 1) { -#else - if (k->get_alt()) { - keycode_handled = false; - break; - } else if (k->get_command() && cursor.column > 1) { -#endif - int line = cursor.line; - int column = cursor.column; - - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < column) { - column = words[i].x; - break; - } - } - - _remove_text(line, column, cursor.line, cursor.column); - - cursor_set_line(line); - cursor_set_column(column); - -#ifdef APPLE_STYLE_KEYS - } else if (k->get_command()) { - int cursor_current_column = cursor.column; - cursor.column = 0; - _remove_text(cursor.line, 0, cursor.line, cursor_current_column); -#endif - } else { - if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) { - unfold_line(cursor.line - 1); - } - backspace_at_cursor(); - } - - } break; - case KEY_KP_4: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; - } - [[fallthrough]]; - } - case KEY_LEFT: { - if (k->get_shift()) { - _pre_shift_selection(); -#ifdef APPLE_STYLE_KEYS - } else { -#else - } else if (!k->get_alt()) { -#endif - deselect(); - } - -#ifdef APPLE_STYLE_KEYS - if (k->get_command()) { - // Start at first column (it's slightly faster that way) and look for the first non-whitespace character. - int new_cursor_pos = 0; - for (int i = 0; i < text[cursor.line].length(); ++i) { - if (!_is_whitespace(text[cursor.line][i])) { - new_cursor_pos = i; - break; - } - } - if (new_cursor_pos == cursor.column) { - // We're already at the first text character, so move to the very beginning of the line. - cursor_set_column(0); - } else { - // We're somewhere to the right of the first text character; move to the first one. - cursor_set_column(new_cursor_pos); - } - } else if (k->get_alt()) { -#else - if (k->get_alt()) { - keycode_handled = false; - break; - } else if (k->get_command()) { -#endif - int cc = cursor.column; - - if (cc == 0 && cursor.line > 0) { - cursor_set_line(cursor.line - 1); - cursor_set_column(text[cursor.line].length()); - } else { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid()); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; - break; - } - } - cursor_set_column(cc); - } + if (k->is_action("ui_text_completion_query", true)) { + query_code_comple(); + accept_event(); + return; + } - } else if (cursor.column == 0) { - if (cursor.line > 0) { - cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1)); - cursor_set_column(text[cursor.line].length()); - } + if (completion_active) { + if (k->is_action("ui_up", true)) { + if (completion_index > 0) { + completion_index--; } else { - if (mid_grapheme_caret_enabled) { - cursor_set_column(cursor_get_column() - 1); - } else { - cursor_set_column(TS->shaped_text_prev_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column())); - } - } - - if (k->get_shift()) { - _post_shift_selection(); - } - - } break; - case KEY_KP_6: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; + completion_index = completion_options.size() - 1; } - [[fallthrough]]; + completion_current = completion_options[completion_index]; + update(); + accept_event(); + return; } - case KEY_RIGHT: { - if (k->get_shift()) { - _pre_shift_selection(); -#ifdef APPLE_STYLE_KEYS - } else { -#else - } else if (!k->get_alt()) { -#endif - deselect(); - } - -#ifdef APPLE_STYLE_KEYS - if (k->get_command()) { - cursor_set_column(text[cursor.line].length()); - } else if (k->get_alt()) { -#else - if (k->get_alt()) { - keycode_handled = false; - break; - } else if (k->get_command()) { -#endif - int cc = cursor.column; - - if (cc == text[cursor.line].length() && cursor.line < text.size() - 1) { - cursor_set_line(cursor.line + 1); - cursor_set_column(0); - } else { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; - break; - } - } - cursor_set_column(cc); - } - - } else if (cursor.column == text[cursor.line].length()) { - if (cursor.line < text.size() - 1) { - cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false); - cursor_set_column(0); - } + if (k->is_action("ui_down", true)) { + if (completion_index < completion_options.size() - 1) { + completion_index++; } else { - if (mid_grapheme_caret_enabled) { - cursor_set_column(cursor_get_column() + 1); - } else { - cursor_set_column(TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column())); - } + completion_index = 0; } - - if (k->get_shift()) { - _post_shift_selection(); - } - - } break; - case KEY_KP_8: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; - } - [[fallthrough]]; + completion_current = completion_options[completion_index]; + update(); + accept_event(); + return; } - case KEY_UP: { - if (k->get_alt()) { - keycode_handled = false; - break; - } -#ifndef APPLE_STYLE_KEYS - if (k->get_command()) { -#else - if (k->get_command() && k->get_alt()) { -#endif - _scroll_lines_up(); - break; - } - - if (k->get_shift()) { - _pre_shift_selection(); + if (k->is_action("ui_page_up", true)) { + completion_index -= get_theme_constant("completion_lines"); + if (completion_index < 0) { + completion_index = 0; } - -#ifdef APPLE_STYLE_KEYS - if (k->get_command()) { - cursor_set_line(0); - } else -#endif - { - int cur_wrap_index = get_cursor_wrap_index(); - if (cur_wrap_index > 0) { - cursor_set_line(cursor.line, true, false, cur_wrap_index - 1); - } else if (cursor.line == 0) { - cursor_set_column(0); - } else { - int new_line = cursor.line - num_lines_from(cursor.line - 1, -1); - if (line_wraps(new_line)) { - cursor_set_line(new_line, true, false, times_line_wraps(new_line)); - } else { - cursor_set_line(new_line, true, false); - } - } - } - - if (k->get_shift()) { - _post_shift_selection(); - } - _cancel_code_hint(); - - } break; - case KEY_KP_2: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; - } - [[fallthrough]]; + completion_current = completion_options[completion_index]; + update(); + accept_event(); + return; } - case KEY_DOWN: { - if (k->get_alt()) { - keycode_handled = false; - break; - } -#ifndef APPLE_STYLE_KEYS - if (k->get_command()) { -#else - if (k->get_command() && k->get_alt()) { -#endif - _scroll_lines_down(); - break; - } - - if (k->get_shift()) { - _pre_shift_selection(); - } - -#ifdef APPLE_STYLE_KEYS - if (k->get_command()) { - cursor_set_line(get_last_unhidden_line(), true, false, 9999); - } else -#endif - { - int cur_wrap_index = get_cursor_wrap_index(); - if (cur_wrap_index < times_line_wraps(cursor.line)) { - cursor_set_line(cursor.line, true, false, cur_wrap_index + 1); - } else if (cursor.line == get_last_unhidden_line()) { - cursor_set_column(text[cursor.line].length()); - } else { - int new_line = cursor.line + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1); - cursor_set_line(new_line, true, false, 0); - } - } - - if (k->get_shift()) { - _post_shift_selection(); + if (k->is_action("ui_page_down", true)) { + completion_index += get_theme_constant("completion_lines"); + if (completion_index >= completion_options.size()) { + completion_index = completion_options.size() - 1; } - _cancel_code_hint(); - - } break; - case KEY_DELETE: { - if (readonly) { - break; - } - - if (k->get_shift() && !k->get_command() && !k->get_alt() && is_shortcut_keys_enabled()) { - cut(); - break; - } - - int curline_len = text[cursor.line].length(); - - if (cursor.line == text.size() - 1 && cursor.column == curline_len) { - break; // Nothing to do. - } - - int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1; - int next_column; - -#ifdef APPLE_STYLE_KEYS - if (k->get_alt() && cursor.column < curline_len - 1) { -#else - if (k->get_alt()) { - keycode_handled = false; - break; - } else if (k->get_command() && cursor.column < curline_len - 1) { -#endif - - int line = cursor.line; - int column = cursor.column; - - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > column) { - column = words[i].y; - break; - } - } - - next_line = line; - next_column = column; -#ifdef APPLE_STYLE_KEYS - } else if (k->get_command()) { - next_column = curline_len; - next_line = cursor.line; -#endif - } else { - if (mid_grapheme_caret_enabled) { - next_column = cursor.column < curline_len ? (cursor.column + 1) : 0; - } else { - next_column = cursor.column < curline_len ? TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), (cursor.column)) : 0; - } - } - - _remove_text(cursor.line, cursor.column, next_line, next_column); + completion_current = completion_options[completion_index]; update(); - - } break; - case KEY_KP_7: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; - } - [[fallthrough]]; + accept_event(); + return; } - case KEY_HOME: { -#ifdef APPLE_STYLE_KEYS - if (k->get_shift()) - _pre_shift_selection(); - - cursor_set_line(0); - - if (k->get_shift()) - _post_shift_selection(); - else if (k->get_command() || k->get_control()) - deselect(); -#else - if (k->get_shift()) { - _pre_shift_selection(); - } - - if (k->get_command()) { - cursor_set_line(0); - cursor_set_column(0); - } else { - // Move cursor column to start of wrapped row and then to start of text. - Vector<String> rows = get_wrap_rows_text(cursor.line); - int wi = get_cursor_wrap_index(); - int row_start_col = 0; - for (int i = 0; i < wi; i++) { - row_start_col += rows[i].length(); - } - if (cursor.column == row_start_col || wi == 0) { - // Compute whitespace symbols seq length. - int current_line_whitespace_len = 0; - while (current_line_whitespace_len < text[cursor.line].length()) { - char32_t c = text[cursor.line][current_line_whitespace_len]; - if (c != '\t' && c != ' ') { - break; - } - current_line_whitespace_len++; - } - - if (cursor_get_column() == current_line_whitespace_len) { - cursor_set_column(0); - } else { - cursor_set_column(current_line_whitespace_len); - } - } else { - cursor_set_column(row_start_col); - } - } - - if (k->get_shift()) { - _post_shift_selection(); - } else if (k->get_command() || k->get_control()) { - deselect(); - } - _cancel_completion(); - completion_hint = ""; -#endif - } break; - case KEY_KP_1: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; + if (k->is_action("ui_home", true)) { + if (completion_index > 0) { + completion_index = 0; + completion_current = completion_options[completion_index]; + update(); } - [[fallthrough]]; + accept_event(); + return; } - case KEY_END: { -#ifdef APPLE_STYLE_KEYS - if (k->get_shift()) - _pre_shift_selection(); - - cursor_set_line(get_last_unhidden_line(), true, false, 9999); - - if (k->get_shift()) - _post_shift_selection(); - else if (k->get_command() || k->get_control()) - deselect(); -#else - if (k->get_shift()) { - _pre_shift_selection(); - } - - if (k->get_command()) { - cursor_set_line(get_last_unhidden_line(), true, false, 9999); - } - - // Move cursor column to end of wrapped row and then to end of text. - Vector<String> rows = get_wrap_rows_text(cursor.line); - int wi = get_cursor_wrap_index(); - int row_end_col = -1; - for (int i = 0; i < wi + 1; i++) { - row_end_col += rows[i].length(); - } - if (wi == rows.size() - 1 || cursor.column == row_end_col) { - cursor_set_column(text[cursor.line].length()); - } else { - cursor_set_column(row_end_col); - } - - if (k->get_shift()) { - _post_shift_selection(); - } else if (k->get_command() || k->get_control()) { - deselect(); - } - - _cancel_completion(); - completion_hint = ""; -#endif - } break; - case KEY_KP_9: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; + if (k->is_action("ui_end", true)) { + if (completion_index < completion_options.size() - 1) { + completion_index = completion_options.size() - 1; + completion_current = completion_options[completion_index]; + update(); } - [[fallthrough]]; + accept_event(); + return; } - case KEY_PAGEUP: { - if (k->get_shift()) { - _pre_shift_selection(); - } - - int wi; - int n_line = cursor.line - num_lines_from_rows(cursor.line, get_cursor_wrap_index(), -get_visible_rows(), wi) + 1; - cursor_set_line(n_line, true, false, wi); - - if (k->get_shift()) { - _post_shift_selection(); - } - + if (k->is_action("ui_accept", true) || k->is_action("ui_text_completion_accept", true)) { + _confirm_completion(); + accept_event(); + return; + } + if (k->is_action("ui_cancel", true)) { _cancel_completion(); - completion_hint = ""; + accept_event(); + return; + } - } break; - case KEY_KP_3: { - if (k->get_unicode() != 0) { - keycode_handled = false; - break; + // Handle Unicode here (if no modifiers active) and update autocomplete. + if (k->get_unicode() >= 32) { + if (allow_unicode_handling && !readonly) { + _handle_unicode_character(k->get_unicode(), had_selection, true); + accept_event(); + return; } - [[fallthrough]]; } - case KEY_PAGEDOWN: { - if (k->get_shift()) { - _pre_shift_selection(); - } - - int wi; - int n_line = cursor.line + num_lines_from_rows(cursor.line, get_cursor_wrap_index(), get_visible_rows(), wi) - 1; - cursor_set_line(n_line, true, false, wi); + } - if (k->get_shift()) { - _post_shift_selection(); - } + // NEWLINES. + if (k->is_action("ui_text_newline_above", true)) { + _new_line(false, true); + accept_event(); + return; + } + if (k->is_action("ui_text_newline_blank", true)) { + _new_line(false); + accept_event(); + return; + } + if (k->is_action("ui_text_newline", true)) { + _new_line(); + accept_event(); + return; + } - _cancel_completion(); - completion_hint = ""; + // INDENTATION. + if (k->is_action("ui_text_dedent", true)) { + _indent_left(); + accept_event(); + return; + } + if (k->is_action("ui_text_indent", true)) { + _indent_right(); + accept_event(); + return; + } - } break; - case KEY_A: { -#ifndef APPLE_STYLE_KEYS - if (!k->get_control() || k->get_shift() || k->get_alt()) { - keycode_handled = false; - break; - } - if (is_shortcut_keys_enabled()) { - select_all(); - } -#else - if ((!k->get_command() && !k->get_control())) { - keycode_handled = false; - break; - } - if (!k->get_shift() && k->get_command() && is_shortcut_keys_enabled()) - select_all(); - else if (k->get_control()) { - if (k->get_shift()) - _pre_shift_selection(); - - int current_line_whitespace_len = 0; - while (current_line_whitespace_len < text[cursor.line].length()) { - char32_t c = text[cursor.line][current_line_whitespace_len]; - if (c != '\t' && c != ' ') - break; - current_line_whitespace_len++; - } + // BACKSPACE AND DELETE. + if (k->is_action("ui_text_backspace_all_to_left", true)) { + _backspace(false, true); + accept_event(); + return; + } + if (k->is_action("ui_text_backspace_word", true)) { + _backspace(true); + accept_event(); + return; + } + if (k->is_action("ui_text_backspace", true)) { + _backspace(); + if (completion_active) { + _update_completion_candidates(); + } + accept_event(); + return; + } + if (k->is_action("ui_text_delete_all_to_right", true)) { + _delete(false, true); + accept_event(); + return; + } + if (k->is_action("ui_text_delete_word", true)) { + _delete(true); + accept_event(); + return; + } + if (k->is_action("ui_text_delete", true)) { + _delete(); + accept_event(); + return; + } - if (cursor_get_column() == current_line_whitespace_len) - cursor_set_column(0); - else - cursor_set_column(current_line_whitespace_len); + // SCROLLING. + if (k->is_action("ui_text_scroll_up", true)) { + _scroll_lines_up(); + accept_event(); + return; + } + if (k->is_action("ui_text_scroll_down", true)) { + _scroll_lines_down(); + accept_event(); + return; + } - if (k->get_shift()) - _post_shift_selection(); - else if (k->get_command() || k->get_control()) - deselect(); - } - } break; - case KEY_E: { - if (!k->get_control() || k->get_command() || k->get_alt()) { - keycode_handled = false; - break; - } + // SELECT ALL, CUT, COPY, PASTE. - if (k->get_shift()) - _pre_shift_selection(); + if (k->is_action("ui_text_select_all", true)) { + select_all(); + accept_event(); + return; + } + if (k->is_action("ui_cut", true)) { + cut(); + accept_event(); + return; + } + if (k->is_action("ui_copy", true)) { + copy(); + accept_event(); + return; + } + if (k->is_action("ui_paste", true)) { + paste(); + accept_event(); + return; + } - if (k->get_command()) - cursor_set_line(text.size() - 1, true, false); - cursor_set_column(text[cursor.line].length()); + // UNDO/REDO. + if (k->is_action("ui_undo", true)) { + undo(); + accept_event(); + return; + } + if (k->is_action("ui_redo", true)) { + redo(); + accept_event(); + return; + } - if (k->get_shift()) - _post_shift_selection(); - else if (k->get_command() || k->get_control()) - deselect(); + // MISC. - _cancel_completion(); + if (k->is_action("ui_menu", true)) { + if (context_menu_enabled) { + menu->set_position(get_screen_transform().xform(_get_cursor_pixel_pos())); + menu->set_size(Vector2(1, 1)); + _generate_context_menu(); + menu->popup(); + menu->grab_focus(); + } + accept_event(); + return; + } + if (k->is_action("ui_text_toggle_insert_mode", true)) { + set_insert_mode(!insert_mode); + accept_event(); + return; + } + if (k->is_action("ui_cancel", true)) { + if (completion_hint != "") { completion_hint = ""; -#endif - } break; - case (KEY_QUOTELEFT): { // Swap current input direction (primary cursor) - if (!k->get_command()) { - keycode_handled = false; - break; - } - - if (input_direction == TEXT_DIRECTION_LTR) { - input_direction = TEXT_DIRECTION_RTL; - } else { - input_direction = TEXT_DIRECTION_LTR; - } - cursor_set_column(cursor.column); update(); - } break; - case KEY_X: { - if (readonly) { - break; - } - if (!k->get_command() || k->get_shift() || k->get_alt()) { - keycode_handled = false; - break; - } - if (is_shortcut_keys_enabled()) { - cut(); - } - - } break; - case KEY_C: { - if (!k->get_command() || k->get_shift() || k->get_alt()) { - keycode_handled = false; - break; - } - - if (is_shortcut_keys_enabled()) { - copy(); - } - - } break; - case KEY_Z: { - if (readonly) { - break; - } - - if (!k->get_command()) { - keycode_handled = false; - break; - } - - if (is_shortcut_keys_enabled()) { - if (k->get_shift()) { - redo(); - } else { - undo(); - } - } - } break; - case KEY_Y: { - if (readonly) { - break; - } - - if (!k->get_command()) { - keycode_handled = false; - break; - } - - if (is_shortcut_keys_enabled()) { - redo(); - } - } break; - case KEY_V: { - if (readonly) { - break; - } - if (!k->get_command() || k->get_shift() || k->get_alt()) { - keycode_handled = false; - break; - } - - if (is_shortcut_keys_enabled()) { - paste(); - } - - } break; - case KEY_SPACE: { -#ifdef OSX_ENABLED - if (completion_enabled && k->get_metakey()) { // cmd-space is spotlight shortcut in OSX -#else - if (completion_enabled && k->get_command()) { -#endif - - query_code_comple(); - keycode_handled = true; - } else { - keycode_handled = false; - } + } + accept_event(); + return; + } + if (k->is_action("ui_swap_input_direction", true)) { + _swap_current_input_direction(); + accept_event(); + return; + } - } break; + // CURSOR MOVEMENT - case KEY_MENU: { - if (context_menu_enabled) { - menu->set_position(get_screen_transform().xform(_get_cursor_pixel_pos())); - menu->set_size(Vector2(1, 1)); - menu->popup(); - menu->grab_focus(); - } - } break; + k = k->duplicate(); + bool shift_pressed = k->get_shift(); + // Remove shift or else actions will not match. Use above variable for selection. + k->set_shift(false); - default: { - keycode_handled = false; - } break; + // CURSOR MOVEMENT - LEFT, RIGHT. + if (k->is_action("ui_text_caret_word_left", true)) { + _move_cursor_left(shift_pressed, true); + accept_event(); + return; } - - if (keycode_handled) { + if (k->is_action("ui_text_caret_left", true)) { + _move_cursor_left(shift_pressed, false); accept_event(); + return; } - - if (k->get_keycode() == KEY_INSERT) { - set_insert_mode(!insert_mode); + if (k->is_action("ui_text_caret_word_right", true)) { + _move_cursor_right(shift_pressed, true); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_right", true)) { + _move_cursor_right(shift_pressed, false); accept_event(); return; } - if (!keycode_handled && !k->get_command()) { // For German keyboards. - - if (k->get_unicode() >= 32) { - if (readonly) { - return; - } - - // Remove the old character if in insert mode and no selection. - if (insert_mode && !had_selection) { - begin_complex_operation(); - - // Make sure we don't try and remove empty space. - if (cursor.column < get_line(cursor.line).length()) { - _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); - } - } - - const char32_t chr[2] = { (char32_t)k->get_unicode(), 0 }; + // CURSOR MOVEMENT - UP, DOWN. + if (k->is_action("ui_text_caret_up", true)) { + _move_cursor_up(shift_pressed); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_down", true)) { + _move_cursor_down(shift_pressed); + accept_event(); + return; + } - if (completion_hint != "" && k->get_unicode() == ')') { - completion_hint = ""; - } - if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { - _consume_pair_symbol(chr[0]); - } else { - _insert_text_at_cursor(chr); - } + // CURSOR MOVEMENT - DOCUMENT START/END. + if (k->is_action("ui_text_caret_document_start", true)) { // && shift_pressed) { + _move_cursor_document_start(shift_pressed); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_document_end", true)) { // && shift_pressed) { + _move_cursor_document_end(shift_pressed); + accept_event(); + return; + } - if (insert_mode && !had_selection) { - end_complex_operation(); - } + // CURSOR MOVEMENT - LINE START/END. + if (k->is_action("ui_text_caret_line_start", true)) { + _move_cursor_to_line_start(shift_pressed); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_line_end", true)) { + _move_cursor_to_line_end(shift_pressed); + accept_event(); + return; + } - if (selection.active != had_selection) { - end_complex_operation(); - } - accept_event(); - } + // CURSOR MOVEMENT - PAGE UP/DOWN. + if (k->is_action("ui_text_caret_page_up", true)) { + _move_cursor_page_up(shift_pressed); + accept_event(); + return; + } + if (k->is_action("ui_text_caret_page_down", true)) { + _move_cursor_page_down(shift_pressed); + accept_event(); + return; } - return; + if (allow_unicode_handling && !readonly && k->get_unicode() >= 32) { + // Handle Unicode (if no modifiers active). + _handle_unicode_character(k->get_unicode(), had_selection, false); + accept_event(); + return; + } } } @@ -3746,8 +3600,8 @@ void TextEdit::_scroll_lines_up() { if (!selection.active) { int cur_line = cursor.line; int cur_wrap = get_cursor_wrap_index(); - int last_vis_line = get_last_visible_line(); - int last_vis_wrap = get_last_visible_line_wrap_index(); + int last_vis_line = get_last_full_visible_line(); + int last_vis_wrap = get_last_full_visible_line_wrap_index(); if (cur_line > last_vis_line || (cur_line == last_vis_line && cur_wrap > last_vis_wrap)) { cursor_set_line(last_vis_line, false, false, last_vis_wrap); @@ -4033,25 +3887,50 @@ int TextEdit::_get_control_height() const { return control_height; } +int TextEdit::_get_menu_action_accelerator(const String &p_action) { + const List<Ref<InputEvent>> *events = InputMap::get_singleton()->action_get_events(p_action); + if (!events) { + return 0; + } + + // Use first event in the list for the accelerator. + const List<Ref<InputEvent>>::Element *first_event = events->front(); + if (!first_event) { + return 0; + } + + const Ref<InputEventKey> event = first_event->get(); + if (event.is_null()) { + return 0; + } + + // Use physical keycode if non-zero + if (event->get_physical_keycode() != 0) { + return event->get_physical_keycode_with_modifiers(); + } else { + return event->get_keycode_with_modifiers(); + } +} + void TextEdit::_generate_context_menu() { // Reorganize context menu. menu->clear(); if (!readonly) { - menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0); + menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_cut") : 0); } - menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0); + menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_copy") : 0); if (!readonly) { - menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0); + menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_paste") : 0); } menu->add_separator(); if (is_selecting_enabled()) { - menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0); + menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_text_select_all") : 0); } if (!readonly) { menu->add_item(RTR("Clear"), MENU_CLEAR); menu->add_separator(); - menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0); - menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0); + menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_undo") : 0); + menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0); } menu->add_separator(); menu->add_submenu_item(RTR("Text writing direction"), "DirMenu"); @@ -4120,8 +3999,8 @@ void TextEdit::adjust_viewport_to_cursor() { int first_vis_line = get_first_visible_line(); int first_vis_wrap = cursor.wrap_ofs; - int last_vis_line = get_last_visible_line(); - int last_vis_wrap = get_last_visible_line_wrap_index(); + int last_vis_line = get_last_full_visible_line(); + int last_vis_wrap = get_last_full_visible_line_wrap_index(); if (cur_line < first_vis_line || (cur_line == first_vis_line && cur_wrap < first_vis_wrap)) { // Cursor is above screen. @@ -4890,11 +4769,13 @@ void TextEdit::_update_caches() { cache.completion_font_color = get_theme_color("completion_font_color"); cache.font = get_theme_font("font"); cache.font_size = get_theme_font_size("font_size"); + cache.outline_color = get_theme_color("font_outline_color"); + cache.outline_size = get_theme_constant("outline_size"); cache.caret_color = get_theme_color("caret_color"); cache.caret_background_color = get_theme_color("caret_background_color"); cache.font_color = get_theme_color("font_color"); - cache.font_color_selected = get_theme_color("font_color_selected"); - cache.font_color_readonly = get_theme_color("font_color_readonly"); + cache.font_selected_color = get_theme_color("font_selected_color"); + cache.font_readonly_color = get_theme_color("font_readonly_color"); cache.selection_color = get_theme_color("selection_color"); cache.mark_color = get_theme_color("mark_color"); cache.current_line_color = get_theme_color("current_line_color"); @@ -5139,6 +5020,10 @@ void TextEdit::set_auto_indent(bool p_auto_indent) { } void TextEdit::cut() { + if (readonly) { + return; + } + if (!selection.active) { String clipboard = text[cursor.line]; DisplayServer::get_singleton()->clipboard_set(clipboard); @@ -5186,6 +5071,10 @@ void TextEdit::copy() { } void TextEdit::paste() { + if (readonly) { + return; + } + String clipboard = DisplayServer::get_singleton()->clipboard_get(); begin_complex_operation(); @@ -5889,6 +5778,10 @@ void TextEdit::_clear_redo() { } void TextEdit::undo() { + if (readonly) { + return; + } + _push_current_op(); if (undo_stack_pos == nullptr) { @@ -5939,6 +5832,9 @@ void TextEdit::undo() { } void TextEdit::redo() { + if (readonly) { + return; + } _push_current_op(); if (undo_stack_pos == nullptr) { @@ -6099,7 +5995,7 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const { } // Count the number of visible lines up to this line. - double new_line_scroll_pos = 0; + double new_line_scroll_pos = 0.0; int to = CLAMP(p_line, 0, text.size() - 1); for (int i = 0; i < to; i++) { if (!text.is_hidden(i)) { @@ -6134,19 +6030,19 @@ int TextEdit::get_first_visible_line() const { return CLAMP(cursor.line_ofs, 0, text.size() - 1); } -int TextEdit::get_last_visible_line() const { +int TextEdit::get_last_full_visible_line() const { int first_vis_line = get_first_visible_line(); int last_vis_line = 0; int wi; - last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi) - 1; + last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows(), wi) - 1; last_vis_line = CLAMP(last_vis_line, 0, text.size() - 1); return last_vis_line; } -int TextEdit::get_last_visible_line_wrap_index() const { +int TextEdit::get_last_full_visible_line_wrap_index() const { int first_vis_line = get_first_visible_line(); int wi; - num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi); + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows(), wi); return wi; } @@ -6877,7 +6773,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -7176,23 +7072,11 @@ void TextEdit::_bind_methods() { } TextEdit::TextEdit() { - setting_row = false; - draw_tabs = false; - draw_spaces = false; - override_selected_font_color = false; - draw_caret = true; - max_chars = 0; clear(); - wrap_enabled = false; - wrap_at = 0; - wrap_right_offset = 10; set_focus_mode(FOCUS_ALL); _update_caches(); - cache.line_spacing = 1; - cache.font_size = 16; set_default_cursor_shape(CURSOR_IBEAM); - indent_size = 4; text.set_indent_size(indent_size); text.clear(); @@ -7202,31 +7086,16 @@ TextEdit::TextEdit() { add_child(h_scroll); add_child(v_scroll); - updating_scrolls = false; - selection.active = false; - h_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved)); v_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved)); v_scroll->connect("scrolling", callable_mp(this, &TextEdit::_v_scroll_input)); - cursor_changed_dirty = false; - text_changed_dirty = false; - - selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE; - selection.selecting_line = 0; - selection.selecting_column = 0; - selection.selecting_text = false; - selection.active = false; - - block_caret = false; - caret_blink_enabled = false; caret_blink_timer = memnew(Timer); add_child(caret_blink_timer); caret_blink_timer->set_wait_time(0.65); caret_blink_timer->connect("timeout", callable_mp(this, &TextEdit::_toggle_draw_caret)); cursor_set_blink_enabled(false); - right_click_moves_caret = true; idle_detect = memnew(Timer); add_child(idle_detect); @@ -7239,54 +7108,8 @@ TextEdit::TextEdit() { click_select_held->set_wait_time(0.05); click_select_held->connect("timeout", callable_mp(this, &TextEdit::_click_selection_held)); - current_op.type = TextOperation::TYPE_NONE; - undo_enabled = true; undo_stack_max_size = GLOBAL_GET("gui/common/text_edit_undo_stack_max_size"); - undo_stack_pos = nullptr; - setting_text = false; - last_dblclk = 0; - current_op.version = 0; - version = 0; - saved_version = 0; - completion_enabled = false; - completion_active = false; - completion_line_ofs = 0; - tooltip_obj = nullptr; - line_length_guidelines = false; - line_length_guideline_soft_col = 80; - line_length_guideline_hard_col = 100; - hiding_enabled = false; - next_operation_is_complex = false; - scroll_past_end_of_file_enabled = false; - auto_brace_completion_enabled = false; - brace_matching_enabled = false; - highlight_all_occurrences = false; - highlight_current_line = false; - indent_using_spaces = false; - space_indent = " "; - auto_indent = false; - insert_mode = false; - window_has_focus = true; - select_identifiers_enabled = false; - smooth_scroll_enabled = false; - scrolling = false; - minimap_clicked = false; - dragging_minimap = false; - can_drag_minimap = false; - minimap_scroll_ratio = 0; - minimap_scroll_click_pos = 0; - dragging_selection = false; - target_v_scroll = 0; - v_scroll_speed = 80; - draw_minimap = false; - minimap_width = 80; - minimap_char_size = Point2(1, 2); - minimap_line_spacing = 1; - - selecting_enabled = true; - context_menu_enabled = true; - shortcut_keys_enabled = true; menu = memnew(PopupMenu); add_child(menu); @@ -7321,12 +7144,10 @@ TextEdit::TextEdit() { menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY); menu->add_child(menu_ctl); - readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly. set_readonly(false); menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); menu_dir->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); menu_ctl->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); - first_draw = true; } TextEdit::~TextEdit() { diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index d5b9b46fe2..b0c7314c65 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -92,14 +92,11 @@ private: Vector<Vector2i> bidi_override; Ref<TextParagraph> data_buf; - bool marked; - bool hidden; + bool marked = false; + bool hidden = false; Line() { data_buf.instance(); - - marked = false; - hidden = false; } }; @@ -173,46 +170,31 @@ private: }; struct Cursor { - int last_fit_x; - int line, column; ///< cursor - int x_ofs, line_ofs, wrap_ofs; - Cursor() { - last_fit_x = 0; - line = 0; - column = 0; ///< cursor - x_ofs = 0; - line_ofs = 0; - wrap_ofs = 0; - } + int last_fit_x = 0; + int line = 0; + int column = 0; ///< cursor + int x_ofs = 0; + int line_ofs = 0; + int wrap_ofs = 0; } cursor; struct Selection { - SelectionMode selecting_mode; - int selecting_line, selecting_column; - int selected_word_beg, selected_word_end, selected_word_origin; - bool selecting_text; - - bool active; - - int from_line, from_column; - int to_line, to_column; - - bool shiftclick_left; - Selection() { - selecting_mode = SelectionMode::SELECTION_MODE_NONE; - selecting_line = 0; - selecting_column = 0; - selected_word_beg = 0; - selected_word_end = 0; - selected_word_origin = 0; - selecting_text = false; - active = false; - from_line = 0; - from_column = 0; - to_line = 0; - to_column = 0; - shiftclick_left = false; - } + SelectionMode selecting_mode = SelectionMode::SELECTION_MODE_NONE; + int selecting_line = 0; + int selecting_column = 0; + int selected_word_beg = 0; + int selected_word_end = 0; + int selected_word_origin = 0; + bool selecting_text = false; + + bool active = false; + + int from_line = 0; + int from_column = 0; + int to_line = 0; + int to_column = 0; + + bool shiftclick_left = false; } selection; Map<int, Dictionary> syntax_highlighting_cache; @@ -224,25 +206,16 @@ private: TYPE_REMOVE }; - Type type; - int from_line, from_column; - int to_line, to_column; + Type type = TYPE_NONE; + int from_line = 0; + int from_column = 0; + int to_line = 0; + int to_column = 0; String text; - uint32_t prev_version; - uint32_t version; - bool chain_forward; - bool chain_backward; - TextOperation() { - type = TYPE_NONE; - from_line = 0; - from_column = 0; - to_line = 0; - to_column = 0; - prev_version = 0; - version = 0; - chain_forward = false; - chain_backward = false; - } + uint32_t prev_version = 0; + uint32_t version = 0; + bool chain_forward = false; + bool chain_backward = false; }; String ime_text; @@ -251,7 +224,7 @@ private: TextOperation current_op; List<TextOperation> undo_stack; - List<TextOperation>::Element *undo_stack_pos; + List<TextOperation>::Element *undo_stack_pos = nullptr; int undo_stack_max_size; void _clear_redo(); @@ -264,20 +237,20 @@ private: Dictionary _get_line_syntax_highlighting(int p_line); Set<String> completion_prefixes; - bool completion_enabled; + bool completion_enabled = false; List<ScriptCodeCompletionOption> completion_sources; Vector<ScriptCodeCompletionOption> completion_options; - bool completion_active; - bool completion_forced; + bool completion_active = false; + bool completion_forced = false; ScriptCodeCompletionOption completion_current; String completion_base; - int completion_index; + int completion_index = 0; Rect2i completion_rect; - int completion_line_ofs; + int completion_line_ofs = 0; String completion_hint; - int completion_hint_offset; + int completion_hint_offset = 0; - bool setting_text; + bool setting_text = false; // data Text text; @@ -290,93 +263,93 @@ private: Array st_args; bool draw_control_chars = false; - uint32_t version; - uint32_t saved_version; + uint32_t version = 0; + uint32_t saved_version = 0; - int max_chars; - bool readonly; - bool indent_using_spaces; - int indent_size; - String space_indent; + int max_chars = 0; + bool readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly. + bool indent_using_spaces = false; + int indent_size = 4; + String space_indent = " "; Timer *caret_blink_timer; - bool caret_blink_enabled; - bool draw_caret; - bool window_has_focus; - bool block_caret; - bool right_click_moves_caret; + bool caret_blink_enabled = false; + bool draw_caret = true; + bool window_has_focus = true; + bool block_caret = false; + bool right_click_moves_caret = true; bool mid_grapheme_caret_enabled = false; - bool wrap_enabled; - int wrap_at; - int wrap_right_offset; - - bool first_draw; - bool setting_row; - bool draw_tabs; - bool draw_spaces; - bool override_selected_font_color; - bool cursor_changed_dirty; - bool text_changed_dirty; - bool undo_enabled; - bool line_length_guidelines; - int line_length_guideline_soft_col; - int line_length_guideline_hard_col; - bool hiding_enabled; - bool draw_minimap; - int minimap_width; - Point2 minimap_char_size; - int minimap_line_spacing; - - bool highlight_all_occurrences; - bool scroll_past_end_of_file_enabled; - bool auto_brace_completion_enabled; - bool brace_matching_enabled; - bool highlight_current_line; - bool auto_indent; + bool wrap_enabled = false; + int wrap_at = 0; + int wrap_right_offset = 10; + + bool first_draw = true; + bool setting_row = false; + bool draw_tabs = false; + bool draw_spaces = false; + bool override_selected_font_color = false; + bool cursor_changed_dirty = false; + bool text_changed_dirty = false; + bool undo_enabled = true; + bool line_length_guidelines = false; + int line_length_guideline_soft_col = 80; + int line_length_guideline_hard_col = 100; + bool hiding_enabled = false; + bool draw_minimap = false; + int minimap_width = 80; + Point2 minimap_char_size = Point2(1, 2); + int minimap_line_spacing = 1; + + bool highlight_all_occurrences = false; + bool scroll_past_end_of_file_enabled = false; + bool auto_brace_completion_enabled = false; + bool brace_matching_enabled = false; + bool highlight_current_line = false; + bool auto_indent = false; String cut_copy_line; - bool insert_mode; - bool select_identifiers_enabled; - - bool smooth_scroll_enabled; - bool scrolling; - bool dragging_selection; - bool dragging_minimap; - bool can_drag_minimap; - bool minimap_clicked; - double minimap_scroll_ratio; - double minimap_scroll_click_pos; - float target_v_scroll; - float v_scroll_speed; + bool insert_mode = false; + bool select_identifiers_enabled = false; + + bool smooth_scroll_enabled = false; + bool scrolling = false; + bool dragging_selection = false; + bool dragging_minimap = false; + bool can_drag_minimap = false; + bool minimap_clicked = false; + double minimap_scroll_ratio = 0.0; + double minimap_scroll_click_pos = 0.0; + float target_v_scroll = 0.0; + float v_scroll_speed = 80.0; String highlighted_word; - uint64_t last_dblclk; + uint64_t last_dblclk = 0; Timer *idle_detect; Timer *click_select_held; HScrollBar *h_scroll; VScrollBar *v_scroll; - bool updating_scrolls; + bool updating_scrolls = false; - Object *tooltip_obj; + Object *tooltip_obj = nullptr; StringName tooltip_func; Variant tooltip_ud; - bool next_operation_is_complex; + bool next_operation_is_complex = false; - bool callhint_below; + bool callhint_below = false; Vector2 callhint_offset; String search_text; - uint32_t search_flags; - int search_result_line; - int search_result_col; + uint32_t search_flags = 0; + int search_result_line = 0; + int search_result_col = 0; - bool selecting_enabled; + bool selecting_enabled = true; - bool context_menu_enabled; - bool shortcut_keys_enabled; + bool context_menu_enabled = true; + bool shortcut_keys_enabled = true; bool virtual_keyboard_enabled = true; void _generate_context_menu(); @@ -400,8 +373,8 @@ private: void set_line_as_center_visible(int p_line, int p_wrap_index = 0); void set_line_as_last_visible(int p_line, int p_wrap_index = 0); int get_first_visible_line() const; - int get_last_visible_line() const; - int get_last_visible_line_wrap_index() const; + int get_last_full_visible_line() const; + int get_last_full_visible_line_wrap_index() const; double get_visible_rows_offset() const; double get_v_scroll_offset() const; @@ -435,6 +408,7 @@ private: int _get_control_height() const; Point2 _get_local_mouse_pos() const; + int _get_menu_action_accelerator(const String &p_action); void _reset_caret_blink_timer(); void _toggle_draw_caret(); @@ -468,6 +442,26 @@ private: int _calculate_spaces_till_next_left_indent(int column); int _calculate_spaces_till_next_right_indent(int column); + // Methods used in shortcuts + void _swap_current_input_direction(); + void _new_line(bool p_split_current = true, bool p_above = false); + void _indent_right(); + void _indent_left(); + void _move_cursor_left(bool p_select, bool p_move_by_word = false); + void _move_cursor_right(bool p_select, bool p_move_by_word = false); + void _move_cursor_up(bool p_select); + void _move_cursor_down(bool p_select); + void _move_cursor_to_line_start(bool p_select); + void _move_cursor_to_line_end(bool p_select); + void _move_cursor_page_up(bool p_select); + void _move_cursor_page_down(bool p_select); + void _backspace(bool p_word = false, bool p_all_to_left = false); + void _delete(bool p_word = false, bool p_all_to_right = false); + void _delete_selection(); + void _move_cursor_document_start(bool p_select); + void _move_cursor_document_end(bool p_select); + void _handle_unicode_character(uint32_t unicode, bool p_had_selection, bool p_update_auto_complete); + protected: struct Cache { Ref<Texture2D> tab_icon; @@ -477,7 +471,9 @@ protected: Ref<StyleBox> style_focus; Ref<StyleBox> style_readonly; Ref<Font> font; - int font_size; + int font_size = 16; + int outline_size = 0; + Color outline_color; Color completion_background_color; Color completion_selected_color; Color completion_existing_color; @@ -485,8 +481,8 @@ protected: Color caret_color; Color caret_background_color; Color font_color; - Color font_color_selected; - Color font_color_readonly; + Color font_selected_color; + Color font_readonly_color; Color selection_color; Color mark_color; Color code_folding_color; @@ -498,12 +494,8 @@ protected: Color search_result_border_color; Color background_color; - int line_spacing; - int minimap_width; - Cache() { - line_spacing = 0; - minimap_width = 0; - } + int line_spacing = 1; + int minimap_width = 0; } cache; virtual String get_tooltip(const Point2 &p_pos) const override; @@ -668,8 +660,8 @@ public: int get_row_height() const; void backspace_at_cursor(); - void indent_left(); - void indent_right(); + void indent_selected_lines_left(); + void indent_selected_lines_right(); int get_indent_level(int p_line) const; bool is_line_comment(int p_line) const; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 23c48b0906..f43e3d1a9d 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -29,7 +29,9 @@ /*************************************************************************/ #include "texture_button.h" + #include "core/typedefs.h" + #include <stdlib.h> Size2 TextureButton::get_minimum_size() const { @@ -247,8 +249,8 @@ void TextureButton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_disabled_texture", "texture"), &TextureButton::set_disabled_texture); ClassDB::bind_method(D_METHOD("set_focused_texture", "texture"), &TextureButton::set_focused_texture); ClassDB::bind_method(D_METHOD("set_click_mask", "mask"), &TextureButton::set_click_mask); - ClassDB::bind_method(D_METHOD("set_expand", "p_expand"), &TextureButton::set_expand); - ClassDB::bind_method(D_METHOD("set_stretch_mode", "p_mode"), &TextureButton::set_stretch_mode); + ClassDB::bind_method(D_METHOD("set_expand", "expand"), &TextureButton::set_expand); + ClassDB::bind_method(D_METHOD("set_stretch_mode", "mode"), &TextureButton::set_stretch_mode); ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureButton::set_flip_h); ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureButton::is_flipped_h); ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureButton::set_flip_v); @@ -375,13 +377,4 @@ bool TextureButton::is_flipped_v() const { return vflip; } -TextureButton::TextureButton() { - expand = false; - stretch_mode = STRETCH_SCALE; - hflip = false; - vflip = false; - - _texture_region = Rect2(); - _position_rect = Rect2(); - _tile = false; -} +TextureButton::TextureButton() {} diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 4b750c3fb1..8361f3c341 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -54,15 +54,15 @@ private: Ref<Texture2D> disabled; Ref<Texture2D> focused; Ref<BitMap> click_mask; - bool expand; - StretchMode stretch_mode; + bool expand = false; + StretchMode stretch_mode = STRETCH_SCALE; Rect2 _texture_region; Rect2 _position_rect; - bool _tile; + bool _tile = false; - bool hflip; - bool vflip; + bool hflip = false; + bool vflip = false; protected: virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp index 76564e2b17..46ce9d5ca9 100644 --- a/scene/gui/texture_progress_bar.cpp +++ b/scene/gui/texture_progress_bar.cpp @@ -145,9 +145,9 @@ Point2 TextureProgressBar::unit_val_to_uv(float val) { float angle = (val * Math_TAU) - Math_PI * 0.5; Point2 dir = Vector2(Math::cos(angle), Math::sin(angle)); float t1 = 1.0; - float cp = 0; - float cq = 0; - float cr = 0; + float cp = 0.0; + float cq = 0.0; + float cr = 0.0; float edgeLeft = 0.0; float edgeRight = 1.0; float edgeBottom = 0.0; @@ -540,17 +540,5 @@ void TextureProgressBar::_bind_methods() { } TextureProgressBar::TextureProgressBar() { - mode = FILL_LEFT_TO_RIGHT; - rad_init_angle = 0; - rad_center_off = Point2(); - rad_max_degrees = 360; set_mouse_filter(MOUSE_FILTER_PASS); - - nine_patch_stretch = false; - stretch_margin[SIDE_LEFT] = 0; - stretch_margin[SIDE_RIGHT] = 0; - stretch_margin[SIDE_BOTTOM] = 0; - stretch_margin[SIDE_TOP] = 0; - - tint_under = tint_progress = tint_over = Color(1, 1, 1); } diff --git a/scene/gui/texture_progress_bar.h b/scene/gui/texture_progress_bar.h index ee33a915f7..a3883a7017 100644 --- a/scene/gui/texture_progress_bar.h +++ b/scene/gui/texture_progress_bar.h @@ -98,13 +98,15 @@ public: TextureProgressBar(); private: - FillMode mode; - float rad_init_angle; - float rad_max_degrees; + FillMode mode = FILL_LEFT_TO_RIGHT; + float rad_init_angle = 0.0; + float rad_max_degrees = 360.0; Point2 rad_center_off; - bool nine_patch_stretch; - int stretch_margin[4]; - Color tint_under, tint_progress, tint_over; + bool nine_patch_stretch = false; + int stretch_margin[4] = {}; + Color tint_under = Color(1, 1, 1); + Color tint_progress = Color(1, 1, 1); + Color tint_over = Color(1, 1, 1); Point2 unit_val_to_uv(float val); Point2 get_relative_center(); diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index beb06b7739..1cba88e06f 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -217,11 +217,7 @@ bool TextureRect::is_flipped_v() const { } TextureRect::TextureRect() { - expand = false; - hflip = false; - vflip = false; set_mouse_filter(MOUSE_FILTER_PASS); - stretch_mode = STRETCH_SCALE_ON_EXPAND; } TextureRect::~TextureRect() { diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index 0f3172f5bd..0f93d5732f 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -49,11 +49,11 @@ public: }; private: - bool expand; - bool hflip; - bool vflip; + bool expand = false; + bool hflip = false; + bool vflip = false; Ref<Texture2D> texture; - StretchMode stretch_mode; + StretchMode stretch_mode = STRETCH_SCALE_ON_EXPAND; void _texture_changed(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index a968a83dad..17fe001b5d 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1018,7 +1018,7 @@ void Tree::update_cache() { cache.custom_button_font_highlight = get_theme_color("custom_button_font_highlight"); cache.font_color = get_theme_color("font_color"); - cache.font_color_selected = get_theme_color("font_color_selected"); + cache.font_selected_color = get_theme_color("font_selected_color"); cache.guide_color = get_theme_color("guide_color"); cache.drop_position_color = get_theme_color("drop_position_color"); cache.hseparation = get_theme_constant("hseparation"); @@ -1118,7 +1118,7 @@ int Tree::get_item_height(TreeItem *p_item) const { return height; } -void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color) { +void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color) { ERR_FAIL_COND(cache.font.is_null()); Rect2i rect = p_rect; @@ -1160,6 +1160,9 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co Point2 draw_pos = rect.position; draw_pos.y += Math::floor((rect.size.y - p_cell.text_buf->get_size().y) / 2.0); p_cell.text_buf->set_width(MAX(0, rect.size.width)); + if (p_ol_size > 0 && p_ol_color.a > 0) { + p_cell.text_buf->draw_outline(ci, draw_pos, p_ol_size, p_ol_color); + } p_cell.text_buf->draw(ci, draw_pos, p_color); rect.position.x += ts.width + cache.hseparation; rect.size.x -= ts.width + cache.hseparation; @@ -1182,6 +1185,9 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co Point2 draw_pos = rect.position; draw_pos.y += Math::floor((rect.size.y - p_cell.text_buf->get_size().y) / 2.0); p_cell.text_buf->set_width(MAX(0, rect.size.width)); + if (p_ol_size > 0 && p_ol_color.a > 0) { + p_cell.text_buf->draw_outline(ci, draw_pos, p_ol_size, p_ol_color); + } p_cell.text_buf->draw(ci, draw_pos, p_color); } } @@ -1433,7 +1439,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } } - Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_theme_color(p_item->cells[i].selected ? "font_color_selected" : "font_color"); + Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_theme_color(p_item->cells[i].selected ? "font_selected_color" : "font_color"); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); Color icon_col = p_item->cells[i].icon_color; if (p_item->cells[i].dirty) { @@ -1450,7 +1458,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 switch (p_item->cells[i].mode) { case TreeItem::CELL_MODE_STRING: { - draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col); + draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); } break; case TreeItem::CELL_MODE_CHECK: { Ref<Texture2D> checked = cache.checked; @@ -1471,7 +1479,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 item_rect.size.x -= check_w; item_rect.position.x += check_w; - draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col); + draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); } break; case TreeItem::CELL_MODE_RANGE: { @@ -1485,8 +1493,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 p_item->cells.write[i].text_buf->set_width(cell_width); if (rtl) { + if (outline_size > 0 && font_outline_color.a > 0) { + p_item->cells[i].text_buf->draw_outline(ci, text_pos + Vector2(cell_width - text_width, 0), outline_size, font_outline_color); + } p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), col); } else { + if (outline_size > 0 && font_outline_color.a > 0) { + p_item->cells[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } p_item->cells[i].text_buf->draw(ci, text_pos, col); } @@ -1501,8 +1515,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int cell_width = item_rect.size.x - updown->get_width(); if (rtl) { + if (outline_size > 0 && font_outline_color.a > 0) { + p_item->cells[i].text_buf->draw_outline(ci, text_pos + Vector2(cell_width - text_width, 0), outline_size, font_outline_color); + } p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), col); } else { + if (outline_size > 0 && font_outline_color.a > 0) { + p_item->cells[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } p_item->cells[i].text_buf->draw(ci, text_pos, col); } @@ -1543,7 +1563,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } if (!p_item->cells[i].editable) { - draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col); + draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color); break; } @@ -1571,7 +1591,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 ir.position += cache.custom_button->get_offset(); } - draw_item_rect(p_item->cells.write[i], ir, col, icon_col); + draw_item_rect(p_item->cells.write[i], ir, col, icon_col, outline_size, font_outline_color); downarrow->draw(ci, arrow_pos); @@ -3143,6 +3163,8 @@ void Tree::_notification(int p_what) { Ref<StyleBox> bg = cache.bg; Ref<StyleBox> bg_focus = get_theme_stylebox("bg_focus"); + Color font_outline_color = get_theme_color("font_outline_color"); + int outline_size = get_theme_constant("outline_size"); Point2 draw_ofs; draw_ofs += bg->get_offset(); @@ -3179,7 +3201,12 @@ void Tree::_notification(int p_what) { //text int clip_w = tbrect.size.width - sb->get_minimum_size().width; columns.write[i].text_buf->set_width(clip_w); - columns[i].text_buf->draw(ci, tbrect.position + Point2i(sb->get_offset().x + (tbrect.size.width - columns[i].text_buf->get_size().x) / 2, (tbrect.size.height - columns[i].text_buf->get_size().y) / 2), cache.title_button_color); + + Vector2 text_pos = tbrect.position + Point2i(sb->get_offset().x + (tbrect.size.width - columns[i].text_buf->get_size().x) / 2, (tbrect.size.height - columns[i].text_buf->get_size().y) / 2); + if (outline_size > 0 && font_outline_color.a > 0) { + columns[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color); + } + columns[i].text_buf->draw(ci, text_pos, cache.title_button_color); } } } @@ -3315,6 +3342,9 @@ void Tree::item_selected(int p_column, TreeItem *p_item) { //emit_signal("multi_selected",p_item,p_column,true); - NO this is for TreeItem::select selected_col = p_column; + if (!selected_item) { + selected_item = p_item; + } } else { select_single_item(p_item, root, p_column); } @@ -3322,6 +3352,14 @@ void Tree::item_selected(int p_column, TreeItem *p_item) { } void Tree::item_deselected(int p_column, TreeItem *p_item) { + if (selected_item == p_item) { + selected_item = nullptr; + } + + if (selected_col == p_column) { + selected_col = -1; + } + if (select_mode == SELECT_MULTI || select_mode == SELECT_SINGLE) { p_item->cells.write[p_column].selected = false; } @@ -4149,6 +4187,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_edited"), &Tree::get_edited); ClassDB::bind_method(D_METHOD("get_edited_column"), &Tree::get_edited_column); + ClassDB::bind_method(D_METHOD("edit_selected"), &Tree::edit_selected); ClassDB::bind_method(D_METHOD("get_custom_popup_rect"), &Tree::get_custom_popup_rect); ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::_get_item_rect, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("get_item_at_position", "position"), &Tree::get_item_at_position); @@ -4174,6 +4213,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language); ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll); + ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::_scroll_to_item); ClassDB::bind_method(D_METHOD("set_hide_folding", "hide"), &Tree::set_hide_folding); ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden); @@ -4223,19 +4263,8 @@ void Tree::_bind_methods() { } Tree::Tree() { - selected_col = 0; columns.resize(1); - selected_item = nullptr; - edited_item = nullptr; - selected_col = -1; - edited_col = -1; - hide_root = false; - select_mode = SELECT_SINGLE; - root = nullptr; - popup_menu = nullptr; - popup_edited_item = nullptr; - text_editor = nullptr; set_focus_mode(FOCUS_ALL); popup_menu = memnew(PopupMenu); @@ -4279,50 +4308,9 @@ Tree::Tree() { set_notify_transform(true); - updating_value_editor = false; - pressed_button = -1; - show_column_titles = false; - - cache.click_type = Cache::CLICK_NONE; - cache.hover_type = Cache::CLICK_NONE; - cache.hover_index = -1; - cache.click_index = -1; - cache.click_id = -1; - cache.click_item = nullptr; - cache.click_column = 0; - cache.hover_cell = -1; - last_keypress = 0; - focus_in_id = 0; - - blocked = 0; - - cursor_can_exit_tree = true; set_mouse_filter(MOUSE_FILTER_STOP); - drag_speed = 0; - drag_touching = false; - drag_touching_deaccel = false; - pressing_for_editor = false; - range_drag_enabled = false; - - hide_folding = false; - - drop_mode_flags = 0; - drop_mode_over = nullptr; - drop_mode_section = 0; - single_select_defer = nullptr; - - scrolling = false; - allow_rmb_select = false; - force_edit_checkbox_only_on_checkbox = false; - set_clip_contents(true); - - cache.hover_item = nullptr; - cache.hover_cell = -1; - - allow_reselect = false; - propagate_mouse_activated = false; } Tree::~Tree() { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index dfc02f760d..1be21cb4a4 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -62,7 +62,7 @@ private: friend class Tree; struct Cell { - TreeCellMode mode; + TreeCellMode mode = TreeItem::CELL_MODE_STRING; Ref<Texture2D> icon; Rect2i icon_region; @@ -74,24 +74,27 @@ private: Control::StructuredTextParser st_parser = Control::STRUCTURED_TEXT_DEFAULT; Array st_args; Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED; - bool dirty; - double min, max, step, val; - int icon_max_w; - bool expr; - bool checked; - bool editable; - bool selected; - bool selectable; - bool custom_color; + bool dirty = true; + double min = 0.0; + double max = 100.0; + double step = 1.0; + double val = 0.0; + int icon_max_w = 0; + bool expr = false; + bool checked = false; + bool editable = false; + bool selected = false; + bool selectable = true; + bool custom_color = false; Color color; - bool custom_bg_color; - bool custom_bg_outline; + bool custom_bg_color = false; + bool custom_bg_outline = false; Color bg_color; - bool custom_button; - bool expand_right; - Color icon_color; + bool custom_button = false; + bool expand_right = false; + Color icon_color = Color(1, 1, 1); - TextAlign text_align; + TextAlign text_align = ALIGN_LEFT; Variant meta; String tooltip; @@ -100,42 +103,17 @@ private: StringName custom_draw_callback; struct Button { - int id; - bool disabled; + int id = 0; + bool disabled = false; Ref<Texture2D> texture; - Color color; + Color color = Color(1, 1, 1, 1); String tooltip; - Button() { - id = 0; - disabled = false; - color = Color(1, 1, 1, 1); - tooltip = ""; - } }; Vector<Button> buttons; Cell() { text_buf.instance(); - dirty = true; - custom_draw_obj = ObjectID(); - custom_button = false; - mode = TreeItem::CELL_MODE_STRING; - min = 0; - max = 100; - step = 1; - val = 0; - checked = false; - editable = false; - selected = false; - selectable = true; - custom_color = false; - custom_bg_color = false; - expr = false; - icon_max_w = 0; - text_align = ALIGN_LEFT; - expand_right = false; - icon_color = Color(1, 1, 1); } Size2 get_icon_size() const; @@ -332,46 +310,46 @@ public: private: friend class TreeItem; - TreeItem *root; - TreeItem *popup_edited_item; - TreeItem *selected_item; - TreeItem *edited_item; + TreeItem *root = nullptr; + TreeItem *popup_edited_item = nullptr; + TreeItem *selected_item = nullptr; + TreeItem *edited_item = nullptr; - TreeItem *drop_mode_over; - int drop_mode_section; + TreeItem *drop_mode_over = nullptr; + int drop_mode_section = 0; - TreeItem *single_select_defer; - int single_select_defer_column; + TreeItem *single_select_defer = nullptr; + int single_select_defer_column = 0; - int pressed_button; - bool pressing_for_editor; + int pressed_button = -1; + bool pressing_for_editor = false; String pressing_for_editor_text; Vector2 pressing_pos; Rect2 pressing_item_rect; - float range_drag_base; - bool range_drag_enabled; + float range_drag_base = 0.0; + bool range_drag_enabled = false; Vector2 range_drag_capture_pos; - bool propagate_mouse_activated; + bool propagate_mouse_activated = false; //TreeItem *cursor_item; //int cursor_column; Rect2 custom_popup_rect; - int edited_col; - int selected_col; - int popup_edited_item_col; - bool hide_root; - SelectMode select_mode; + int edited_col = -1; + int selected_col = -1; + int popup_edited_item_col = -1; + bool hide_root = false; + SelectMode select_mode = SELECT_SINGLE; - int blocked; + int blocked = 0; - int drop_mode_flags; + int drop_mode_flags = 0; struct ColumnInfo { - int min_width; - bool expand; + int min_width = 1; + bool expand = true; String title; Ref<TextLine> text_buf; Dictionary opentype_features; @@ -379,27 +357,25 @@ private: Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED; ColumnInfo() { text_buf.instance(); - min_width = 1; - expand = true; } }; - bool show_column_titles; + bool show_column_titles = false; VBoxContainer *popup_editor_vb; Popup *popup_editor; - LineEdit *text_editor; + LineEdit *text_editor = nullptr; HSlider *value_editor; - bool updating_value_editor; - uint64_t focus_in_id; - PopupMenu *popup_menu; + bool updating_value_editor = false; + uint64_t focus_in_id = 0; + PopupMenu *popup_menu = nullptr; Vector<ColumnInfo> columns; Timer *range_click_timer; - TreeItem *range_item_last; - bool range_up_last; + TreeItem *range_item_last = nullptr; + bool range_up_last = false; void _range_click_timeout(); int compute_item_height(TreeItem *p_item) const; @@ -409,7 +385,7 @@ private: void update_item_cell(TreeItem *p_item, int p_col); void update_item_cache(TreeItem *p_item); //void draw_item_text(String p_text,const Ref<Texture2D>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color); - void draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color); + void draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color); int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item); void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = nullptr, bool *r_in_range = nullptr, bool p_force_deselect = false); int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod); @@ -434,8 +410,8 @@ private: struct Cache { Ref<Font> font; Ref<Font> tb_font; - int font_size; - int tb_font_size; + int font_size = 0; + int tb_font_size = 0; Ref<StyleBox> bg; Ref<StyleBox> selected; Ref<StyleBox> selected_focus; @@ -459,21 +435,21 @@ private: Ref<Texture2D> updown; Color font_color; - Color font_color_selected; + Color font_selected_color; Color guide_color; Color drop_position_color; Color relationship_line_color; Color custom_button_font_highlight; - int hseparation; - int vseparation; - int item_margin; - int button_margin; + int hseparation = 0; + int vseparation = 0; + int item_margin = 0; + int button_margin = 0; Point2 offset; - int draw_relationship_lines; - int draw_guides; - int scroll_border; - int scroll_speed; + int draw_relationship_lines = 0; + int draw_guides = 0; + int scroll_border = 0; + int scroll_speed = 0; enum ClickType { CLICK_NONE, @@ -482,17 +458,17 @@ private: }; - ClickType click_type; - ClickType hover_type; - int click_index; - int click_id; - TreeItem *click_item; - int click_column; - int hover_index; + ClickType click_type = Cache::CLICK_NONE; + ClickType hover_type = Cache::CLICK_NONE; + int click_index = -1; + int click_id = -1; + TreeItem *click_item = nullptr; + int click_column = 0; + int hover_index = -1; Point2 click_pos; - TreeItem *hover_item; - int hover_cell; + TreeItem *hover_item = nullptr; + int hover_cell = -1; Point2i text_editor_position; @@ -510,9 +486,9 @@ private: Rect2 search_item_rect(TreeItem *p_from, TreeItem *p_item); //Rect2 get_item_rect(TreeItem *p_item); - uint64_t last_keypress; + uint64_t last_keypress = 0; String incr_search; - bool cursor_can_exit_tree; + bool cursor_can_exit_tree = true; void _do_incr_search(const String &p_add); TreeItem *_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards = false); @@ -526,21 +502,21 @@ private: float last_drag_time; float time_since_motion;*/ - float drag_speed; - float drag_from; - float drag_accum; + float drag_speed = 0.0; + float drag_from = 0.0; + float drag_accum = 0.0; Vector2 last_speed; - bool drag_touching; - bool drag_touching_deaccel; - bool click_handled; - bool allow_rmb_select; - bool scrolling; + bool drag_touching = false; + bool drag_touching_deaccel = false; + bool click_handled = false; + bool allow_rmb_select = false; + bool scrolling = false; - bool allow_reselect; + bool allow_reselect = false; - bool force_edit_checkbox_only_on_checkbox; + bool force_edit_checkbox_only_on_checkbox = false; - bool hide_folding; + bool hide_folding = false; int _count_selected_items(TreeItem *p_from) const; void _go_left(); @@ -564,6 +540,10 @@ protected: return get_item_rect(Object::cast_to<TreeItem>(p_item), p_column); } + void _scroll_to_item(Object *p_item) { + scroll_to_item(Object::cast_to<TreeItem>(p_item)); + } + public: virtual String get_tooltip(const Point2 &p_pos) const override; diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 84d689369b..0590ae2415 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -462,25 +462,7 @@ void VideoPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); } -VideoPlayer::VideoPlayer() { - volume = 1; - loops = false; - paused = false; - autoplay = false; - expand = true; - - audio_track = 0; - bus_index = 0; - - buffering_ms = 500; - - // internal_stream.player=this; - // stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream); - last_audio_time = 0; - - wait_resampler = 0; - wait_resampler_limit = 2; -}; +VideoPlayer::VideoPlayer() {} VideoPlayer::~VideoPlayer() { // if (stream_rid.is_valid()) diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h index 089337eed5..0edad296a1 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_player.h @@ -41,8 +41,8 @@ class VideoPlayer : public Control { struct Output { AudioFrame vol; - int bus_index; - Viewport *viewport; //pointer only used for reference to previous mix + int bus_index = 0; + Viewport *viewport = nullptr; //pointer only used for reference to previous mix }; Ref<VideoStreamPlayback> playback; Ref<VideoStream> stream; @@ -56,17 +56,18 @@ class VideoPlayer : public Control { AudioRBResampler resampler; Vector<AudioFrame> mix_buffer; - int wait_resampler, wait_resampler_limit; - - bool paused; - bool autoplay; - float volume; - double last_audio_time; - bool expand; - bool loops; - int buffering_ms; - int audio_track; - int bus_index; + int wait_resampler = 0; + int wait_resampler_limit = 2; + + bool paused = false; + bool autoplay = false; + float volume = 1.0; + double last_audio_time = 0.0; + bool expand = true; + bool loops = false; + int buffering_ms = 500; + int audio_track = 0; + int bus_index = 0; StringName bus; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index efef49fbf0..90bc99a941 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -203,7 +203,7 @@ CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const { void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) { particles_animation = p_particles_anim; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool CanvasItemMaterial::get_particles_animation() const { @@ -387,7 +387,6 @@ void CanvasItem::show() { } _propagate_visibility_changed(true); - _change_notify("visible"); } void CanvasItem::hide() { @@ -403,7 +402,6 @@ void CanvasItem::hide() { } _propagate_visibility_changed(false); - _change_notify("visible"); } CanvasItem *CanvasItem::current_item_drawn = nullptr; @@ -1035,7 +1033,7 @@ void CanvasItem::set_material(const Ref<Material> &p_material) { rid = material->get_rid(); } RS::get_singleton()->canvas_item_set_material(canvas_item, rid); - _change_notify(); //properties for material exposed + notify_property_list_changed(); //properties for material exposed } void CanvasItem::set_use_parent_material(bool p_use_parent_material) { @@ -1341,7 +1339,7 @@ void CanvasItem::set_texture_filter(TextureFilter p_texture_filter) { } texture_filter = p_texture_filter; _update_texture_filter_changed(true); - _change_notify(); + notify_property_list_changed(); } CanvasItem::TextureFilter CanvasItem::get_texture_filter() const { @@ -1381,7 +1379,7 @@ void CanvasItem::set_texture_repeat(TextureRepeat p_texture_repeat) { } texture_repeat = p_texture_repeat; _update_texture_repeat_changed(true); - _change_notify(); + notify_property_list_changed(); } void CanvasItem::set_clip_children(bool p_enabled) { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 64eb3f4e0a..e22f93a7ea 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -90,7 +90,7 @@ private: struct ShaderData { RID shader; - int users; + int users = 0; }; static Map<MaterialKey, ShaderData> shader_map; diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 9826d9d4db..91daa08ff8 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -303,17 +303,7 @@ void CanvasLayer::_bind_methods() { } CanvasLayer::CanvasLayer() { - vp = nullptr; - scale = Vector2(1, 1); - rot = 0; - locrotscale_dirty = false; - layer = 1; canvas = RS::get_singleton()->canvas_create(); - custom_viewport = nullptr; - - sort_index = 0; - follow_viewport = false; - follow_viewport_scale = 1.0; } CanvasLayer::~CanvasLayer() { diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index cb10c6299b..181d1dd659 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -38,24 +38,24 @@ class Viewport; class CanvasLayer : public Node { GDCLASS(CanvasLayer, Node); - bool locrotscale_dirty; + bool locrotscale_dirty = false; Vector2 ofs; - Size2 scale; - real_t rot; - int layer; + Size2 scale = Vector2(1, 1); + real_t rot = 0.0; + int layer = 1; Transform2D transform; RID canvas; ObjectID custom_viewport_id; // to check validity - Viewport *custom_viewport; + Viewport *custom_viewport = nullptr; RID viewport; - Viewport *vp; + Viewport *vp = nullptr; - int sort_index; + int sort_index = 0; - bool follow_viewport; - float follow_viewport_scale; + bool follow_viewport = false; + float follow_viewport_scale = 1.0; void _update_xform(); void _update_locrotscale(); diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index ddcf07c8e9..77bdf09426 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -49,7 +49,7 @@ Error HTTPRequest::_parse_url(const String &p_url) { got_response = false; body_len = -1; body.resize(0); - downloaded = 0; + downloaded.set(0); redirections = 0; String url_lower = url.to_lower(); @@ -159,11 +159,11 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust requesting = true; - if (use_threads) { - thread_done = false; - thread_request_quit = false; + if (use_threads.is_set()) { + thread_done.clear(); + thread_request_quit.clear(); client->set_blocking_mode(true); - thread = Thread::create(_thread_func, this); + thread.start(_thread_func, this); } else { client->set_blocking_mode(false); err = _request(); @@ -186,7 +186,7 @@ void HTTPRequest::_thread_func(void *p_userdata) { if (err != OK) { hr->call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray()); } else { - while (!hr->thread_request_quit) { + while (!hr->thread_request_quit.is_set()) { bool exit = hr->_update_connection(); if (exit) { break; @@ -195,7 +195,7 @@ void HTTPRequest::_thread_func(void *p_userdata) { } } - hr->thread_done = true; + hr->thread_done.set(); } void HTTPRequest::cancel_request() { @@ -205,13 +205,11 @@ void HTTPRequest::cancel_request() { return; } - if (!use_threads) { + if (!use_threads.is_set()) { set_process_internal(false); } else { - thread_request_quit = true; - Thread::wait_to_finish(thread); - memdelete(thread); - thread = nullptr; + thread_request_quit.set(); + thread.wait_to_finish(); } if (file) { @@ -238,7 +236,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) { List<String> rheaders; client->get_response_headers(&rheaders); response_headers.resize(0); - downloaded = 0; + downloaded.set(0); for (List<String>::Element *E = rheaders.front(); E; E = E->next()) { response_headers.push_back(E->get()); } @@ -278,7 +276,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) { got_response = false; body_len = -1; body.resize(0); - downloaded = 0; + downloaded.set(0); redirections = new_redirs; *ret_value = false; return true; @@ -391,7 +389,7 @@ bool HTTPRequest::_update_connection() { client->poll(); PackedByteArray chunk = client->read_response_body_chunk(); - downloaded += chunk.size(); + downloaded.add(chunk.size()); if (file) { const uint8_t *r = chunk.ptr(); @@ -404,19 +402,20 @@ bool HTTPRequest::_update_connection() { body.append_array(chunk); } - if (body_size_limit >= 0 && downloaded > body_size_limit) { + if (body_size_limit >= 0 && downloaded.get() > body_size_limit) { call_deferred("_request_done", RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray()); return true; } if (body_len >= 0) { - if (downloaded == body_len) { + if (downloaded.get() == body_len) { call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body); return true; } } else if (client->get_status() == HTTPClient::STATUS_DISCONNECTED) { // We read till EOF, with no errors. Request is done. call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body); + return true; } return false; @@ -480,7 +479,7 @@ void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArra void HTTPRequest::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (use_threads) { + if (use_threads.is_set()) { return; } bool done = _update_connection(); @@ -499,11 +498,11 @@ void HTTPRequest::_notification(int p_what) { void HTTPRequest::set_use_threads(bool p_use) { ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED); - use_threads = p_use; + use_threads.set_to(p_use); } bool HTTPRequest::is_using_threads() const { - return use_threads; + return use_threads.is_set(); } void HTTPRequest::set_accept_gzip(bool p_gzip) { @@ -557,7 +556,7 @@ int HTTPRequest::get_max_redirects() const { } int HTTPRequest::get_downloaded_bytes() const { - return downloaded; + return downloaded.get(); } int HTTPRequest::get_body_size() const { @@ -640,31 +639,11 @@ void HTTPRequest::_bind_methods() { } HTTPRequest::HTTPRequest() { - thread = nullptr; - - port = 80; - redirections = 0; - max_redirects = 8; - body_len = -1; - got_response = false; - validate_ssl = false; - use_ssl = false; - accept_gzip = true; - response_code = 0; - request_sent = false; - requesting = false; client.instance(); - use_threads = false; - thread_done = false; - downloaded = 0; - body_size_limit = -1; - file = nullptr; - timer = memnew(Timer); timer->set_one_shot(true); timer->connect("timeout", callable_mp(this, &HTTPRequest::_timeout)); add_child(timer); - timeout = 0; } HTTPRequest::~HTTPRequest() { diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 6f606296e4..92b0ff28e9 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -34,6 +34,7 @@ #include "core/io/http_client.h" #include "core/os/file_access.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "node.h" #include "scene/main/timer.h" @@ -60,42 +61,42 @@ public: }; private: - bool requesting; + bool requesting = false; String request_string; String url; - int port; + int port = 80; Vector<String> headers; - bool validate_ssl; - bool use_ssl; + bool validate_ssl = false; + bool use_ssl = false; HTTPClient::Method method; Vector<uint8_t> request_data; - bool request_sent; + bool request_sent = false; Ref<HTTPClient> client; PackedByteArray body; - volatile bool use_threads; - bool accept_gzip; + SafeFlag use_threads; + bool accept_gzip = true; - bool got_response; - int response_code; + bool got_response = false; + int response_code = 0; Vector<String> response_headers; String download_to_file; - FileAccess *file; + FileAccess *file = nullptr; - int body_len; - volatile int downloaded; - int body_size_limit; + int body_len = -1; + SafeNumeric<int> downloaded; + int body_size_limit = -1; - int redirections; + int redirections = 0; bool _update_connection(); - int max_redirects; + int max_redirects = 8; - int timeout; + int timeout = 0; void _redirect_request(const String &p_new_url); @@ -107,10 +108,10 @@ private: bool has_header(const PackedStringArray &p_headers, const String &p_header_name); String get_header_value(const PackedStringArray &p_headers, const String &header_name); - volatile bool thread_done; - volatile bool thread_request_quit; + SafeFlag thread_done; + SafeFlag thread_request_quit; - Thread *thread; + Thread thread; void _request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data); static void _thread_func(void *p_userdata); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1b6f73efe1..9d8c7981e6 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -46,7 +46,7 @@ #include <stdint.h> -VARIANT_ENUM_CAST(Node::PauseMode); +VARIANT_ENUM_CAST(Node::ProcessMode); int Node::orphan_node_count = 0; @@ -69,14 +69,14 @@ void Node::_notification(int p_notification) { ERR_FAIL_COND(!get_viewport()); ERR_FAIL_COND(!get_tree()); - if (data.pause_mode == PAUSE_MODE_INHERIT) { + if (data.process_mode == PROCESS_MODE_INHERIT) { if (data.parent) { - data.pause_owner = data.parent->data.pause_owner; + data.process_owner = data.parent->data.process_owner; } else { - data.pause_owner = nullptr; + data.process_owner = nullptr; } } else { - data.pause_owner = this; + data.process_owner = this; } if (data.input) { @@ -110,7 +110,7 @@ void Node::_notification(int p_notification) { remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id())); } - data.pause_owner = nullptr; + data.process_owner = nullptr; if (data.path_cache) { memdelete(data.path_cache); data.path_cache = nullptr; @@ -367,8 +367,6 @@ void Node::set_physics_process(bool p_process) { } else { remove_from_group("physics_process"); } - - _change_notify("physics_process"); } bool Node::is_physics_processing() const { @@ -387,52 +385,87 @@ void Node::set_physics_process_internal(bool p_process_internal) { } else { remove_from_group("physics_process_internal"); } - - _change_notify("physics_process_internal"); } bool Node::is_physics_processing_internal() const { return data.physics_process_internal; } -void Node::set_pause_mode(PauseMode p_mode) { - if (data.pause_mode == p_mode) { +void Node::set_process_mode(ProcessMode p_mode) { + if (data.process_mode == p_mode) { return; } - bool prev_inherits = data.pause_mode == PAUSE_MODE_INHERIT; - data.pause_mode = p_mode; if (!is_inside_tree()) { - return; //pointless - } - if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) { - return; ///nothing changed + data.process_mode = p_mode; + return; } - Node *owner = nullptr; + bool prev_can_process = can_process(); + + data.process_mode = p_mode; - if (data.pause_mode == PAUSE_MODE_INHERIT) { + if (data.process_mode == PROCESS_MODE_INHERIT) { if (data.parent) { - owner = data.parent->data.pause_owner; + data.process_owner = data.parent->data.owner; + } else { + data.process_owner = nullptr; } } else { - owner = this; + data.process_owner = this; } - _propagate_pause_owner(owner); + bool next_can_process = can_process(); + + int pause_notification = 0; + + if (prev_can_process && !next_can_process) { + pause_notification = NOTIFICATION_PAUSED; + } else if (!prev_can_process && next_can_process) { + pause_notification = NOTIFICATION_UNPAUSED; + } + + _propagate_process_owner(data.process_owner, pause_notification); +#ifdef TOOLS_ENABLED + // This is required for the editor to update the visibility of disabled nodes + // Its very expensive during runtime to change, so editor-only + if (Engine::get_singleton()->is_editor_hint()) { + get_tree()->emit_signal("tree_process_mode_changed"); + } +#endif } -Node::PauseMode Node::get_pause_mode() const { - return data.pause_mode; +void Node::_propagate_pause_notification(bool p_enable) { + bool prev_can_process = _can_process(!p_enable); + bool next_can_process = _can_process(p_enable); + + if (prev_can_process && !next_can_process) { + notification(NOTIFICATION_PAUSED); + } else if (!prev_can_process && next_can_process) { + notification(NOTIFICATION_UNPAUSED); + } + + for (int i = 0; i < data.children.size(); i++) { + data.children[i]->_propagate_pause_notification(p_enable); + } } -void Node::_propagate_pause_owner(Node *p_owner) { - if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) { - return; +Node::ProcessMode Node::get_process_mode() const { + return data.process_mode; +} + +void Node::_propagate_process_owner(Node *p_owner, int p_notification) { + data.process_owner = p_owner; + + if (p_notification != 0) { + notification(p_notification); } - data.pause_owner = p_owner; + for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_pause_owner(p_owner); + Node *c = data.children[i]; + if (c->data.process_mode == PROCESS_MODE_INHERIT) { + c->_propagate_process_owner(p_owner, p_notification); + } } } @@ -466,7 +499,7 @@ uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_ nd.name = p_method; nd.mode = p_mode; data.rpc_methods.push_back(nd); - return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); + return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); } else { int c_mid = (~(1 << 15)) & mid; data.rpc_methods.write[c_mid].mode = p_mode; @@ -555,7 +588,7 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { + if (p_args[0]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -584,7 +617,7 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal return Variant(); } - if (p_args[1]->get_type() != Variant::STRING) { + if (p_args[1]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -607,7 +640,7 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Calla return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { + if (p_args[0]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -636,7 +669,7 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Ca return Variant(); } - if (p_args[1]->get_type() != Variant::STRING) { + if (p_args[1]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -809,30 +842,33 @@ bool Node::can_process_notification(int p_what) const { bool Node::can_process() const { ERR_FAIL_COND_V(!is_inside_tree(), false); + return _can_process(get_tree()->is_paused()); +} - if (get_tree()->is_paused()) { - if (data.pause_mode == PAUSE_MODE_STOP) { - return false; - } - if (data.pause_mode == PAUSE_MODE_PROCESS) { - return true; - } - if (data.pause_mode == PAUSE_MODE_INHERIT) { - if (!data.pause_owner) { - return false; //clearly no pause owner by default - } - - if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) { - return true; - } +bool Node::_can_process(bool p_paused) const { + ProcessMode process_mode; - if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) { - return false; - } + if (data.process_mode == PROCESS_MODE_INHERIT) { + if (!data.process_owner) { + process_mode = PROCESS_MODE_PAUSABLE; + } else { + process_mode = data.process_owner->data.process_mode; } + } else { + process_mode = data.process_mode; } - return true; + if (process_mode == PROCESS_MODE_DISABLED) { + return false; + } else if (process_mode == PROCESS_MODE_ALWAYS) { + return true; + } + + if (p_paused) { + return process_mode == PROCESS_MODE_WHEN_PAUSED; + } else { + return process_mode == PROCESS_MODE_PAUSABLE; + } } float Node::get_physics_process_delta_time() const { @@ -863,8 +899,6 @@ void Node::set_process(bool p_process) { } else { remove_from_group("process"); } - - _change_notify("process"); } bool Node::is_processing() const { @@ -883,8 +917,6 @@ void Node::set_process_internal(bool p_process_internal) { } else { remove_from_group("process_internal"); } - - _change_notify("process_internal"); } bool Node::is_processing_internal() const { @@ -1116,7 +1148,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co name = p_child->get_class(); // Adjust casing according to project setting. The current type name is expected to be in PascalCase. - switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) { + switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) { case NAME_CASING_PASCAL_CASE: break; case NAME_CASING_CAMEL_CASE: { @@ -1410,7 +1442,15 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { Node *Node::get_node(const NodePath &p_path) const { Node *node = get_node_or_null(p_path); - ERR_FAIL_COND_V_MSG(!node, nullptr, "Node not found: " + p_path + "."); + + if (p_path.is_absolute()) { + ERR_FAIL_COND_V_MSG(!node, nullptr, + vformat(R"(Node not found: "%s" (absolute path attempted from "%s").)", p_path, get_path())); + } else { + ERR_FAIL_COND_V_MSG(!node, nullptr, + vformat(R"(Node not found: "%s" (relative to "%s").)", p_path, get_path())); + } + return node; } @@ -1906,46 +1946,49 @@ String Node::get_filename() const { } void Node::set_editor_description(const String &p_editor_description) { - set_meta("_editor_description_", p_editor_description); + data.editor_description = p_editor_description; } String Node::get_editor_description() const { - if (has_meta("_editor_description_")) { - return get_meta("_editor_description_"); - } else { - return ""; - } + return data.editor_description; } void Node::set_editable_instance(Node *p_node, bool p_editable) { ERR_FAIL_NULL(p_node); ERR_FAIL_COND(!is_a_parent_of(p_node)); - NodePath p = get_path_to(p_node); if (!p_editable) { - data.editable_instances.erase(p); + p_node->data.editable_instance = false; // Avoid this flag being needlessly saved; // also give more visual feedback if editable children is re-enabled set_display_folded(false); } else { - data.editable_instances[p] = true; + p_node->data.editable_instance = true; } } bool Node::is_editable_instance(const Node *p_node) const { if (!p_node) { - return false; //easier, null is never editable :) + return false; // Easier, null is never editable. :) } ERR_FAIL_COND_V(!is_a_parent_of(p_node), false); - NodePath p = get_path_to(p_node); - return data.editable_instances.has(p); + return p_node->data.editable_instance; } -void Node::set_editable_instances(const HashMap<NodePath, int> &p_editable_instances) { - data.editable_instances = p_editable_instances; -} +Node *Node::get_deepest_editable_node(Node *p_start_node) const { + ERR_FAIL_NULL_V(p_start_node, nullptr); + ERR_FAIL_COND_V(!is_a_parent_of(p_start_node), p_start_node); -HashMap<NodePath, int> Node::get_editable_instances() const { - return data.editable_instances; + Node const *iterated_item = p_start_node; + Node *node = p_start_node; + + while (iterated_item->get_owner() && iterated_item->get_owner() != this) { + if (!is_editable_instance(iterated_item->get_owner())) + node = iterated_item->get_owner(); + + iterated_item = iterated_item->get_owner(); + } + + return node; } void Node::set_scene_instance_state(const Ref<SceneState> &p_state) { @@ -2009,6 +2052,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const if (get_filename() != "") { //an instance node->set_filename(get_filename()); + node->data.editable_instance = data.editable_instance; } StringName script_property_name = CoreStringNames::get_singleton()->_script; @@ -2156,8 +2200,17 @@ Node *Node::duplicate(int p_flags) const { #ifdef TOOLS_ENABLED Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { + return duplicate_from_editor(r_duplimap, Map<RES, RES>()); +} + +Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const { Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); + // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. + if (!p_resource_remap.is_empty()) { + remap_node_resources(dupe, p_resource_remap); + } + // Duplication of signals must happen after all the node descendants have been copied, // because re-targeting of connections from some descendant to another is not possible // if the emitter node comes later in tree order than the receiver @@ -2165,75 +2218,55 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { return dupe; } -#endif - -void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const { - if (get_owner() != get_parent()->get_owner()) { - return; - } - - Node *node = nullptr; - - if (get_filename() != "") { - Ref<PackedScene> res = ResourceLoader::load(get_filename()); - ERR_FAIL_COND_MSG(res.is_null(), "Cannot load scene: " + get_filename()); - node = res->instance(); - ERR_FAIL_COND(!node); - } else { - Object *obj = ClassDB::instance(get_class()); - ERR_FAIL_COND_MSG(!obj, "Node: Could not duplicate: " + String(get_class()) + "."); - node = Object::cast_to<Node>(obj); - if (!node) { - memdelete(obj); - ERR_FAIL_MSG("Node: Could not duplicate: " + String(get_class()) + "."); - } - } - - List<PropertyInfo> plist; - get_property_list(&plist); +void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const { + List<PropertyInfo> props; + p_node->get_property_list(&props); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E->get().name; - Variant value = get(name).duplicate(true); - - node->set(name, value); + Variant v = p_node->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if (p_resource_remap.has(res)) { + p_node->set(E->get().name, p_resource_remap[res]); + remap_nested_resources(res, p_resource_remap); + } + } + } } - List<GroupInfo> groups; - get_groups(&groups); - - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - node->add_to_group(E->get().name, E->get().persistent); + for (int i = 0; i < p_node->get_child_count(); i++) { + remap_node_resources(p_node->get_child(i), p_resource_remap); } +} - node->set_name(get_name()); - p_new_parent->add_child(node); - - Node *owner = get_owner(); +void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const { + List<PropertyInfo> props; + p_resource->get_property_list(&props); - if (p_reown_map.has(owner)) { - owner = p_reown_map[owner]; - } + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } - if (owner) { - NodePath p = get_path_to(owner); - if (owner != this) { - Node *new_owner = node->get_node(p); - if (new_owner) { - node->set_owner(new_owner); + Variant v = p_resource->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if (p_resource_remap.has(res)) { + p_resource->set(E->get().name, p_resource_remap[res]); + remap_nested_resources(res, p_resource_remap); + } } } } - - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_and_reown(node, p_reown_map); - } } +#endif // Duplication of signals must happen after all the node descendants have been copied, // because re-targeting of connections from some descendant to another is not possible @@ -2289,49 +2322,6 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { } } -Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { - ERR_FAIL_COND_V(get_filename() != "", nullptr); - - Object *obj = ClassDB::instance(get_class()); - ERR_FAIL_COND_V_MSG(!obj, nullptr, "Node: Could not duplicate: " + String(get_class()) + "."); - - Node *node = Object::cast_to<Node>(obj); - if (!node) { - memdelete(obj); - ERR_FAIL_V_MSG(nullptr, "Node: Could not duplicate: " + String(get_class()) + "."); - } - node->set_name(get_name()); - - List<PropertyInfo> plist; - - get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - String name = E->get().name; - node->set(name, get(name)); - } - - List<GroupInfo> groups; - get_groups(&groups); - - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - node->add_to_group(E->get().name, E->get().persistent); - } - - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_and_reown(node, p_reown_map); - } - - // Duplication of signals must happen after all the node descendants have been copied, - // because re-targeting of connections from some descendant to another is not possible - // if the emitter node comes later in tree order than the receiver - _duplicate_signals(this, node); - return node; -} - static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) { if (p_node->get_owner() == p_by) { p_owned->push_back(p_node); @@ -2342,12 +2332,7 @@ static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) { } } -struct _NodeReplaceByPair { - String name; - Variant value; -}; - -void Node::replace_by(Node *p_node, bool p_keep_data) { +void Node::replace_by(Node *p_node, bool p_keep_groups) { ERR_FAIL_NULL(p_node); ERR_FAIL_COND(p_node->data.parent); @@ -2355,21 +2340,7 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { List<Node *> owned_by_owner; Node *owner = (data.owner == this) ? p_node : data.owner; - List<_NodeReplaceByPair> replace_data; - - if (p_keep_data) { - List<PropertyInfo> plist; - get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - _NodeReplaceByPair rd; - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - rd.name = E->get().name; - rd.value = get(rd.name); - } - + if (p_keep_groups) { List<GroupInfo> groups; get_groups(&groups); @@ -2414,10 +2385,6 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { } p_node->set_filename(get_filename()); - - for (List<_NodeReplaceByPair>::Element *E = replace_data.front(); E; E = E->next()) { - p_node->set(E->get().name, E->get().value); - } } void Node::_replace_connections_target(Node *p_new_target) { @@ -2709,10 +2676,10 @@ void Node::request_ready() { } void Node::_bind_methods() { - GLOBAL_DEF("node/name_num_separator", 0); - ProjectSettings::get_singleton()->set_custom_property_info("node/name_num_separator", PropertyInfo(Variant::INT, "node/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash")); - GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE); - ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); + GLOBAL_DEF("editor/node_naming/name_num_separator", 0); + ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_num_separator", PropertyInfo(Variant::INT, "editor/node_naming/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash")); + GLOBAL_DEF("editor/node_naming/name_casing", NAME_CASING_PASCAL_CASE); + ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_casing", PropertyInfo(Variant::INT, "editor/node_naming/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "legible_unique_name"), &Node::add_sibling, DEFVAL(false)); @@ -2767,8 +2734,8 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input); ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input); ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input); - ClassDB::bind_method(D_METHOD("set_pause_mode", "mode"), &Node::set_pause_mode); - ClassDB::bind_method(D_METHOD("get_pause_mode"), &Node::get_pause_mode); + ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode); ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process); ClassDB::bind_method(D_METHOD("print_stray_nodes"), &Node::_print_stray_nodes); @@ -2784,7 +2751,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree); ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANCING | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS)); - ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_data"), &Node::replace_by, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder); ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder); @@ -2806,12 +2773,12 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config); ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_config); - ClassDB::bind_method(D_METHOD("_set_editor_description", "editor_description"), &Node::set_editor_description); - ClassDB::bind_method(D_METHOD("_get_editor_description"), &Node::get_editor_description); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_editor_description", "_get_editor_description"); + ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description); + ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description); ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path); ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path"); { @@ -2875,9 +2842,11 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT); BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED); - BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT); - BIND_ENUM_CONSTANT(PAUSE_MODE_STOP); - BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS); + BIND_ENUM_CONSTANT(PROCESS_MODE_INHERIT); + BIND_ENUM_CONSTANT(PROCESS_MODE_PAUSABLE); + BIND_ENUM_CONSTANT(PROCESS_MODE_WHEN_PAUSED); + BIND_ENUM_CONSTANT(PROCESS_MODE_ALWAYS); + BIND_ENUM_CONSTANT(PROCESS_MODE_DISABLED); BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS); BIND_ENUM_CONSTANT(DUPLICATE_GROUPS); @@ -2890,15 +2859,19 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_exiting")); ADD_SIGNAL(MethodInfo("tree_exited")); - ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); + + ADD_GROUP("Process", "process_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,WhenPaused,Always,Disabled"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); + ADD_GROUP("Editor Description", "editor_"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description"); + BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_enter_tree")); @@ -2911,7 +2884,7 @@ void Node::_bind_methods() { } String Node::_get_name_num_separator() { - switch (ProjectSettings::get_singleton()->get("node/name_num_separator").operator int()) { + switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_num_separator").operator int()) { case 0: return ""; case 1: diff --git a/scene/main/node.h b/scene/main/node.h index fc7590c5a4..d47d271a10 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -46,10 +46,12 @@ class Node : public Object { OBJ_CATEGORY("Nodes"); public: - enum PauseMode { - PAUSE_MODE_INHERIT, - PAUSE_MODE_STOP, - PAUSE_MODE_PROCESS + enum ProcessMode { + PROCESS_MODE_INHERIT, // same as parent node + PROCESS_MODE_PAUSABLE, // process only if not paused + PROCESS_MODE_WHEN_PAUSED, // process only if paused + PROCESS_MODE_ALWAYS, // process always + PROCESS_MODE_DISABLED, // never process }; enum DuplicateFlags { @@ -80,7 +82,7 @@ private: struct NetData { StringName name; - MultiplayerAPI::RPCMode mode; + MultiplayerAPI::RPCMode mode = MultiplayerAPI::RPCMode::RPC_MODE_DISABLED; }; struct Data { @@ -88,8 +90,6 @@ private: Ref<SceneState> instance_state; Ref<SceneState> inherited_state; - HashMap<NodePath, int> editable_instances; - Node *parent = nullptr; Node *owner = nullptr; Vector<Node *> children; @@ -104,6 +104,7 @@ private: #ifdef TOOLS_ENABLED NodePath import_path; // Path used when imported, used by scene editors to keep tracking. #endif + String editor_description; Viewport *viewport = nullptr; @@ -111,8 +112,8 @@ private: List<Node *>::Element *OW = nullptr; // Owned element. List<Node *> owned; - PauseMode pause_mode = PAUSE_MODE_INHERIT; - Node *pause_owner = nullptr; + ProcessMode process_mode = PROCESS_MODE_INHERIT; + Node *process_owner = nullptr; int network_master = 1; // Server by default. Vector<NetData> rpc_methods; @@ -136,6 +137,7 @@ private: bool use_placeholder = false; bool display_folded = false; + bool editable_instance = false; mutable NodePath *path_cache = nullptr; @@ -167,11 +169,10 @@ private: void _propagate_after_exit_tree(); void _propagate_validate_owner(); void _print_stray_nodes(); - void _propagate_pause_owner(Node *p_owner); + void _propagate_process_owner(Node *p_owner, int p_notification); Array _get_node_and_resource(const NodePath &p_path); void _duplicate_signals(const Node *p_original, Node *p_copy) const; - void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const; Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const; TypedArray<Node> _get_children() const; @@ -185,6 +186,9 @@ private: friend class SceneTree; void _set_tree(SceneTree *p_tree); + void _propagate_pause_notification(bool p_enable); + + _FORCE_INLINE_ bool _can_process(bool p_paused) const; #ifdef TOOLS_ENABLED friend class SceneTreeEditor; @@ -298,7 +302,7 @@ public: struct GroupInfo { StringName name; - bool persistent; + bool persistent = false; }; void get_groups(List<GroupInfo> *p_groups) const; @@ -325,8 +329,7 @@ public: void set_editable_instance(Node *p_node, bool p_editable); bool is_editable_instance(const Node *p_node) const; - void set_editable_instances(const HashMap<NodePath, int> &p_editable_instances); - HashMap<NodePath, int> get_editable_instances() const; + Node *get_deepest_editable_node(Node *p_start_node) const; /* NOTIFICATIONS */ @@ -362,9 +365,11 @@ public: bool is_processing_unhandled_key_input() const; Node *duplicate(int p_flags = DUPLICATE_GROUPS | DUPLICATE_SIGNALS | DUPLICATE_SCRIPTS) const; - Node *duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const; #ifdef TOOLS_ENABLED Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const; + Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const; + void remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const; + void remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const; #endif // used by editors, to save what has changed only @@ -381,8 +386,8 @@ public: void replace_by(Node *p_node, bool p_keep_data = false); - void set_pause_mode(PauseMode p_mode); - PauseMode get_pause_mode() const; + void set_process_mode(ProcessMode p_mode); + ProcessMode get_process_mode() const; bool can_process() const; bool can_process_notification(int p_what) const; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index f18ac3b801..9aaddfd373 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -54,6 +54,7 @@ #include "window.h" #include <stdio.h> +#include <stdlib.h> void SceneTreeTimer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_time_left", "time"), &SceneTreeTimer::set_time_left); @@ -72,12 +73,12 @@ float SceneTreeTimer::get_time_left() const { return time_left; } -void SceneTreeTimer::set_pause_mode_process(bool p_pause_mode_process) { - process_pause = p_pause_mode_process; +void SceneTreeTimer::set_process_always(bool p_process_always) { + process_always = p_process_always; } -bool SceneTreeTimer::is_pause_mode_process() { - return process_pause; +bool SceneTreeTimer::is_process_always() { + return process_always; } void SceneTreeTimer::release_connections() { @@ -90,10 +91,7 @@ void SceneTreeTimer::release_connections() { } } -SceneTreeTimer::SceneTreeTimer() { - time_left = 0; - process_pause = true; -} +SceneTreeTimer::SceneTreeTimer() {} void SceneTree::tree_changed() { tree_version++; @@ -409,6 +407,7 @@ bool SceneTree::physics_process(float p_time) { emit_signal("physics_frame"); _notify_group_pause("physics_process_internal", Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); + call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_process_picking"); _notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS); _flush_ugc(); MessageQueue::get_singleton()->flush(); //small little hack @@ -457,7 +456,7 @@ bool SceneTree::process(float p_time) { for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) { List<Ref<SceneTreeTimer>>::Element *N = E->next(); - if (pause && !E->get()->is_pause_mode_process()) { + if (paused && !E->get()->is_process_always()) { if (E == L) { break; //break on last, so if new timers were added during list traversal, ignore them. } @@ -486,7 +485,7 @@ bool SceneTree::process(float p_time) { if (Engine::get_singleton()->is_editor_hint()) { //simple hack to reload fallback environment if it changed from editor - String env_path = ProjectSettings::get_singleton()->get("rendering/environment/default_environment"); + String env_path = ProjectSettings::get_singleton()->get("rendering/environment/defaults/default_environment"); env_path = env_path.strip_edges(); //user may have added a space or two String cpath; Ref<Environment> fallback = get_root()->get_world_3d()->get_fallback_environment(); @@ -498,7 +497,7 @@ bool SceneTree::process(float p_time) { fallback = ResourceLoader::load(env_path); if (fallback.is_null()) { //could not load fallback, set as empty - ProjectSettings::get_singleton()->set("rendering/environment/default_environment", ""); + ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", ""); } } else { fallback.unref(); @@ -536,12 +535,7 @@ void SceneTree::finalize() { } void SceneTree::quit(int p_exit_code) { - if (p_exit_code >= 0) { - // Override the exit code if a positive argument is given (the default is `-1`). - // This is a shorthand for calling `set_exit_code()` on the OS singleton then quitting. - OS::get_singleton()->set_exit_code(p_exit_code); - } - + OS::get_singleton()->set_exit_code(p_exit_code); _quit = true; } @@ -761,20 +755,20 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() { } void SceneTree::set_pause(bool p_enabled) { - if (p_enabled == pause) { + if (p_enabled == paused) { return; } - pause = p_enabled; + paused = p_enabled; NavigationServer3D::get_singleton()->set_active(!p_enabled); PhysicsServer3D::get_singleton()->set_active(!p_enabled); PhysicsServer2D::get_singleton()->set_active(!p_enabled); if (get_root()) { - get_root()->propagate_notification(p_enabled ? Node::NOTIFICATION_PAUSED : Node::NOTIFICATION_UNPAUSED); + get_root()->_propagate_pause_notification(p_enabled); } } bool SceneTree::is_paused() const { - return pause; + return paused; } void SceneTree::_notify_group_pause(const StringName &p_group, int p_notification) { @@ -958,6 +952,21 @@ bool SceneTree::has_group(const StringName &p_identifier) const { return group_map.has(p_identifier); } +Node *SceneTree::get_first_node_in_group(const StringName &p_group) { + Map<StringName, Group>::Element *E = group_map.find(p_group); + if (!E) { + return nullptr; //no group + } + + _update_group_order(E->get()); //update order just in case + + if (E->get().nodes.size() == 0) { + return nullptr; + } + + return E->get().nodes[0]; +} + void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_list) { Map<StringName, Group>::Element *E = group_map.find(p_group); if (!E) { @@ -1072,10 +1081,10 @@ void SceneTree::add_current_scene(Node *p_current) { root->add_child(p_current); } -Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_pause) { +Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_always) { Ref<SceneTreeTimer> stt; stt.instance(); - stt->set_pause_mode_process(p_process_pause); + stt->set_process_always(p_process_always); stt->set_time_left(p_delay_sec); timers.push_back(stt); return stt; @@ -1188,11 +1197,11 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause); ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused); - ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "pause_mode_process"), &SceneTree::create_timer, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "process_always"), &SceneTree::create_timer, DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_node_count"), &SceneTree::get_node_count); ClassDB::bind_method(D_METHOD("get_frame"), &SceneTree::get_frame); - ClassDB::bind_method(D_METHOD("quit", "exit_code"), &SceneTree::quit, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("quit", "exit_code"), &SceneTree::quit, DEFVAL(EXIT_SUCCESS)); ClassDB::bind_method(D_METHOD("queue_delete", "obj"), &SceneTree::queue_delete); @@ -1218,6 +1227,7 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_group", "group", "property", "value"), &SceneTree::set_group); ClassDB::bind_method(D_METHOD("get_nodes_in_group", "group"), &SceneTree::_get_nodes_in_group); + ClassDB::bind_method(D_METHOD("get_first_node_in_group", "group"), &SceneTree::get_first_node_in_group); ClassDB::bind_method(D_METHOD("set_current_scene", "child_node"), &SceneTree::set_current_scene); ClassDB::bind_method(D_METHOD("get_current_scene"), &SceneTree::get_current_scene); @@ -1256,6 +1266,7 @@ void SceneTree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multiplayer_poll"), "set_multiplayer_poll_enabled", "is_multiplayer_poll_enabled"); ADD_SIGNAL(MethodInfo("tree_changed")); + ADD_SIGNAL(MethodInfo("tree_process_mode_changed")); //editor only signal, but due to API hash it cant be removed in run-time ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_renamed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); @@ -1328,13 +1339,15 @@ SceneTree::SceneTree() { if (singleton == nullptr) { singleton = this; } - debug_collisions_color = GLOBAL_DEF("debug/shapes/collision/shape_color", Color(0.0, 0.6, 0.7, 0.5)); + debug_collisions_color = GLOBAL_DEF("debug/shapes/collision/shape_color", Color(0.0, 0.6, 0.7, 0.42)); debug_collision_contact_color = GLOBAL_DEF("debug/shapes/collision/contact_color", Color(1.0, 0.2, 0.1, 0.8)); debug_navigation_color = GLOBAL_DEF("debug/shapes/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4)); debug_navigation_disabled_color = GLOBAL_DEF("debug/shapes/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4)); collision_debug_contacts = GLOBAL_DEF("debug/shapes/collision/max_contacts_displayed", 10000); ProjectSettings::get_singleton()->set_custom_property_info("debug/shapes/collision/max_contacts_displayed", PropertyInfo(Variant::INT, "debug/shapes/collision/max_contacts_displayed", PROPERTY_HINT_RANGE, "0,20000,1")); // No negative + GLOBAL_DEF("debug/shapes/collision/draw_2d_outlines", true); + // Create with mainloop. root = memnew(Window); @@ -1351,34 +1364,54 @@ SceneTree::SceneTree() { root->set_as_audio_listener_2d(true); current_scene = nullptr; - const int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)")); + const int msaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/msaa", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)")); root->set_msaa(Viewport::MSAA(msaa_mode)); - const int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)")); + const int ssaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/screen_space_aa", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/screen_space_aa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)")); root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); - const bool use_debanding = GLOBAL_DEF("rendering/quality/screen_filters/use_debanding", false); + const bool use_debanding = GLOBAL_DEF("rendering/anti_aliasing/quality/use_debanding", false); root->set_use_debanding(use_debanding); - float lod_threshold = GLOBAL_DEF("rendering/quality/mesh_lod/threshold_pixels", 1.0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/mesh_lod/threshold_pixels", PropertyInfo(Variant::FLOAT, "rendering/quality/mesh_lod/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1")); + float lod_threshold = GLOBAL_DEF("rendering/mesh_lod/lod_change/threshold_pixels", 1.0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/mesh_lod/lod_change/threshold_pixels", PropertyInfo(Variant::FLOAT, "rendering/mesh_lod/lod_change/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1")); root->set_lod_threshold(lod_threshold); - bool snap_2d_transforms = GLOBAL_DEF("rendering/quality/2d/snap_2d_transforms_to_pixel", false); + bool snap_2d_transforms = GLOBAL_DEF("rendering/2d/snap/snap_2d_transforms_to_pixel", false); root->set_snap_2d_transforms_to_pixel(snap_2d_transforms); - bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false); + bool snap_2d_vertices = GLOBAL_DEF("rendering/2d/snap/snap_2d_vertices_to_pixel", false); root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); - Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/quality/2d_sdf/oversize", 1))); + int shadowmap_size = GLOBAL_DEF("rendering/shadows/shadow_atlas/size", 4096); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384")); + GLOBAL_DEF("rendering/shadows/shadow_atlas/size.mobile", 2048); + bool shadowmap_16_bits = GLOBAL_DEF("rendering/shadows/shadow_atlas/16_bits", true); + int atlas_q0 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_0_subdiv", 2); + int atlas_q1 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_1_subdiv", 2); + int atlas_q2 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_2_subdiv", 3); + int atlas_q3 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_3_subdiv", 4); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + + root->set_shadow_atlas_size(shadowmap_size); + root->set_shadow_atlas_16_bits(shadowmap_16_bits); + root->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); + root->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); + root->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); + root->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); + + Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/2d/sdf/oversize", 1))); root->set_sdf_oversize(sdf_oversize); - Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/quality/2d_sdf/scale", 1))); + Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/2d/sdf/scale", 1))); root->set_sdf_scale(sdf_scale); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/2d_sdf/oversize", PropertyInfo(Variant::INT, "rendering/quality/2d_sdf/oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/2d_sdf/scale", PropertyInfo(Variant::INT, "rendering/quality/2d_sdf/scale", PROPERTY_HINT_ENUM, "100%,50%,25%")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/sdf/oversize", PropertyInfo(Variant::INT, "rendering/2d/sdf/oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/sdf/scale", PropertyInfo(Variant::INT, "rendering/2d/sdf/scale", PROPERTY_HINT_ENUM, "100%,50%,25%")); { // Load default fallback environment. // Get possible extensions. @@ -1392,9 +1425,9 @@ SceneTree::SceneTree() { ext_hint += "*." + E->get(); } // Get path. - String env_path = GLOBAL_DEF("rendering/environment/default_environment", ""); + String env_path = GLOBAL_DEF("rendering/environment/defaults/default_environment", ""); // Setup property. - ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint)); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/defaults/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint)); env_path = env_path.strip_edges(); if (env_path != String()) { Ref<Environment> env = ResourceLoader::load(env_path); @@ -1403,7 +1436,7 @@ SceneTree::SceneTree() { } else { if (Engine::get_singleton()->is_editor_hint()) { // File was erased, clear the field. - ProjectSettings::get_singleton()->set("rendering/environment/default_environment", ""); + ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", ""); } else { // File was erased, notify user. ERR_PRINT(RTR("Default Environment as specified in Project Settings (Rendering -> Environment -> Default Environment) could not be loaded.")); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 748908c8a6..a2f2adb8f8 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -51,8 +51,8 @@ class SceneDebugger; class SceneTreeTimer : public Reference { GDCLASS(SceneTreeTimer, Reference); - float time_left; - bool process_pause; + float time_left = 0.0; + bool process_always = true; protected: static void _bind_methods(); @@ -61,8 +61,8 @@ public: void set_time_left(float p_time); float get_time_left() const; - void set_pause_mode_process(bool p_pause_mode_process); - bool is_pause_mode_process(); + void set_process_always(bool p_process_always); + bool is_process_always(); void release_connections(); @@ -80,8 +80,7 @@ public: private: struct Group { Vector<Node *> nodes; - bool changed; - Group() { changed = false; }; + bool changed = false; }; Window *root = nullptr; @@ -96,7 +95,7 @@ private: bool debug_collisions_hint = false; bool debug_navigation_hint = false; #endif - bool pause = false; + bool paused = false; int root_lock = 0; Map<StringName, Group> group_map; @@ -246,7 +245,7 @@ public: void set_auto_accept_quit(bool p_enable); void set_quit_on_go_back(bool p_enable); - void quit(int p_exit_code = -1); + void quit(int p_exit_code = EXIT_SUCCESS); _FORCE_INLINE_ float get_physics_process_time() const { return physics_process_time; } _FORCE_INLINE_ float get_process_time() const { return process_time; } @@ -303,6 +302,7 @@ public: void queue_delete(Object *p_object); void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list); + Node *get_first_node_in_group(const StringName &p_group); bool has_group(const StringName &p_identifier) const; //void change_scene(const String& p_path); @@ -317,7 +317,7 @@ public: Error change_scene_to(const Ref<PackedScene> &p_scene); Error reload_current_scene(); - Ref<SceneTreeTimer> create_timer(float p_delay_sec, bool p_process_pause = true); + Ref<SceneTreeTimer> create_timer(float p_delay_sec, bool p_process_always = true); //used by Main::start, don't use otherwise void add_current_scene(Node *p_current); diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 4485cffff5..b6b2982155 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -277,6 +277,4 @@ void ShaderGlobalsOverride::_bind_methods() { ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate); } -ShaderGlobalsOverride::ShaderGlobalsOverride() { - active = false; -} +ShaderGlobalsOverride::ShaderGlobalsOverride() {} diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h index 9e666a0ec5..8d8794d465 100644 --- a/scene/main/shader_globals_override.h +++ b/scene/main/shader_globals_override.h @@ -43,7 +43,7 @@ class ShaderGlobalsOverride : public Node { StringName *_remap(const StringName &p_name) const; - bool active; + bool active = false; mutable HashMap<StringName, Override> overrides; mutable HashMap<StringName, StringName> param_remaps; diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index d7b2292ff5..4bc159f6aa 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -46,7 +46,7 @@ void Timer::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PROCESS: { - if (!processing || timer_process_mode == TIMER_PROCESS_PHYSICS || !is_processing_internal()) { + if (!processing || timer_process_callback == TIMER_PROCESS_PHYSICS || !is_processing_internal()) { return; } time_left -= get_process_delta_time(); @@ -63,7 +63,7 @@ void Timer::_notification(int p_what) { } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - if (!processing || timer_process_mode == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) { + if (!processing || timer_process_callback == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) { return; } time_left -= get_physics_process_delta_time(); @@ -143,12 +143,12 @@ float Timer::get_time_left() const { return time_left > 0 ? time_left : 0; } -void Timer::set_timer_process_mode(TimerProcessMode p_mode) { - if (timer_process_mode == p_mode) { +void Timer::set_timer_process_callback(TimerProcessCallback p_callback) { + if (timer_process_callback == p_callback) { return; } - switch (timer_process_mode) { + switch (timer_process_callback) { case TIMER_PROCESS_PHYSICS: if (is_physics_processing_internal()) { set_physics_process_internal(false); @@ -162,15 +162,15 @@ void Timer::set_timer_process_mode(TimerProcessMode p_mode) { } break; } - timer_process_mode = p_mode; + timer_process_callback = p_callback; } -Timer::TimerProcessMode Timer::get_timer_process_mode() const { - return timer_process_mode; +Timer::TimerProcessCallback Timer::get_timer_process_callback() const { + return timer_process_callback; } void Timer::_set_process(bool p_process, bool p_force) { - switch (timer_process_mode) { + switch (timer_process_callback) { case TIMER_PROCESS_PHYSICS: set_physics_process_internal(p_process && !paused); break; @@ -201,12 +201,12 @@ void Timer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_time_left"), &Timer::get_time_left); - ClassDB::bind_method(D_METHOD("set_timer_process_mode", "mode"), &Timer::set_timer_process_mode); - ClassDB::bind_method(D_METHOD("get_timer_process_mode"), &Timer::get_timer_process_mode); + ClassDB::bind_method(D_METHOD("set_timer_process_callback", "callback"), &Timer::set_timer_process_callback); + ClassDB::bind_method(D_METHOD("get_timer_process_callback"), &Timer::get_timer_process_callback); ADD_SIGNAL(MethodInfo("timeout")); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_timer_process_mode", "get_timer_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_timer_process_callback", "get_timer_process_callback"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.001,4096,0.001,or_greater"), "set_wait_time", "get_wait_time"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "is_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autostart"), "set_autostart", "has_autostart"); @@ -217,12 +217,4 @@ void Timer::_bind_methods() { BIND_ENUM_CONSTANT(TIMER_PROCESS_IDLE); } -Timer::Timer() { - timer_process_mode = TIMER_PROCESS_IDLE; - autostart = false; - wait_time = 1; - one_shot = false; - time_left = -1; - processing = false; - paused = false; -} +Timer::Timer() {} diff --git a/scene/main/timer.h b/scene/main/timer.h index 0604a2d990..3d9e21d7fc 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -36,20 +36,20 @@ class Timer : public Node { GDCLASS(Timer, Node); - float wait_time; - bool one_shot; - bool autostart; - bool processing; - bool paused; + float wait_time = 1.0; + bool one_shot = false; + bool autostart = false; + bool processing = false; + bool paused = false; - double time_left; + double time_left = -1.0; protected: void _notification(int p_what); static void _bind_methods(); public: - enum TimerProcessMode { + enum TimerProcessCallback { TIMER_PROCESS_PHYSICS, TIMER_PROCESS_IDLE, }; @@ -73,15 +73,15 @@ public: float get_time_left() const; - void set_timer_process_mode(TimerProcessMode p_mode); - TimerProcessMode get_timer_process_mode() const; + void set_timer_process_callback(TimerProcessCallback p_callback); + TimerProcessCallback get_timer_process_callback() const; Timer(); private: - TimerProcessMode timer_process_mode; + TimerProcessCallback timer_process_callback = TIMER_PROCESS_IDLE; void _set_process(bool p_process, bool p_force = false); }; -VARIANT_ENUM_CAST(Timer::TimerProcessMode); +VARIANT_ENUM_CAST(Timer::TimerProcessCallback); #endif // TIMER_H diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 4baec0f995..40b85e6d7b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -144,7 +144,6 @@ void ViewportTexture::_bind_methods() { } ViewportTexture::ViewportTexture() { - vp = nullptr; set_local_to_scene(true); } @@ -184,26 +183,6 @@ public: ///////////////////////////////////// -Viewport::GUI::GUI() { - embed_subwindows_hint = false; - embedding_subwindows = false; - - dragging = false; - mouse_focus = nullptr; - forced_mouse_focus = false; - mouse_click_grabber = nullptr; - mouse_focus_mask = 0; - key_focus = nullptr; - mouse_over = nullptr; - drag_mouse_over = nullptr; - - tooltip_control = nullptr; - tooltip_popup = nullptr; - tooltip_label = nullptr; -} - -///////////////////////////////////// - void Viewport::update_worlds() { if (!is_inside_tree()) { return; @@ -299,6 +278,11 @@ void Viewport::_sub_window_update(Window *p_window) { int x = (r.size.width - title_text.get_size().x) / 2; int y = (-title_height - title_text.get_size().y) / 2; + Color font_outline_color = p_window->get_theme_color("title_outline_modulate"); + int outline_size = p_window->get_theme_constant("title_outline_size"); + if (outline_size > 0 && font_outline_color.a > 0) { + title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color); + } title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color); bool hl = gui.subwindow_focused == sw.window && gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE && gui.subwindow_drag_close_inside; @@ -468,7 +452,7 @@ void Viewport::_notification(int p_what) { //3D PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create(); - RenderingServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); + RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0); RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid()); contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create(); @@ -567,280 +551,297 @@ void Viewport::_notification(int p_what) { int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space()); RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); + + for (int i = 0; i < point_count; i++) { + Transform point_transform; + point_transform.origin = points[i]; + RS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform); + } + } + } break; + case NOTIFICATION_WM_MOUSE_EXIT: { + _drop_physics_mouseover(); + + // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not + // drop the gui mouseover here, as a scrollbar may be dragged while the + // mouse is outside the window (without the window having lost focus). + // See bug #39634 + } break; + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { + _drop_physics_mouseover(); + + if (gui.mouse_focus && !gui.forced_mouse_focus) { + _drop_mouse_focus(); } + } break; + } +} + +void Viewport::_process_picking() { + if (!is_inside_tree()) { + return; + } + if (!physics_object_picking) { + return; + } + if (to_screen_rect != Rect2i() && Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) { + return; + } + + _drop_physics_mouseover(true); - if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) { #ifndef _3D_DISABLED - Vector2 last_pos(1e20, 1e20); - CollisionObject3D *last_object = nullptr; - ObjectID last_id; + Vector2 last_pos(1e20, 1e20); + CollisionObject3D *last_object = nullptr; + ObjectID last_id; #endif - PhysicsDirectSpaceState3D::RayResult result; - PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); - - if (physics_has_last_mousepos) { - // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. - // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame - bool has_mouse_event = false; - for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) { - Ref<InputEventMouse> m = E->get(); - if (m.is_valid()) { - has_mouse_event = true; - break; - } - } + PhysicsDirectSpaceState3D::RayResult result; + PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); + + if (physics_has_last_mousepos) { + // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. + // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame + bool has_mouse_event = false; + for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) { + Ref<InputEventMouse> m = E->get(); + if (m.is_valid()) { + has_mouse_event = true; + break; + } + } - if (!has_mouse_event) { - Ref<InputEventMouseMotion> mm; - mm.instance(); - - mm->set_device(InputEvent::DEVICE_ID_INTERNAL); - mm->set_global_position(physics_last_mousepos); - mm->set_position(physics_last_mousepos); - mm->set_alt(physics_last_mouse_state.alt); - mm->set_shift(physics_last_mouse_state.shift); - mm->set_control(physics_last_mouse_state.control); - mm->set_metakey(physics_last_mouse_state.meta); - mm->set_button_mask(physics_last_mouse_state.mouse_mask); - physics_picking_events.push_back(mm); - } - } + if (!has_mouse_event) { + Ref<InputEventMouseMotion> mm; + mm.instance(); - while (physics_picking_events.size()) { - Ref<InputEvent> ev = physics_picking_events.front()->get(); - physics_picking_events.pop_front(); + mm->set_device(InputEvent::DEVICE_ID_INTERNAL); + mm->set_global_position(physics_last_mousepos); + mm->set_position(physics_last_mousepos); + mm->set_alt(physics_last_mouse_state.alt); + mm->set_shift(physics_last_mouse_state.shift); + mm->set_control(physics_last_mouse_state.control); + mm->set_metakey(physics_last_mouse_state.meta); + mm->set_button_mask(physics_last_mouse_state.mouse_mask); + physics_picking_events.push_back(mm); + } + } - Vector2 pos; - bool is_mouse = false; + while (physics_picking_events.size()) { + Ref<InputEvent> ev = physics_picking_events.front()->get(); + physics_picking_events.pop_front(); - Ref<InputEventMouseMotion> mm = ev; + Vector2 pos; + bool is_mouse = false; - if (mm.is_valid()) { - pos = mm->get_position(); - is_mouse = true; + Ref<InputEventMouseMotion> mm = ev; - physics_has_last_mousepos = true; - physics_last_mousepos = pos; - physics_last_mouse_state.alt = mm->get_alt(); - physics_last_mouse_state.shift = mm->get_shift(); - physics_last_mouse_state.control = mm->get_control(); - physics_last_mouse_state.meta = mm->get_metakey(); - physics_last_mouse_state.mouse_mask = mm->get_button_mask(); - } + if (mm.is_valid()) { + pos = mm->get_position(); + is_mouse = true; - Ref<InputEventMouseButton> mb = ev; + physics_has_last_mousepos = true; + physics_last_mousepos = pos; + physics_last_mouse_state.alt = mm->get_alt(); + physics_last_mouse_state.shift = mm->get_shift(); + physics_last_mouse_state.control = mm->get_control(); + physics_last_mouse_state.meta = mm->get_metakey(); + physics_last_mouse_state.mouse_mask = mm->get_button_mask(); + } - if (mb.is_valid()) { - pos = mb->get_position(); - is_mouse = true; + Ref<InputEventMouseButton> mb = ev; - physics_has_last_mousepos = true; - physics_last_mousepos = pos; - physics_last_mouse_state.alt = mb->get_alt(); - physics_last_mouse_state.shift = mb->get_shift(); - physics_last_mouse_state.control = mb->get_control(); - physics_last_mouse_state.meta = mb->get_metakey(); + if (mb.is_valid()) { + pos = mb->get_position(); + is_mouse = true; - if (mb->is_pressed()) { - physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); - } else { - physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1)); + physics_has_last_mousepos = true; + physics_last_mousepos = pos; + physics_last_mouse_state.alt = mb->get_alt(); + physics_last_mouse_state.shift = mb->get_shift(); + physics_last_mouse_state.control = mb->get_control(); + physics_last_mouse_state.meta = mb->get_metakey(); - // If touch mouse raised, assume we don't know last mouse pos until new events come - if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { - physics_has_last_mousepos = false; - } - } - } + if (mb->is_pressed()) { + physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); + } else { + physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1)); - Ref<InputEventKey> k = ev; - if (k.is_valid()) { - //only for mask - physics_last_mouse_state.alt = k->get_alt(); - physics_last_mouse_state.shift = k->get_shift(); - physics_last_mouse_state.control = k->get_control(); - physics_last_mouse_state.meta = k->get_metakey(); - continue; - } + // If touch mouse raised, assume we don't know last mouse pos until new events come + if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { + physics_has_last_mousepos = false; + } + } + } - Ref<InputEventScreenDrag> sd = ev; + Ref<InputEventKey> k = ev; + if (k.is_valid()) { + //only for mask + physics_last_mouse_state.alt = k->get_alt(); + physics_last_mouse_state.shift = k->get_shift(); + physics_last_mouse_state.control = k->get_control(); + physics_last_mouse_state.meta = k->get_metakey(); + continue; + } - if (sd.is_valid()) { - pos = sd->get_position(); - } + Ref<InputEventScreenDrag> sd = ev; - Ref<InputEventScreenTouch> st = ev; + if (sd.is_valid()) { + pos = sd->get_position(); + } - if (st.is_valid()) { - pos = st->get_position(); - } + Ref<InputEventScreenTouch> st = ev; - if (ss2d) { - //send to 2D + if (st.is_valid()) { + pos = st->get_position(); + } - uint64_t frame = get_tree()->get_frame(); + if (ss2d) { + //send to 2D - PhysicsDirectSpaceState2D::ShapeResult res[64]; - for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) { - Transform2D canvas_transform; - ObjectID canvas_layer_id; - if (E->get()) { - // A descendant CanvasLayer - canvas_transform = E->get()->get_transform(); - canvas_layer_id = E->get()->get_instance_id(); - } else { - // This Viewport's builtin canvas - canvas_transform = get_canvas_transform(); - canvas_layer_id = ObjectID(); - } + uint64_t frame = get_tree()->get_frame(); + + PhysicsDirectSpaceState2D::ShapeResult res[64]; + for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) { + Transform2D canvas_transform; + ObjectID canvas_layer_id; + if (E->get()) { + // A descendant CanvasLayer + canvas_transform = E->get()->get_transform(); + canvas_layer_id = E->get()->get_instance_id(); + } else { + // This Viewport's builtin canvas + canvas_transform = get_canvas_transform(); + canvas_layer_id = ObjectID(); + } - Vector2 point = canvas_transform.affine_inverse().xform(pos); - - int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); - for (int i = 0; i < rc; i++) { - if (res[i].collider_id.is_valid() && res[i].collider) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); - if (co) { - bool send_event = true; - if (is_mouse) { - Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id); - - if (!F) { - physics_2d_mouseover.insert(res[i].collider_id, frame); - co->_mouse_enter(); - } else { - F->get() = frame; - // It was already hovered, so don't send the event if it's faked - if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { - send_event = false; - } - } - } - - if (send_event) { - co->_input_event(this, ev, res[i].shape); - } + Vector2 point = canvas_transform.affine_inverse().xform(pos); + + int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); + for (int i = 0; i < rc; i++) { + if (res[i].collider_id.is_valid() && res[i].collider) { + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); + if (co && co->can_process()) { + bool send_event = true; + if (is_mouse) { + Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id); + + if (!F) { + physics_2d_mouseover.insert(res[i].collider_id, frame); + co->_mouse_enter(); + } else { + F->get() = frame; + // It was already hovered, so don't send the event if it's faked + if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { + send_event = false; } } } - } - if (is_mouse) { - List<Map<ObjectID, uint64_t>::Element *> to_erase; - - for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { - if (E->get() != frame) { - Object *o = ObjectDB::get_instance(E->key()); - if (o) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - if (co) { - co->_mouse_exit(); - } - } - to_erase.push_back(E); - } + if (send_event) { + co->_input_event(this, ev, res[i].shape); } + } + } + } + } + + if (is_mouse) { + List<Map<ObjectID, uint64_t>::Element *> to_erase; - while (to_erase.size()) { - physics_2d_mouseover.erase(to_erase.front()->get()); - to_erase.pop_front(); + for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { + if (E->get() != frame) { + Object *o = ObjectDB::get_instance(E->key()); + if (o) { + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); + if (co) { + co->_mouse_exit(); } } + to_erase.push_back(E); } + } + + while (to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); + } + } + } #ifndef _3D_DISABLED - bool captured = false; - - if (physics_object_capture.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); - if (co && camera) { - _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0); - captured = true; - if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { - physics_object_capture = ObjectID(); - } + bool captured = false; + + if (physics_object_capture.is_valid()) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); + if (co && camera) { + _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0); + captured = true; + if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { + physics_object_capture = ObjectID(); + } - } else { - physics_object_capture = ObjectID(); + } else { + physics_object_capture = ObjectID(); + } + } + + if (captured) { + //none + } else if (pos == last_pos) { + if (last_id.is_valid()) { + if (ObjectDB::get_instance(last_id) && last_object) { + //good, exists + _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape); + if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { + physics_object_capture = last_id; + } + } + } + } else { + if (camera) { + Vector3 from = camera->project_ray_origin(pos); + Vector3 dir = camera->project_ray_normal(pos); + + PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space()); + if (space) { + bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); + ObjectID new_collider; + if (col) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); + if (co && co->can_process()) { + _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape); + last_object = co; + last_id = result.collider_id; + new_collider = last_id; + if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { + physics_object_capture = last_id; + } } } - if (captured) { - //none - } else if (pos == last_pos) { - if (last_id.is_valid()) { - if (ObjectDB::get_instance(last_id) && last_object) { - //good, exists - _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape); - if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { - physics_object_capture = last_id; - } + if (is_mouse && new_collider != physics_object_over) { + if (physics_object_over.is_valid()) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); + if (co) { + co->_mouse_exit(); } } - } else { - if (camera) { - Vector3 from = camera->project_ray_origin(pos); - Vector3 dir = camera->project_ray_normal(pos); - - PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space()); - if (space) { - bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); - ObjectID new_collider; - if (col) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); - if (co) { - _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape); - last_object = co; - last_id = result.collider_id; - new_collider = last_id; - if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { - physics_object_capture = last_id; - } - } - } - if (is_mouse && new_collider != physics_object_over) { - if (physics_object_over.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); - if (co) { - co->_mouse_exit(); - } - } - - if (new_collider.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider)); - if (co) { - co->_mouse_enter(); - } - } - - physics_object_over = new_collider; - } + if (new_collider.is_valid()) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider)); + if (co) { + co->_mouse_enter(); } - - last_pos = pos; } + + physics_object_over = new_collider; } -#endif } - } - - } break; - case NOTIFICATION_WM_MOUSE_EXIT: { - _drop_physics_mouseover(); - - // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not - // drop the gui mouseover here, as a scrollbar may be dragged while the - // mouse is outside the window (without the window having lost focus). - // See bug #39634 - } break; - case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { - _drop_physics_mouseover(); - if (gui.mouse_focus && !gui.forced_mouse_focus) { - _drop_mouse_focus(); + last_pos = pos; } - } break; + } +#endif } } @@ -1416,18 +1417,26 @@ Ref<ViewportTexture> Viewport::get_texture() const { } void Viewport::set_shadow_atlas_size(int p_size) { - if (shadow_atlas_size == p_size) { - return; - } - shadow_atlas_size = p_size; - RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size); + RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size, shadow_atlas_16_bits); } int Viewport::get_shadow_atlas_size() const { return shadow_atlas_size; } +void Viewport::set_shadow_atlas_16_bits(bool p_16_bits) { + if (shadow_atlas_16_bits == p_16_bits) { + return; + } + + shadow_atlas_16_bits = p_16_bits; + RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, shadow_atlas_size, shadow_atlas_16_bits); +} + +bool Viewport::get_shadow_atlas_16_bits() const { + return shadow_atlas_16_bits; +} void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) { ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); @@ -1580,7 +1589,8 @@ void Viewport::_gui_show_tooltip() { Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset"); Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size()); - Rect2i vr = gui.tooltip_popup->get_usable_parent_rect(); + Window *window = gui.tooltip_popup->get_parent_visible_window(); + Rect2i vr = window->get_usable_parent_rect(); if (r.size.x + r.position.x > vr.size.x + vr.position.x) { r.position.x = vr.position.x + vr.size.x - r.size.x; @@ -1594,6 +1604,7 @@ void Viewport::_gui_show_tooltip() { r.position.y = vr.position.y; } + gui.tooltip_popup->set_current_screen(window->get_current_screen()); gui.tooltip_popup->set_position(r.position); gui.tooltip_popup->set_size(r.size); @@ -1759,19 +1770,22 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_ } } - if (!c) { + if (!c || c->data.mouse_filter == Control::MOUSE_FILTER_IGNORE) { return nullptr; } matrix.affine_invert(); + if (!c->has_point(matrix.xform(p_global))) { + return nullptr; + } - //conditions for considering this as a valid control for return - if (c->data.mouse_filter != Control::MOUSE_FILTER_IGNORE && c->has_point(matrix.xform(p_global)) && (!gui.drag_preview || (c != gui.drag_preview && !gui.drag_preview->is_a_parent_of(c)))) { + Control *drag_preview = _gui_get_drag_preview(); + if (!drag_preview || (c != drag_preview && !drag_preview->is_a_parent_of(c))) { r_inv_xform = matrix; return c; - } else { - return nullptr; } + + return nullptr; } bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check) { @@ -1909,9 +1923,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.drag_data = Variant(); gui.dragging = false; - if (gui.drag_preview) { - memdelete(gui.drag_preview); - gui.drag_preview = nullptr; + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { + memdelete(drag_preview); + gui.drag_preview_id = ObjectID(); } _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); //change mouse accordingly @@ -1924,9 +1939,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false); } - if (gui.drag_preview && mb->get_button_index() == BUTTON_LEFT) { - memdelete(gui.drag_preview); - gui.drag_preview = nullptr; + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { + memdelete(drag_preview); + gui.drag_preview_id = ObjectID(); } gui.drag_data = Variant(); @@ -2023,10 +2039,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.mouse_focus_mask = 0; break; } else { - if (gui.drag_preview != nullptr) { + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { ERR_PRINT("Don't set a drag preview and return null data. Preview was deleted and drag request ignored."); - memdelete(gui.drag_preview); - gui.drag_preview = nullptr; + memdelete(drag_preview); + gui.drag_preview_id = ObjectID(); } gui.dragging = false; } @@ -2166,8 +2183,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.drag_data.get_type() != Variant::NIL) { //handle dragandrop - if (gui.drag_preview) { - gui.drag_preview->set_position(mpos); + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { + drag_preview->set_position(mpos); } gui.drag_mouse_over = over; @@ -2442,15 +2460,29 @@ void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) { ERR_FAIL_COND(p_control->is_inside_tree()); ERR_FAIL_COND(p_control->get_parent() != nullptr); - if (gui.drag_preview) { - memdelete(gui.drag_preview); + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { + memdelete(drag_preview); } p_control->set_as_top_level(true); p_control->set_position(gui.last_mouse_pos); p_base->get_root_parent_control()->add_child(p_control); //add as child of viewport p_control->raise(); - gui.drag_preview = p_control; + gui.drag_preview_id = p_control->get_instance_id(); +} + +Control *Viewport::_gui_get_drag_preview() { + if (gui.drag_preview_id.is_null()) { + return nullptr; + } else { + Control *drag_preview = Object::cast_to<Control>(ObjectDB::get_instance(gui.drag_preview_id)); + if (!drag_preview) { + ERR_PRINT("Don't free the control set as drag preview."); + gui.drag_preview_id = ObjectID(); + } + return drag_preview; + } } void Viewport::_gui_remove_root_control(List<Control *>::Element *RI) { @@ -2572,28 +2604,41 @@ void Viewport::_drop_mouse_focus() { } } -void Viewport::_drop_physics_mouseover() { +void Viewport::_drop_physics_mouseover(bool p_paused_only) { physics_has_last_mousepos = false; - while (physics_2d_mouseover.size()) { - Object *o = ObjectDB::get_instance(physics_2d_mouseover.front()->key()); + List<Map<ObjectID, uint64_t>::Element *> to_erase; + + for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { + Object *o = ObjectDB::get_instance(E->key()); if (o) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - co->_mouse_exit(); + if (co) { + if (p_paused_only && co->can_process()) { + continue; + } + co->_mouse_exit(); + to_erase.push_back(E); + } } - physics_2d_mouseover.erase(physics_2d_mouseover.front()); + } + + while (to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); } #ifndef _3D_DISABLED if (physics_object_over.is_valid()) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); if (co) { - co->_mouse_exit(); + if (!(p_paused_only && co->can_process())) { + co->_mouse_exit(); + physics_object_over = ObjectID(); + physics_object_capture = ObjectID(); + } } } - - physics_object_over = ObjectID(); - physics_object_capture = ObjectID(); #endif } @@ -3479,6 +3524,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size); ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size); + ClassDB::bind_method(D_METHOD("set_shadow_atlas_16_bits", "enable"), &Viewport::set_shadow_atlas_16_bits); + ClassDB::bind_method(D_METHOD("get_shadow_atlas_16_bits"), &Viewport::get_shadow_atlas_16_bits); + ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels); ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled); @@ -3516,6 +3564,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_threshold", "pixels"), &Viewport::set_lod_threshold); ClassDB::bind_method(D_METHOD("get_lod_threshold"), &Viewport::get_lod_threshold); + ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); @@ -3546,6 +3596,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale"); ADD_GROUP("Shadow Atlas", "shadow_atlas_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_atlas_16_bits"), "set_shadow_atlas_16_bits", "get_shadow_atlas_16_bits"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2); @@ -3603,6 +3654,10 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_SDFGI_PROBES); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_BUFFER); BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLE_LOD); + BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_OMNI_LIGHTS); + BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_SPOT_LIGHTS); + BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_DECALS); + BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_REFLECTION_PROBES); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR); @@ -3638,25 +3693,12 @@ Viewport::Viewport() { viewport_textures.insert(default_texture.ptr()); default_texture->proxy = RS::get_singleton()->texture_proxy_create(texture_rid); - audio_listener = false; //internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create(); - audio_listener_2d = false; - transparent_bg = false; - parent = nullptr; - listener = nullptr; - camera = nullptr; - override_canvas_transform = false; canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport) - gen_mipmaps = false; - //clear=true; + set_shadow_atlas_size(shadow_atlas_size); - physics_object_picking = false; - physics_has_last_mousepos = false; - physics_last_mousepos = Vector2(Math_INF, Math_INF); - - shadow_atlas_size = 0; for (int i = 0; i < 4; i++) { shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX; } @@ -3673,50 +3715,11 @@ Viewport::Viewport() { unhandled_input_group = "_vp_unhandled_input" + id; unhandled_key_input_group = "_vp_unhandled_key_input" + id; - disable_input = false; - // Window tooltip. - gui.tooltip_timer = -1; - gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers - gui.tooltip_control = nullptr; - gui.tooltip_label = nullptr; - gui.drag_preview = nullptr; - gui.drag_attempted = false; - gui.canvas_sort_index = 0; - gui.roots_order_dirty = false; - gui.mouse_focus = nullptr; - gui.forced_mouse_focus = false; - gui.last_mouse_focus = nullptr; - gui.subwindow_focused = nullptr; - gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED; - - msaa = MSAA_DISABLED; - screen_space_aa = SCREEN_SPACE_AA_DISABLED; - debug_draw = DEBUG_DRAW_DISABLED; - - snap_controls_to_pixels = true; - snap_2d_transforms_to_pixel = false; - snap_2d_vertices_to_pixel = false; - - physics_last_mouse_state.alt = false; - physics_last_mouse_state.control = false; - physics_last_mouse_state.shift = false; - physics_last_mouse_state.meta = false; - physics_last_mouse_state.mouse_mask = 0; - local_input_handled = false; - handle_input_locally = true; - - size_allocated = false; - - default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; - default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - - sdf_oversize = SDF_OVERSIZE_120_PERCENT; - sdf_scale = SDF_SCALE_50_PERCENT; - set_sdf_oversize(SDF_OVERSIZE_120_PERCENT); //set to server + set_sdf_oversize(sdf_oversize); //set to server } Viewport::~Viewport() { @@ -3848,12 +3851,6 @@ void SubViewport::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_ALWAYS); } -SubViewport::SubViewport() { - xr = false; - size_2d_override_stretch = false; - update_mode = UPDATE_WHEN_VISIBLE; - clear_mode = CLEAR_MODE_ALWAYS; -} +SubViewport::SubViewport() {} -SubViewport::~SubViewport() { -} +SubViewport::~SubViewport() {} diff --git a/scene/main/viewport.h b/scene/main/viewport.h index f0818a9fed..0f11e6fb19 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -56,7 +56,7 @@ class ViewportTexture : public Texture2D { NodePath path; friend class Viewport; - Viewport *vp; + Viewport *vp = nullptr; mutable RID proxy_ph; mutable RID proxy; @@ -143,6 +143,10 @@ public: DEBUG_DRAW_SDFGI_PROBES, DEBUG_DRAW_GI_BUFFER, DEBUG_DRAW_DISABLE_LOD, + DEBUG_DRAW_CLUSTER_OMNI_LIGHTS, + DEBUG_DRAW_CLUSTER_SPOT_LIGHTS, + DEBUG_DRAW_CLUSTER_DECALS, + DEBUG_DRAW_CLUSTER_REFLECTION_PROBES, }; enum DefaultCanvasItemTextureFilter { @@ -182,9 +186,9 @@ public: private: friend class ViewportTexture; - Viewport *parent; + Viewport *parent = nullptr; - Listener3D *listener; + Listener3D *listener = nullptr; Set<Listener3D *> listeners; struct CameraOverrideData { @@ -193,11 +197,11 @@ private: PROJECTION_PERSPECTIVE, PROJECTION_ORTHOGONAL }; - Projection projection; - float fov; - float size; - float z_near; - float z_far; + Projection projection = Projection::PROJECTION_PERSPECTIVE; + float fov = 0.0; + float size = 0.0; + float z_near = 0.0; + float z_far = 0.0; RID rid; operator bool() const { @@ -205,7 +209,7 @@ private: } } camera_override; - Camera3D *camera; + Camera3D *camera = nullptr; Set<Camera3D *> cameras; Set<CanvasLayer *> canvas_layers; @@ -213,13 +217,13 @@ private: RID current_canvas; RID subwindow_canvas; - bool audio_listener; + bool audio_listener = false; RID internal_listener; - bool audio_listener_2d; + bool audio_listener_2d = false; RID internal_listener_2d; - bool override_canvas_transform; + bool override_canvas_transform = false; Transform2D canvas_transform_override; Transform2D canvas_transform; @@ -228,7 +232,7 @@ private: Size2i size; Size2i size_2d_override; - bool size_allocated; + bool size_allocated = false; RID contact_2d_debug; RID contact_3d_debug_multimesh; @@ -236,36 +240,36 @@ private: Rect2 last_vp_rect; - bool transparent_bg; + bool transparent_bg = false; bool filter; - bool gen_mipmaps; + bool gen_mipmaps = false; - bool snap_controls_to_pixels; - bool snap_2d_transforms_to_pixel; - bool snap_2d_vertices_to_pixel; + bool snap_controls_to_pixels = true; + bool snap_2d_transforms_to_pixel = false; + bool snap_2d_vertices_to_pixel = false; - bool physics_object_picking; + bool physics_object_picking = false; List<Ref<InputEvent>> physics_picking_events; ObjectID physics_object_capture; ObjectID physics_object_over; Transform physics_last_object_transform; Transform physics_last_camera_transform; ObjectID physics_last_id; - bool physics_has_last_mousepos; - Vector2 physics_last_mousepos; + bool physics_has_last_mousepos = false; + Vector2 physics_last_mousepos = Vector2(Math_INF, Math_INF); struct { - bool alt; - bool control; - bool shift; - bool meta; - int mouse_mask; + bool alt = false; + bool control = false; + bool shift = false; + bool meta = false; + int mouse_mask = 0; } physics_last_mouse_state; void _collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape); - bool handle_input_locally; - bool local_input_handled; + bool handle_input_locally = true; + bool local_input_handled = false; Map<ObjectID, uint64_t> physics_2d_mouseover; @@ -290,21 +294,22 @@ private: RID texture_rid; - DebugDraw debug_draw; + DebugDraw debug_draw = DEBUG_DRAW_DISABLED; - int shadow_atlas_size; + int shadow_atlas_size = 2048; + bool shadow_atlas_16_bits = true; ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; - MSAA msaa; - ScreenSpaceAA screen_space_aa; + MSAA msaa = MSAA_DISABLED; + ScreenSpaceAA screen_space_aa = SCREEN_SPACE_AA_DISABLED; bool use_debanding = false; float lod_threshold = 1.0; Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; - SDFOversize sdf_oversize; - SDFScale sdf_scale; + SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT; + SDFScale sdf_scale = SDF_SCALE_50_PERCENT; enum SubWindowDrag { SUB_WINDOW_DRAG_DISABLED, @@ -327,60 +332,58 @@ private: }; struct SubWindow { - Window *window; + Window *window = nullptr; RID canvas_item; }; struct GUI { // info used when this is a window - bool forced_mouse_focus; //used for menu buttons - bool key_event_accepted; - Control *mouse_focus; - Control *last_mouse_focus; - Control *mouse_click_grabber; - int mouse_focus_mask; - Control *key_focus; - Control *mouse_over; - Control *drag_mouse_over; + bool forced_mouse_focus = false; //used for menu buttons + bool key_event_accepted = false; + Control *mouse_focus = nullptr; + Control *last_mouse_focus = nullptr; + Control *mouse_click_grabber = nullptr; + int mouse_focus_mask = 0; + Control *key_focus = nullptr; + Control *mouse_over = nullptr; + Control *drag_mouse_over = nullptr; Vector2 drag_mouse_over_pos; - Control *tooltip_control; - Window *tooltip_popup; - Label *tooltip_label; + Control *tooltip_control = nullptr; + Window *tooltip_popup = nullptr; + Label *tooltip_label = nullptr; Point2 tooltip_pos; Point2 last_mouse_pos; Point2 drag_accum; - bool drag_attempted; + bool drag_attempted = false; Variant drag_data; - Control *drag_preview; - float tooltip_timer; - float tooltip_delay; + ObjectID drag_preview_id; + float tooltip_timer = -1.0; + float tooltip_delay = 0.0; Transform2D focus_inv_xform; - bool roots_order_dirty; + bool roots_order_dirty = false; List<Control *> roots; - int canvas_sort_index; //for sorting items with canvas as root - bool dragging; - bool embed_subwindows_hint; - bool embedding_subwindows; + int canvas_sort_index = 0; //for sorting items with canvas as root + bool dragging = false; + bool embed_subwindows_hint = false; + bool embedding_subwindows = false; - Window *subwindow_focused; - SubWindowDrag subwindow_drag; + Window *subwindow_focused = nullptr; + SubWindowDrag subwindow_drag = SUB_WINDOW_DRAG_DISABLED; Vector2 subwindow_drag_from; Vector2 subwindow_drag_pos; Rect2i subwindow_drag_close_rect; - bool subwindow_drag_close_inside; + bool subwindow_drag_close_inside = false; SubWindowResize subwindow_resize_mode; Rect2i subwindow_resize_from_rect; Vector<SubWindow> sub_windows; - - GUI(); } gui; - DefaultCanvasItemTextureFilter default_canvas_item_texture_filter; - DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat; + DefaultCanvasItemTextureFilter default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; + DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - bool disable_input; + bool disable_input = false; void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input); void _gui_call_notification(Control *p_control, int p_what); @@ -412,6 +415,7 @@ private: void _gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control); void _gui_set_drag_preview(Control *p_base, Control *p_control); + Control *_gui_get_drag_preview(); void _gui_remove_focus_for_window(Node *p_window); void _gui_remove_focus(); @@ -445,7 +449,7 @@ private: void _canvas_layer_remove(CanvasLayer *p_canvas_layer); void _drop_mouse_focus(); - void _drop_physics_mouseover(); + void _drop_physics_mouseover(bool p_paused_only = false); void _update_canvas_items(Node *p_node); @@ -474,6 +478,7 @@ protected: bool _is_size_allocated() const; void _notification(int p_what); + void _process_picking(); static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; @@ -533,6 +538,9 @@ public: void set_shadow_atlas_size(int p_size); int get_shadow_atlas_size() const; + void set_shadow_atlas_16_bits(bool p_16_bits); + bool get_shadow_atlas_16_bits() const; + void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv); ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const; @@ -642,10 +650,10 @@ public: }; private: - UpdateMode update_mode; - ClearMode clear_mode; - bool xr; - bool size_2d_override_stretch; + UpdateMode update_mode = UPDATE_WHEN_VISIBLE; + ClearMode clear_mode = CLEAR_MODE_ALWAYS; + bool xr = false; + bool size_2d_override_stretch = false; protected: static void _bind_methods(); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 0a541a2d07..e40e990cf7 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -881,10 +881,6 @@ bool Window::_can_consume_input_events() const { } void Window::_window_input(const Ref<InputEvent> &p_ev) { - if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) { - return; //avoid joy input on editor - } - if (EngineDebugger::is_active()) { //quit from game window using F8 Ref<InputEventKey> k = p_ev; @@ -1039,6 +1035,9 @@ void Window::popup_centered_ratio(float p_ratio) { void Window::popup(const Rect2i &p_screen_rect) { emit_signal("about_to_popup"); + // Update window size to calculate the actual window size based on contents minimum size and minimum size. + _update_window_size(); + if (p_screen_rect != Rect2i()) { set_position(p_screen_rect.position); set_size(p_screen_rect.size); @@ -1283,14 +1282,14 @@ bool Window::is_layout_rtl() const { if (parent) { return parent->is_layout_rtl(); } else { - if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) { + if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) { return true; } String locale = TranslationServer::get_singleton()->get_tool_locale(); return TS->is_locale_right_to_left(locale); } } else if (layout_dir == LAYOUT_DIRECTION_LOCALE) { - if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) { + if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) { return true; } String locale = TranslationServer::get_singleton()->get_tool_locale(); @@ -1349,8 +1348,8 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus); ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus); - ClassDB::bind_method(D_METHOD("set_ime_active"), &Window::set_ime_active); - ClassDB::bind_method(D_METHOD("set_ime_position"), &Window::set_ime_position); + ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &Window::set_ime_active); + ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &Window::set_ime_position); ClassDB::bind_method(D_METHOD("is_embedded"), &Window::is_embedded); @@ -1466,11 +1465,6 @@ void Window::_bind_methods() { } Window::Window() { - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; - } - content_scale_mode = CONTENT_SCALE_MODE_DISABLED; - content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED); } diff --git a/scene/main/window.h b/scene/main/window.h index 2ffeff03ff..38846ed00e 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -90,7 +90,7 @@ private: mutable Size2i min_size; mutable Size2i max_size; mutable Mode mode = MODE_WINDOWED; - mutable bool flags[FLAG_MAX]; + mutable bool flags[FLAG_MAX] = {}; bool visible = true; bool focused = false; @@ -106,8 +106,8 @@ private: void _update_child_controls(); Size2i content_scale_size; - ContentScaleMode content_scale_mode; - ContentScaleAspect content_scale_aspect; + ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED; + ContentScaleAspect content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; void _make_window(); void _clear_window(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index b809eea43b..51d4643883 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -175,6 +175,7 @@ #include "scene/resources/video_stream.h" #include "scene/resources/visual_shader.h" #include "scene/resources/visual_shader_nodes.h" +#include "scene/resources/visual_shader_sdf_nodes.h" #include "scene/resources/world_2d.h" #include "scene/resources/world_3d.h" #include "scene/resources/world_margin_shape_3d.h" @@ -533,6 +534,7 @@ void register_scene_types() { ClassDB::register_virtual_class<VisualShaderNodeOutput>(); ClassDB::register_virtual_class<VisualShaderNodeResizableBase>(); ClassDB::register_virtual_class<VisualShaderNodeGroupBase>(); + ClassDB::register_virtual_class<VisualShaderNodeConstant>(); ClassDB::register_class<VisualShaderNodeFloatConstant>(); ClassDB::register_class<VisualShaderNodeIntConstant>(); ClassDB::register_class<VisualShaderNodeBooleanConstant>(); @@ -555,19 +557,14 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeDeterminant>(); ClassDB::register_class<VisualShaderNodeScalarDerivativeFunc>(); ClassDB::register_class<VisualShaderNodeVectorDerivativeFunc>(); - ClassDB::register_class<VisualShaderNodeScalarClamp>(); - ClassDB::register_class<VisualShaderNodeVectorClamp>(); + ClassDB::register_class<VisualShaderNodeClamp>(); ClassDB::register_class<VisualShaderNodeFaceForward>(); ClassDB::register_class<VisualShaderNodeOuterProduct>(); - ClassDB::register_class<VisualShaderNodeVectorScalarStep>(); - ClassDB::register_class<VisualShaderNodeScalarSmoothStep>(); - ClassDB::register_class<VisualShaderNodeVectorSmoothStep>(); - ClassDB::register_class<VisualShaderNodeVectorScalarSmoothStep>(); + ClassDB::register_class<VisualShaderNodeSmoothStep>(); + ClassDB::register_class<VisualShaderNodeStep>(); ClassDB::register_class<VisualShaderNodeVectorDistance>(); ClassDB::register_class<VisualShaderNodeVectorRefract>(); - ClassDB::register_class<VisualShaderNodeScalarInterp>(); - ClassDB::register_class<VisualShaderNodeVectorInterp>(); - ClassDB::register_class<VisualShaderNodeVectorScalarMix>(); + ClassDB::register_class<VisualShaderNodeMix>(); ClassDB::register_class<VisualShaderNodeVectorCompose>(); ClassDB::register_class<VisualShaderNodeTransformCompose>(); ClassDB::register_class<VisualShaderNodeVectorDecompose>(); @@ -593,7 +590,6 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeCubemapUniform>(); ClassDB::register_class<VisualShaderNodeIf>(); ClassDB::register_class<VisualShaderNodeSwitch>(); - ClassDB::register_class<VisualShaderNodeScalarSwitch>(); ClassDB::register_class<VisualShaderNodeFresnel>(); ClassDB::register_class<VisualShaderNodeExpression>(); ClassDB::register_class<VisualShaderNodeGlobalExpression>(); @@ -601,6 +597,12 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeCompare>(); ClassDB::register_class<VisualShaderNodeMultiplyAdd>(); + ClassDB::register_class<VisualShaderNodeSDFToScreenUV>(); + ClassDB::register_class<VisualShaderNodeScreenUVToSDF>(); + ClassDB::register_class<VisualShaderNodeTextureSDF>(); + ClassDB::register_class<VisualShaderNodeTextureSDFNormal>(); + ClassDB::register_class<VisualShaderNodeSDFRaymarch>(); + ClassDB::register_class<ShaderMaterial>(); ClassDB::register_virtual_class<CanvasItem>(); ClassDB::register_class<CanvasTexture>(); @@ -927,6 +929,16 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarClamp", "VisualShaderNodeClamp"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorClamp", "VisualShaderNodeClamp"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarInterp", "VisualShaderNodeMix"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorInterp", "VisualShaderNodeMix"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarMix", "VisualShaderNodeMix"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarSmoothStep", "VisualShaderNodeSmoothStep"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorSmoothStep", "VisualShaderNodeSmoothStep"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarSmoothStep", "VisualShaderNodeSmoothStep"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarStep", "VisualShaderNodeStep"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch"); ClassDB::add_compatibility_class("World", "World3D"); ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); ClassDB::add_compatibility_class("Light2D", "PointLight2D"); @@ -936,10 +948,10 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init for (int i = 0; i < 20; i++) { - GLOBAL_DEF(vformat("layer_names/2d_render/layer_%d", i), ""); - GLOBAL_DEF(vformat("layer_names/2d_physics/layer_%d", i), ""); - GLOBAL_DEF(vformat("layer_names/3d_render/layer_%d", i), ""); - GLOBAL_DEF(vformat("layer_names/3d_physics/layer_%d", i), ""); + GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i), ""); + GLOBAL_DEF_BASIC(vformat("layer_names/2d_physics/layer_%d", i), ""); + GLOBAL_DEF_BASIC(vformat("layer_names/3d_render/layer_%d", i), ""); + GLOBAL_DEF_BASIC(vformat("layer_names/3d_physics/layer_%d", i), ""); } bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 796fe1d106..cc1dafd0db 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -580,6 +580,10 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const { } } +void Animation::reset_state() { + clear(); +} + int Animation::add_track(TrackType p_type, int p_at_pos) { if (p_at_pos < 0 || p_at_pos >= tracks.size()) { p_at_pos = tracks.size(); @@ -1604,7 +1608,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola bool result = true; int next = 0; - float c = 0; + float c = 0.0; // prepare for all cases of interpolation if (loop && p_loop_wrap) { @@ -2278,8 +2282,8 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { int iterations = 10; float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes - float low = 0; // 0% of the current animation segment - float high = 1; // 100% of the current animation segment + float low = 0.0; // 0% of the current animation segment + float high = 1.0; // 100% of the current animation segment float middle; Vector2 start(0, bt->values[idx].value.value); @@ -2836,7 +2840,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons erase = true; } else { erase = true; - real_t lt = -1; + real_t lt = -1.0; for (int j = 0; j < 3; j++) { //search for t on first, one must be it if (t[j] != -1) { @@ -2919,11 +2923,7 @@ void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err } } -Animation::Animation() { - step = 0.1; - loop = false; - length = 1; -} +Animation::Animation() {} Animation::~Animation() { for (int i = 0; i < tracks.size(); i++) { diff --git a/scene/resources/animation.h b/scene/resources/animation.h index fa374e6ad2..fd22cc445c 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -65,28 +65,19 @@ public: private: struct Track { - TrackType type; - InterpolationType interpolation; - bool loop_wrap; + TrackType type = TrackType::TYPE_ANIMATION; + InterpolationType interpolation = INTERPOLATION_LINEAR; + bool loop_wrap = true; NodePath path; // path to something - bool imported; - bool enabled; - Track() { - interpolation = INTERPOLATION_LINEAR; - imported = false; - loop_wrap = true; - enabled = true; - } + bool imported = false; + bool enabled = false; + Track() {} virtual ~Track() {} }; struct Key { - float transition; - float time; // time in secs - Key() { - transition = 1; - time = 0; - } + float transition = 1.0; + float time = 0.0; // time in secs }; // transform key holds either Vector3 or Quaternion @@ -112,13 +103,12 @@ private: /* PROPERTY VALUE TRACK */ struct ValueTrack : public Track { - UpdateMode update_mode; - bool update_on_seek; + UpdateMode update_mode = UPDATE_CONTINUOUS; + bool update_on_seek = false; Vector<TKey<Variant>> values; ValueTrack() { type = TYPE_VALUE; - update_mode = UPDATE_CONTINUOUS; } }; @@ -139,7 +129,7 @@ private: struct BezierKey { Vector2 in_handle; //relative (x always <0) Vector2 out_handle; //relative (x always >0) - float value; + float value = 0.0; }; struct BezierTrack : public Track { @@ -154,11 +144,9 @@ private: struct AudioKey { RES stream; - float start_offset; //offset from start - float end_offset; //offset from end, if 0 then full length or infinite + float start_offset = 0.0; //offset from start + float end_offset = 0.0; //offset from end, if 0 then full length or infinite AudioKey() { - start_offset = 0; - end_offset = 0; } }; @@ -217,9 +205,9 @@ private: _FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const; _FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const; - float length; - float step; - bool loop; + float length = 1.0; + float step = 0.1; + bool loop = false; // bind helpers private: @@ -264,6 +252,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + static void _bind_methods(); public: diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index 8fdb004e65..06a91fb2f8 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -403,11 +403,7 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in } } -AudioStreamPlaybackSample::AudioStreamPlaybackSample() { - active = false; - offset = 0; - sign = 1; -} +AudioStreamPlaybackSample::AudioStreamPlaybackSample() {} ///////////////////// @@ -651,16 +647,7 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_BACKWARD); } -AudioStreamSample::AudioStreamSample() { - format = FORMAT_8_BITS; - loop_mode = LOOP_DISABLED; - stereo = false; - loop_begin = 0; - loop_end = 0; - mix_rate = 44100; - data = nullptr; - data_bytes = 0; -} +AudioStreamSample::AudioStreamSample() {} AudioStreamSample::~AudioStreamSample() { if (data) { diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index ba475c0888..70b8ba79ad 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -44,19 +44,19 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback { }; struct IMA_ADPCM_State { - int16_t step_index; - int32_t predictor; + int16_t step_index = 0; + int32_t predictor = 0; /* values at loop point */ - int16_t loop_step_index; - int32_t loop_predictor; - int32_t last_nibble; - int32_t loop_pos; - int32_t window_ofs; + int16_t loop_step_index = 0; + int32_t loop_predictor = 0; + int32_t last_nibble = 0; + int32_t loop_pos = 0; + int32_t window_ofs = 0; } ima_adpcm[2]; - int64_t offset; - int sign; - bool active; + int64_t offset = 0; + int sign = 1; + bool active = false; friend class AudioStreamSample; Ref<AudioStreamSample> base; @@ -103,14 +103,14 @@ private: DATA_PAD = 16 //padding for interpolation }; - Format format; - LoopMode loop_mode; - bool stereo; - int loop_begin; - int loop_end; - int mix_rate; - void *data; - uint32_t data_bytes; + Format format = FORMAT_8_BITS; + LoopMode loop_mode = LOOP_DISABLED; + bool stereo = false; + int loop_begin = 0; + int loop_end = 0; + int mix_rate = 44100; + void *data = nullptr; + uint32_t data_bytes = 0; protected: static void _bind_methods(); diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index dfb7a1fdfb..8ffc7b4b4c 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -346,7 +346,7 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) { } int index = -1; - float dist = 0; + float dist = 0.0; //not looping first and last point for (size_t i = 1, size = v.size(); i < size - 1; ++i) { float cdist = perpendicular_distance(v[i], v[0], v[v.size() - 1]); @@ -406,8 +406,8 @@ static Vector<Vector2> reduce(const Vector<Vector2> &points, const Rect2i &rect, struct FillBitsStackEntry { Point2i pos; - int i; - int j; + int i = 0; + int j = 0; }; static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) { @@ -677,9 +677,6 @@ void BitMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); } -BitMap::BitMap() { - width = 0; - height = 0; -} +BitMap::BitMap() {} ////////////////////////////////////// diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index 7414265cee..68fd0b999a 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -40,8 +40,8 @@ class BitMap : public Resource { OBJ_SAVE_TYPE(BitMap); Vector<uint8_t> bitmask; - int width; - int height; + int width = 0; + int height = 0; Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const; diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp index fadbf21e43..6e7adc0bd7 100644 --- a/scene/resources/box_shape_3d.cpp +++ b/scene/resources/box_shape_3d.cpp @@ -60,7 +60,6 @@ void BoxShape3D::set_size(const Vector3 &p_size) { size = p_size; _update_shape(); notify_change_to_owners(); - _change_notify("size"); } Vector3 BoxShape3D::get_size() const { diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp index 695b14939f..4038338e1e 100644 --- a/scene/resources/camera_effects.cpp +++ b/scene/resources/camera_effects.cpp @@ -41,7 +41,7 @@ RID CameraEffects::get_rid() const { void CameraEffects::set_dof_blur_far_enabled(bool p_enabled) { dof_blur_far_enabled = p_enabled; _update_dof_blur(); - _change_notify(); + notify_property_list_changed(); } bool CameraEffects::is_dof_blur_far_enabled() const { @@ -69,7 +69,7 @@ float CameraEffects::get_dof_blur_far_transition() const { void CameraEffects::set_dof_blur_near_enabled(bool p_enabled) { dof_blur_near_enabled = p_enabled; _update_dof_blur(); - _change_notify(); + notify_property_list_changed(); } bool CameraEffects::is_dof_blur_near_enabled() const { diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h index cf12b6d3c0..28aa6b8660 100644 --- a/scene/resources/camera_effects.h +++ b/scene/resources/camera_effects.h @@ -42,12 +42,12 @@ private: // DOF blur bool dof_blur_far_enabled = false; - float dof_blur_far_distance = 10; - float dof_blur_far_transition = 5; + float dof_blur_far_distance = 10.0; + float dof_blur_far_transition = 5.0; bool dof_blur_near_enabled = false; - float dof_blur_near_distance = 2; - float dof_blur_near_transition = 1; + float dof_blur_near_distance = 2.0; + float dof_blur_near_transition = 1.0; float dof_blur_amount = 0.1; void _update_dof_blur(); diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 6041f4a8b0..e5edba8a67 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -36,12 +36,13 @@ Vector<Vector2> CapsuleShape2D::_get_points() const { Vector<Vector2> points; + const real_t turn_step = Math_TAU / 24.0; for (int i = 0; i < 24; i++) { Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5); - points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs); + points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * get_radius() + ofs); if (i == 6 || i == 18) { - points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs); + points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * get_radius() - ofs); } } @@ -84,6 +85,11 @@ void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector<Color> col; col.push_back(p_color); RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col); + if (is_collision_outline_enabled()) { + RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col); + // Draw the last segment as it's not drawn by `canvas_item_add_polyline()`. + RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color); + } } Rect2 CapsuleShape2D::get_rect() const { @@ -111,7 +117,5 @@ void CapsuleShape2D::_bind_methods() { CapsuleShape2D::CapsuleShape2D() : Shape2D(PhysicsServer2D::get_singleton()->capsule_shape_create()) { - radius = 10; - height = 20; _update_shape(); } diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h index 8c8c1b259b..439b67e8c3 100644 --- a/scene/resources/capsule_shape_2d.h +++ b/scene/resources/capsule_shape_2d.h @@ -36,8 +36,8 @@ class CapsuleShape2D : public Shape2D { GDCLASS(CapsuleShape2D, Shape2D); - real_t height; - real_t radius; + real_t height = 20.0; + real_t radius = 10.0; void _update_shape(); Vector<Vector2> _get_points() const; diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index a0b454a00f..226fe1ecd2 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -82,7 +82,6 @@ void CapsuleShape3D::set_radius(float p_radius) { radius = p_radius; _update_shape(); notify_change_to_owners(); - _change_notify("radius"); } float CapsuleShape3D::get_radius() const { @@ -93,7 +92,6 @@ void CapsuleShape3D::set_height(float p_height) { height = p_height; _update_shape(); notify_change_to_owners(); - _change_notify("height"); } float CapsuleShape3D::get_height() const { @@ -112,7 +110,5 @@ void CapsuleShape3D::_bind_methods() { CapsuleShape3D::CapsuleShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CAPSULE)) { - radius = 1.0; - height = 1.0; _update_shape(); } diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h index b5b8912445..25645ecf9d 100644 --- a/scene/resources/capsule_shape_3d.h +++ b/scene/resources/capsule_shape_3d.h @@ -35,8 +35,8 @@ class CapsuleShape3D : public Shape3D { GDCLASS(CapsuleShape3D, Shape3D); - float radius; - float height; + float radius = 1.0; + float height = 1.0; protected: static void _bind_methods(); diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index ba49587d9d..f06bc4248d 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -71,17 +71,22 @@ real_t CircleShape2D::get_enclosing_radius() const { void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector<Vector2> points; + const real_t turn_step = Math_TAU / 24.0; for (int i = 0; i < 24; i++) { - points.push_back(Vector2(Math::cos(i * Math_PI * 2 / 24.0), Math::sin(i * Math_PI * 2 / 24.0)) * get_radius()); + points.push_back(Vector2(Math::cos(i * turn_step), Math::sin(i * turn_step)) * get_radius()); } Vector<Color> col; col.push_back(p_color); RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col); + if (is_collision_outline_enabled()) { + RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col); + // Draw the last segment as it's not drawn by `canvas_item_add_polyline()`. + RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color); + } } CircleShape2D::CircleShape2D() : Shape2D(PhysicsServer2D::get_singleton()->circle_shape_create()) { - radius = 10; _update_shape(); } diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h index a066b773ef..333f299236 100644 --- a/scene/resources/circle_shape_2d.h +++ b/scene/resources/circle_shape_2d.h @@ -36,7 +36,7 @@ class CircleShape2D : public Shape2D { GDCLASS(CircleShape2D, Shape2D); - real_t radius; + real_t radius = 10.0; void _update_shape(); protected: diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp index 3d6df3bb9c..0c767c8a52 100644 --- a/scene/resources/concave_polygon_shape_2d.cpp +++ b/scene/resources/concave_polygon_shape_2d.cpp @@ -98,7 +98,7 @@ Rect2 ConcavePolygonShape2D::get_rect() const { real_t ConcavePolygonShape2D::get_enclosing_radius() const { Vector<Vector2> data = get_segments(); const Vector2 *read = data.ptr(); - real_t r = 0; + real_t r = 0.0; for (int i(0); i < data.size(); i++) { r = MAX(read[i].length_squared(), r); } diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp index 358c99ad09..f067695d7d 100644 --- a/scene/resources/concave_polygon_shape_3d.cpp +++ b/scene/resources/concave_polygon_shape_3d.cpp @@ -63,7 +63,7 @@ Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const { real_t ConcavePolygonShape3D::get_enclosing_radius() const { Vector<Vector3> data = get_faces(); const Vector3 *read = data.ptr(); - real_t r = 0; + real_t r = 0.0; for (int i(0); i < data.size(); i++) { r = MAX(read[i].length_squared(), r); } diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index 656e064356..d331f83daf 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -75,6 +75,11 @@ void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector<Color> col; col.push_back(p_color); RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col); + if (is_collision_outline_enabled()) { + RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col); + // Draw the last segment as it's not drawn by `canvas_item_add_polyline()`. + RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color); + } } Rect2 ConvexPolygonShape2D::get_rect() const { @@ -91,7 +96,7 @@ Rect2 ConvexPolygonShape2D::get_rect() const { } real_t ConvexPolygonShape2D::get_enclosing_radius() const { - real_t r = 0; + real_t r = 0.0; for (int i(0); i < get_points().size(); i++) { r = MAX(get_points()[i].length_squared(), r); } diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp index 770d547231..9e030bc077 100644 --- a/scene/resources/convex_polygon_shape_3d.cpp +++ b/scene/resources/convex_polygon_shape_3d.cpp @@ -56,7 +56,7 @@ Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const { real_t ConvexPolygonShape3D::get_enclosing_radius() const { Vector<Vector3> data = get_points(); const Vector3 *read = data.ptr(); - real_t r = 0; + real_t r = 0.0; for (int i(0); i < data.size(); i++) { r = MAX(read[i].length_squared(), r); } diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 123c77a036..bc479e557a 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -47,11 +47,6 @@ static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed"; Curve::Curve() { - _bake_resolution = 100; - _baked_cache_dirty = false; - _min_value = 0; - _max_value = 1; - _minmax_set_once = 0b00; } int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) { @@ -683,7 +678,7 @@ void Curve2D::_bake() const { for (int i = 0; i < points.size() - 1; i++) { float step = 0.1; // at least 10 substeps ought to be enough? - float p = 0; + float p = 0.0; while (p < 1.0) { float np = p + step; @@ -993,12 +988,9 @@ void Curve2D::_bind_methods() { } Curve2D::Curve2D() { - baked_cache_dirty = false; - baked_max_ofs = 0; /* add_point(Vector2(-1,0,0)); add_point(Vector2(0,2,0)); add_point(Vector2(0,3,5));*/ - bake_interval = 5; } /***********************************************************************************/ @@ -1178,7 +1170,7 @@ void Curve3D::_bake() const { for (int i = 0; i < points.size() - 1; i++) { float step = 0.1; // at least 10 substeps ought to be enough? - float p = 0; + float p = 0.0; while (p < 1.0) { float np = p + step; @@ -1669,11 +1661,7 @@ void Curve3D::_bind_methods() { } Curve3D::Curve3D() { - baked_cache_dirty = false; - baked_max_ofs = 0; /* add_point(Vector3(-1,0,0)); add_point(Vector3(0,2,0)); add_point(Vector3(0,3,5));*/ - bake_interval = 0.2; - up_vector_enabled = true; } diff --git a/scene/resources/curve.h b/scene/resources/curve.h index f33f3c5abe..402c893cd8 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -51,21 +51,17 @@ public: struct Point { Vector2 pos; - real_t left_tangent; - real_t right_tangent; - TangentMode left_mode; - TangentMode right_mode; + real_t left_tangent = 0.0; + real_t right_tangent = 0.0; + TangentMode left_mode = TANGENT_FREE; + TangentMode right_mode = TANGENT_FREE; Point() { - left_tangent = 0; - right_tangent = 0; - left_mode = TANGENT_FREE; - right_mode = TANGENT_FREE; } Point(Vector2 p_pos, - real_t p_left = 0, - real_t p_right = 0, + real_t p_left = 0.0, + real_t p_right = 0.0, TangentMode p_left_mode = TANGENT_FREE, TangentMode p_right_mode = TANGENT_FREE) { pos = p_pos; @@ -137,12 +133,12 @@ private: void mark_dirty(); Vector<Point> _points; - bool _baked_cache_dirty; + bool _baked_cache_dirty = false; Vector<real_t> _baked_cache; - int _bake_resolution; - float _min_value; - float _max_value; - int _minmax_set_once; // Encodes whether min and max have been set a first time, first bit for min and second for max. + int _bake_resolution = 100; + float _min_value = 0.0; + float _max_value = 1.0; + int _minmax_set_once = 0b00; // Encodes whether min and max have been set a first time, first bit for min and second for max. }; VARIANT_ENUM_CAST(Curve::TangentMode) @@ -159,17 +155,17 @@ class Curve2D : public Resource { Vector<Point> points; struct BakedPoint { - float ofs; + float ofs = 0.0; Vector2 point; }; - mutable bool baked_cache_dirty; + mutable bool baked_cache_dirty = false; mutable PackedVector2Array baked_point_cache; - mutable float baked_max_ofs; + mutable float baked_max_ofs = 0.0; void _bake() const; - float bake_interval; + float bake_interval = 5.0; void _bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const; Dictionary _get_data() const; @@ -214,28 +210,26 @@ class Curve3D : public Resource { Vector3 in; Vector3 out; Vector3 pos; - float tilt; - - Point() { tilt = 0; } + float tilt = 0.0; }; Vector<Point> points; struct BakedPoint { - float ofs; + float ofs = 0.0; Vector3 point; }; - mutable bool baked_cache_dirty; + mutable bool baked_cache_dirty = false; mutable PackedVector3Array baked_point_cache; mutable PackedFloat32Array baked_tilt_cache; mutable PackedVector3Array baked_up_vector_cache; - mutable float baked_max_ofs; + mutable float baked_max_ofs = 0.0; void _bake() const; - float bake_interval; - bool up_vector_enabled; + float bake_interval = 0.2; + bool up_vector_enabled = true; void _bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const; Dictionary _get_data() const; diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp index 3e9cdca872..63bdc8d26d 100644 --- a/scene/resources/cylinder_shape_3d.cpp +++ b/scene/resources/cylinder_shape_3d.cpp @@ -75,7 +75,6 @@ void CylinderShape3D::set_radius(float p_radius) { radius = p_radius; _update_shape(); notify_change_to_owners(); - _change_notify("radius"); } float CylinderShape3D::get_radius() const { @@ -86,7 +85,6 @@ void CylinderShape3D::set_height(float p_height) { height = p_height; _update_shape(); notify_change_to_owners(); - _change_notify("height"); } float CylinderShape3D::get_height() const { @@ -105,7 +103,5 @@ void CylinderShape3D::_bind_methods() { CylinderShape3D::CylinderShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CYLINDER)) { - radius = 1.0; - height = 2.0; _update_shape(); } diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h index 93e8345727..d1b8364672 100644 --- a/scene/resources/cylinder_shape_3d.h +++ b/scene/resources/cylinder_shape_3d.h @@ -35,8 +35,8 @@ class CylinderShape3D : public Shape3D { GDCLASS(CylinderShape3D, Shape3D); - float radius; - float height; + float radius = 1.0; + float height = 2.0; protected: static void _bind_methods(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index dad5622117..a94209c75f 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -43,10 +43,10 @@ typedef Map<const void *, Ref<ImageTexture>> TexCacheMap; static TexCacheMap *tex_cache; -static float scale = 1; +static float scale = 1.0; template <class T> -static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) { +static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) { Ref<ImageTexture> texture; if (tex_cache->has(p_src)) { @@ -66,11 +66,11 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl style->set_texture(texture); style->set_margin_size(SIDE_LEFT, p_left * scale); style->set_margin_size(SIDE_RIGHT, p_right * scale); - style->set_margin_size(SIDE_BOTTOM, p_botton * scale); + style->set_margin_size(SIDE_BOTTOM, p_bottom * scale); style->set_margin_size(SIDE_TOP, p_top * scale); style->set_default_margin(SIDE_LEFT, p_margin_left * scale); style->set_default_margin(SIDE_RIGHT, p_margin_right * scale); - style->set_default_margin(SIDE_BOTTOM, p_margin_botton * scale); + style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * scale); style->set_default_margin(SIDE_TOP, p_margin_top * scale); style->set_draw_center(p_draw_center); @@ -88,11 +88,11 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = return style; } -static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_botton) { +static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_bottom) { p_sbox->set_expand_margin_size(SIDE_LEFT, p_left * scale); p_sbox->set_expand_margin_size(SIDE_TOP, p_top * scale); p_sbox->set_expand_margin_size(SIDE_RIGHT, p_right * scale); - p_sbox->set_expand_margin_size(SIDE_BOTTOM, p_botton * scale); + p_sbox->set_expand_margin_size(SIDE_BOTTOM, p_bottom * scale); return p_sbox; } @@ -115,6 +115,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, Ref<ImageTexture> texture(memnew(ImageTexture)); Ref<Image> img = p_texture->get_data(); + img = img->duplicate(); if (p_flip_y) { img->flip_y(); @@ -127,12 +128,44 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, return texture; } -static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1) { +static Ref<FontData> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) { + Ref<FontData> font(memnew(FontData)); + font->new_bitmap(p_height, p_ascent, p_height); + + Ref<Image> image = memnew(Image(p_img)); + Ref<ImageTexture> tex = memnew(ImageTexture); + tex->create_from_image(image); + + font->bitmap_add_texture(tex); + + for (int i = 0; i < p_charcount; i++) { + const int *c = &p_char_rects[i * 8]; + + int chr = c[0]; + Rect2 frect; + frect.position.x = c[1]; + frect.position.y = c[2]; + frect.size.x = c[3]; + frect.size.y = c[4]; + Point2 align(c[6], c[5]); + int advance = c[7]; + + font->bitmap_add_char(chr, 0, frect, align, advance); + } + + for (int i = 0; i < p_kerning_count; i++) { + font->bitmap_add_kerning_pair(p_kernings[i * 3 + 0], p_kernings[i * 3 + 1], p_kernings[i * 3 + 2]); + } + + return font; +} + +static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) { Ref<StyleBox> style(memnew(StyleBoxEmpty)); style->set_default_margin(SIDE_LEFT, p_margin_left * scale); style->set_default_margin(SIDE_RIGHT, p_margin_right * scale); - style->set_default_margin(SIDE_BOTTOM, p_margin_botton * scale); + style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * scale); style->set_default_margin(SIDE_TOP, p_margin_top * scale); return style; @@ -146,12 +179,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Font Colors Color control_font_color = Color(0.88, 0.88, 0.88); - Color control_font_color_lower = Color(0.63, 0.63, 0.63); - Color control_font_color_low = Color(0.69, 0.69, 0.69); - Color control_font_color_hover = Color(0.94, 0.94, 0.94); - Color control_font_color_disabled = Color(0.9, 0.9, 0.9, 0.2); - Color control_font_color_pressed = Color(1, 1, 1); - Color font_color_selection = Color(0.49, 0.49, 0.49); + Color control_font_lower_color = Color(0.63, 0.63, 0.63); + Color control_font_low_color = Color(0.69, 0.69, 0.69); + Color control_font_hover_color = Color(0.94, 0.94, 0.94); + Color control_font_disabled_color = Color(0.9, 0.9, 0.9, 0.2); + Color control_font_pressed_color = Color(1, 1, 1); + + Color control_selection_color = Color(0.49, 0.49, 0.49); // Panel @@ -184,10 +218,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("outline_size", "Button", 0 * scale); theme->set_color("font_color", "Button", control_font_color); - theme->set_color("font_color_pressed", "Button", control_font_color_pressed); - theme->set_color("font_color_hover", "Button", control_font_color_hover); - theme->set_color("font_color_disabled", "Button", control_font_color_disabled); - theme->set_color("font_outline_modulate", "Button", Color(1, 1, 1)); + theme->set_color("font_pressed_color", "Button", control_font_pressed_color); + theme->set_color("font_hover_color", "Button", control_font_hover_color); + theme->set_color("font_hover_pressed_color", "Button", control_font_pressed_color); + theme->set_color("font_disabled_color", "Button", control_font_disabled_color); + theme->set_color("font_outline_color", "Button", Color(1, 1, 1)); + + theme->set_color("icon_normal_color", "Button", Color(1, 1, 1, 1)); + theme->set_color("icon_pressed_color", "Button", Color(1, 1, 1, 1)); + theme->set_color("icon_hover_color", "Button", Color(1, 1, 1, 1)); + theme->set_color("icon_hover_pressed_color", "Button", Color(1, 1, 1, 1)); + theme->set_color("icon_disabled_color", "Button", Color(1, 1, 1, 1)); theme->set_constant("hseparation", "Button", 2 * scale); @@ -199,9 +240,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "LinkButton", -1); theme->set_color("font_color", "LinkButton", control_font_color); - theme->set_color("font_color_pressed", "LinkButton", control_font_color_pressed); - theme->set_color("font_color_hover", "LinkButton", control_font_color_hover); + theme->set_color("font_pressed_color", "LinkButton", control_font_pressed_color); + theme->set_color("font_hover_color", "LinkButton", control_font_hover_color); + theme->set_color("font_outline_color", "LinkButton", Color(1, 1, 1)); + theme->set_constant("outline_size", "LinkButton", 0); theme->set_constant("underline_spacing", "LinkButton", 2 * scale); // ColorPickerButton @@ -216,11 +259,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "ColorPickerButton", -1); theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1)); - theme->set_color("font_color_pressed", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1)); - theme->set_color("font_color_hover", "ColorPickerButton", Color(1, 1, 1, 1)); - theme->set_color("font_color_disabled", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3)); + theme->set_color("font_pressed_color", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1)); + theme->set_color("font_hover_color", "ColorPickerButton", Color(1, 1, 1, 1)); + theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3)); + theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1)); theme->set_constant("hseparation", "ColorPickerButton", 2 * scale); + theme->set_constant("outline_size", "ColorPickerButton", 0); // OptionButton @@ -253,12 +298,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "OptionButton", -1); theme->set_color("font_color", "OptionButton", control_font_color); - theme->set_color("font_color_pressed", "OptionButton", control_font_color_pressed); - theme->set_color("font_color_hover", "OptionButton", control_font_color_hover); - theme->set_color("font_color_disabled", "OptionButton", control_font_color_disabled); + theme->set_color("font_pressed_color", "OptionButton", control_font_pressed_color); + theme->set_color("font_hover_color", "OptionButton", control_font_hover_color); + theme->set_color("font_disabled_color", "OptionButton", control_font_disabled_color); + theme->set_color("font_outline_color", "OptionButton", Color(1, 1, 1)); theme->set_constant("hseparation", "OptionButton", 2 * scale); theme->set_constant("arrow_margin", "OptionButton", 2 * scale); + theme->set_constant("outline_size", "OptionButton", 0); // MenuButton @@ -272,11 +319,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "MenuButton", -1); theme->set_color("font_color", "MenuButton", control_font_color); - theme->set_color("font_color_pressed", "MenuButton", control_font_color_pressed); - theme->set_color("font_color_hover", "MenuButton", control_font_color_hover); - theme->set_color("font_color_disabled", "MenuButton", Color(1, 1, 1, 0.3)); + theme->set_color("font_pressed_color", "MenuButton", control_font_pressed_color); + theme->set_color("font_hover_color", "MenuButton", control_font_hover_color); + theme->set_color("font_disabled_color", "MenuButton", Color(1, 1, 1, 0.3)); + theme->set_color("font_outline_color", "MenuButton", Color(1, 1, 1)); theme->set_constant("hseparation", "MenuButton", 3 * scale); + theme->set_constant("outline_size", "MenuButton", 0); // CheckBox @@ -307,13 +356,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "CheckBox", -1); theme->set_color("font_color", "CheckBox", control_font_color); - theme->set_color("font_color_pressed", "CheckBox", control_font_color_pressed); - theme->set_color("font_color_hover", "CheckBox", control_font_color_hover); - theme->set_color("font_color_hover_pressed", "CheckBox", control_font_color_pressed); - theme->set_color("font_color_disabled", "CheckBox", control_font_color_disabled); + theme->set_color("font_pressed_color", "CheckBox", control_font_pressed_color); + theme->set_color("font_hover_color", "CheckBox", control_font_hover_color); + theme->set_color("font_hover_pressed_color", "CheckBox", control_font_pressed_color); + theme->set_color("font_disabled_color", "CheckBox", control_font_disabled_color); + theme->set_color("font_outline_color", "CheckBox", Color(1, 1, 1)); theme->set_constant("hseparation", "CheckBox", 4 * scale); theme->set_constant("check_vadjust", "CheckBox", 0 * scale); + theme->set_constant("outline_size", "CheckBox", 0); // CheckButton @@ -344,13 +395,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "CheckButton", -1); theme->set_color("font_color", "CheckButton", control_font_color); - theme->set_color("font_color_pressed", "CheckButton", control_font_color_pressed); - theme->set_color("font_color_hover", "CheckButton", control_font_color_hover); - theme->set_color("font_color_hover_pressed", "CheckButton", control_font_color_pressed); - theme->set_color("font_color_disabled", "CheckButton", control_font_color_disabled); + theme->set_color("font_pressed_color", "CheckButton", control_font_pressed_color); + theme->set_color("font_hover_color", "CheckButton", control_font_hover_color); + theme->set_color("font_hover_pressed_color", "CheckButton", control_font_pressed_color); + theme->set_color("font_disabled_color", "CheckButton", control_font_disabled_color); + theme->set_color("font_outline_color", "CheckButton", Color(1, 1, 1)); theme->set_constant("hseparation", "CheckButton", 4 * scale); theme->set_constant("check_vadjust", "CheckButton", 0 * scale); + theme->set_constant("outline_size", "CheckButton", 0); // Label @@ -359,12 +412,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "Label", -1); theme->set_color("font_color", "Label", Color(1, 1, 1)); - theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0)); - theme->set_color("font_outline_modulate", "Label", Color(1, 1, 1)); + theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); + theme->set_color("font_outline_color", "Label", Color(1, 1, 1)); theme->set_constant("shadow_offset_x", "Label", 1 * scale); theme->set_constant("shadow_offset_y", "Label", 1 * scale); - theme->set_constant("outline_size", "Label", 0 * scale); + theme->set_constant("outline_size", "Label", 0); theme->set_constant("shadow_outline_size", "Label", 1 * scale); theme->set_constant("line_spacing", "Label", 3 * scale); @@ -378,14 +431,16 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "LineEdit", -1); theme->set_color("font_color", "LineEdit", control_font_color); - theme->set_color("font_color_selected", "LineEdit", Color(0, 0, 0)); - theme->set_color("font_color_uneditable", "LineEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); - theme->set_color("cursor_color", "LineEdit", control_font_color_hover); - theme->set_color("selection_color", "LineEdit", font_color_selection); + theme->set_color("font_selected_color", "LineEdit", Color(0, 0, 0)); + theme->set_color("font_uneditable_color", "LineEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); + theme->set_color("font_outline_color", "LineEdit", Color(1, 1, 1)); + theme->set_color("cursor_color", "LineEdit", control_font_hover_color); + theme->set_color("selection_color", "LineEdit", control_selection_color); theme->set_color("clear_button_color", "LineEdit", control_font_color); - theme->set_color("clear_button_color_pressed", "LineEdit", control_font_color_pressed); + theme->set_color("clear_button_color_pressed", "LineEdit", control_font_pressed_color); - theme->set_constant("minimum_spaces", "LineEdit", 12 * scale); + theme->set_constant("minimum_character_width", "LineEdit", 4); + theme->set_constant("outline_size", "LineEdit", 0); theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png)); @@ -397,8 +452,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "ProgressBar", Ref<Font>()); theme->set_font_size("font_size", "ProgressBar", -1); - theme->set_color("font_color", "ProgressBar", control_font_color_hover); - theme->set_color("font_color_shadow", "ProgressBar", Color(0, 0, 0)); + theme->set_color("font_color", "ProgressBar", control_font_hover_color); + theme->set_color("font_shadow_color", "ProgressBar", Color(0, 0, 0)); + theme->set_color("font_outline_color", "ProgressBar", Color(1, 1, 1)); + + theme->set_constant("outline_size", "ProgressBar", 0); // TextEdit @@ -417,12 +475,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("completion_background_color", "TextEdit", Color(0.17, 0.16, 0.2)); theme->set_color("completion_selected_color", "TextEdit", Color(0.26, 0.26, 0.27)); theme->set_color("completion_existing_color", "TextEdit", Color(0.87, 0.87, 0.87, 0.13)); - theme->set_color("completion_scroll_color", "TextEdit", control_font_color_pressed); + theme->set_color("completion_scroll_color", "TextEdit", control_font_pressed_color); theme->set_color("completion_font_color", "TextEdit", Color(0.67, 0.67, 0.67)); theme->set_color("font_color", "TextEdit", control_font_color); - theme->set_color("font_color_selected", "TextEdit", Color(0, 0, 0)); - theme->set_color("font_color_readonly", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); - theme->set_color("selection_color", "TextEdit", font_color_selection); + theme->set_color("font_selected_color", "TextEdit", Color(0, 0, 0)); + theme->set_color("font_readonly_color", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); + theme->set_color("font_outline_color", "TextEdit", Color(1, 1, 1)); + theme->set_color("selection_color", "TextEdit", control_selection_color); theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4)); theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8)); theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8)); @@ -435,8 +494,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("completion_max_width", "TextEdit", 50); theme->set_constant("completion_scroll_width", "TextEdit", 3); theme->set_constant("line_spacing", "TextEdit", 4 * scale); + theme->set_constant("outline_size", "TextEdit", 0); // CodeEdit + theme->set_stylebox("normal", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0)); theme->set_stylebox("focus", "CodeEdit", focus); theme->set_stylebox("read_only", "CodeEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4, 0, 0, 0, 0)); @@ -457,12 +518,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2)); theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27)); theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13)); - theme->set_color("completion_scroll_color", "CodeEdit", control_font_color_pressed); + theme->set_color("completion_scroll_color", "CodeEdit", control_font_pressed_color); theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67)); theme->set_color("font_color", "CodeEdit", control_font_color); - theme->set_color("font_color_selected", "CodeEdit", Color(0, 0, 0)); - theme->set_color("font_color_readonly", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); - theme->set_color("selection_color", "CodeEdit", font_color_selection); + theme->set_color("font_selected_color", "CodeEdit", Color(0, 0, 0)); + theme->set_color("font_readonly_color", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); + theme->set_color("font_outline_color", "CodeEdit", Color(1, 1, 1)); + theme->set_color("selection_color", "CodeEdit", control_selection_color); theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4)); theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8)); theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3)); @@ -480,6 +542,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("completion_max_width", "CodeEdit", 50); theme->set_constant("completion_scroll_width", "CodeEdit", 3); theme->set_constant("line_spacing", "CodeEdit", 4 * scale); + theme->set_constant("outline_size", "CodeEdit", 0); Ref<Texture2D> empty_icon = memnew(ImageTexture); @@ -535,7 +598,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("updown", "SpinBox", make_icon(spinbox_updown_png)); - //scroll container + // ScrollContainer + Ref<StyleBoxEmpty> empty; empty.instance(); theme->set_stylebox("bg", "ScrollContainer", empty); @@ -547,7 +611,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("scaleborder_size", "Window", 4 * scale); theme->set_font("title_font", "Window", large_font); + theme->set_font_size("title_font_size", "Window", -1); + theme->set_color("title_color", "Window", Color(0, 0, 0)); + theme->set_color("title_outline_modulate", "Window", Color(1, 1, 1)); + + theme->set_constant("title_outline_size", "Window", 0); theme->set_constant("title_height", "Window", 20 * scale); theme->set_constant("resize_margin", "Window", 4 * scale); @@ -598,13 +667,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "PopupMenu", -1); theme->set_color("font_color", "PopupMenu", control_font_color); - theme->set_color("font_color_accel", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8)); - theme->set_color("font_color_disabled", "PopupMenu", Color(0.4, 0.4, 0.4, 0.8)); - theme->set_color("font_color_hover", "PopupMenu", control_font_color); - theme->set_color("font_color_separator", "PopupMenu", control_font_color); + theme->set_color("font_accelerator_color", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8)); + theme->set_color("font_disabled_color", "PopupMenu", Color(0.4, 0.4, 0.4, 0.8)); + theme->set_color("font_hover_color", "PopupMenu", control_font_color); + theme->set_color("font_separator_color", "PopupMenu", control_font_color); + theme->set_color("font_outline_color", "PopupMenu", Color(1, 1, 1)); theme->set_constant("hseparation", "PopupMenu", 4 * scale); theme->set_constant("vseparation", "PopupMenu", 4 * scale); + theme->set_constant("outline_size", "PopupMenu", 0); + theme->set_constant("item_start_padding", "PopupMenu", 2 * scale); + theme->set_constant("item_end_padding", "PopupMenu", 2 * scale); // GraphNode @@ -671,12 +744,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "Tree", -1); theme->set_color("title_button_color", "Tree", control_font_color); - theme->set_color("font_color", "Tree", control_font_color_low); - theme->set_color("font_color_selected", "Tree", control_font_color_pressed); + theme->set_color("font_color", "Tree", control_font_low_color); + theme->set_color("font_selected_color", "Tree", control_font_pressed_color); + theme->set_color("font_outline_color", "Tree", Color(1, 1, 1)); theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1)); theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); - theme->set_color("custom_button_font_highlight", "Tree", control_font_color_hover); + theme->set_color("custom_button_font_highlight", "Tree", control_font_hover_color); theme->set_constant("hseparation", "Tree", 4 * scale); theme->set_constant("vseparation", "Tree", 4 * scale); @@ -686,8 +760,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("draw_guides", "Tree", 1); theme->set_constant("scroll_border", "Tree", 4); theme->set_constant("scroll_speed", "Tree", 12); + theme->set_constant("outline_size", "Tree", 0); // ItemList + Ref<StyleBoxTexture> item_selected = make_stylebox(selection_png, 4, 4, 4, 4, 8, 2, 8, 2); Ref<StyleBoxTexture> item_selected_oof = make_stylebox(selection_oof_png, 4, 4, 4, 4, 8, 2, 8, 2); @@ -701,14 +777,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "ItemList", Ref<Font>()); theme->set_font_size("font_size", "ItemList", -1); - theme->set_color("font_color", "ItemList", control_font_color_lower); - theme->set_color("font_color_selected", "ItemList", control_font_color_pressed); + theme->set_color("font_color", "ItemList", control_font_lower_color); + theme->set_color("font_selected_color", "ItemList", control_font_pressed_color); + theme->set_color("font_outline_color", "ItemList", Color(1, 1, 1)); theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1)); theme->set_stylebox("selected", "ItemList", item_selected_oof); theme->set_stylebox("selected_focus", "ItemList", item_selected); theme->set_stylebox("cursor", "ItemList", focus); theme->set_stylebox("cursor_unfocused", "ItemList", focus); + theme->set_constant("outline_size", "ItemList", 0); + // TabContainer Ref<StyleBoxTexture> tc_sb = sb_expand(make_stylebox(tab_container_bg_png, 4, 4, 4, 4, 4, 4, 4, 4), 3, 3, 3, 3); @@ -716,8 +795,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const tc_sb->set_expand_margin_size(SIDE_TOP, 2 * scale); tc_sb->set_default_margin(SIDE_TOP, 8 * scale); - theme->set_stylebox("tab_fg", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); - theme->set_stylebox("tab_bg", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("tab_selected", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2)); + theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("panel", "TabContainer", tc_sb); @@ -731,17 +810,19 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "TabContainer", Ref<Font>()); theme->set_font_size("font_size", "TabContainer", -1); - theme->set_color("font_color_fg", "TabContainer", control_font_color_hover); - theme->set_color("font_color_bg", "TabContainer", control_font_color_low); - theme->set_color("font_color_disabled", "TabContainer", control_font_color_disabled); + theme->set_color("font_selected_color", "TabContainer", control_font_hover_color); + theme->set_color("font_unselected_color", "TabContainer", control_font_low_color); + theme->set_color("font_disabled_color", "TabContainer", control_font_disabled_color); + theme->set_color("font_outline_color", "TabContainer", Color(1, 1, 1)); theme->set_constant("side_margin", "TabContainer", 8 * scale); theme->set_constant("icon_separation", "TabContainer", 4 * scale); + theme->set_constant("outline_size", "TabContainer", 0); // Tabs - theme->set_stylebox("tab_fg", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); - theme->set_stylebox("tab_bg", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); + theme->set_stylebox("tab_selected", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); + theme->set_stylebox("tab_unselected", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); theme->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); theme->set_stylebox("panel", "Tabs", tc_sb); theme->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4)); @@ -756,11 +837,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "Tabs", Ref<Font>()); theme->set_font_size("font_size", "Tabs", -1); - theme->set_color("font_color_fg", "Tabs", control_font_color_hover); - theme->set_color("font_color_bg", "Tabs", control_font_color_low); - theme->set_color("font_color_disabled", "Tabs", control_font_color_disabled); + theme->set_color("font_selected_color", "Tabs", control_font_hover_color); + theme->set_color("font_unselected_color", "Tabs", control_font_low_color); + theme->set_color("font_disabled_color", "Tabs", control_font_disabled_color); + theme->set_color("font_outline_color", "Tabs", Color(1, 1, 1)); theme->set_constant("hseparation", "Tabs", 4 * scale); + theme->set_constant("outline_size", "Tabs", 0); // Separators @@ -817,10 +900,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("font_size", "TooltipLabel", -1); theme->set_color("font_color", "TooltipLabel", Color(0, 0, 0)); - theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0.1)); + theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0.1)); + theme->set_color("font_outline_color", "TooltipLabel", Color(1, 1, 1)); theme->set_constant("shadow_offset_x", "TooltipLabel", 1); theme->set_constant("shadow_offset_y", "TooltipLabel", 1); + theme->set_constant("outline_size", "TooltipLabel", 0); // RichTextLabel @@ -840,10 +925,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font_size("mono_font_size", "RichTextLabel", -1); theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1)); - theme->set_color("font_color_selected", "RichTextLabel", font_color_selection); + theme->set_color("font_selected_color", "RichTextLabel", Color(0, 0, 0)); theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8)); - theme->set_color("font_color_shadow", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); + + theme->set_color("font_outline_color", "RichTextLabel", Color(1, 1, 1)); theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * scale); theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * scale); @@ -853,9 +940,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale); theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale); + theme->set_constant("outline_size", "RichTextLabel", 0); + theme->set_color("table_odd_row_bg", "RichTextLabel", Color(0, 0, 0, 0)); theme->set_color("table_even_row_bg", "RichTextLabel", Color(0, 0, 0, 0)); theme->set_color("table_border", "RichTextLabel", Color(0, 0, 0, 0)); + // Containers theme->set_stylebox("bg", "VSplitContainer", make_stylebox(vsplit_bg_png, 1, 1, 1, 1)); @@ -895,6 +985,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale); // Visual Node Ports + theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 48 * scale); theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale); @@ -930,41 +1021,11 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { if (p_font.is_valid()) { default_font = p_font; } else if (p_hidpi) { - TextServer::BitmapFontData data; - data.height = _hidpi_font_height; - data.ascent = _hidpi_font_ascent; - data.charcount = _hidpi_font_charcount; - data.char_rects = &_hidpi_font_charrects[0][0]; - data.kerning_count = _hidpi_font_kerning_pair_count; - data.kernings = &_hidpi_font_kerning_pairs[0][0]; - data.w = _hidpi_font_img_width; - data.h = _hidpi_font_img_height; - data.img = _hidpi_font_img_data; - - Ref<FontData> font_data; - font_data.instance(); - font_data->load_memory((const uint8_t *)&data, sizeof(data), "fnt"); - default_font_size = font_data->get_base_size(); - + Ref<FontData> font_data = make_font(_hidpi_font_height, _hidpi_font_ascent, _hidpi_font_charcount, &_hidpi_font_charrects[0][0], _hidpi_font_kerning_pair_count, &_hidpi_font_kerning_pairs[0][0], _hidpi_font_img_width, _hidpi_font_img_height, _hidpi_font_img_data); default_font.instance(); default_font->add_data(font_data); } else { - TextServer::BitmapFontData data; - data.height = _lodpi_font_height; - data.ascent = _lodpi_font_ascent; - data.charcount = _lodpi_font_charcount; - data.char_rects = &_lodpi_font_charrects[0][0]; - data.kerning_count = _lodpi_font_kerning_pair_count; - data.kernings = &_lodpi_font_kerning_pairs[0][0]; - data.w = _lodpi_font_img_width; - data.h = _lodpi_font_img_height; - data.img = _lodpi_font_img_data; - - Ref<FontData> font_data; - font_data.instance(); - font_data->load_memory((const uint8_t *)&data, sizeof(data), "fnt"); - default_font_size = font_data->get_base_size(); - + Ref<FontData> font_data = make_font(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data); default_font.instance(); default_font->add_data(font_data); } diff --git a/scene/resources/default_theme/xpmfix.sh b/scene/resources/default_theme/xpmfix.sh deleted file mode 100755 index a24dede3c9..0000000000 --- a/scene/resources/default_theme/xpmfix.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sed -i 's/static char/static const char/g' *.xpm diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index b7b5f72fcd..6f6af93848 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -44,7 +44,7 @@ RID Environment::get_rid() const { void Environment::set_background(BGMode p_bg) { bg_mode = p_bg; RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg)); - _change_notify(); + notify_property_list_changed(); if (bg_mode != BG_SKY) { set_fog_aerial_perspective(0.0); } @@ -138,7 +138,7 @@ Color Environment::get_ambient_light_color() const { void Environment::set_ambient_source(AmbientSource p_source) { ambient_source = p_source; _update_ambient_light(); - _change_notify(); + notify_property_list_changed(); } Environment::AmbientSource Environment::get_ambient_source() const { @@ -166,7 +166,7 @@ float Environment::get_ambient_light_sky_contribution() const { void Environment::set_reflection_source(ReflectionSource p_source) { reflection_source = p_source; _update_ambient_light(); - _change_notify(); + notify_property_list_changed(); } Environment::ReflectionSource Environment::get_reflection_source() const { @@ -224,7 +224,7 @@ float Environment::get_tonemap_white() const { void Environment::set_tonemap_auto_exposure_enabled(bool p_enabled) { tonemap_auto_exposure_enabled = p_enabled; _update_tonemap(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_tonemap_auto_exposure_enabled() const { @@ -285,7 +285,7 @@ void Environment::_update_tonemap() { void Environment::set_ssr_enabled(bool p_enabled) { ssr_enabled = p_enabled; _update_ssr(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_ssr_enabled() const { @@ -343,7 +343,7 @@ void Environment::_update_ssr() { void Environment::set_ssao_enabled(bool p_enabled) { ssao_enabled = p_enabled; _update_ssao(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_ssao_enabled() const { @@ -458,8 +458,6 @@ Environment::SDFGICascades Environment::get_sdfgi_cascades() const { void Environment::set_sdfgi_min_cell_size(float p_size) { sdfgi_min_cell_size = p_size; - _change_notify("sdfgi_max_distance"); - _change_notify("sdfgi_cascade0_distance"); _update_sdfgi(); } @@ -475,8 +473,6 @@ void Environment::set_sdfgi_max_distance(float p_distance) { p_distance *= 0.5; //halve for each cascade } sdfgi_min_cell_size = p_distance; - _change_notify("sdfgi_min_cell_size"); - _change_notify("sdfgi_cascade0_distance"); _update_sdfgi(); } @@ -493,8 +489,6 @@ float Environment::get_sdfgi_max_distance() const { void Environment::set_sdfgi_cascade0_distance(float p_distance) { sdfgi_min_cell_size = p_distance / 64.0; - _change_notify("sdfgi_min_cell_size"); - _change_notify("sdfgi_max_distance"); _update_sdfgi(); } @@ -520,13 +514,12 @@ bool Environment::is_sdfgi_using_occlusion() const { return sdfgi_use_occlusion; } -void Environment::set_sdfgi_use_multi_bounce(bool p_enabled) { - sdfgi_use_multibounce = p_enabled; +void Environment::set_sdfgi_bounce_feedback(float p_amount) { + sdfgi_bounce_feedback = p_amount; _update_sdfgi(); } - -bool Environment::is_sdfgi_using_multi_bounce() const { - return sdfgi_use_multibounce; +float Environment::get_sdfgi_bounce_feedback() const { + return sdfgi_bounce_feedback; } void Environment::set_sdfgi_read_sky_light(bool p_enabled) { @@ -573,7 +566,7 @@ void Environment::_update_sdfgi() { sdfgi_min_cell_size, RS::EnvironmentSDFGIYScale(sdfgi_y_scale), sdfgi_use_occlusion, - sdfgi_use_multibounce, + sdfgi_bounce_feedback, sdfgi_read_sky_light, sdfgi_energy, sdfgi_normal_bias, @@ -585,7 +578,7 @@ void Environment::_update_sdfgi() { void Environment::set_glow_enabled(bool p_enabled) { glow_enabled = p_enabled; _update_glow(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_glow_enabled() const { @@ -655,7 +648,7 @@ float Environment::get_glow_bloom() const { void Environment::set_glow_blend_mode(GlowBlendMode p_mode) { glow_blend_mode = p_mode; _update_glow(); - _change_notify(); + notify_property_list_changed(); } Environment::GlowBlendMode Environment::get_glow_blend_mode() const { @@ -723,7 +716,7 @@ void Environment::_update_glow() { void Environment::set_fog_enabled(bool p_enabled) { fog_enabled = p_enabled; _update_fog(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_fog_enabled() const { @@ -797,13 +790,13 @@ void Environment::_update_fog() { // Volumetric Fog void Environment::_update_volumetric_fog() { - RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter)); + RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount); } void Environment::set_volumetric_fog_enabled(bool p_enable) { volumetric_fog_enabled = p_enable; _update_volumetric_fog(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_volumetric_fog_enabled() const { @@ -854,13 +847,20 @@ float Environment::get_volumetric_fog_gi_inject() const { return volumetric_fog_gi_inject; } -void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) { - volumetric_fog_shadow_filter = p_filter; +void Environment::set_volumetric_fog_temporal_reprojection_enabled(bool p_enable) { + volumetric_fog_temporal_reproject = p_enable; + _update_volumetric_fog(); +} +bool Environment::is_volumetric_fog_temporal_reprojection_enabled() const { + return volumetric_fog_temporal_reproject; +} +void Environment::set_volumetric_fog_temporal_reprojection_amount(float p_amount) { + volumetric_fog_temporal_reproject_amount = p_amount; _update_volumetric_fog(); } -Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_filter() const { - return volumetric_fog_shadow_filter; +float Environment::get_volumetric_fog_temporal_reprojection_amount() const { + return volumetric_fog_temporal_reproject_amount; } // Adjustment @@ -868,7 +868,7 @@ Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_fi void Environment::set_adjustment_enabled(bool p_enabled) { adjustment_enabled = p_enabled; _update_adjustment(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_adjustment_enabled() const { @@ -1200,8 +1200,8 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_sdfgi_y_scale"), &Environment::get_sdfgi_y_scale); ClassDB::bind_method(D_METHOD("set_sdfgi_use_occlusion", "enable"), &Environment::set_sdfgi_use_occlusion); ClassDB::bind_method(D_METHOD("is_sdfgi_using_occlusion"), &Environment::is_sdfgi_using_occlusion); - ClassDB::bind_method(D_METHOD("set_sdfgi_use_multi_bounce", "enable"), &Environment::set_sdfgi_use_multi_bounce); - ClassDB::bind_method(D_METHOD("is_sdfgi_using_multi_bounce"), &Environment::is_sdfgi_using_multi_bounce); + ClassDB::bind_method(D_METHOD("set_sdfgi_bounce_feedback", "amount"), &Environment::set_sdfgi_bounce_feedback); + ClassDB::bind_method(D_METHOD("get_sdfgi_bounce_feedback"), &Environment::get_sdfgi_bounce_feedback); ClassDB::bind_method(D_METHOD("set_sdfgi_read_sky_light", "enable"), &Environment::set_sdfgi_read_sky_light); ClassDB::bind_method(D_METHOD("is_sdfgi_reading_sky_light"), &Environment::is_sdfgi_reading_sky_light); ClassDB::bind_method(D_METHOD("set_sdfgi_energy", "amount"), &Environment::set_sdfgi_energy); @@ -1213,9 +1213,9 @@ void Environment::_bind_methods() { ADD_GROUP("SDFGI", "sdfgi_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_enabled"), "set_sdfgi_enabled", "is_sdfgi_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_multi_bounce"), "set_sdfgi_use_multi_bounce", "is_sdfgi_using_multi_bounce"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_occlusion"), "set_sdfgi_use_occlusion", "is_sdfgi_using_occlusion"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_read_sky_light"), "set_sdfgi_read_sky_light", "is_sdfgi_reading_sky_light"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_bounce_feedback", PROPERTY_HINT_RANGE, "0,1.99,0.01"), "set_sdfgi_bounce_feedback", "get_sdfgi_bounce_feedback"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_ENUM, "4 Cascades,6 Cascades,8 Cascades"), "set_sdfgi_cascades", "get_sdfgi_cascades"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); @@ -1317,8 +1317,10 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread); ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject); ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject); - ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter); - ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled); + ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_temporal_reprojection_amount"), &Environment::get_volumetric_fog_temporal_reprojection_amount); ADD_GROUP("Volumetric Fog", "volumetric_fog_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled"), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled"); @@ -1328,7 +1330,9 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter"); + ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.0,0.999,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount"); // Adjustment @@ -1417,7 +1421,7 @@ Environment::Environment() { _update_fog(); _update_adjustment(); _update_volumetric_fog(); - _change_notify(); + notify_property_list_changed(); } Environment::~Environment() { diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 1676a28b39..0df2c3cc27 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -103,7 +103,7 @@ private: // Background BGMode bg_mode = BG_CLEAR_COLOR; Ref<Sky> bg_sky; - float bg_sky_custom_fov = 0; + float bg_sky_custom_fov = 0.0; Vector3 bg_sky_rotation; Color bg_color; float bg_energy = 1.0; @@ -125,7 +125,7 @@ private: float tonemap_white = 1.0; bool tonemap_auto_exposure_enabled = false; float tonemap_auto_exposure_min = 0.05; - float tonemap_auto_exposure_max = 8; + float tonemap_auto_exposure_max = 8.0; float tonemap_auto_exposure_speed = 0.5; float tonemap_auto_exposure_grey = 0.4; void _update_tonemap(); @@ -156,7 +156,7 @@ private: float sdfgi_min_cell_size = 0.2; SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED; bool sdfgi_use_occlusion = false; - bool sdfgi_use_multibounce = false; + float sdfgi_bounce_feedback = 0.0; bool sdfgi_read_sky_light = false; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; @@ -196,8 +196,9 @@ private: float volumetric_fog_light_energy = 1.0; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW; float volumetric_fog_gi_inject = 0.0; + bool volumetric_fog_temporal_reproject = true; + float volumetric_fog_temporal_reproject_amount = 0.9; void _update_volumetric_fog(); // Adjustment @@ -317,8 +318,8 @@ public: SDFGIYScale get_sdfgi_y_scale() const; void set_sdfgi_use_occlusion(bool p_enabled); bool is_sdfgi_using_occlusion() const; - void set_sdfgi_use_multi_bounce(bool p_enabled); - bool is_sdfgi_using_multi_bounce() const; + void set_sdfgi_bounce_feedback(float p_amount); + float get_sdfgi_bounce_feedback() const; void set_sdfgi_read_sky_light(bool p_enabled); bool is_sdfgi_reading_sky_light() const; void set_sdfgi_energy(float p_energy); @@ -385,10 +386,12 @@ public: float get_volumetric_fog_length() const; void set_volumetric_fog_detail_spread(float p_detail_spread); float get_volumetric_fog_detail_spread() const; - void set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter); - VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const; void set_volumetric_fog_gi_inject(float p_gi_inject); float get_volumetric_fog_gi_inject() const; + void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable); + bool is_volumetric_fog_temporal_reprojection_enabled() const; + void set_volumetric_fog_temporal_reprojection_amount(float p_amount); + float get_volumetric_fog_temporal_reprojection_amount() const; // Adjustment void set_adjustment_enabled(bool p_enabled); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 1c06d7b519..6f87c524d8 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -39,6 +39,11 @@ void FontData::_bind_methods() { ClassDB::bind_method(D_METHOD("load_resource", "filename", "base_size"), &FontData::load_resource, DEFVAL(16)); ClassDB::bind_method(D_METHOD("load_memory", "data", "type", "base_size"), &FontData::_load_memory, DEFVAL(16)); + ClassDB::bind_method(D_METHOD("new_bitmap", "height", "ascent", "base_size"), &FontData::new_bitmap); + + ClassDB::bind_method(D_METHOD("bitmap_add_texture", "texture"), &FontData::bitmap_add_texture); + ClassDB::bind_method(D_METHOD("bitmap_add_char", "char", "texture_idx", "rect", "align", "advance"), &FontData::bitmap_add_char); + ClassDB::bind_method(D_METHOD("bitmap_add_kerning_pair", "A", "B", "kerning"), &FontData::bitmap_add_kerning_pair); ClassDB::bind_method(D_METHOD("set_data_path", "path"), &FontData::set_data_path); ClassDB::bind_method(D_METHOD("get_data_path"), &FontData::get_data_path); @@ -50,6 +55,9 @@ void FontData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_underline_position", "size"), &FontData::get_underline_position); ClassDB::bind_method(D_METHOD("get_underline_thickness", "size"), &FontData::get_underline_thickness); + ClassDB::bind_method(D_METHOD("get_spacing", "type"), &FontData::get_spacing); + ClassDB::bind_method(D_METHOD("set_spacing", "type", "value"), &FontData::set_spacing); + ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontData::set_antialiased); ClassDB::bind_method(D_METHOD("get_antialiased"), &FontData::get_antialiased); @@ -100,6 +108,13 @@ void FontData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_field_hint"), "set_distance_field_hint", "get_distance_field_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); + + ADD_GROUP("Extra Spacing", "extra_spacing"); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_glyph"), "set_spacing", "get_spacing", SPACING_GLYPH); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_space"), "set_spacing", "get_spacing", SPACING_SPACE); + + BIND_ENUM_CONSTANT(SPACING_GLYPH); + BIND_ENUM_CONSTANT(SPACING_SPACE); } bool FontData::_set(const StringName &p_name, const Variant &p_value) { @@ -177,6 +192,14 @@ void FontData::_get_property_list(List<PropertyInfo> *p_list) const { } } +void FontData::reset_state() { + if (rid != RID()) { + TS->free(rid); + } + base_size = 16; + path = String(); +} + RID FontData::get_rid() const { return rid; } @@ -211,6 +234,34 @@ void FontData::load_memory(const uint8_t *p_data, size_t p_size, const String &p emit_changed(); } +void FontData::new_bitmap(float p_height, float p_ascent, int p_base_size) { + if (rid != RID()) { + TS->free(rid); + } + rid = TS->create_font_bitmap(p_height, p_ascent, p_base_size); + path = TTR("(Bitmap: " + String::num_int64(rid.get_id(), 16, true) + ")"); + base_size = TS->font_get_base_size(rid); + emit_changed(); +} + +void FontData::bitmap_add_texture(const Ref<Texture> &p_texture) { + if (rid != RID()) { + TS->font_bitmap_add_texture(rid, p_texture); + } +} + +void FontData::bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { + if (rid != RID()) { + TS->font_bitmap_add_char(rid, p_char, p_texture_idx, p_rect, p_align, p_advance); + } +} + +void FontData::bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { + if (rid != RID()) { + TS->font_bitmap_add_kerning_pair(rid, p_A, p_B, p_kerning); + } +} + void FontData::set_data_path(const String &p_path) { load_resource(p_path, base_size); } @@ -281,6 +332,27 @@ double FontData::get_variation(const String &p_name) const { return TS->font_get_variation(rid, p_name); } +int FontData::get_spacing(int p_type) const { + if (rid == RID()) { + return 0; + } + if (p_type == SPACING_GLYPH) { + return TS->font_get_spacing_glyph(rid); + } else { + return TS->font_get_spacing_space(rid); + } +} + +void FontData::set_spacing(int p_type, int p_value) { + ERR_FAIL_COND(rid == RID()); + if (p_type == SPACING_GLYPH) { + TS->font_set_spacing_glyph(rid, p_value); + } else { + TS->font_set_spacing_space(rid, p_value); + } + emit_changed(); +} + void FontData::set_antialiased(bool p_antialiased) { ERR_FAIL_COND(rid == RID()); TS->font_set_antialiased(rid, p_antialiased); @@ -509,7 +581,7 @@ void Font::_data_changed() { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } bool Font::_set(const StringName &p_name, const Variant &p_value) { @@ -588,6 +660,14 @@ void Font::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::OBJECT, "data/" + itos(data.size()), PROPERTY_HINT_RESOURCE_TYPE, "FontData")); } +void Font::reset_state() { + spacing_top = 0; + spacing_bottom = 0; + cache.clear(); + cache_wrap.clear(); + data.clear(); +} + void Font::add_data(const Ref<FontData> &p_data) { ERR_FAIL_COND(p_data.is_null()); data.push_back(p_data); @@ -600,7 +680,7 @@ void Font::add_data(const Ref<FontData> &p_data) { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void Font::set_data(int p_idx, const Ref<FontData> &p_data) { @@ -621,7 +701,7 @@ void Font::set_data(int p_idx, const Ref<FontData> &p_data) { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } int Font::get_data_count() const { @@ -646,7 +726,7 @@ void Font::remove_data(int p_idx) { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } Dictionary Font::get_feature_list() const { @@ -718,7 +798,7 @@ void Font::set_spacing(int p_type, int p_value) { } emit_changed(); - _change_notify(); + notify_property_list_changed(); } // Drawing string and string sizes, cached. @@ -781,6 +861,8 @@ Size2 Font::get_multiline_string_size(const String &p_text, float p_width, int p } void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const { + ERR_FAIL_COND(data.is_empty()); + uint64_t hash = p_text.hash64(); hash = hash_djb2_one_64(p_size, hash); @@ -811,6 +893,8 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t } void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const { + ERR_FAIL_COND(data.is_empty()); + uint64_t hash = p_text.hash64(); hash = hash_djb2_one_64(p_size, hash); @@ -951,7 +1035,7 @@ Font::~Font() { /*************************************************************************/ -RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -1006,7 +1090,7 @@ String ResourceFormatLoaderFont::get_resource_type(const String &p_path) const { #ifndef DISABLE_DEPRECATED -RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/scene/resources/font.h b/scene/resources/font.h index 086226c082..200373aa8c 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -42,6 +42,13 @@ class FontData : public Resource { GDCLASS(FontData, Resource); +public: + enum SpacingType { + SPACING_GLYPH, + SPACING_SPACE, + }; + +private: RID rid; int base_size = 16; String path; @@ -53,6 +60,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: virtual RID get_rid() const override; @@ -60,6 +69,12 @@ public: void load_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16); void _load_memory(const PackedByteArray &p_data, const String &p_type, int p_base_size = 16); + void new_bitmap(float p_height, float p_ascent, int p_base_size = 16); + + void bitmap_add_texture(const Ref<Texture> &p_texture); + void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance); + void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning); + void set_data_path(const String &p_path); String get_data_path() const; @@ -76,6 +91,9 @@ public: float get_underline_position(int p_size) const; float get_underline_thickness(int p_size) const; + int get_spacing(int p_type) const; + void set_spacing(int p_type, int p_value); + void set_antialiased(bool p_antialiased); bool get_antialiased() const; @@ -132,7 +150,7 @@ class Font : public Resource { public: enum SpacingType { SPACING_TOP, - SPACING_BOTTOM + SPACING_BOTTOM, }; private: @@ -151,6 +169,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + void _data_changed(); public: @@ -195,13 +215,14 @@ public: ~Font(); }; +VARIANT_ENUM_CAST(FontData::SpacingType); VARIANT_ENUM_CAST(Font::SpacingType); /*************************************************************************/ class ResourceFormatLoaderFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; @@ -212,7 +233,7 @@ public: class ResourceFormatLoaderCompatFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp index b87235518f..7b9b942142 100644 --- a/scene/resources/gradient.cpp +++ b/scene/resources/gradient.cpp @@ -39,7 +39,6 @@ Gradient::Gradient() { points.write[0].offset = 0; points.write[1].color = Color(1, 1, 1, 1); points.write[1].offset = 1; - is_sorted = true; } Gradient::~Gradient() { diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h index 344a3fd283..cf5b179c45 100644 --- a/scene/resources/gradient.h +++ b/scene/resources/gradient.h @@ -39,7 +39,7 @@ class Gradient : public Resource { public: struct Point { - float offset; + float offset = 0.0; Color color; bool operator<(const Point &p_ponit) const { return offset < p_ponit.offset; @@ -48,7 +48,7 @@ public: private: Vector<Point> points; - bool is_sorted; + bool is_sorted = true; _FORCE_INLINE_ void _update_sorting() { if (!is_sorted) { points.sort(); diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp index a32cc1c4df..5593bb766f 100644 --- a/scene/resources/height_map_shape_3d.cpp +++ b/scene/resources/height_map_shape_3d.cpp @@ -107,8 +107,6 @@ void HeightMapShape3D::set_map_width(int p_new) { _update_shape(); notify_change_to_owners(); - _change_notify("map_width"); - _change_notify("map_data"); } } @@ -133,8 +131,6 @@ void HeightMapShape3D::set_map_depth(int p_new) { _update_shape(); notify_change_to_owners(); - _change_notify("map_depth"); - _change_notify("map_data"); } } @@ -171,7 +167,6 @@ void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) { _update_shape(); notify_change_to_owners(); - _change_notify("map_data"); } PackedFloat32Array HeightMapShape3D::get_map_data() const { @@ -193,16 +188,12 @@ void HeightMapShape3D::_bind_methods() { HeightMapShape3D::HeightMapShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_HEIGHTMAP)) { - map_width = 2; - map_depth = 2; map_data.resize(map_width * map_depth); real_t *w = map_data.ptrw(); w[0] = 0.0; w[1] = 0.0; w[2] = 0.0; w[3] = 0.0; - min_height = 0.0; - max_height = 0.0; _update_shape(); } diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index eda405fc06..6fc88cff90 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -36,11 +36,11 @@ class HeightMapShape3D : public Shape3D { GDCLASS(HeightMapShape3D, Shape3D); - int map_width; - int map_depth; + int map_width = 2; + int map_depth = 2; PackedFloat32Array map_data; - float min_height; - float max_height; + float min_height = 0.0; + float max_height = 0.0; protected: static void _bind_methods(); diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp index 2b08c21c34..d206f12287 100644 --- a/scene/resources/line_shape_2d.cpp +++ b/scene/resources/line_shape_2d.cpp @@ -113,7 +113,5 @@ void LineShape2D::_bind_methods() { LineShape2D::LineShape2D() : Shape2D(PhysicsServer2D::get_singleton()->line_shape_create()) { - normal = Vector2(0, 1); - distance = 0; _update_shape(); } diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h index 043be1eebe..9f0405ad29 100644 --- a/scene/resources/line_shape_2d.h +++ b/scene/resources/line_shape_2d.h @@ -36,8 +36,8 @@ class LineShape2D : public Shape2D { GDCLASS(LineShape2D, Shape2D); - Vector2 normal; - real_t distance; + Vector2 normal = Vector2(0, 1); + real_t distance = 0.0; void _update_shape(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 445c0d9677..062d921855 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -192,7 +192,7 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) { void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { // Only connect/disconnect the signal when running in the editor. - // This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`) + // This can be a slow operation, and `notify_property_list_changed()` (which is called by `_shader_changed()`) // does nothing in non-editor builds anyway. See GH-34741 for details. if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) { shader->disconnect("changed", callable_mp(this, &ShaderMaterial::_shader_changed)); @@ -210,7 +210,7 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { } RS::get_singleton()->material_set_shader(_get_material(), rid); - _change_notify(); //properties for shader exposed + notify_property_list_changed(); //properties for shader exposed emit_changed(); } @@ -227,7 +227,7 @@ Variant ShaderMaterial::get_shader_param(const StringName &p_param) const { } void ShaderMaterial::_shader_changed() { - _change_notify(); //update all properties + notify_property_list_changed(); //update all properties } void ShaderMaterial::_bind_methods() { @@ -735,7 +735,7 @@ void BaseMaterial3D::_update_shader() { if (flags[FLAG_SRGB_VERTEX_COLOR]) { code += "\tif (!OUTPUT_IS_SRGB) {\n"; - code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n"; + code += "\t\tCOLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n"; code += "\t}\n"; } if (flags[FLAG_USE_POINT_SIZE]) { @@ -1489,7 +1489,7 @@ void BaseMaterial3D::set_transparency(Transparency p_transparency) { transparency = p_transparency; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const { @@ -1503,7 +1503,7 @@ void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) { alpha_antialiasing_mode = p_alpha_aa; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::AlphaAntiAliasing BaseMaterial3D::get_alpha_antialiasing() const { @@ -1517,7 +1517,7 @@ void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) { shading_mode = p_shading_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const { @@ -1585,7 +1585,7 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { flags[p_flag] = p_enabled; if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) { - _change_notify(); + notify_property_list_changed(); } _queue_shader_change(); } @@ -1602,7 +1602,7 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) { } features[p_feature] = p_enabled; - _change_notify(); + notify_property_list_changed(); _queue_shader_change(); } @@ -1620,7 +1620,7 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size, Vector2i(p_texture->get_width(), p_texture->get_height())); } - _change_notify(); + notify_property_list_changed(); _queue_shader_change(); } @@ -1860,7 +1860,7 @@ float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const { void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) { billboard_mode = p_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const { @@ -1897,7 +1897,7 @@ bool BaseMaterial3D::get_particles_anim_loop() const { void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) { deep_parallax = p_enable; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const { @@ -1943,7 +1943,7 @@ bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const { void BaseMaterial3D::set_grow_enabled(bool p_enable) { grow_enabled = p_enable; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool BaseMaterial3D::is_grow_enabled() const { @@ -2093,7 +2093,7 @@ void BaseMaterial3D::set_on_top_of_alpha() { void BaseMaterial3D::set_proximity_fade(bool p_enable) { proximity_fade_enabled = p_enable; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool BaseMaterial3D::is_proximity_fade_enabled() const { @@ -2112,7 +2112,7 @@ float BaseMaterial3D::get_proximity_fade_distance() const { void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) { distance_fade = p_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const { @@ -2655,9 +2655,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : element(this) { orm = p_orm; // Initialize to the same values as the shader - shading_mode = SHADING_MODE_PER_PIXEL; - transparency = TRANSPARENCY_DISABLED; - alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; set_albedo(Color(1.0, 1.0, 1.0, 1.0)); set_specular(0.5); set_roughness(1.0); @@ -2689,7 +2686,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_particles_anim_h_frames(1); set_particles_anim_v_frames(1); set_particles_anim_loop(false); - emission_op = EMISSION_OP_ADD; set_transparency(TRANSPARENCY_DISABLED); set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF); @@ -2697,8 +2693,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_alpha_hash_scale(1.0); set_alpha_antialiasing_edge(0.3); - proximity_fade_enabled = false; - distance_fade = DISTANCE_FADE_DISABLED; set_proximity_fade_distance(1); set_distance_fade_min_distance(0); set_distance_fade_max_distance(10); @@ -2710,35 +2704,14 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_ao_texture_channel(TEXTURE_CHANNEL_RED); set_refraction_texture_channel(TEXTURE_CHANNEL_RED); - grow_enabled = false; set_grow(0.0); - deep_parallax = false; - heightmap_parallax_flip_tangent = false; - heightmap_parallax_flip_binormal = false; set_heightmap_deep_parallax_min_layers(8); set_heightmap_deep_parallax_max_layers(32); set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal - detail_uv = DETAIL_UV_1; - blend_mode = BLEND_MODE_MIX; - detail_blend_mode = BLEND_MODE_MIX; - depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY; - cull_mode = CULL_BACK; - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; - } flags[FLAG_USE_TEXTURE_REPEAT] = true; - diffuse_mode = DIFFUSE_BURLEY; - specular_mode = SPECULAR_SCHLICK_GGX; - - for (int i = 0; i < FEATURE_MAX; i++) { - features[i] = false; - } - - texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; - _queue_shader_change(); } diff --git a/scene/resources/material.h b/scene/resources/material.h index 0048b43c8b..70452a5f74 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -330,7 +330,7 @@ private: struct ShaderData { RID shader; - int users; + int users = 0; }; static Map<MaterialKey, ShaderData> shader_map; @@ -468,16 +468,16 @@ private: float alpha_scissor_threshold; float alpha_hash_scale; float alpha_antialiasing_edge; - bool grow_enabled; + bool grow_enabled = false; float ao_light_affect; float grow; int particles_anim_h_frames; int particles_anim_v_frames; bool particles_anim_loop; - Transparency transparency; - ShadingMode shading_mode; + Transparency transparency = TRANSPARENCY_DISABLED; + ShadingMode shading_mode = SHADING_MODE_PER_PIXEL; - TextureFilter texture_filter; + TextureFilter texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; Vector3 uv1_scale; Vector3 uv1_offset; @@ -487,39 +487,39 @@ private: Vector3 uv2_offset; float uv2_triplanar_sharpness; - DetailUV detail_uv; + DetailUV detail_uv = DETAIL_UV_1; - bool deep_parallax; + bool deep_parallax = false; int deep_parallax_min_layers; int deep_parallax_max_layers; - bool heightmap_parallax_flip_tangent; - bool heightmap_parallax_flip_binormal; + bool heightmap_parallax_flip_tangent = false; + bool heightmap_parallax_flip_binormal = false; - bool proximity_fade_enabled; + bool proximity_fade_enabled = false; float proximity_fade_distance; - DistanceFadeMode distance_fade; + DistanceFadeMode distance_fade = DISTANCE_FADE_DISABLED; float distance_fade_max_distance; float distance_fade_min_distance; - BlendMode blend_mode; - BlendMode detail_blend_mode; - DepthDrawMode depth_draw_mode; - CullMode cull_mode; - bool flags[FLAG_MAX]; - SpecularMode specular_mode; - DiffuseMode diffuse_mode; + BlendMode blend_mode = BLEND_MODE_MIX; + BlendMode detail_blend_mode = BLEND_MODE_MIX; + DepthDrawMode depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY; + CullMode cull_mode = CULL_BACK; + bool flags[FLAG_MAX] = {}; + SpecularMode specular_mode = SPECULAR_SCHLICK_GGX; + DiffuseMode diffuse_mode = DIFFUSE_BURLEY; BillboardMode billboard_mode; - EmissionOperator emission_op; + EmissionOperator emission_op = EMISSION_OP_ADD; TextureChannel metallic_texture_channel; TextureChannel roughness_texture_channel; TextureChannel ao_texture_channel; TextureChannel refraction_texture_channel; - AlphaAntiAliasing alpha_antialiasing_mode; + AlphaAntiAliasing alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; - bool features[FEATURE_MAX]; + bool features[FEATURE_MAX] = {}; Ref<Texture2D> textures[TEXTURE_MAX]; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 32fede1e5f..1a2b21299a 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1095,6 +1095,15 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { return true; } +void ArrayMesh::reset_state() { + clear_surfaces(); + clear_blend_shapes(); + + aabb = AABB(); + blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; + custom_aabb = AABB(); +} + void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { if (_is_generated()) { return; @@ -1156,7 +1165,7 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const RenderingServer::get_singleton()->mesh_add_surface(mesh, sd); clear_cache(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -1278,7 +1287,6 @@ void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) surfaces.write[p_idx].material = p_material; RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid()); - _change_notify("material"); emit_changed(); } @@ -1375,8 +1383,8 @@ bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_v struct ArrayMeshLightmapSurface { Ref<Material> material; LocalVector<SurfaceTool::Vertex> vertices; - Mesh::PrimitiveType primitive; - uint32_t format; + Mesh::PrimitiveType primitive = Mesh::PrimitiveType::PRIMITIVE_MAX; + uint32_t format = 0; }; Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { @@ -1565,6 +1573,19 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach return OK; } +void ArrayMesh::set_shadow_mesh(const Ref<ArrayMesh> &p_mesh) { + shadow_mesh = p_mesh; + if (shadow_mesh.is_valid()) { + RS::get_singleton()->mesh_set_shadow_mesh(mesh, shadow_mesh->get_rid()); + } else { + RS::get_singleton()->mesh_set_shadow_mesh(mesh, RID()); + } +} + +Ref<ArrayMesh> ArrayMesh::get_shadow_mesh() const { + return shadow_mesh; +} + void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape); ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count); @@ -1596,6 +1617,9 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb); ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb); + ClassDB::bind_method(D_METHOD("set_shadow_mesh", "mesh"), &ArrayMesh::set_shadow_mesh); + ClassDB::bind_method(D_METHOD("get_shadow_mesh"), &ArrayMesh::get_shadow_mesh); + ClassDB::bind_method(D_METHOD("_set_blend_shape_names", "blend_shape_names"), &ArrayMesh::_set_blend_shape_names); ClassDB::bind_method(D_METHOD("_get_blend_shape_names"), &ArrayMesh::_get_blend_shape_names); @@ -1606,6 +1630,7 @@ void ArrayMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces"); ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shadow_mesh", PROPERTY_HINT_RESOURCE_TYPE, "ArrayMesh"), "set_shadow_mesh", "get_shadow_mesh"); } void ArrayMesh::reload_from_file() { @@ -1616,13 +1641,12 @@ void ArrayMesh::reload_from_file() { Resource::reload_from_file(); - _change_notify(); + notify_property_list_changed(); } ArrayMesh::ArrayMesh() { //mesh is now created on demand //mesh = RenderingServer::get_singleton()->mesh_create(); - blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; } ArrayMesh::~ArrayMesh() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 2f25ecd60b..2ce519e644 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -176,23 +176,24 @@ class ArrayMesh : public Mesh { Array _get_surfaces() const; void _set_surfaces(const Array &p_data); + Ref<ArrayMesh> shadow_mesh; private: struct Surface { - uint32_t format; - int array_length; - int index_array_length; - PrimitiveType primitive; + uint32_t format = 0; + int array_length = 0; + int index_array_length = 0; + PrimitiveType primitive = PrimitiveType::PRIMITIVE_MAX; String name; AABB aabb; Ref<Material> material; - bool is_2d; + bool is_2d = false; }; Vector<Surface> surfaces; mutable RID mesh; AABB aabb; - BlendShapeMode blend_shape_mode; + BlendShapeMode blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; Vector<StringName> blend_shapes; AABB custom_aabb; @@ -206,6 +207,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + static void _bind_methods(); public: @@ -259,6 +262,9 @@ public: virtual void reload_from_file() override; + void set_shadow_mesh(const Ref<ArrayMesh> &p_mesh); + Ref<ArrayMesh> get_shadow_mesh() const; + ArrayMesh(); ~ArrayMesh(); diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 1b82aca386..3fb4f8f211 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -50,6 +50,28 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf int vcount = varray.size(); ERR_FAIL_COND_V(vcount == 0, ERR_INVALID_PARAMETER); + Vector<int> indices; + + if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) { + indices = arrays[Mesh::ARRAY_INDEX]; + } else { + //make code simpler + indices.resize(vcount); + int *iw = indices.ptrw(); + for (int i = 0; i < vcount; i++) { + iw[i] = i; + } + } + + int icount = indices.size(); + const int *r = indices.ptr(); + + ERR_FAIL_COND_V(icount == 0, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(icount % 3, ERR_INVALID_PARAMETER); + for (int i = 0; i < icount; i++) { + ERR_FAIL_INDEX_V(r[i], vcount, ERR_INVALID_PARAMETER); + } + clear(); format = p_mesh->surface_get_format(p_surface); material = p_mesh->surface_get_material(p_surface); @@ -128,22 +150,6 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf vertices.write[i] = v; } - Vector<int> indices; - - if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) { - indices = arrays[Mesh::ARRAY_INDEX]; - } else { - //make code simpler - indices.resize(vcount); - int *iw = indices.ptrw(); - for (int i = 0; i < vcount; i++) { - iw[i] = i; - } - } - - int icount = indices.size(); - const int *r = indices.ptr(); - Map<Point2i, int> edge_indices; for (int i = 0; i < icount; i += 3) { diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h index d8b8d85900..f5c8f11437 100644 --- a/scene/resources/mesh_data_tool.h +++ b/scene/resources/mesh_data_tool.h @@ -36,7 +36,7 @@ class MeshDataTool : public Reference { GDCLASS(MeshDataTool, Reference); - int format; + int format = 0; struct Vertex { Vector3 vertex; Color color; @@ -54,7 +54,7 @@ class MeshDataTool : public Reference { Vector<Vertex> vertices; struct Edge { - int vertex[2]; + int vertex[2] = {}; Vector<int> faces; Variant meta; }; @@ -62,8 +62,8 @@ class MeshDataTool : public Reference { Vector<Edge> edges; struct Face { - int v[3]; - int edges[3]; + int v[3] = {}; + int edges[3] = {}; Variant meta; }; diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index 96d3a5750e..ad90481fbd 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -109,14 +109,14 @@ void MeshLibrary::create_item(int p_item) { ERR_FAIL_COND(p_item < 0); ERR_FAIL_COND(item_map.has(p_item)); item_map[p_item] = Item(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_name(int p_item, const String &p_name) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].name = p_name; emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) { @@ -124,25 +124,25 @@ void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) { item_map[p_item].mesh = p_mesh; notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].shapes = p_shapes; - _change_notify(); + notify_property_list_changed(); notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].navmesh = p_navmesh; - _change_notify(); + notify_property_list_changed(); notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) { @@ -150,14 +150,14 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran item_map[p_item].navmesh_transform = p_transform; notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].preview = p_preview; emit_changed(); - _change_notify(); + notify_property_list_changed(); } String MeshLibrary::get_item_name(int p_item) const { @@ -198,14 +198,14 @@ void MeshLibrary::remove_item(int p_item) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map.erase(p_item); notify_change_to_owners(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } void MeshLibrary::clear() { item_map.clear(); notify_change_to_owners(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -264,6 +264,9 @@ Array MeshLibrary::_get_item_shapes(int p_item) const { return ret; } +void MeshLibrary::reset_state() { + clear(); +} void MeshLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("create_item", "id"), &MeshLibrary::create_item); ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 5c302fcf08..1da624c275 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -65,6 +65,7 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; static void _bind_methods(); public: diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 050e398ca4..4991887eb3 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -217,7 +217,7 @@ Ref<Mesh> MultiMesh::get_mesh() const { void MultiMesh::set_instance_count(int p_count) { ERR_FAIL_COND(p_count < 0); - RenderingServer::get_singleton()->multimesh_allocate(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data); + RenderingServer::get_singleton()->multimesh_allocate_data(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data); instance_count = p_count; } @@ -361,11 +361,6 @@ void MultiMesh::_bind_methods() { MultiMesh::MultiMesh() { multimesh = RenderingServer::get_singleton()->multimesh_create(); - use_colors = false; - use_custom_data = false; - transform_format = TRANSFORM_2D; - visible_instance_count = -1; - instance_count = 0; } MultiMesh::~MultiMesh() { diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 633d754b8e..ca5c42d47a 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -47,11 +47,11 @@ public: private: Ref<Mesh> mesh; RID multimesh; - TransformFormat transform_format; - bool use_colors; - bool use_custom_data; - int instance_count; - int visible_instance_count; + TransformFormat transform_format = TRANSFORM_2D; + bool use_colors = false; + bool use_custom_data = false; + int instance_count = 0; + int visible_instance_count = -1; protected: static void _bind_methods(); diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 43c3ef4edc..84f3c23f77 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -74,7 +74,7 @@ int NavigationMesh::get_sample_partition_type() const { void NavigationMesh::set_parsed_geometry_type(int p_value) { ERR_FAIL_COND(p_value >= PARSED_GEOMETRY_MAX); parsed_geometry_type = static_cast<ParsedGeometryType>(p_value); - _change_notify(); + notify_property_list_changed(); } int NavigationMesh::get_parsed_geometry_type() const { @@ -106,7 +106,7 @@ bool NavigationMesh::get_collision_mask_bit(int p_bit) const { void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) { ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX); source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode); - _change_notify(); + notify_property_list_changed(); } int NavigationMesh::get_source_geometry_mode() const { @@ -251,7 +251,7 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const { void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) { vertices = p_vertices; - _change_notify(); + notify_property_list_changed(); } Vector<Vector3> NavigationMesh::get_vertices() const { @@ -263,7 +263,7 @@ void NavigationMesh::_set_polygons(const Array &p_array) { for (int i = 0; i < p_array.size(); i++) { polygons.write[i].indices = p_array[i]; } - _change_notify(); + notify_property_list_changed(); } Array NavigationMesh::_get_polygons() const { @@ -280,7 +280,7 @@ void NavigationMesh::add_polygon(const Vector<int> &p_polygon) { Polygon polygon; polygon.indices = p_polygon; polygons.push_back(polygon); - _change_notify(); + notify_property_list_changed(); } int NavigationMesh::get_polygon_count() const { @@ -510,27 +510,4 @@ void NavigationMesh::_validate_property(PropertyInfo &property) const { } } -NavigationMesh::NavigationMesh() { - cell_size = 0.3f; - cell_height = 0.2f; - agent_height = 2.0f; - agent_radius = 0.6f; - agent_max_climb = 0.9f; - agent_max_slope = 45.0f; - region_min_size = 8.0f; - region_merge_size = 20.0f; - edge_max_length = 12.0f; - edge_max_error = 1.3f; - verts_per_poly = 6.0f; - detail_sample_distance = 6.0f; - detail_sample_max_error = 1.0f; - - partition_type = SAMPLE_PARTITION_WATERSHED; - parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES; - collision_mask = 0xFFFFFFFF; - source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN; - source_group_name = "navmesh"; - filter_low_hanging_obstacles = false; - filter_ledge_spans = false; - filter_walkable_low_height_spans = false; -} +NavigationMesh::NavigationMesh() {} diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 693c4184bc..966221c7c6 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -82,30 +82,30 @@ public: }; protected: - float cell_size; - float cell_height; - float agent_height; - float agent_radius; - float agent_max_climb; - float agent_max_slope; - float region_min_size; - float region_merge_size; - float edge_max_length; - float edge_max_error; - float verts_per_poly; - float detail_sample_distance; - float detail_sample_max_error; - - SamplePartitionType partition_type; - ParsedGeometryType parsed_geometry_type; - uint32_t collision_mask; - - SourceGeometryMode source_geometry_mode; - StringName source_group_name; - - bool filter_low_hanging_obstacles; - bool filter_ledge_spans; - bool filter_walkable_low_height_spans; + float cell_size = 0.3f; + float cell_height = 0.2f; + float agent_height = 2.0f; + float agent_radius = 0.6f; + float agent_max_climb = 0.9f; + float agent_max_slope = 45.0f; + float region_min_size = 8.0f; + float region_merge_size = 20.0f; + float edge_max_length = 12.0f; + float edge_max_error = 1.3f; + float verts_per_poly = 6.0f; + float detail_sample_distance = 6.0f; + float detail_sample_max_error = 1.0f; + + SamplePartitionType partition_type = SAMPLE_PARTITION_WATERSHED; + ParsedGeometryType parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES; + uint32_t collision_mask = 0xFFFFFFFF; + + SourceGeometryMode source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN; + StringName source_group_name = "navmesh"; + + bool filter_low_hanging_obstacles = false; + bool filter_ledge_spans = false; + bool filter_walkable_low_height_spans = false; public: // Recast settings diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 794b281100..ab8a4b7934 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -147,15 +147,20 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } #endif } - } else if (ClassDB::is_class_enabled(snames[n.type])) { - //node belongs to this scene and must be created - Object *obj = ClassDB::instance(snames[n.type]); + } else { + Object *obj = nullptr; + + if (ClassDB::is_class_enabled(snames[n.type])) { + //node belongs to this scene and must be created + obj = ClassDB::instance(snames[n.type]); + } + if (!Object::cast_to<Node>(obj)) { if (obj) { memdelete(obj); obj = nullptr; } - WARN_PRINT(String("Warning node of type " + snames[n.type].operator String() + " does not exist.").ascii().get_data()); + WARN_PRINT(vformat("Node %s of type %s cannot be created. A placeholder will be created instead.", snames[n.name], snames[n.type]).ascii().get_data()); if (n.parent >= 0 && n.parent < nc && ret_nodes[n.parent]) { if (Object::cast_to<Node3D>(ret_nodes[n.parent])) { obj = memnew(Node3D); @@ -172,10 +177,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } node = Object::cast_to<Node>(obj); - - } else { - //print_line("Class is disabled for: " + itos(n.type)); - //print_line("name: " + String(snames[n.type])); } if (node) { @@ -469,6 +470,11 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map p_node->get_property_list(&plist); StringName type = p_node->get_class(); + Ref<Script> script = p_node->get_script(); + if (script.is_valid()) { + script->update_exports(); + } + for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; @@ -484,7 +490,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map isdefault = bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value)); } - Ref<Script> script = p_node->get_script(); if (!isdefault && script.is_valid() && script->get_property_default_value(name, default_value)) { isdefault = bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value)); } @@ -1589,8 +1594,6 @@ void SceneState::_bind_methods() { } SceneState::SceneState() { - base_scene_idx = -1; - last_modified_time = 0; } //////////////// @@ -1663,6 +1666,9 @@ void PackedScene::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); } +void PackedScene::reset_state() { + clear(); +} void PackedScene::_bind_methods() { ClassDB::bind_method(D_METHOD("pack", "path"), &PackedScene::pack); ClassDB::bind_method(D_METHOD("instance", "edit_state"), &PackedScene::instance, DEFVAL(GEN_EDIT_STATE_DISABLED)); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index a31dcd8d39..78a0aeaa9a 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -44,7 +44,7 @@ class SceneState : public Reference { mutable HashMap<NodePath, int> node_path_cache; mutable Map<int, int> base_scene_node_remap; - int base_scene_idx; + int base_scene_idx = -1; enum { NO_PARENT_SAVED = 0x7FFFFFFF, @@ -53,16 +53,16 @@ class SceneState : public Reference { }; struct NodeData { - int parent; - int owner; - int type; - int name; - int instance; - int index; + int parent = 0; + int owner = 0; + int type = 0; + int name = 0; + int instance = 0; + int index = 0; struct Property { - int name; - int value; + int name = 0; + int value = 0; }; Vector<Property> properties; @@ -71,18 +71,17 @@ class SceneState : public Reference { struct PackState { Ref<SceneState> state; - int node; - PackState() { node = -1; } + int node = -1; }; Vector<NodeData> nodes; struct ConnectionData { - int from; - int to; - int signal; - int method; - int flags; + int from = 0; + int to = 0; + int signal = 0; + int method = 0; + int flags = 0; Vector<int> binds; }; @@ -93,7 +92,7 @@ class SceneState : public Reference { String path; - uint64_t last_modified_time; + uint64_t last_modified_time = 0; _FORCE_INLINE_ Ref<SceneState> _get_base_scene_state() const; @@ -201,6 +200,7 @@ class PackedScene : public Resource { protected: virtual bool editor_can_reload_from_file() override { return false; } // this is handled by editor better static void _bind_methods(); + virtual void reset_state() override; public: enum GenEditState { diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 73b7a5cfe9..167540eb77 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -305,6 +305,7 @@ void ParticlesMaterial::_update_shader() { code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n"; code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n"; } + code += " float tv = 0.0;\n"; code += " if (RESTART) {\n"; if (tex_parameters[PARAM_ANGLE].is_valid()) { @@ -407,64 +408,65 @@ void ParticlesMaterial::_update_shader() { code += " } else {\n"; code += " CUSTOM.y += DELTA / LIFETIME;\n"; + code += " tv = CUSTOM.y / CUSTOM.w;\n"; if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_linear_velocity = 0.0;\n"; } if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_orbit_velocity = 0.0;\n"; } } if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { - code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_angular_velocity = 0.0;\n"; } if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) { - code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_linear_accel = 0.0;\n"; } if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) { - code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_radial_accel = 0.0;\n"; } if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { - code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_tangent_accel = 0.0;\n"; } if (tex_parameters[PARAM_DAMPING].is_valid()) { - code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_damping = textureLod(damping_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_damping = 0.0;\n"; } if (tex_parameters[PARAM_ANGLE].is_valid()) { - code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_angle = textureLod(angle_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_angle = 0.0;\n"; } if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) { - code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_anim_speed = 0.0;\n"; } if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) { - code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_anim_offset = 0.0;\n"; } @@ -526,13 +528,13 @@ void ParticlesMaterial::_update_shader() { // apply color // apply hue rotation if (tex_parameters[PARAM_SCALE].is_valid()) { - code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_scale = 1.0;\n"; } if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) { - code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_hue_variation = 0.0;\n"; } @@ -553,7 +555,7 @@ void ParticlesMaterial::_update_shader() { code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; if (color_ramp.is_valid()) { - code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(CUSTOM.y, 0.0), 0.0);\n"; + code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n"; } else { code += " COLOR = hue_rot_mat * color_value;\n"; } @@ -646,7 +648,7 @@ void ParticlesMaterial::_update_shader() { code += " for(int i=0;i<emit_count;i++) {\n"; code += " uint flags = FLAG_EMIT_POSITION|FLAG_EMIT_ROT_SCALE;\n"; code += " if (sub_emitter_keep_velocity) flags|=FLAG_EMIT_VELOCITY;\n"; - code += " emit_particle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n"; + code += " emit_subparticle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n"; code += " }"; } @@ -909,7 +911,7 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { color_ramp = p_texture; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture); _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { @@ -921,7 +923,7 @@ void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_ particle_flags[p_particle_flag] = p_enable; _queue_shader_change(); if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { - _change_notify(); + notify_property_list_changed(); } } @@ -933,7 +935,7 @@ bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; - _change_notify(); + notify_property_list_changed(); _queue_shader_change(); } @@ -1064,7 +1066,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { sub_emitter_mode = p_sub_emitter_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const { @@ -1368,7 +1370,6 @@ ParticlesMaterial::ParticlesMaterial() : set_emission_box_extents(Vector3(1, 1, 1)); set_gravity(Vector3(0, -9.8, 0)); set_lifetime_randomness(0); - emission_point_count = 1; set_sub_emitter_mode(SUB_EMITTER_DISABLED); set_sub_emitter_frequency(4); @@ -1391,7 +1392,6 @@ ParticlesMaterial::ParticlesMaterial() : set_color(Color(1, 1, 1, 1)); - current_key.key = 0; current_key.invalid_key = 1; _queue_shader_change(); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 49b48a01b7..3f874bd68c 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -100,7 +100,7 @@ private: uint32_t collision_scale : 1; }; - uint32_t key; + uint32_t key = 0; bool operator<(const MaterialKey &p_key) const { return key < p_key.key; @@ -109,7 +109,7 @@ private: struct ShaderData { RID shader; - int users; + int users = 0; }; static Map<MaterialKey, ShaderData> shader_map; @@ -235,7 +235,7 @@ private: Ref<Texture2D> emission_point_texture; Ref<Texture2D> emission_normal_texture; Ref<Texture2D> emission_color_texture; - int emission_point_count; + int emission_point_count = 1; bool anim_loop; diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h index dfb2d1480b..d302800823 100644 --- a/scene/resources/physics_material.h +++ b/scene/resources/physics_material.h @@ -39,9 +39,9 @@ class PhysicsMaterial : public Resource { OBJ_SAVE_TYPE(PhysicsMaterial); RES_BASE_EXTENSION("phymat"); - real_t friction = 1; + real_t friction = 1.0; bool rough = false; - real_t bounce = 0; + real_t bounce = 0.0; bool absorbent = false; protected: diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index 410e1dba52..2f3cb634fb 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -39,13 +39,13 @@ class PolygonPathFinder : public Resource { struct Point { Vector2 pos; Set<int> connections; - float distance; - float penalty; - int prev; + float distance = 0.0; + float penalty = 0.0; + int prev = 0; }; struct Edge { - int points[2]; + int points[2] = {}; _FORCE_INLINE_ bool operator<(const Edge &p_edge) const { if (points[0] == p_edge.points[0]) { diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index a6e9e7b5d2..ba6c4591c9 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -214,7 +214,7 @@ void PrimitiveMesh::set_material(const Ref<Material> &p_material) { if (!pending_request) { // just apply it, else it'll happen when _update is called. RenderingServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); - _change_notify(); + notify_property_list_changed(); emit_changed(); }; } @@ -247,18 +247,7 @@ bool PrimitiveMesh::get_flip_faces() const { } PrimitiveMesh::PrimitiveMesh() { - flip_faces = false; - // defaults mesh = RenderingServer::get_singleton()->mesh_create(); - - // assume primitive triangles as the type, correct for all but one and it will change this :) - primitive_type = Mesh::PRIMITIVE_TRIANGLES; - - // make sure we do an update after we've finished constructing our object - pending_request = true; - - array_len = 0; - index_array_len = 0; } PrimitiveMesh::~PrimitiveMesh() { @@ -304,8 +293,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { u = i; u /= radial_segments; - x = -sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = -sin(u * Math_TAU); + z = cos(u * Math_TAU); Vector3 p = Vector3(x * radius * w, y, -z * radius * w); points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0)); @@ -343,8 +332,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { u = i; u /= radial_segments; - x = -sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = -sin(u * Math_TAU); + z = cos(u * Math_TAU); Vector3 p = Vector3(x * radius, y, -z * radius); points.push_back(p); @@ -383,8 +372,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { float u2 = i; u2 /= radial_segments; - x = -sin(u2 * (Math_PI * 2.0)); - z = cos(u2 * (Math_PI * 2.0)); + x = -sin(u2 * Math_TAU); + z = cos(u2 * Math_TAU); Vector3 p = Vector3(x * radius * w, y, -z * radius * w); points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0)); @@ -468,13 +457,7 @@ int CapsuleMesh::get_rings() const { return rings; } -CapsuleMesh::CapsuleMesh() { - // defaults - radius = 1.0; - mid_height = 1.0; - radial_segments = 64; - rings = 8; -} +CapsuleMesh::CapsuleMesh() {} /** BoxMesh @@ -725,13 +708,7 @@ int BoxMesh::get_subdivide_depth() const { return subdivide_d; } -BoxMesh::BoxMesh() { - // defaults - size = Vector3(2.0, 2.0, 2.0); - subdivide_w = 0; - subdivide_h = 0; - subdivide_d = 0; -} +BoxMesh::BoxMesh() {} /** CylinderMesh @@ -769,8 +746,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { u = i; u /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = sin(u * Math_TAU); + z = cos(u * Math_TAU); Vector3 p = Vector3(x * radius, y, z * radius); points.push_back(p); @@ -809,8 +786,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { float r = i; r /= radial_segments; - x = sin(r * (Math_PI * 2.0)); - z = cos(r * (Math_PI * 2.0)); + x = sin(r * Math_TAU); + z = cos(r * Math_TAU); u = ((x + 1.0) * 0.25); v = 0.5 + ((z + 1.0) * 0.25); @@ -845,8 +822,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { float r = i; r /= radial_segments; - x = sin(r * (Math_PI * 2.0)); - z = cos(r * (Math_PI * 2.0)); + x = sin(r * Math_TAU); + z = cos(r * Math_TAU); u = 0.5 + ((x + 1.0) * 0.25); v = 1.0 - ((z + 1.0) * 0.25); @@ -938,14 +915,7 @@ int CylinderMesh::get_rings() const { return rings; } -CylinderMesh::CylinderMesh() { - // defaults - top_radius = 1.0; - bottom_radius = 1.0; - height = 2.0; - radial_segments = 64; - rings = 4; -} +CylinderMesh::CylinderMesh() {} /** PlaneMesh @@ -1053,12 +1023,7 @@ int PlaneMesh::get_subdivide_depth() const { return subdivide_d; } -PlaneMesh::PlaneMesh() { - // defaults - size = Size2(2.0, 2.0); - subdivide_w = 0; - subdivide_d = 0; -} +PlaneMesh::PlaneMesh() {} /** PrismMesh @@ -1338,14 +1303,7 @@ int PrismMesh::get_subdivide_depth() const { return subdivide_d; } -PrismMesh::PrismMesh() { - // defaults - left_to_right = 0.5; - size = Vector3(2.0, 2.0, 2.0); - subdivide_w = 0; - subdivide_h = 0; - subdivide_d = 0; -} +PrismMesh::PrismMesh() {} /** QuadMesh @@ -1409,7 +1367,6 @@ void QuadMesh::_bind_methods() { QuadMesh::QuadMesh() { primitive_type = PRIMITIVE_TRIANGLES; - size = Size2(1.0, 1.0); } void QuadMesh::set_size(const Size2 &p_size) { @@ -1458,8 +1415,8 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const { float u = i; u /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = sin(u * Math_TAU); + z = cos(u * Math_TAU); if (is_hemisphere && y < 0.0) { points.push_back(Vector3(x * radius * w, 0.0, z * radius * w)); @@ -1561,14 +1518,7 @@ bool SphereMesh::get_is_hemisphere() const { return is_hemisphere; } -SphereMesh::SphereMesh() { - // defaults - radius = 1.0; - height = 2.0; - radial_segments = 64; - rings = 32; - is_hemisphere = false; -} +SphereMesh::SphereMesh() {} /** PointMesh diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index d0ca4b10e7..bb3df9d10e 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -49,17 +49,19 @@ private: mutable AABB aabb; AABB custom_aabb; - mutable int array_len; - mutable int index_array_len; + mutable int array_len = 0; + mutable int index_array_len = 0; Ref<Material> material; - bool flip_faces; + bool flip_faces = false; - mutable bool pending_request; + // make sure we do an update after we've finished constructing our object + mutable bool pending_request = true; void _update() const; protected: - Mesh::PrimitiveType primitive_type; + // assume primitive triangles as the type, correct for all but one and it will change this :) + Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES; static void _bind_methods(); @@ -104,10 +106,10 @@ class CapsuleMesh : public PrimitiveMesh { GDCLASS(CapsuleMesh, PrimitiveMesh); private: - float radius; - float mid_height; - int radial_segments; - int rings; + float radius = 1.0; + float mid_height = 1.0; + int radial_segments = 64; + int rings = 8; protected: static void _bind_methods(); @@ -136,10 +138,10 @@ class BoxMesh : public PrimitiveMesh { GDCLASS(BoxMesh, PrimitiveMesh); private: - Vector3 size; - int subdivide_w; - int subdivide_h; - int subdivide_d; + Vector3 size = Vector3(2.0, 2.0, 2.0); + int subdivide_w = 0; + int subdivide_h = 0; + int subdivide_d = 0; protected: static void _bind_methods(); @@ -169,11 +171,11 @@ class CylinderMesh : public PrimitiveMesh { GDCLASS(CylinderMesh, PrimitiveMesh); private: - float top_radius; - float bottom_radius; - float height; - int radial_segments; - int rings; + float top_radius = 1.0; + float bottom_radius = 1.0; + float height = 2.0; + int radial_segments = 64; + int rings = 4; protected: static void _bind_methods(); @@ -205,9 +207,9 @@ class PlaneMesh : public PrimitiveMesh { GDCLASS(PlaneMesh, PrimitiveMesh); private: - Size2 size; - int subdivide_w; - int subdivide_d; + Size2 size = Size2(2.0, 2.0); + int subdivide_w = 0; + int subdivide_d = 0; protected: static void _bind_methods(); @@ -233,11 +235,11 @@ class PrismMesh : public PrimitiveMesh { GDCLASS(PrismMesh, PrimitiveMesh); private: - float left_to_right; - Vector3 size; - int subdivide_w; - int subdivide_h; - int subdivide_d; + float left_to_right = 0.5; + Vector3 size = Vector3(2.0, 2.0, 2.0); + int subdivide_w = 0; + int subdivide_h = 0; + int subdivide_d = 0; protected: static void _bind_methods(); @@ -270,7 +272,7 @@ class QuadMesh : public PrimitiveMesh { GDCLASS(QuadMesh, PrimitiveMesh); private: - Size2 size; + Size2 size = Size2(1.0, 1.0); protected: static void _bind_methods(); @@ -290,11 +292,11 @@ class SphereMesh : public PrimitiveMesh { GDCLASS(SphereMesh, PrimitiveMesh); private: - float radius; - float height; - int radial_segments; - int rings; - bool is_hemisphere; + float radius = 1.0; + float height = 2.0; + int radial_segments = 64; + int rings = 32; + bool is_hemisphere = false; protected: static void _bind_methods(); diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp index 98fd160810..d2125445fa 100644 --- a/scene/resources/ray_shape_2d.cpp +++ b/scene/resources/ray_shape_2d.cpp @@ -45,7 +45,7 @@ void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector2 tip = Vector2(0, get_length()); RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3); Vector<Vector2> pts; - float tsize = 4; + float tsize = 4.0; pts.push_back(tip + Vector2(0, tsize)); pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0)); pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0)); @@ -99,7 +99,5 @@ bool RayShape2D::get_slips_on_slope() const { RayShape2D::RayShape2D() : Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) { - length = 20; - slips_on_slope = false; _update_shape(); } diff --git a/scene/resources/ray_shape_2d.h b/scene/resources/ray_shape_2d.h index 3570b7be52..56ecfa2722 100644 --- a/scene/resources/ray_shape_2d.h +++ b/scene/resources/ray_shape_2d.h @@ -36,8 +36,8 @@ class RayShape2D : public Shape2D { GDCLASS(RayShape2D, Shape2D); - real_t length; - bool slips_on_slope; + real_t length = 20.0; + bool slips_on_slope = false; void _update_shape(); diff --git a/scene/resources/ray_shape_3d.cpp b/scene/resources/ray_shape_3d.cpp index a332bb575f..5446b4daab 100644 --- a/scene/resources/ray_shape_3d.cpp +++ b/scene/resources/ray_shape_3d.cpp @@ -56,7 +56,6 @@ void RayShape3D::set_length(float p_length) { length = p_length; _update_shape(); notify_change_to_owners(); - _change_notify("length"); } float RayShape3D::get_length() const { @@ -67,7 +66,6 @@ void RayShape3D::set_slips_on_slope(bool p_active) { slips_on_slope = p_active; _update_shape(); notify_change_to_owners(); - _change_notify("slips_on_slope"); } bool RayShape3D::get_slips_on_slope() const { @@ -87,12 +85,7 @@ void RayShape3D::_bind_methods() { RayShape3D::RayShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_RAY)) { - length = 1.0; - slips_on_slope = false; - /* Code copied from setters to prevent the use of uninitialized variables */ _update_shape(); notify_change_to_owners(); - _change_notify("length"); - _change_notify("slips_on_slope"); } diff --git a/scene/resources/ray_shape_3d.h b/scene/resources/ray_shape_3d.h index 2c27d56c63..2da6311321 100644 --- a/scene/resources/ray_shape_3d.h +++ b/scene/resources/ray_shape_3d.h @@ -34,8 +34,8 @@ class RayShape3D : public Shape3D { GDCLASS(RayShape3D, Shape3D); - float length; - bool slips_on_slope; + float length = 1.0; + bool slips_on_slope = false; protected: static void _bind_methods(); diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index a5b909c9a7..dc4c6dc2d7 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -33,7 +33,7 @@ #include "servers/physics_server_2d.h" #include "servers/rendering_server.h" void RectangleShape2D::_update_shape() { - PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), size / 2); + PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), size * 0.5); emit_changed(); } @@ -47,11 +47,29 @@ Vector2 RectangleShape2D::get_size() const { } void RectangleShape2D::draw(const RID &p_to_rid, const Color &p_color) { - RenderingServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-size / 2, size), p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-size * 0.5, size), p_color); + if (is_collision_outline_enabled()) { + // Draw an outlined rectangle to make individual shapes easier to distinguish. + Vector<Vector2> stroke_points; + stroke_points.resize(5); + stroke_points.write[0] = -size * 0.5; + stroke_points.write[1] = Vector2(size.x, -size.y) * 0.5; + stroke_points.write[2] = size * 0.5; + stroke_points.write[3] = Vector2(-size.x, size.y) * 0.5; + stroke_points.write[4] = -size * 0.5; + + Vector<Color> stroke_colors; + stroke_colors.resize(5); + for (int i = 0; i < 5; i++) { + stroke_colors.write[i] = (p_color); + } + + RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, stroke_points, stroke_colors); + } } Rect2 RectangleShape2D::get_rect() const { - return Rect2(-size / 2, size); + return Rect2(-size * 0.5, size); } real_t RectangleShape2D::get_enclosing_radius() const { diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 433e3392e3..7ca532e1d6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -114,23 +114,8 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R } int index = token.value; - - if (use_nocache) { - r_res = int_resources[index]; - } else { - String path = local_path + "::" + itos(index); - - if (!ignore_resource_parsing) { - if (!ResourceCache::has(path)) { - r_err_str = "Can't load cached sub-resource: " + path; - return ERR_PARSE_ERROR; - } - - r_res = RES(ResourceCache::get(path)); - } else { - r_res = RES(); - } - } + ERR_FAIL_COND_V(!int_resources.has(index), ERR_INVALID_PARAMETER); + r_res = int_resources[index]; VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -440,7 +425,7 @@ Error ResourceLoaderText::load() { er.type = type; if (use_sub_threads) { - Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, local_path); + Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, ResourceFormatLoader::CACHE_MODE_REUSE, local_path); if (err != OK) { if (ResourceLoader::get_abort_on_missing_resources()) { @@ -517,29 +502,44 @@ Error ResourceLoaderText::load() { //bool exists=ResourceCache::has(path); Ref<Resource> res; + bool do_assign = false; - if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist - - Object *obj = ClassDB::instance(type); - if (!obj) { - error_text += "Can't create sub resource of type: " + type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) { + //reuse existing + Resource *r = ResourceCache::get(path); + if (r && r->get_class() == type) { + res = Ref<Resource>(r); + res->reset_state(); + do_assign = true; } + } - Resource *r = Object::cast_to<Resource>(obj); - if (!r) { - error_text += "Can't create sub resource of type, because not a resource: " + type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } + if (res.is_null()) { //not reuse + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && ResourceCache::has(path)) { //only if it doesn't exist + //cached, do not assign + Resource *r = ResourceCache::get(path); + res = Ref<Resource>(r); + } else { + //create - res = Ref<Resource>(r); - int_resources[id] = res; - if (!use_nocache) { - res->set_path(path); + Object *obj = ClassDB::instance(type); + if (!obj) { + error_text += "Can't create sub resource of type: " + type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + Resource *r = Object::cast_to<Resource>(obj); + if (!r) { + error_text += "Can't create sub resource of type, because not a resource: " + type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + res = Ref<Resource>(r); + do_assign = true; } } @@ -557,7 +557,7 @@ Error ResourceLoaderText::load() { } if (assign != String()) { - if (res.is_valid()) { + if (do_assign) { res->set(assign, value); } //it's assignment @@ -572,6 +572,11 @@ Error ResourceLoaderText::load() { } } + int_resources[id] = res; //always assign int resources + if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); + } + if (progress && resources_total > 0) { *progress = resource_current / float(resources_total); } @@ -589,23 +594,33 @@ Error ResourceLoaderText::load() { return error; } - Object *obj = ClassDB::instance(res_type); - if (!obj) { - error_text += "Can't create sub resource of type: " + res_type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(local_path)) { + Resource *r = ResourceCache::get(local_path); + if (r->get_class() == res_type) { + r->reset_state(); + resource = Ref<Resource>(r); + } } - Resource *r = Object::cast_to<Resource>(obj); - if (!r) { - error_text += "Can't create sub resource of type, because not a resource: " + res_type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } + if (!resource.is_valid()) { + Object *obj = ClassDB::instance(res_type); + if (!obj) { + error_text += "Can't create sub resource of type: " + res_type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + Resource *r = Object::cast_to<Resource>(obj); + if (!r) { + error_text += "Can't create sub resource of type, because not a resource: " + res_type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } - resource = Ref<Resource>(r); + resource = Ref<Resource>(r); + } resource_current++; @@ -620,7 +635,7 @@ Error ResourceLoaderText::load() { _printerr(); } else { error = OK; - if (!use_nocache) { + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { if (!ResourceCache::has(res_path)) { resource->set_path(res_path); } @@ -668,7 +683,7 @@ Error ResourceLoaderText::load() { error = OK; //get it here resource = packed_scene; - if (!use_nocache && !ResourceCache::has(res_path)) { + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && !ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } @@ -699,18 +714,7 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) { translation_remapped = p_remapped; } -ResourceLoaderText::ResourceLoaderText() { - use_nocache = false; - - resources_total = 0; - resource_current = 0; - - progress = nullptr; - lines = false; - translation_remapped = false; - use_sub_threads = false; - error = OK; -} +ResourceLoaderText::ResourceLoaderText() {} ResourceLoaderText::~ResourceLoaderText() { memdelete(f); @@ -1252,7 +1256,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) { ///////////////////// -RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -1265,7 +1269,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina ResourceLoaderText loader; String path = p_original_path != "" ? p_original_path : p_path; - loader.use_nocache = p_no_cache; + loader.cache_mode = p_cache_mode; loader.use_sub_threads = p_use_sub_threads; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.progress = r_progress; diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index e67a13d41a..2dc683415d 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -38,12 +38,12 @@ #include "scene/resources/packed_scene.h" class ResourceLoaderText { - bool translation_remapped; + bool translation_remapped = false; String local_path; String res_path; String error_text; - FileAccess *f; + FileAccess *f = nullptr; VariantParser::StreamFile stream; @@ -53,28 +53,28 @@ class ResourceLoaderText { String type; }; - bool is_scene; + bool is_scene = false; String res_type; - bool ignore_resource_parsing; + bool ignore_resource_parsing = false; //Map<String,String> remaps; Map<int, ExtResource> ext_resources; Map<int, RES> int_resources; - int resources_total; - int resource_current; + int resources_total = 0; + int resource_current = 0; String resource_type; VariantParser::Tag next_tag; - bool use_nocache; + ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; - bool use_sub_threads; - float *progress; + bool use_sub_threads = false; + float *progress = nullptr; - mutable int lines; + mutable int lines = 0; Map<String, String> remaps; //void _printerr(); @@ -107,7 +107,7 @@ class ResourceLoaderText { friend class ResourceFormatLoaderText; - Error error; + Error error = OK; RES resource; @@ -134,7 +134,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; @@ -152,11 +152,11 @@ class ResourceFormatSaverTextInstance { Ref<PackedScene> packed_scene; - bool takeover_paths; - bool relative_paths; - bool bundle_resources; - bool skip_editor; - FileAccess *f; + bool takeover_paths = false; + bool relative_paths = false; + bool bundle_resources = false; + bool skip_editor = false; + FileAccess *f = nullptr; struct NonPersistentKey { //for resource properties generated on the fly RES base; @@ -173,7 +173,7 @@ class ResourceFormatSaverTextInstance { struct ResourceSort { RES resource; - int index; + int index = 0; bool operator<(const ResourceSort &p_right) const { return index < p_right.index; } diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 53f3dd1a4b..77c6199794 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -152,9 +152,7 @@ void Shader::_bind_methods() { } Shader::Shader() { - mode = MODE_SPATIAL; shader = RenderingServer::get_singleton()->shader_create(); - params_cache_dirty = true; } Shader::~Shader() { @@ -163,7 +161,7 @@ Shader::~Shader() { //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/scene/resources/shader.h b/scene/resources/shader.h index a3f9330055..6563181ca2 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -51,12 +51,12 @@ public: private: RID shader; - Mode mode; + Mode mode = MODE_SPATIAL; // hack the name of performance // shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make // conversion fast and save memory. - mutable bool params_cache_dirty; + mutable bool params_cache_dirty = true; mutable Map<StringName, StringName> params_cache; //map a shader param to a material param.. Map<StringName, Ref<Texture2D>> default_textures; @@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 6f3897b0cd..013b1ef1a9 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -29,7 +29,11 @@ /*************************************************************************/ #include "shape_2d.h" + +#include "core/config/engine.h" +#include "core/config/project_settings.h" #include "servers/physics_server_2d.h" + RID Shape2D::get_rid() const { return shape; } @@ -105,9 +109,17 @@ void Shape2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias"); } +bool Shape2D::is_collision_outline_enabled() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return true; + } +#endif + return GLOBAL_DEF("debug/shapes/collision/draw_2d_outlines", true); +} + Shape2D::Shape2D(const RID &p_rid) { shape = p_rid; - custom_bias = 0; } Shape2D::~Shape2D() { diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index f5814c42f8..14bdd60e4b 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -38,7 +38,7 @@ class Shape2D : public Resource { OBJ_SAVE_TYPE(Shape2D); RID shape; - real_t custom_bias; + real_t custom_bias = 0.0; protected: static void _bind_methods(); @@ -61,6 +61,9 @@ public: /// Returns the radius of a circle that fully enclose this shape virtual real_t get_enclosing_radius() const = 0; virtual RID get_rid() const override; + + static bool is_collision_outline_enabled(); + Shape2D(); ~Shape2D(); }; diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp index e2df965138..fee8fdbde2 100644 --- a/scene/resources/skin.cpp +++ b/scene/resources/skin.cpp @@ -58,7 +58,7 @@ void Skin::set_bind_name(int p_index, const StringName &p_name) { binds_ptr[p_index].name = p_name; emit_changed(); if (notify_change) { - _change_notify(); + notify_property_list_changed(); } } @@ -81,6 +81,10 @@ void Skin::clear_binds() { emit_changed(); } +void Skin::reset_state() { + clear_binds(); +} + bool Skin::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name == "bind_count") { @@ -153,6 +157,4 @@ void Skin::_bind_methods() { } Skin::Skin() { - bind_count = 0; - binds_ptr = nullptr; } diff --git a/scene/resources/skin.h b/scene/resources/skin.h index 64fe24bbe4..f5d64f96aa 100644 --- a/scene/resources/skin.h +++ b/scene/resources/skin.h @@ -44,14 +44,15 @@ class Skin : public Resource { Vector<Bind> binds; - Bind *binds_ptr; - int bind_count; + Bind *binds_ptr = nullptr; + int bind_count = 0; protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; static void _bind_methods(); public: diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp index 8fcd92bb89..71424ba8ac 100644 --- a/scene/resources/sky.cpp +++ b/scene/resources/sky.cpp @@ -102,8 +102,6 @@ void Sky::_bind_methods() { } Sky::Sky() { - mode = PROCESS_MODE_AUTOMATIC; - radiance_size = RADIANCE_SIZE_256; sky = RS::get_singleton()->sky_create(); } diff --git a/scene/resources/sky.h b/scene/resources/sky.h index 46f645a53d..f0226d321d 100644 --- a/scene/resources/sky.h +++ b/scene/resources/sky.h @@ -59,8 +59,8 @@ public: private: RID sky; - ProcessMode mode; - RadianceSize radiance_size; + ProcessMode mode = PROCESS_MODE_AUTOMATIC; + RadianceSize radiance_size = RADIANCE_SIZE_256; Ref<Material> sky_material; protected: diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 1cdabe4662..b2efecb1cb 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -522,53 +522,59 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "}\n\n"; code += "void fragment() {\n"; - code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n"; - code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n"; - code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n"; - - code += "\t// rayleigh coefficients\n"; - code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n"; - code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n"; - code += "\t// mie coefficients from Preetham\n"; - code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n"; - - code += "\t// optical length\n"; - code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n"; - code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n"; - code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n"; - code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n"; - - code += "\t// light extinction based on thickness of atmosphere\n"; - code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n"; - - code += "\t// in scattering\n"; - code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n"; - - code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n"; - code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n"; - - code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n"; - code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n"; - - code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n"; - code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n"; - code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n"; - - code += "\t// Hack in the ground color\n"; - code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n"; - - code += "\t// Solar disk and out-scattering\n"; - code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n"; - code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n"; - code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n"; - code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n"; - code += "\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n"; - - code += "\tvec3 color = (Lin + L0) * 0.04;\n"; - code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n"; - code += "\tCOLOR *= exposure;\n"; - code += "\t// Make optional, eliminates banding\n"; - code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n"; + code += "\tif (LIGHT0_ENABLED) {\n"; + code += "\t\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n"; + code += "\t\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n"; + code += "\t\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n"; + + code += "\t\t// rayleigh coefficients\n"; + code += "\t\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n"; + code += "\t\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n"; + code += "\t\t// mie coefficients from Preetham\n"; + code += "\t\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n"; + + code += "\t\t// optical length\n"; + code += "\t\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n"; + code += "\t\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n"; + code += "\t\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n"; + code += "\t\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n"; + + code += "\t\t// light extinction based on thickness of atmosphere\n"; + code += "\t\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n"; + + code += "\t\t// in scattering\n"; + code += "\t\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n"; + + code += "\t\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n"; + code += "\t\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n"; + + code += "\t\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n"; + code += "\t\tvec3 betaMTheta = mie_beta * mie_phase;\n\n"; + + code += "\t\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n"; + code += "\t\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n"; + code += "\t\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n"; + + code += "\t\t// Hack in the ground color\n"; + code += "\t\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n"; + + code += "\t\t// Solar disk and out-scattering\n"; + code += "\t\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n"; + code += "\t\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n"; + code += "\t\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n"; + code += "\t\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n"; + code += "\t\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n"; + + code += "\t\tvec3 color = (Lin + L0) * 0.04;\n"; + code += "\t\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n"; + code += "\t\tCOLOR *= exposure;\n"; + code += "\t\t// Make optional, eliminates banding\n"; + code += "\t\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n"; + code += "\t} else {\n"; + code += "\t\t// There is no sun, so display night_sky and nothing else\n"; + code += "\t\tCOLOR = texture(night_sky, SKY_COORDS).xyz * 0.04;\n"; + code += "\t\tCOLOR *= exposure;\n"; + code += "\t}\n"; code += "}\n"; shader = RS::get_singleton()->shader_create(); @@ -591,5 +597,4 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { PhysicalSkyMaterial::~PhysicalSkyMaterial() { RS::get_singleton()->free(shader); - RS::get_singleton()->material_set_shader(_get_material(), RID()); } diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp index 008cb3e1d6..e4b4398063 100644 --- a/scene/resources/sphere_shape_3d.cpp +++ b/scene/resources/sphere_shape_3d.cpp @@ -66,7 +66,6 @@ void SphereShape3D::set_radius(float p_radius) { radius = p_radius; _update_shape(); notify_change_to_owners(); - _change_notify("radius"); } float SphereShape3D::get_radius() const { diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 93bab1b042..9b80224c3f 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -123,7 +123,6 @@ void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) { } emit_signal("texture_changed"); emit_changed(); - _change_notify("texture"); } Ref<Texture2D> StyleBoxTexture::get_texture() const { @@ -135,13 +134,6 @@ void StyleBoxTexture::set_margin_size(Side p_side, float p_size) { margin[p_side] = p_size; emit_changed(); - static const char *margin_prop[4] = { - "content_margin_left", - "content_margin_top", - "content_margin_right", - "content_margin_bottom", - }; - _change_notify(margin_prop[p_side]); } float StyleBoxTexture::get_margin_size(Side p_side) const { @@ -228,7 +220,6 @@ void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) { region_rect = p_region_rect; emit_changed(); - _change_notify("region"); } Rect2 StyleBoxTexture::get_region_rect() const { @@ -320,20 +311,9 @@ void StyleBoxTexture::_bind_methods() { BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE_FIT); } -StyleBoxTexture::StyleBoxTexture() { - for (int i = 0; i < 4; i++) { - margin[i] = 0; - expand_margin[i] = 0; - } - draw_center = true; - modulate = Color(1, 1, 1, 1); +StyleBoxTexture::StyleBoxTexture() {} - axis_h = AXIS_STRETCH_MODE_STRETCH; - axis_v = AXIS_STRETCH_MODE_STRETCH; -} - -StyleBoxTexture::~StyleBoxTexture() { -} +StyleBoxTexture::~StyleBoxTexture() {} //////////////// @@ -395,10 +375,10 @@ void StyleBoxFlat::set_corner_radius_all(int radius) { emit_changed(); } -void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left) { +void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_bottom_right, const int radius_bottom_left) { corner_radius[0] = radius_top_left; corner_radius[1] = radius_top_right; - corner_radius[2] = radius_botton_right; + corner_radius[2] = radius_bottom_right; corner_radius[3] = radius_bottom_left; emit_changed(); @@ -576,8 +556,8 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color color = outer_color; corner_point = outer_points[corner_index]; } - float x = radius * (float)cos((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.x; - float y = radius * (float)sin((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.y; + real_t x = radius * (real_t)cos((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.x; + real_t y = radius * (real_t)sin((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.y; verts.push_back(Vector2(x, y)); colors.push_back(color); } @@ -888,38 +868,9 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "anti_aliasing_size", PROPERTY_HINT_RANGE, "1,5,1"), "set_aa_size", "get_aa_size"); } -StyleBoxFlat::StyleBoxFlat() { - bg_color = Color(0.6, 0.6, 0.6); - shadow_color = Color(0, 0, 0, 0.6); - border_color = Color(0.8, 0.8, 0.8); - - blend_border = false; - draw_center = true; - anti_aliased = true; - - shadow_size = 0; - shadow_offset = Point2(0, 0); - corner_detail = 8; - aa_size = 1; - - border_width[0] = 0; - border_width[1] = 0; - border_width[2] = 0; - border_width[3] = 0; - - expand_margin[0] = 0; - expand_margin[1] = 0; - expand_margin[2] = 0; - expand_margin[3] = 0; - - corner_radius[0] = 0; - corner_radius[1] = 0; - corner_radius[2] = 0; - corner_radius[3] = 0; -} +StyleBoxFlat::StyleBoxFlat() {} -StyleBoxFlat::~StyleBoxFlat() { -} +StyleBoxFlat::~StyleBoxFlat() {} void StyleBoxLine::set_color(const Color &p_color) { color = p_color; @@ -986,8 +937,17 @@ void StyleBoxLine::_bind_methods() { } float StyleBoxLine::get_style_margin(Side p_side) const { - ERR_FAIL_INDEX_V((int)p_side, 4, thickness); - return thickness; + ERR_FAIL_INDEX_V((int)p_side, 4, 0); + + if (vertical) { + if (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) { + return thickness / 2.0; + } + } else if (p_side == SIDE_TOP || p_side == SIDE_BOTTOM) { + return thickness / 2.0; + } + + return 0; } Size2 StyleBoxLine::get_center_size() const { @@ -1011,12 +971,6 @@ void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const { vs->canvas_item_add_rect(p_canvas_item, r, color); } -StyleBoxLine::StyleBoxLine() { - grow_begin = 1.0; - grow_end = 1.0; - thickness = 1; - color = Color(0.0, 0.0, 0.0); - vertical = false; -} +StyleBoxLine::StyleBoxLine() {} StyleBoxLine::~StyleBoxLine() {} diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 53ce72790a..8a273afbfd 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -86,14 +86,14 @@ public: }; private: - float expand_margin[4]; - float margin[4]; + float expand_margin[4] = {}; + float margin[4] = {}; Rect2 region_rect; Ref<Texture2D> texture; - bool draw_center; - Color modulate; - AxisStretchMode axis_h; - AxisStretchMode axis_v; + bool draw_center = true; + Color modulate = Color(1, 1, 1, 1); + AxisStretchMode axis_h = AXIS_STRETCH_MODE_STRETCH; + AxisStretchMode axis_v = AXIS_STRETCH_MODE_STRETCH; protected: virtual float get_style_margin(Side p_side) const override; @@ -139,22 +139,22 @@ VARIANT_ENUM_CAST(StyleBoxTexture::AxisStretchMode) class StyleBoxFlat : public StyleBox { GDCLASS(StyleBoxFlat, StyleBox); - Color bg_color; - Color shadow_color; - Color border_color; + Color bg_color = Color(0.6, 0.6, 0.6); + Color shadow_color = Color(0, 0, 0, 0.6); + Color border_color = Color(0.8, 0.8, 0.8); - int border_width[4]; - int expand_margin[4]; - int corner_radius[4]; + int border_width[4] = {}; + int expand_margin[4] = {}; + int corner_radius[4] = {}; - bool draw_center; - bool blend_border; - bool anti_aliased; + bool draw_center = true; + bool blend_border = false; + bool anti_aliased = true; - int corner_detail; - int shadow_size; + int corner_detail = 8; + int shadow_size = 0; Point2 shadow_offset; - int aa_size; + int aa_size = 1; protected: virtual float get_style_margin(Side p_side) const override; @@ -183,7 +183,7 @@ public: //CORNER void set_corner_radius_all(int radius); - void set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left); + void set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_bottom_right, const int radius_bottom_left); void set_corner_radius(Corner p_corner, const int radius); int get_corner_radius(Corner p_corner) const; @@ -231,10 +231,10 @@ public: class StyleBoxLine : public StyleBox { GDCLASS(StyleBoxLine, StyleBox); Color color; - int thickness; - bool vertical; - float grow_begin; - float grow_end; + int thickness = 1; + bool vertical = false; + float grow_begin = 1.0; + float grow_end = 1.0; protected: virtual float get_style_margin(Side p_side) const override; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index c1c87be42d..47933bd69a 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -35,6 +35,8 @@ SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr; SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr; +SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr; +SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr; bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { if (vertex != p_vertex.vertex) { @@ -158,7 +160,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { //cap weights.resize(expected_vertices); //renormalize - float total = 0; + float total = 0.0; for (int i = 0; i < expected_vertices; i++) { total += weights[i].weight; } @@ -297,6 +299,7 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect void SurfaceTool::add_index(int p_index) { ERR_FAIL_COND(!begun); + ERR_FAIL_COND(p_index < 0); format |= Mesh::ARRAY_FORMAT_INDEX; index_array.push_back(p_index); @@ -1194,12 +1197,7 @@ void SurfaceTool::_bind_methods() { } SurfaceTool::SurfaceTool() { - first = false; - begun = false; for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { last_custom_format[i] = CUSTOM_MAX; } - primitive = Mesh::PRIMITIVE_LINES; - skin_weights = SKIN_4_WEIGHTS; - format = 0; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index dcb689bfc0..17efdcba71 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -78,6 +78,10 @@ public: static OptimizeVertexCacheFunc optimize_vertex_cache_func; typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_error); static SimplifyFunc simplify_func; + typedef float (*SimplifyScaleFunc)(const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride); + static SimplifyScaleFunc simplify_scale_func; + typedef size_t (*SimplifySloppyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *out_result_error); + static SimplifySloppyFunc simplify_sloppy_func; private: struct VertexHasher { @@ -85,17 +89,17 @@ private: }; struct WeightSort { - int index; - float weight; + int index = 0; + float weight = 0.0; bool operator<(const WeightSort &p_right) const { return weight < p_right.weight; } }; - bool begun; - bool first; - Mesh::PrimitiveType primitive; - uint32_t format; + bool begun = false; + bool first = false; + Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_LINES; + uint32_t format = 0; Ref<Material> material; //arrays LocalVector<Vertex> vertex_array; @@ -111,7 +115,7 @@ private: Plane last_tangent; uint32_t last_smooth_group = 0; - SkinWeightCount skin_weights; + SkinWeightCount skin_weights = SKIN_4_WEIGHTS; Color last_custom[RS::ARRAY_CUSTOM_COUNT]; diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index f3f881a774..9dd00849f4 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -110,16 +110,13 @@ TextEdit *SyntaxHighlighter::get_text_edit() { } void SyntaxHighlighter::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::get_line_syntax_highlighting); + ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "line"), &SyntaxHighlighter::get_line_syntax_highlighting); ClassDB::bind_method(D_METHOD("update_cache"), &SyntaxHighlighter::update_cache); ClassDB::bind_method(D_METHOD("clear_highlighting_cache"), &SyntaxHighlighter::clear_highlighting_cache); ClassDB::bind_method(D_METHOD("get_text_edit"), &SyntaxHighlighter::get_text_edit); - ClassDB::bind_method(D_METHOD("_get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::_get_line_syntax_highlighting); - ClassDB::bind_method(D_METHOD("_update_cache"), &SyntaxHighlighter::_update_cache); - ClassDB::bind_method(D_METHOD("_clear_highlighting_cache"), &SyntaxHighlighter::_clear_highlighting_cache); - - BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "p_line"))); + BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "line"))); + BIND_VMETHOD(MethodInfo("_clear_highlighting_cache")); BIND_VMETHOD(MethodInfo("_update_cache")); } @@ -576,11 +573,11 @@ void CodeHighlighter::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_member_keyword_colors"), &CodeHighlighter::clear_member_keyword_colors); ClassDB::bind_method(D_METHOD("get_member_keyword_colors"), &CodeHighlighter::get_member_keyword_colors); - ClassDB::bind_method(D_METHOD("add_color_region", "p_start_key", "p_end_key", "p_color", "p_line_only"), &CodeHighlighter::add_color_region, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("remove_color_region", "p_start_key"), &CodeHighlighter::remove_color_region); - ClassDB::bind_method(D_METHOD("has_color_region", "p_start_key"), &CodeHighlighter::has_color_region); + ClassDB::bind_method(D_METHOD("add_color_region", "start_key", "end_key", "color", "line_only"), &CodeHighlighter::add_color_region, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("remove_color_region", "start_key"), &CodeHighlighter::remove_color_region); + ClassDB::bind_method(D_METHOD("has_color_region", "start_key"), &CodeHighlighter::has_color_region); - ClassDB::bind_method(D_METHOD("set_color_regions", "p_color_regions"), &CodeHighlighter::set_color_regions); + ClassDB::bind_method(D_METHOD("set_color_regions", "color_regions"), &CodeHighlighter::set_color_regions); ClassDB::bind_method(D_METHOD("clear_color_regions"), &CodeHighlighter::clear_color_regions); ClassDB::bind_method(D_METHOD("get_color_regions"), &CodeHighlighter::get_color_regions); diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index c9db8e31a2..f3964b0c8f 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -75,7 +75,7 @@ private: Color color; String start_key; String end_key; - bool line_only; + bool line_only = false; }; Vector<ColorRegion> color_regions; Map<int, int> color_region_cache; diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index ed69c093cf..925867a1f2 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -167,6 +167,7 @@ void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) { } bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { + ERR_FAIL_COND_V(p_fonts.is_null(), false); bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h index 3e0a74a84b..74d4f2c32c 100644 --- a/scene/resources/text_line.h +++ b/scene/resources/text_line.h @@ -45,7 +45,7 @@ class TextLine : public Reference { bool dirty = true; - float width = -1; + float width = -1.0; uint8_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; HAlign align = HALIGN_LEFT; diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 94957df510..444a4bb22a 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -243,6 +243,7 @@ TextServer::Orientation TextParagraph::get_orientation() const { } bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins, const Dictionary &p_opentype_features, const String &p_language) { + ERR_FAIL_COND_V(p_fonts.is_null(), false); TS->shaped_text_clear(dropcap_rid); dropcap_margins = p_dropcap_margins; bool res = TS->shaped_text_add_string(dropcap_rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); @@ -257,6 +258,7 @@ void TextParagraph::clear_dropcap() { } bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { + ERR_FAIL_COND_V(p_fonts.is_null(), false); bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index e58c157b01..a16fa8c3c4 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -50,7 +50,7 @@ class TextParagraph : public Reference { bool dirty_lines = true; - float width = -1; + float width = -1.0; uint8_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; HAlign align = HALIGN_LEFT; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 342a97fd85..8cccf81659 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -94,7 +94,7 @@ void ImageTexture::reload_from_file() { create_from_image(img); } else { Resource::reload_from_file(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -146,7 +146,7 @@ void ImageTexture::_reload_hook(const RID &p_hook) { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(img); RenderingServer::get_singleton()->texture_replace(texture, new_texture); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -163,7 +163,7 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image) { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image); RenderingServer::get_singleton()->texture_replace(texture, new_texture); } - _change_notify(); + notify_property_list_changed(); emit_changed(); image_stored = true; @@ -189,7 +189,7 @@ void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) { RenderingServer::get_singleton()->texture_2d_update(texture, p_image); } - _change_notify(); + notify_property_list_changed(); emit_changed(); alpha_cache.unref(); @@ -310,12 +310,7 @@ void ImageTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook); } -ImageTexture::ImageTexture() { - w = h = 0; - image_stored = false; - mipmaps = false; - format = Image::FORMAT_L8; -} +ImageTexture::ImageTexture() {} ImageTexture::~ImageTexture() { if (texture.is_valid()) { @@ -617,7 +612,7 @@ Error StreamTexture2D::load(const String &p_path) { } #endif - _change_notify(); + notify_property_list_changed(); emit_changed(); return OK; } @@ -733,11 +728,7 @@ void StreamTexture2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); } -StreamTexture2D::StreamTexture2D() { - format = Image::FORMAT_MAX; - w = 0; - h = 0; -} +StreamTexture2D::StreamTexture2D() {} StreamTexture2D::~StreamTexture2D() { if (texture.is_valid()) { @@ -745,7 +736,7 @@ StreamTexture2D::~StreamTexture2D() { } } -RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<StreamTexture2D> st; st.instance(); Error err = st->load(p_path); @@ -968,7 +959,7 @@ Error StreamTexture3D::load(const String &p_path) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } - _change_notify(); + notify_property_list_changed(); emit_changed(); return OK; } @@ -1033,13 +1024,7 @@ void StreamTexture3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); } -StreamTexture3D::StreamTexture3D() { - format = Image::FORMAT_MAX; - w = 0; - h = 0; - d = 0; - mipmaps = false; -} +StreamTexture3D::StreamTexture3D() {} StreamTexture3D::~StreamTexture3D() { if (texture.is_valid()) { @@ -1049,7 +1034,7 @@ StreamTexture3D::~StreamTexture3D() { ///////////////////////////// -RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<StreamTexture3D> st; st.instance(); Error err = st->load(p_path); @@ -1125,7 +1110,6 @@ void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) { } atlas = p_atlas; emit_changed(); - _change_notify("atlas"); } Ref<Texture2D> AtlasTexture::get_atlas() const { @@ -1138,7 +1122,6 @@ void AtlasTexture::set_region(const Rect2 &p_region) { } region = p_region; emit_changed(); - _change_notify("region"); } Rect2 AtlasTexture::get_region() const { @@ -1151,7 +1134,6 @@ void AtlasTexture::set_margin(const Rect2 &p_margin) { } margin = p_margin; emit_changed(); - _change_notify("margin"); } Rect2 AtlasTexture::get_margin() const { @@ -1161,7 +1143,6 @@ Rect2 AtlasTexture::get_margin() const { void AtlasTexture::set_filter_clip(const bool p_enable) { filter_clip = p_enable; emit_changed(); - _change_notify("filter_clip"); } bool AtlasTexture::has_filter_clip() const { @@ -1295,9 +1276,7 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { return atlas->is_pixel_opaque(x, y); } -AtlasTexture::AtlasTexture() { - filter_clip = false; -} +AtlasTexture::AtlasTexture() {} ///////////////////////////////////////// @@ -1698,9 +1677,7 @@ RID CurveTexture::get_rid() const { return _texture; } -CurveTexture::CurveTexture() { - _width = 2048; -} +CurveTexture::CurveTexture() {} CurveTexture::~CurveTexture() { if (_texture.is_valid()) { @@ -1711,9 +1688,6 @@ CurveTexture::~CurveTexture() { ////////////////// GradientTexture::GradientTexture() { - update_pending = false; - width = 2048; - _queue_update(); } @@ -1926,7 +1900,7 @@ void AnimatedTexture::_update_proxy() { } } time -= frame_limit; - _change_notify("current_frame"); + } else { break; } @@ -2128,28 +2102,12 @@ AnimatedTexture::AnimatedTexture() { proxy = RS::get_singleton()->texture_proxy_create(proxy_ph); RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true); - time = 0; - frame_count = 1; - fps = 4; - prev_ticks = 0; - current_frame = 0; - pause = false; - oneshot = false; RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy)); - -#ifndef NO_THREADS - rw_lock = RWLock::create(); -#else - rw_lock = nullptr; -#endif } AnimatedTexture::~AnimatedTexture() { RS::get_singleton()->free(proxy); RS::get_singleton()->free(proxy_ph); - if (rw_lock) { - memdelete(rw_lock); - } } /////////////////////////////// @@ -2297,11 +2255,6 @@ void ImageTextureLayered::_bind_methods() { ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) { layered_type = p_layered_type; - format = Image::FORMAT_MAX; - - width = 0; - height = 0; - layers = 0; } ImageTextureLayered::~ImageTextureLayered() { @@ -2398,7 +2351,7 @@ Error StreamTextureLayered::load(const String &p_path) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } - _change_notify(); + notify_property_list_changed(); emit_changed(); return OK; } @@ -2469,11 +2422,6 @@ void StreamTextureLayered::_bind_methods() { StreamTextureLayered::StreamTextureLayered(LayeredType p_type) { layered_type = p_type; - format = Image::FORMAT_MAX; - w = 0; - h = 0; - layers = 0; - mipmaps = false; } StreamTextureLayered::~StreamTextureLayered() { @@ -2484,7 +2432,7 @@ StreamTextureLayered::~StreamTextureLayered() { ///////////////////////////////////////////////// -RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<StreamTextureLayered> st; if (p_path.get_extension().to_lower() == "stexarray") { Ref<StreamTexture2DArray> s; @@ -2602,7 +2550,7 @@ Ref<Image> CameraTexture::get_data() const { void CameraTexture::set_camera_feed_id(int p_new_id) { camera_feed_id = p_new_id; - _change_notify(); + notify_property_list_changed(); } int CameraTexture::get_camera_feed_id() const { @@ -2611,7 +2559,7 @@ int CameraTexture::get_camera_feed_id() const { void CameraTexture::set_which_feed(CameraServer::FeedImage p_which) { which_feed = p_which; - _change_notify(); + notify_property_list_changed(); } CameraServer::FeedImage CameraTexture::get_which_feed() const { @@ -2622,7 +2570,7 @@ void CameraTexture::set_camera_active(bool p_active) { Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id); if (feed.is_valid()) { feed->set_active(p_active); - _change_notify(); + notify_property_list_changed(); } } @@ -2635,10 +2583,7 @@ bool CameraTexture::get_camera_active() const { } } -CameraTexture::CameraTexture() { - camera_feed_id = 0; - which_feed = CameraServer::FEED_RGBA_IMAGE; -} +CameraTexture::CameraTexture() {} CameraTexture::~CameraTexture() { // nothing to do here yet diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 3bbce050f7..a0d917fd86 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -83,12 +83,13 @@ class ImageTexture : public Texture2D { RES_BASE_EXTENSION("tex"); mutable RID texture; - Image::Format format; - bool mipmaps; - int w, h; + Image::Format format = Image::FORMAT_L8; + bool mipmaps = false; + int w = 0; + int h = 0; Size2 size_override; mutable Ref<BitMap> alpha_cache; - bool image_stored; + bool image_stored = false; protected: virtual void reload_from_file() override; @@ -160,8 +161,9 @@ private: Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0); String path_to_file; mutable RID texture; - Image::Format format; - int w, h; + Image::Format format = Image::FORMAT_MAX; + int w = 0; + int h = 0; mutable Ref<BitMap> alpha_cache; virtual void reload_from_file() override; @@ -209,7 +211,7 @@ public: class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -223,7 +225,7 @@ protected: Ref<Texture2D> atlas; Rect2 region; Rect2 margin; - bool filter_clip; + bool filter_clip = false; static void _bind_methods(); @@ -370,12 +372,12 @@ class ImageTextureLayered : public TextureLayered { LayeredType layered_type; mutable RID texture; - Image::Format format; + Image::Format format = Image::FORMAT_MAX; - int width; - int height; - int layers; - bool mipmaps; + int width = 0; + int height = 0; + int layers = 0; + bool mipmaps = false; Error _create_from_images(const Array &p_images); @@ -453,10 +455,12 @@ private: Error _load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit = 0); String path_to_file; mutable RID texture; - Image::Format format; - int w, h, layers; - bool mipmaps; - LayeredType layered_type; + Image::Format format = Image::FORMAT_MAX; + int w = 0; + int h = 0; + int layers = 0; + bool mipmaps = false; + LayeredType layered_type = LayeredType::LAYERED_TYPE_2D_ARRAY; virtual void reload_from_file() override; @@ -509,7 +513,7 @@ public: class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -594,9 +598,11 @@ private: Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps); String path_to_file; mutable RID texture; - Image::Format format; - int w, h, d; - bool mipmaps; + Image::Format format = Image::FORMAT_MAX; + int w = 0; + int h = 0; + int d = 0; + bool mipmaps = false; virtual void reload_from_file() override; @@ -625,7 +631,7 @@ public: class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -638,7 +644,7 @@ class CurveTexture : public Texture2D { private: mutable RID _texture; Ref<Curve> _curve; - int _width; + int _width = 2048; void _update(); @@ -680,7 +686,7 @@ class GradientTexture : public Texture2D { public: struct Point { - float offset; + float offset = 0.0; Color color; bool operator<(const Point &p_ponit) const { return offset < p_ponit.offset; @@ -689,9 +695,9 @@ public: private: Ref<Gradient> gradient; - bool update_pending; + bool update_pending = false; RID texture; - int width; + int width = 2048; void _queue_update(); void _update(); @@ -745,7 +751,7 @@ class AnimatedTexture : public Texture2D { GDCLASS(AnimatedTexture, Texture2D); //use readers writers lock for this, since its far more times read than written to - RWLock *rw_lock; + RWLock rw_lock; public: enum { @@ -758,23 +764,19 @@ private: struct Frame { Ref<Texture2D> texture; - float delay_sec; - - Frame() { - delay_sec = 0; - } + float delay_sec = 0.0; }; Frame frames[MAX_FRAMES]; - int frame_count; - int current_frame; - bool pause; - bool oneshot; - float fps; + int frame_count = 1.0; + int current_frame = 0; + bool pause = false; + bool oneshot = false; + float fps = 4.0; - float time; + float time = 0.0; - uint64_t prev_ticks; + uint64_t prev_ticks = 0; void _update_proxy(); @@ -822,8 +824,8 @@ class CameraTexture : public Texture2D { GDCLASS(CameraTexture, Texture2D); private: - int camera_feed_id; - CameraServer::FeedImage which_feed; + int camera_feed_id = 0; + CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE; protected: static void _bind_methods(); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 5279f59d77..0405ea98bb 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -358,7 +358,7 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -373,7 +373,7 @@ void Theme::set_default_theme_font_size(int p_font_size) { default_theme_font_size = p_font_size; - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -436,7 +436,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, co } if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -463,7 +463,7 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_node_type) icon_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -506,7 +506,7 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_node_type } if (new_value) { - _change_notify(); + notify_property_list_changed(); } emit_changed(); } @@ -533,7 +533,7 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_node_ty style_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -576,7 +576,7 @@ void Theme::set_font(const StringName &p_name, const StringName &p_node_type, co } if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -604,7 +604,7 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_node_type) } font_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -637,7 +637,7 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_node_typ font_size_map[p_node_type][p_name] = p_font_size; if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -661,7 +661,7 @@ void Theme::clear_font_size(const StringName &p_name, const StringName &p_node_t ERR_FAIL_COND(!font_size_map[p_node_type].has(p_name)); font_size_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -685,7 +685,7 @@ void Theme::set_color(const StringName &p_name, const StringName &p_node_type, c color_map[p_node_type][p_name] = p_color; if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -707,7 +707,7 @@ void Theme::clear_color(const StringName &p_name, const StringName &p_node_type) ERR_FAIL_COND(!color_map[p_node_type].has(p_name)); color_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -739,7 +739,7 @@ void Theme::set_constant(const StringName &p_name, const StringName &p_node_type constant_map[p_node_type][p_name] = p_constant; if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -761,7 +761,7 @@ void Theme::clear_constant(const StringName &p_name, const StringName &p_node_ty ERR_FAIL_COND(!constant_map[p_node_type].has(p_name)); constant_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -835,7 +835,7 @@ void Theme::clear() { color_map.clear(); constant_map.clear(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -887,7 +887,7 @@ void Theme::copy_theme(const Ref<Theme> &p_other) { color_map = p_other->color_map; constant_map = p_other->constant_map; - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -930,6 +930,9 @@ void Theme::get_type_list(List<StringName> *p_list) const { } } +void Theme::reset_state() { + clear(); +} void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("set_icon", "name", "node_type", "texture"), &Theme::set_icon); ClassDB::bind_method(D_METHOD("get_icon", "name", "node_type"), &Theme::get_icon); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index c802ba2536..35481126ea 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -80,6 +80,8 @@ protected: static void _bind_methods(); + virtual void reset_state() override; + public: static Ref<Theme> get_default(); static void set_default(const Ref<Theme> &p_default); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index ae536a2928..84be69d0d6 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -369,14 +369,14 @@ void TileSet::create_tile(int p_id) { ERR_FAIL_COND(tile_map.has(p_id)); tile_map[p_id] = TileData(); tile_map[p_id].autotile_data = AutotileData(); - _change_notify(""); + notify_property_list_changed(); emit_changed(); } void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].autotile_data.bitmask_mode = p_mode; - _change_notify(""); + notify_property_list_changed(); emit_changed(); } @@ -389,7 +389,6 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].texture = p_texture; emit_changed(); - _change_notify("texture"); } Ref<Texture2D> TileSet::tile_get_texture(int p_id) const { @@ -412,7 +411,6 @@ void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].modulate = p_modulate; emit_changed(); - _change_notify("modulate"); } Color TileSet::tile_get_modulate(int p_id) const { @@ -435,7 +433,6 @@ void TileSet::tile_set_region(int p_id, const Rect2 &p_region) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].region = p_region; emit_changed(); - _change_notify("region"); } Rect2 TileSet::tile_get_region(int p_id) const { @@ -447,7 +444,6 @@ void TileSet::tile_set_tile_mode(int p_id, TileMode p_tile_mode) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].tile_mode = p_tile_mode; emit_changed(); - _change_notify("tile_mode"); } TileSet::TileMode TileSet::tile_get_tile_mode(int p_id) const { @@ -669,7 +665,6 @@ void TileSet::tile_set_name(int p_id, const String &p_name) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].name = p_name; emit_changed(); - _change_notify("name"); } String TileSet::tile_get_name(int p_id) const { @@ -1060,7 +1055,7 @@ bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) { void TileSet::remove_tile(int p_id) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map.erase(p_id); - _change_notify(""); + notify_property_list_changed(); emit_changed(); } @@ -1081,9 +1076,13 @@ int TileSet::find_tile_by_name(const String &p_name) const { return -1; } +void TileSet::reset_state() { + clear(); +} + void TileSet::clear() { tile_map.clear(); - _change_notify(""); + notify_property_list_changed(); emit_changed(); } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 210520350f..0a8721f35b 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -136,6 +136,8 @@ protected: static void _bind_methods(); + virtual void reset_state() override; + public: void create_tile(int p_id); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 2e2077d811..859546694f 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -33,6 +33,7 @@ #include "core/templates/vmap.h" #include "servers/rendering/shader_types.h" #include "visual_shader_nodes.h" +#include "visual_shader_sdf_nodes.h" bool VisualShaderNode::is_simple_decl() const { return simple_decl; @@ -486,6 +487,22 @@ void VisualShader::remove_node(Type p_type, int p_id) { _queue_update(); } +void VisualShader::replace_node(Type p_type, int p_id, const StringName &p_new_class) { + ERR_FAIL_INDEX(p_type, TYPE_MAX); + ERR_FAIL_COND(p_id < 2); + Graph *g = &graph[p_type]; + ERR_FAIL_COND(!g->nodes.has(p_id)); + + if (g->nodes[p_id].node->get_class_name() == p_new_class) { + return; + } + VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(p_new_class)); + vsn->connect("changed", callable_mp(this, &VisualShader::_queue_update)); + g->nodes[p_id].node = Ref<VisualShaderNode>(vsn); + + _queue_update(); +} + bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false); const Graph *g = &graph[p_type]; @@ -568,6 +585,12 @@ bool VisualShader::is_port_types_compatible(int p_a, int p_b) const { void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { ERR_FAIL_INDEX(p_type, TYPE_MAX); Graph *g = &graph[p_type]; + + ERR_FAIL_COND(!g->nodes.has(p_from_node)); + ERR_FAIL_INDEX(p_from_port, g->nodes[p_from_node].node->get_output_port_count()); + ERR_FAIL_COND(!g->nodes.has(p_to_node)); + ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count()); + Connection c; c.from_node = p_from_node; c.from_port = p_from_port; @@ -658,6 +681,8 @@ void VisualShader::get_node_connections(Type p_type, List<Connection> *r_connect } void VisualShader::set_mode(Mode p_mode) { + ERR_FAIL_INDEX_MSG(p_mode, Mode::MODE_MAX, vformat("Invalid shader mode: %d.", p_mode)); + if (shader_mode == p_mode) { return; } @@ -713,7 +738,7 @@ void VisualShader::set_mode(Mode p_mode) { } _queue_update(); - _change_notify(); + notify_property_list_changed(); } void VisualShader::set_graph_offset(const Vector2 &p_offset) { @@ -1078,6 +1103,12 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { return false; } +void VisualShader::reset_state() { +#ifndef _MSC_VER +#warning everything needs to be cleared here +#endif + emit_changed(); +} void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { //mode p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Node3D,CanvasItem,Particles,Sky")); @@ -1375,11 +1406,11 @@ bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const Strin } void VisualShader::_update_shader() const { - if (!dirty) { + if (!dirty.is_set()) { return; } - dirty = false; + dirty.clear(); StringBuilder global_code; StringBuilder global_code_per_node; @@ -1565,15 +1596,16 @@ void VisualShader::_update_shader() const { } void VisualShader::_queue_update() { - if (dirty) { + if (dirty.is_set()) { return; } - dirty = true; + dirty.set(); call_deferred("_update_shader"); } void VisualShader::_input_type_changed(Type p_type, int p_id) { + ERR_FAIL_INDEX(p_type, TYPE_MAX); //erase connections using this input, as type changed Graph *g = &graph[p_type]; @@ -1588,7 +1620,7 @@ void VisualShader::_input_type_changed(Type p_type, int p_id) { } void VisualShader::rebuild() { - dirty = true; + dirty.set(); _update_shader(); } @@ -1605,6 +1637,7 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_valid_node_id", "type"), &VisualShader::get_valid_node_id); ClassDB::bind_method(D_METHOD("remove_node", "type", "id"), &VisualShader::remove_node); + ClassDB::bind_method(D_METHOD("replace_node", "type", "id", "new_class"), &VisualShader::replace_node); ClassDB::bind_method(D_METHOD("is_node_connection", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection); ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::can_connect_nodes); @@ -1641,6 +1674,7 @@ void VisualShader::_bind_methods() { } VisualShader::VisualShader() { + dirty.set(); for (int i = 0; i < TYPE_MAX; i++) { Ref<VisualShaderNodeOutput> output; output.instance(); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 3c59a922fc..ef724c7650 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -32,6 +32,7 @@ #define VISUAL_SHADER_H #include "core/string/string_builder.h" +#include "core/templates/safe_refcount.h" #include "scene/gui/control.h" #include "scene/resources/shader.h" @@ -57,10 +58,10 @@ public: }; struct Connection { - int from_node; - int from_port; - int to_node; - int to_port; + int from_node = 0; + int from_port = 0; + int to_node = 0; + int to_port = 0; }; struct DefaultTextureParam { @@ -90,7 +91,7 @@ private: Vector2 graph_offset; struct RenderModeEnums { - Shader::Mode mode; + Shader::Mode mode = Shader::Mode::MODE_MAX; const char *string; }; @@ -99,7 +100,7 @@ private: static RenderModeEnums render_mode_enums[]; - volatile mutable bool dirty = true; + mutable SafeFlag dirty; void _queue_update(); union ConnectionKey { @@ -107,7 +108,7 @@ private: uint64_t node : 32; uint64_t port : 32; }; - uint64_t key; + uint64_t key = 0; bool operator<(const ConnectionKey &p_key) const { return key < p_key.key; } @@ -126,6 +127,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: // internal methods void set_shader_type(Type p_type); Type get_shader_type() const; @@ -152,6 +155,7 @@ public: int find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const; void remove_node(Type p_type, int p_id); + void replace_node(Type p_type, int p_id, const StringName &p_new_class); bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const; @@ -264,7 +268,7 @@ class VisualShaderNodeCustom : public VisualShaderNode { struct Port { String name; - int type; + int type = 0; }; List<Port> input_ports; @@ -304,9 +308,9 @@ class VisualShaderNodeInput : public VisualShaderNode { Shader::Mode shader_mode = Shader::MODE_MAX; struct Port { - Shader::Mode mode; - VisualShader::Type shader_type; - PortType type; + Shader::Mode mode = Shader::Mode::MODE_MAX; + VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX; + PortType type = PortType::PORT_TYPE_MAX; const char *name; const char *string; }; @@ -355,13 +359,13 @@ class VisualShaderNodeOutput : public VisualShaderNode { public: friend class VisualShader; - VisualShader::Type shader_type; - Shader::Mode shader_mode; + VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX; + Shader::Mode shader_mode = Shader::Mode::MODE_MAX; struct Port { - Shader::Mode mode; - VisualShader::Type shader_type; - PortType type; + Shader::Mode mode = Shader::Mode::MODE_MAX; + VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX; + PortType type = PortType::PORT_TYPE_MAX; const char *name; const char *string; }; @@ -518,7 +522,7 @@ protected: bool editable = false; struct Port { - PortType type; + PortType type = PortType::PORT_TYPE_MAX; String name; }; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 7629f435a5..a99c09e89c 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -30,6 +30,11 @@ #include "visual_shader_nodes.h" +////////////// Constants Base + +VisualShaderNodeConstant::VisualShaderNodeConstant() { +} + ////////////// Scalar(Float) String VisualShaderNodeFloatConstant::get_caption() const { @@ -2081,9 +2086,6 @@ String VisualShaderNodeIntFunc::get_caption() const { } int VisualShaderNodeIntFunc::get_input_port_count() const { - if (func == FUNC_CLAMP) { - return 3; - } return 1; } @@ -2092,15 +2094,6 @@ VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(i } String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const { - if (func == FUNC_CLAMP) { - if (p_port == 0) { - return ""; - } else if (p_port == 1) { - return "min"; - } else if (p_port == 2) { - return "max"; - } - } return ""; } @@ -2117,13 +2110,8 @@ String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const { } String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - if (func == FUNC_CLAMP) { - return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; - } - static const char *int_func_id[FUNC_SIGN + 1] = { "abs($)", - "", "-($)", "sign($)" }; @@ -2132,12 +2120,6 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader: } void VisualShaderNodeIntFunc::set_function(Function p_func) { - if (func != p_func) { - if (p_func == FUNC_CLAMP) { - set_input_port_default_value(1, 0); - set_input_port_default_value(2, 0); - } - } func = p_func; emit_changed(); } @@ -2156,10 +2138,9 @@ void VisualShaderNodeIntFunc::_bind_methods() { ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function); ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function); - ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Clamp,Negate,Sign"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function"); BIND_ENUM_CONSTANT(FUNC_ABS); - BIND_ENUM_CONSTANT(FUNC_CLAMP); BIND_ENUM_CONSTANT(FUNC_NEGATE); BIND_ENUM_CONSTANT(FUNC_SIGN); } @@ -2749,21 +2730,29 @@ VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() { set_input_port_default_value(0, Vector3()); } -////////////// Scalar Clamp +////////////// Clamp -String VisualShaderNodeScalarClamp::get_caption() const { - return "ScalarClamp"; +String VisualShaderNodeClamp::get_caption() const { + return "Clamp"; } -int VisualShaderNodeScalarClamp::get_input_port_count() const { +int VisualShaderNodeClamp::get_input_port_count() const { return 3; } -VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_input_port_type(int p_port) const { +VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const { +String VisualShaderNodeClamp::get_input_port_name(int p_port) const { if (p_port == 0) { return ""; } else if (p_port == 1) { @@ -2774,73 +2763,84 @@ String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeScalarClamp::get_output_port_count() const { +int VisualShaderNodeClamp::get_output_port_count() const { return 1; } -VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_output_port_type(int p_port) const { +VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarClamp::get_output_port_name(int p_port) const { +String VisualShaderNodeClamp::get_output_port_name(int p_port) const { return ""; } -String VisualShaderNodeScalarClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { +String VisualShaderNodeClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -VisualShaderNodeScalarClamp::VisualShaderNodeScalarClamp() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 1.0); -} - -////////////// Vector Clamp - -String VisualShaderNodeVectorClamp::get_caption() const { - return "VectorClamp"; -} - -int VisualShaderNodeVectorClamp::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorClamp::get_input_port_name(int p_port) const { - if (p_port == 0) { - return ""; - } else if (p_port == 1) { - return "min"; - } else if (p_port == 2) { - return "max"; +void VisualShaderNodeClamp::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; } - return ""; + switch (p_op_type) { + case OP_TYPE_FLOAT: + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 0.0); + break; + case OP_TYPE_INT: + set_input_port_default_value(0, 0); + set_input_port_default_value(1, 0); + set_input_port_default_value(2, 0); + break; + case OP_TYPE_VECTOR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + break; + default: + break; + } + op_type = p_op_type; + emit_changed(); } -int VisualShaderNodeVectorClamp::get_output_port_count() const { - return 1; +VisualShaderNodeClamp::OpType VisualShaderNodeClamp::get_op_type() const { + return op_type; } -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +Vector<StringName> VisualShaderNodeClamp::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -String VisualShaderNodeVectorClamp::get_output_port_name(int p_port) const { - return ""; -} +void VisualShaderNodeClamp::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeClamp::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeClamp::get_op_type); -String VisualShaderNodeVectorClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_FLOAT); + BIND_ENUM_CONSTANT(OP_TYPE_INT); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeVectorClamp::VisualShaderNodeVectorClamp() { - set_input_port_default_value(0, Vector3(0, 0, 0)); - set_input_port_default_value(1, Vector3(0, 0, 0)); - set_input_port_default_value(2, Vector3(1, 1, 1)); +VisualShaderNodeClamp::VisualShaderNodeClamp() { + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 1.0); } ////////////// FaceForward @@ -2938,24 +2938,32 @@ VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() { set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); } -////////////// Vector-Scalar Step +////////////// Step -String VisualShaderNodeVectorScalarStep::get_caption() const { - return "VectorScalarStep"; +String VisualShaderNodeStep::get_caption() const { + return "Step"; } -int VisualShaderNodeVectorScalarStep::get_input_port_count() const { +int VisualShaderNodeStep::get_input_port_count() const { return 2; } -VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_SCALAR; +VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + if (p_port == 1) { + return PORT_TYPE_VECTOR; + } + break; + default: + break; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const { +String VisualShaderNodeStep::get_input_port_name(int p_port) const { if (p_port == 0) { return "edge"; } else if (p_port == 1) { @@ -2964,89 +2972,120 @@ String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeVectorScalarStep::get_output_port_count() const { +int VisualShaderNodeStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + return PORT_TYPE_VECTOR; + default: + break; + } + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorScalarStep::get_output_port_name(int p_port) const { +String VisualShaderNodeStep::get_output_port_name(int p_port) const { return ""; } -String VisualShaderNodeVectorScalarStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; -} - -VisualShaderNodeVectorScalarStep::VisualShaderNodeVectorScalarStep() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); -} - -////////////// Scalar SmoothStep - -String VisualShaderNodeScalarSmoothStep::get_caption() const { - return "ScalarSmoothStep"; -} - -int VisualShaderNodeScalarSmoothStep::get_input_port_count() const { - return 3; +void VisualShaderNodeStep::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge + } + if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(1, 0.0); // x + } + break; + case OP_TYPE_VECTOR: + if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x + } + break; + case OP_TYPE_VECTOR_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x + } + break; + default: + break; + } + op_type = p_op_type; + emit_changed(); } -VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get_input_port_type(int p_port) const { - return PORT_TYPE_SCALAR; +VisualShaderNodeStep::OpType VisualShaderNodeStep::get_op_type() const { + return op_type; } -String VisualShaderNodeScalarSmoothStep::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "edge0"; - } else if (p_port == 1) { - return "edge1"; - } else if (p_port == 2) { - return "x"; - } - return ""; +String VisualShaderNodeStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } -int VisualShaderNodeScalarSmoothStep::get_output_port_count() const { - return 1; +Vector<StringName> VisualShaderNodeStep::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get_output_port_type(int p_port) const { - return PORT_TYPE_SCALAR; -} +void VisualShaderNodeStep::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeStep::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeStep::get_op_type); -String VisualShaderNodeScalarSmoothStep::get_output_port_name(int p_port) const { - return ""; -} + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); -String VisualShaderNodeScalarSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeScalarSmoothStep::VisualShaderNodeScalarSmoothStep() { +VisualShaderNodeStep::VisualShaderNodeStep() { set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 0.0); } -////////////// Vector SmoothStep +////////////// SmoothStep -String VisualShaderNodeVectorSmoothStep::get_caption() const { - return "VectorSmoothStep"; +String VisualShaderNodeSmoothStep::get_caption() const { + return "SmoothStep"; } -int VisualShaderNodeVectorSmoothStep::get_input_port_count() const { +int VisualShaderNodeSmoothStep::get_input_port_count() const { return 3; } -VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + if (p_port == 2) { + return PORT_TYPE_VECTOR; // x + } + break; + default: + break; + } + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const { +String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const { if (p_port == 0) { return "edge0"; } else if (p_port == 1) { @@ -3057,78 +3096,96 @@ String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeVectorSmoothStep::get_output_port_count() const { +int VisualShaderNodeSmoothStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + return PORT_TYPE_VECTOR; + default: + break; + } + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorSmoothStep::get_output_port_name(int p_port) const { +String VisualShaderNodeSmoothStep::get_output_port_name(int p_port) const { return ""; } -String VisualShaderNodeVectorSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; -} - -VisualShaderNodeVectorSmoothStep::VisualShaderNodeVectorSmoothStep() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); -} - -////////////// Vector-Scalar SmoothStep - -String VisualShaderNodeVectorScalarSmoothStep::get_caption() const { - return "VectorScalarSmoothStep"; -} - -int VisualShaderNodeVectorScalarSmoothStep::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_SCALAR; - } else if (p_port == 1) { - return PORT_TYPE_SCALAR; +void VisualShaderNodeSmoothStep::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge0 + set_input_port_default_value(1, 0.0); // edge1 + } + if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(2, 0.0); // x + } + break; + case OP_TYPE_VECTOR: + if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge0 + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // edge1 + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x + } + break; + case OP_TYPE_VECTOR_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge0 + set_input_port_default_value(1, 0.0); // edge1 + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x + } + break; + default: + break; } - return PORT_TYPE_VECTOR; + op_type = p_op_type; + emit_changed(); } -String VisualShaderNodeVectorScalarSmoothStep::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "edge0"; - } else if (p_port == 1) { - return "edge1"; - } else if (p_port == 2) { - return "x"; - } - return ""; +VisualShaderNodeSmoothStep::OpType VisualShaderNodeSmoothStep::get_op_type() const { + return op_type; } -int VisualShaderNodeVectorScalarSmoothStep::get_output_port_count() const { - return 1; +String VisualShaderNodeSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +Vector<StringName> VisualShaderNodeSmoothStep::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -String VisualShaderNodeVectorScalarSmoothStep::get_output_port_name(int p_port) const { - return ""; -} +void VisualShaderNodeSmoothStep::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSmoothStep::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSmoothStep::get_op_type); -String VisualShaderNodeVectorScalarSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeVectorScalarSmoothStep::VisualShaderNodeVectorScalarSmoothStep() { +VisualShaderNodeSmoothStep::VisualShaderNodeSmoothStep() { set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(2, 0.0); } ////////////// Distance @@ -3226,21 +3283,32 @@ VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() { set_input_port_default_value(2, 0.0); } -////////////// Scalar Mix +////////////// Mix -String VisualShaderNodeScalarInterp::get_caption() const { - return "ScalarMix"; +String VisualShaderNodeMix::get_caption() const { + return "Mix"; } -int VisualShaderNodeScalarInterp::get_input_port_count() const { +int VisualShaderNodeMix::get_input_port_count() const { return 3; } -VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_input_port_type(int p_port) const { +VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + if (p_port == 2) { + break; + } + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const { +String VisualShaderNodeMix::get_input_port_name(int p_port) const { if (p_port == 0) { return "a"; } else if (p_port == 1) { @@ -3250,121 +3318,90 @@ String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const { } } -int VisualShaderNodeScalarInterp::get_output_port_count() const { +int VisualShaderNodeMix::get_output_port_count() const { return 1; } -VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_output_port_type(int p_port) const { +VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const { +String VisualShaderNodeMix::get_output_port_name(int p_port) const { return "mix"; } -String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; -} - -VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 1.0); - set_input_port_default_value(2, 0.5); -} - -////////////// Vector Mix - -String VisualShaderNodeVectorInterp::get_caption() const { - return "VectorMix"; -} - -int VisualShaderNodeVectorInterp::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorInterp::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "a"; - } else if (p_port == 1) { - return "b"; - } else { - return "weight"; +void VisualShaderNodeMix::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: + set_input_port_default_value(0, 0.0); // a + set_input_port_default_value(1, 1.0); // b + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(2, 0.5); // weight + } + break; + case OP_TYPE_VECTOR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b + if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); // weight + } + break; + case OP_TYPE_VECTOR_SCALAR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(2, 0.5); // weight + } + break; + default: + break; } + op_type = p_op_type; + emit_changed(); } -int VisualShaderNodeVectorInterp::get_output_port_count() const { - return 1; -} - -VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const { - return "mix"; +VisualShaderNodeMix::OpType VisualShaderNodeMix::get_op_type() const { + return op_type; } -String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { +String VisualShaderNodeMix::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); -} - -////////////// Vector Mix (by scalar) - -String VisualShaderNodeVectorScalarMix::get_caption() const { - return "VectorScalarMix"; -} - -int VisualShaderNodeVectorScalarMix::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const { - if (p_port == 2) { - return PORT_TYPE_SCALAR; - } - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorScalarMix::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "a"; - } else if (p_port == 1) { - return "b"; - } else { - return "weight"; - } -} - -int VisualShaderNodeVectorScalarMix::get_output_port_count() const { - return 1; +Vector<StringName> VisualShaderNodeMix::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} +void VisualShaderNodeMix::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMix::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMix::get_op_type); -String VisualShaderNodeVectorScalarMix::get_output_port_name(int p_port) const { - return "mix"; -} + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); -String VisualShaderNodeVectorScalarMix::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, 0.5); +VisualShaderNodeMix::VisualShaderNodeMix() { + set_input_port_default_value(0, 0.0); // a + set_input_port_default_value(1, 1.0); // b + set_input_port_default_value(2, 0.5); // weight } ////////////// Vector Compose @@ -4472,9 +4509,7 @@ int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { } VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_VECTOR; - } else if (p_port == 1) { + if (p_port == 0 || p_port == 1) { return PORT_TYPE_VECTOR; } return PORT_TYPE_SCALAR; @@ -4842,7 +4877,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() { ////////////// Switch String VisualShaderNodeSwitch::get_caption() const { - return "VectorSwitch"; + return "Switch"; } int VisualShaderNodeSwitch::get_input_port_count() const { @@ -4853,7 +4888,21 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int if (p_port == 0) { return PORT_TYPE_BOOLEAN; } - return PORT_TYPE_VECTOR; + if (p_port == 1 || p_port == 2) { + switch (op_type) { + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case OP_TYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + default: + break; + } + } + return PORT_TYPE_SCALAR; } String VisualShaderNodeSwitch::get_input_port_name(int p_port) const { @@ -4874,13 +4923,82 @@ int VisualShaderNodeSwitch::get_output_port_count() const { } VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + switch (op_type) { + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case OP_TYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + default: + break; + } + return PORT_TYPE_SCALAR; } String VisualShaderNodeSwitch::get_output_port_name(int p_port) const { return "result"; } +void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_FLOAT: + set_input_port_default_value(1, 1.0); + set_input_port_default_value(2, 0.0); + break; + case OP_TYPE_INT: + set_input_port_default_value(1, 1); + set_input_port_default_value(2, 0); + break; + case OP_TYPE_VECTOR: + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + break; + case OP_TYPE_BOOLEAN: + set_input_port_default_value(1, true); + set_input_port_default_value(2, false); + break; + case OP_TYPE_TRANSFORM: + set_input_port_default_value(1, Transform()); + set_input_port_default_value(2, Transform()); + break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + +VisualShaderNodeSwitch::OpType VisualShaderNodeSwitch::get_op_type() const { + return op_type; +} + +Vector<StringName> VisualShaderNodeSwitch::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; +} + +void VisualShaderNodeSwitch::_bind_methods() { // static + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSwitch::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSwitch::get_op_type); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_FLOAT); + BIND_ENUM_CONSTANT(OP_TYPE_INT); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_BOOLEAN); + BIND_ENUM_CONSTANT(OP_TYPE_TRANSFORM); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); +} + String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; code += "\tif(" + p_input_vars[0] + ")\n"; @@ -4897,29 +5015,6 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader:: VisualShaderNodeSwitch::VisualShaderNodeSwitch() { simple_decl = false; set_input_port_default_value(0, false); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); -} - -////////////// Switch(scalar) - -String VisualShaderNodeScalarSwitch::get_caption() const { - return "ScalarSwitch"; -} - -VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_BOOLEAN; - } - return PORT_TYPE_SCALAR; -} - -VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_output_port_type(int p_port) const { - return PORT_TYPE_SCALAR; -} - -VisualShaderNodeScalarSwitch::VisualShaderNodeScalarSwitch() { - set_input_port_default_value(0, false); set_input_port_default_value(1, 1.0); set_input_port_default_value(2, 0.0); } @@ -5106,9 +5201,6 @@ int VisualShaderNodeCompare::get_input_port_count() const { } VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const { - if (p_port == 2) { - return PORT_TYPE_SCALAR; - } switch (ctype) { case CTYPE_SCALAR: return PORT_TYPE_SCALAR; @@ -5120,8 +5212,9 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i return PORT_TYPE_BOOLEAN; case CTYPE_TRANSFORM: return PORT_TYPE_TRANSFORM; + default: + return PORT_TYPE_SCALAR; } - return PORT_TYPE_VECTOR; } String VisualShaderNodeCompare::get_input_port_name(int p_port) const { @@ -5340,10 +5433,10 @@ int VisualShaderNodeMultiplyAdd::get_input_port_count() const { } VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const { - if (op_type == OP_TYPE_SCALAR) { - return PORT_TYPE_SCALAR; + if (op_type == OP_TYPE_VECTOR) { + return PORT_TYPE_VECTOR; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_SCALAR; } String VisualShaderNodeMultiplyAdd::get_input_port_name(int p_port) const { @@ -5379,16 +5472,22 @@ String VisualShaderNodeMultiplyAdd::generate_code(Shader::Mode p_mode, VisualSha void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) { ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); - if (p_op_type != op_type) { - if (p_op_type == OP_TYPE_SCALAR) { + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, 0.0); - } else { + break; + case OP_TYPE_VECTOR: set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); - } + break; + default: + break; } op_type = p_op_type; emit_changed(); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 35ecaaacb5..a5d0fe4649 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -37,8 +37,27 @@ /// CONSTANTS /////////////////////////////////////// -class VisualShaderNodeFloatConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode); +class VisualShaderNodeConstant : public VisualShaderNode { + GDCLASS(VisualShaderNodeConstant, VisualShaderNode); + +public: + virtual String get_caption() const override = 0; + + virtual int get_input_port_count() const override = 0; + virtual PortType get_input_port_type(int p_port) const override = 0; + virtual String get_input_port_name(int p_port) const override = 0; + + virtual int get_output_port_count() const override = 0; + virtual PortType get_output_port_type(int p_port) const override = 0; + virtual String get_output_port_name(int p_port) const override = 0; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override = 0; + + VisualShaderNodeConstant(); +}; + +class VisualShaderNodeFloatConstant : public VisualShaderNodeConstant { + GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNodeConstant); float constant = 0.0f; protected: @@ -67,8 +86,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeIntConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode); +class VisualShaderNodeIntConstant : public VisualShaderNodeConstant { + GDCLASS(VisualShaderNodeIntConstant, VisualShaderNodeConstant); int constant = 0; protected: @@ -97,8 +116,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeBooleanConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNode); +class VisualShaderNodeBooleanConstant : public VisualShaderNodeConstant { + GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNodeConstant); bool constant = false; protected: @@ -127,8 +146,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeColorConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeColorConstant, VisualShaderNode); +class VisualShaderNodeColorConstant : public VisualShaderNodeConstant { + GDCLASS(VisualShaderNodeColorConstant, VisualShaderNodeConstant); Color constant = Color(1, 1, 1, 1); protected: @@ -157,8 +176,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeVec3Constant : public VisualShaderNode { - GDCLASS(VisualShaderNodeVec3Constant, VisualShaderNode); +class VisualShaderNodeVec3Constant : public VisualShaderNodeConstant { + GDCLASS(VisualShaderNodeVec3Constant, VisualShaderNodeConstant); Vector3 constant; protected: @@ -187,8 +206,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeTransformConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeTransformConstant, VisualShaderNode); +class VisualShaderNodeTransformConstant : public VisualShaderNodeConstant { + GDCLASS(VisualShaderNodeTransformConstant, VisualShaderNodeConstant); Transform constant; protected: @@ -807,7 +826,6 @@ class VisualShaderNodeIntFunc : public VisualShaderNode { public: enum Function { FUNC_ABS, - FUNC_CLAMP, FUNC_NEGATE, FUNC_SIGN, }; @@ -1069,29 +1087,20 @@ public: /// CLAMP /////////////////////////////////////// -class VisualShaderNodeScalarClamp : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarClamp, VisualShaderNode); +class VisualShaderNodeClamp : public VisualShaderNode { + GDCLASS(VisualShaderNodeClamp, VisualShaderNode); public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; - - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeScalarClamp(); -}; - -/////////////////////////////////////// + enum OpType { + OP_TYPE_FLOAT, + OP_TYPE_INT, + OP_TYPE_VECTOR, + OP_TYPE_MAX, + }; -class VisualShaderNodeVectorClamp : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorClamp, VisualShaderNode); +protected: + OpType op_type = OP_TYPE_FLOAT; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1104,11 +1113,18 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorClamp(); + VisualShaderNodeClamp(); }; +VARIANT_ENUM_CAST(VisualShaderNodeClamp::OpType) + /////////////////////////////////////// /// DERIVATIVE FUNCTIONS /////////////////////////////////////// @@ -1241,8 +1257,20 @@ public: /// STEP /////////////////////////////////////// -class VisualShaderNodeVectorScalarStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorScalarStep, VisualShaderNode); +class VisualShaderNodeStep : public VisualShaderNode { + GDCLASS(VisualShaderNodeStep, VisualShaderNode); + +public: + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_VECTOR_SCALAR, + OP_TYPE_MAX, + }; + +protected: + OpType op_type = OP_TYPE_SCALAR; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1255,38 +1283,36 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorScalarStep(); + VisualShaderNodeStep(); }; +VARIANT_ENUM_CAST(VisualShaderNodeStep::OpType) + /////////////////////////////////////// /// SMOOTHSTEP /////////////////////////////////////// -class VisualShaderNodeScalarSmoothStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarSmoothStep, VisualShaderNode); +class VisualShaderNodeSmoothStep : public VisualShaderNode { + GDCLASS(VisualShaderNodeSmoothStep, VisualShaderNode); public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; - - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeScalarSmoothStep(); -}; - -/////////////////////////////////////// + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_VECTOR_SCALAR, + OP_TYPE_MAX, + }; -class VisualShaderNodeVectorSmoothStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorSmoothStep, VisualShaderNode); +protected: + OpType op_type = OP_TYPE_SCALAR; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1299,32 +1325,18 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeVectorSmoothStep(); -}; - -/////////////////////////////////////// - -class VisualShaderNodeVectorScalarSmoothStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorScalarSmoothStep, VisualShaderNode); - -public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; + virtual Vector<StringName> get_editable_properties() const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorScalarSmoothStep(); + VisualShaderNodeSmoothStep(); }; +VARIANT_ENUM_CAST(VisualShaderNodeSmoothStep::OpType) + /////////////////////////////////////// /// DISTANCE /////////////////////////////////////// @@ -1375,29 +1387,20 @@ public: /// MIX /////////////////////////////////////// -class VisualShaderNodeScalarInterp : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarInterp, VisualShaderNode); +class VisualShaderNodeMix : public VisualShaderNode { + GDCLASS(VisualShaderNodeMix, VisualShaderNode); public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; - - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeScalarInterp(); -}; - -/////////////////////////////////////// + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_VECTOR_SCALAR, + OP_TYPE_MAX, + }; -class VisualShaderNodeVectorInterp : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorInterp, VisualShaderNode); +protected: + OpType op_type = OP_TYPE_SCALAR; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1410,32 +1413,18 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeVectorInterp(); -}; - -/////////////////////////////////////// - -class VisualShaderNodeVectorScalarMix : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorScalarMix, VisualShaderNode); - -public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; + virtual Vector<StringName> get_editable_properties() const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorScalarMix(); + VisualShaderNodeMix(); }; +VARIANT_ENUM_CAST(VisualShaderNodeMix::OpType) + /////////////////////////////////////// /// COMPOSE /////////////////////////////////////// @@ -2004,6 +1993,21 @@ class VisualShaderNodeSwitch : public VisualShaderNode { GDCLASS(VisualShaderNodeSwitch, VisualShaderNode); public: + enum OpType { + OP_TYPE_FLOAT, + OP_TYPE_INT, + OP_TYPE_VECTOR, + OP_TYPE_BOOLEAN, + OP_TYPE_TRANSFORM, + OP_TYPE_MAX, + }; + +protected: + OpType op_type = OP_TYPE_FLOAT; + + static void _bind_methods(); + +public: virtual String get_caption() const override; virtual int get_input_port_count() const override; @@ -2014,22 +2018,17 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeSwitch(); }; -class VisualShaderNodeScalarSwitch : public VisualShaderNodeSwitch { - GDCLASS(VisualShaderNodeScalarSwitch, VisualShaderNodeSwitch); - -public: - virtual String get_caption() const override; - - virtual PortType get_input_port_type(int p_port) const override; - virtual PortType get_output_port_type(int p_port) const override; - - VisualShaderNodeScalarSwitch(); -}; +VARIANT_ENUM_CAST(VisualShaderNodeSwitch::OpType) /////////////////////////////////////// /// FRESNEL diff --git a/scene/resources/visual_shader_sdf_nodes.cpp b/scene/resources/visual_shader_sdf_nodes.cpp new file mode 100644 index 0000000000..d25e32b070 --- /dev/null +++ b/scene/resources/visual_shader_sdf_nodes.cpp @@ -0,0 +1,283 @@ +/*************************************************************************/ +/* visual_shader_sdf_nodes.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "visual_shader_sdf_nodes.h" + +// VisualShaderNodeSDFToScreenUV + +String VisualShaderNodeSDFToScreenUV::get_caption() const { + return "SDFToScreenUV"; +} + +int VisualShaderNodeSDFToScreenUV::get_input_port_count() const { + return 1; +} + +VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_input_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeSDFToScreenUV::get_input_port_name(int p_port) const { + return "sdf_pos"; +} + +int VisualShaderNodeSDFToScreenUV::get_output_port_count() const { + return 1; +} + +VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeSDFToScreenUV::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; +} + +VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() { +} + +// VisualShaderNodeScreenUVToSDF + +String VisualShaderNodeScreenUVToSDF::get_caption() const { + return "ScreenUVToSDF"; +} + +int VisualShaderNodeScreenUVToSDF::get_input_port_count() const { + return 1; +} + +VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_input_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeScreenUVToSDF::get_input_port_name(int p_port) const { + return "uv"; +} + +int VisualShaderNodeScreenUVToSDF::get_output_port_count() const { + return 1; +} + +VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeScreenUVToSDF::get_output_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeScreenUVToSDF::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "default"; + } + return ""; +} + +String VisualShaderNodeScreenUVToSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; +} + +VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() { +} + +// VisualShaderNodeTextureSDF + +String VisualShaderNodeTextureSDF::get_caption() const { + return "TextureSDF"; +} + +int VisualShaderNodeTextureSDF::get_input_port_count() const { + return 1; +} + +VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_input_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeTextureSDF::get_input_port_name(int p_port) const { + return "sdf_pos"; +} + +int VisualShaderNodeTextureSDF::get_output_port_count() const { + return 1; +} + +VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeTextureSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n"; +} + +VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() { +} + +// VisualShaderNodeTextureSDFNormal + +String VisualShaderNodeTextureSDFNormal::get_caption() const { + return "TextureSDFNormal"; +} + +int VisualShaderNodeTextureSDFNormal::get_input_port_count() const { + return 1; +} + +VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_input_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeTextureSDFNormal::get_input_port_name(int p_port) const { + return "sdf_pos"; +} + +int VisualShaderNodeTextureSDFNormal::get_output_port_count() const { + return 1; +} + +VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeTextureSDFNormal::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; +} + +VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() { +} + +// VisualShaderNodeSDFRaymarch + +String VisualShaderNodeSDFRaymarch::get_caption() const { + return "SDFRaymarch"; +} + +int VisualShaderNodeSDFRaymarch::get_input_port_count() const { + return 2; +} + +VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_input_port_type(int p_port) const { + if (p_port == 0 || p_port == 1) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeSDFRaymarch::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "from_pos"; + } else if (p_port == 1) { + return "to_pos"; + } + return String(); +} + +int VisualShaderNodeSDFRaymarch::get_output_port_count() const { + return 3; +} + +VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_output_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_SCALAR; + } else if (p_port == 1) { + return PORT_TYPE_BOOLEAN; + } else if (p_port == 2) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeSDFRaymarch::get_output_port_name(int p_port) const { + if (p_port == 0) { + return "distance"; + } else if (p_port == 1) { + return "hit"; + } else if (p_port == 2) { + return "end_pos"; + } + return String(); +} + +String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + code += "\t{\n"; + + if (p_input_vars[0] == String()) { + code += "\t\tvec2 __from_pos = vec2(0.0f);\n"; + } else { + code += "\t\tvec2 __from_pos = " + p_input_vars[0] + ".xy;\n"; + } + + if (p_input_vars[1] == String()) { + code += "\t\tvec2 __to_pos = vec2(0.0f);\n"; + } else { + code += "\t\tvec2 __to_pos = " + p_input_vars[1] + ".xy;\n"; + } + + code += "\n\t\tvec2 __at = __from_pos;\n"; + code += "\t\tfloat __max_dist = distance(__from_pos, __to_pos);\n"; + code += "\t\tvec2 __dir = normalize(__to_pos - __from_pos);\n\n"; + + code += "\t\tfloat __accum = 0.0f;\n"; + code += "\t\twhile(__accum < __max_dist) {\n"; + code += "\t\t\tfloat __d = texture_sdf(__at);\n"; + code += "\t\t\t__accum += __d;\n"; + code += "\t\t\tif (__d < 0.01f) {\n"; + code += "\t\t\t\tbreak;\n"; + code += "\t\t\t}\n"; + code += "\t\t\t__at += __d * __dir;\n"; + code += "\t\t}\n"; + + code += "\t\tfloat __dist = min(__max_dist, __accum);\n"; + code += "\t\t" + p_output_vars[0] + " = __dist;\n"; + code += "\t\t" + p_output_vars[1] + " = __accum < __max_dist;\n"; + code += "\t\t" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n"; + + code += "\t}\n"; + + return code; +} + +VisualShaderNodeSDFRaymarch::VisualShaderNodeSDFRaymarch() { + simple_decl = false; +} diff --git a/scene/resources/visual_shader_sdf_nodes.h b/scene/resources/visual_shader_sdf_nodes.h new file mode 100644 index 0000000000..0fcf5ec0b5 --- /dev/null +++ b/scene/resources/visual_shader_sdf_nodes.h @@ -0,0 +1,132 @@ +/*************************************************************************/ +/* visual_shader_sdf_nodes.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VISUAL_SHADER_SDF_NODES_H +#define VISUAL_SHADER_SDF_NODES_H + +#include "scene/resources/visual_shader.h" + +class VisualShaderNodeSDFToScreenUV : public VisualShaderNode { + GDCLASS(VisualShaderNodeSDFToScreenUV, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeSDFToScreenUV(); +}; + +class VisualShaderNodeScreenUVToSDF : public VisualShaderNode { + GDCLASS(VisualShaderNodeScreenUVToSDF, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String get_input_port_default_hint(int p_port) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeScreenUVToSDF(); +}; + +class VisualShaderNodeTextureSDF : public VisualShaderNode { + GDCLASS(VisualShaderNodeTextureSDF, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeTextureSDF(); +}; + +class VisualShaderNodeTextureSDFNormal : public VisualShaderNode { + GDCLASS(VisualShaderNodeTextureSDFNormal, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeTextureSDFNormal(); +}; + +class VisualShaderNodeSDFRaymarch : public VisualShaderNode { + GDCLASS(VisualShaderNodeSDFRaymarch, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeSDFRaymarch(); +}; + +#endif // VISUAL_SHADER_SDF_NODES_H diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index cadbd93fed..156c7d0576 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -39,7 +39,7 @@ struct SpatialIndexer2D { struct CellRef { - int ref; + int ref = 0; _FORCE_INLINE_ int inc() { ref++; @@ -49,10 +49,6 @@ struct SpatialIndexer2D { ref--; return ref; } - - _FORCE_INLINE_ CellRef() { - ref = 0; - } }; struct CellKey { @@ -61,7 +57,7 @@ struct SpatialIndexer2D { int32_t x; int32_t y; }; - uint64_t key; + uint64_t key = 0; }; bool operator==(const CellKey &p_key) const { return key == p_key.key; } @@ -86,9 +82,9 @@ struct SpatialIndexer2D { Map<Viewport *, ViewportData> viewports; - bool changed; + bool changed = false; - uint64_t pass; + uint64_t pass = 0; void _notifier_update_cells(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect, bool p_add) { Point2i begin = p_rect.position; @@ -287,8 +283,6 @@ struct SpatialIndexer2D { } SpatialIndexer2D() { - pass = 0; - changed = false; cell_size = GLOBAL_DEF("world/2d/cell_size", 100); } }; diff --git a/scene/resources/world_margin_shape_3d.cpp b/scene/resources/world_margin_shape_3d.cpp index 79cbb3bbe0..28d50e1921 100644 --- a/scene/resources/world_margin_shape_3d.cpp +++ b/scene/resources/world_margin_shape_3d.cpp @@ -69,7 +69,6 @@ void WorldMarginShape3D::set_plane(Plane p_plane) { plane = p_plane; _update_shape(); notify_change_to_owners(); - _change_notify("plane"); } Plane WorldMarginShape3D::get_plane() const { diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 12cadb9301..a28dcb1015 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -39,16 +39,16 @@ Error AudioDriverDummy::init() { exit_thread = false; samples_in = nullptr; - mix_rate = GLOBAL_GET("audio/mix_rate"); + mix_rate = GLOBAL_GET("audio/driver/mix_rate"); speaker_mode = SPEAKER_MODE_STEREO; channels = 2; - int latency = GLOBAL_GET("audio/output_latency"); + int latency = GLOBAL_GET("audio/driver/output_latency"); buffer_frames = closest_power_of_2(latency * mix_rate / 1000); samples_in = memnew_arr(int32_t, buffer_frames * channels); - thread = Thread::create(AudioDriverDummy::thread_func, this); + thread.start(AudioDriverDummy::thread_func, this); return OK; }; @@ -86,31 +86,18 @@ AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const { }; void AudioDriverDummy::lock() { - if (!thread) { - return; - } mutex.lock(); }; void AudioDriverDummy::unlock() { - if (!thread) { - return; - } mutex.unlock(); }; void AudioDriverDummy::finish() { - if (!thread) { - return; - } - exit_thread = true; - Thread::wait_to_finish(thread); + thread.wait_to_finish(); if (samples_in) { memdelete_arr(samples_in); }; - - memdelete(thread); - thread = nullptr; }; diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index 617ffb2c79..7d84e7ffc8 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -37,7 +37,7 @@ #include "core/os/thread.h" class AudioDriverDummy : public AudioDriver { - Thread *thread = nullptr; + Thread thread; Mutex mutex; int32_t *samples_in; diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp index 580e061496..bcfa4c4c37 100644 --- a/servers/audio/audio_filter_sw.cpp +++ b/servers/audio/audio_filter_sw.cpp @@ -58,7 +58,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { final_cutoff = 1; //don't allow less than this } - double omega = 2.0 * Math_PI * final_cutoff / sampling_rate; + double omega = Math_TAU * final_cutoff / sampling_rate; double sin_v = Math::sin(omega); double cos_v = Math::cos(omega); @@ -132,7 +132,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { double hicutoff = resonance; double centercutoff = (cutoff + resonance) / 2.0; double bandwidth = (Math::log(centercutoff) - Math::log(hicutoff)) / Math::log((double)2); - omega = 2.0 * Math_PI * centercutoff / sampling_rate; + omega = Math_TAU * centercutoff / sampling_rate; alpha = Math::sin(omega) * Math::sinh(Math::log((double)2) / 2 * bandwidth * omega / Math::sin(omega)); a0 = 1 + alpha; @@ -197,7 +197,7 @@ void AudioFilterSW::set_stages(int p_stages) { //adjust for multiple stages /* Fouriertransform kernel to obtain response */ float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) { - float freq = p_freq / sampling_rate * Math_PI * 2.0f; + float freq = p_freq / sampling_rate * Math_TAU; float cx = p_coeffs->b0, cy = 0.0; diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp index efdcb916ed..3c8a1469cd 100644 --- a/servers/audio/audio_rb_resampler.cpp +++ b/servers/audio/audio_rb_resampler.cpp @@ -131,7 +131,7 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) { src_read = read_space; } - rb_read_pos = (rb_read_pos + src_read) & rb_mask; + rb_read_pos.set((rb_read_pos.get() + src_read) & rb_mask); // Create fadeout effect for the end of stream (note that it can be because of slow writer) if (p_frames - target_todo > 0) { @@ -183,8 +183,8 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m src_mix_rate = p_src_mix_rate; target_mix_rate = p_target_mix_rate; offset = 0; - rb_read_pos = 0; - rb_write_pos = 0; + rb_read_pos.set(0); + rb_write_pos.set(0); //avoid maybe strange noises upon load for (unsigned int i = 0; i < (rb_len * channels); i++) { @@ -205,8 +205,8 @@ void AudioRBResampler::clear() { memdelete_arr(read_buf); rb = nullptr; offset = 0; - rb_read_pos = 0; - rb_write_pos = 0; + rb_read_pos.set(0); + rb_write_pos.set(0); read_buf = nullptr; } @@ -214,8 +214,8 @@ AudioRBResampler::AudioRBResampler() { rb = nullptr; offset = 0; read_buf = nullptr; - rb_read_pos = 0; - rb_write_pos = 0; + rb_read_pos.set(0); + rb_write_pos.set(0); rb_bits = 0; rb_len = 0; diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h index 7b74e3a2a1..c0f981704b 100644 --- a/servers/audio/audio_rb_resampler.h +++ b/servers/audio/audio_rb_resampler.h @@ -32,6 +32,7 @@ #define AUDIO_RB_RESAMPLER_H #include "core/os/memory.h" +#include "core/templates/safe_refcount.h" #include "core/typedefs.h" #include "servers/audio_server.h" @@ -44,8 +45,8 @@ struct AudioRBResampler { uint32_t src_mix_rate; uint32_t target_mix_rate; - volatile int rb_read_pos; - volatile int rb_write_pos; + SafeNumeric<int> rb_read_pos; + SafeNumeric<int> rb_write_pos; int32_t offset; //contains the fractional remainder of the resampler enum { @@ -62,8 +63,8 @@ struct AudioRBResampler { public: _FORCE_INLINE_ void flush() { - rb_read_pos = 0; - rb_write_pos = 0; + rb_read_pos.set(0); + rb_write_pos.set(0); offset = 0; } @@ -78,8 +79,8 @@ public: _FORCE_INLINE_ int get_writer_space() const { int space, r, w; - r = rb_read_pos; - w = rb_write_pos; + r = rb_read_pos.get(); + w = rb_write_pos.get(); if (r == w) { space = rb_len - 1; @@ -95,8 +96,8 @@ public: _FORCE_INLINE_ int get_reader_space() const { int space, r, w; - r = rb_read_pos; - w = rb_write_pos; + r = rb_read_pos.get(); + w = rb_write_pos.get(); if (r == w) { space = 0; @@ -110,48 +111,52 @@ public: } _FORCE_INLINE_ bool has_data() const { - return rb && rb_read_pos != rb_write_pos; + return rb && rb_read_pos.get() != rb_write_pos.get(); } _FORCE_INLINE_ float *get_write_buffer() { return read_buf; } _FORCE_INLINE_ void write(uint32_t p_frames) { ERR_FAIL_COND(p_frames >= rb_len); + int wp = rb_write_pos.get(); + switch (channels) { case 1: { for (uint32_t i = 0; i < p_frames; i++) { - rb[rb_write_pos] = read_buf[i]; - rb_write_pos = (rb_write_pos + 1) & rb_mask; + rb[wp] = read_buf[i]; + wp = (wp + 1) & rb_mask; } } break; case 2: { for (uint32_t i = 0; i < p_frames; i++) { - rb[(rb_write_pos << 1) + 0] = read_buf[(i << 1) + 0]; - rb[(rb_write_pos << 1) + 1] = read_buf[(i << 1) + 1]; - rb_write_pos = (rb_write_pos + 1) & rb_mask; + rb[(wp << 1) + 0] = read_buf[(i << 1) + 0]; + rb[(wp << 1) + 1] = read_buf[(i << 1) + 1]; + wp = (wp + 1) & rb_mask; } } break; case 4: { for (uint32_t i = 0; i < p_frames; i++) { - rb[(rb_write_pos << 2) + 0] = read_buf[(i << 2) + 0]; - rb[(rb_write_pos << 2) + 1] = read_buf[(i << 2) + 1]; - rb[(rb_write_pos << 2) + 2] = read_buf[(i << 2) + 2]; - rb[(rb_write_pos << 2) + 3] = read_buf[(i << 2) + 3]; - rb_write_pos = (rb_write_pos + 1) & rb_mask; + rb[(wp << 2) + 0] = read_buf[(i << 2) + 0]; + rb[(wp << 2) + 1] = read_buf[(i << 2) + 1]; + rb[(wp << 2) + 2] = read_buf[(i << 2) + 2]; + rb[(wp << 2) + 3] = read_buf[(i << 2) + 3]; + wp = (wp + 1) & rb_mask; } } break; case 6: { for (uint32_t i = 0; i < p_frames; i++) { - rb[(rb_write_pos * 6) + 0] = read_buf[(i * 6) + 0]; - rb[(rb_write_pos * 6) + 1] = read_buf[(i * 6) + 1]; - rb[(rb_write_pos * 6) + 2] = read_buf[(i * 6) + 2]; - rb[(rb_write_pos * 6) + 3] = read_buf[(i * 6) + 3]; - rb[(rb_write_pos * 6) + 4] = read_buf[(i * 6) + 4]; - rb[(rb_write_pos * 6) + 5] = read_buf[(i * 6) + 5]; - rb_write_pos = (rb_write_pos + 1) & rb_mask; + rb[(wp * 6) + 0] = read_buf[(i * 6) + 0]; + rb[(wp * 6) + 1] = read_buf[(i * 6) + 1]; + rb[(wp * 6) + 2] = read_buf[(i * 6) + 2]; + rb[(wp * 6) + 3] = read_buf[(i * 6) + 3]; + rb[(wp * 6) + 4] = read_buf[(i * 6) + 4]; + rb[(wp * 6) + 5] = read_buf[(i * 6) + 5]; + wp = (wp + 1) & rb_mask; } } break; } + + rb_write_pos.set(wp); } int get_channel_count() const; diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 91fce5d34e..ae07f999ed 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -54,21 +54,21 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, for (int i = 0; i < p_frames; i++) { uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS); - //standard cubic interpolation (great quality/performance ratio) - //this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory. + // 4 point, 4th order optimal resampling algorithm from: http://yehar.com/blog/wp-content/uploads/2009/08/deip.pdf float mu = (mix_offset & FP_MASK) / float(FP_LEN); AudioFrame y0 = internal_buffer[idx - 3]; AudioFrame y1 = internal_buffer[idx - 2]; AudioFrame y2 = internal_buffer[idx - 1]; AudioFrame y3 = internal_buffer[idx - 0]; - float mu2 = mu * mu; - AudioFrame a0 = y3 - y2 - y0 + y1; - AudioFrame a1 = y0 - y1 - a0; - AudioFrame a2 = y2 - y0; - AudioFrame a3 = y1; - - p_buffer[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3); + AudioFrame even1 = y2 + y1, odd1 = y2 - y1; + AudioFrame even2 = y3 + y0, odd2 = y3 - y0; + AudioFrame c0 = even1 * 0.46835497211269561 + even2 * 0.03164502784253309; + AudioFrame c1 = odd1 * 0.56001293337091440 + odd2 * 0.14666238593949288; + AudioFrame c2 = even1 * -0.250038759826233691 + even2 * 0.25003876124297131; + AudioFrame c3 = odd1 * -0.49949850957839148 + odd2 * 0.16649935475113800; + AudioFrame c4 = even1 * 0.00016095224137360 + even2 * -0.00016095810460478; + p_buffer[i] = (((c4 * mu + c3) * mu + c2) * mu + c1) * mu + c0; mix_offset += mix_increment; @@ -184,7 +184,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) { return; } - if (!GLOBAL_GET("audio/enable_audio_input")) { + if (!GLOBAL_GET("audio/driver/enable_input")) { WARN_PRINT("Need to enable Project settings > Audio > Enable Audio Input option to use capturing."); return; } diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp new file mode 100644 index 0000000000..37e4122e50 --- /dev/null +++ b/servers/audio/effects/audio_effect_capture.cpp @@ -0,0 +1,140 @@ +/*************************************************************************/ +/* audio_effect_capture.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "audio_effect_capture.h" + +bool AudioEffectCapture::can_get_buffer(int p_frames) const { + return buffer.data_left() >= p_frames; +} + +PackedVector2Array AudioEffectCapture::get_buffer(int p_frames) { + ERR_FAIL_COND_V(!buffer_initialized, PackedVector2Array()); + ERR_FAIL_INDEX_V(p_frames, buffer.size(), PackedVector2Array()); + int data_left = buffer.data_left(); + if (data_left < p_frames || p_frames == 0) { + return PackedVector2Array(); + } + + PackedVector2Array ret; + ret.resize(p_frames); + + Vector<AudioFrame> streaming_data; + streaming_data.resize(p_frames); + buffer.read(streaming_data.ptrw(), p_frames); + for (int32_t i = 0; i < p_frames; i++) { + ret.write[i] = Vector2(streaming_data[i].l, streaming_data[i].r); + } + return ret; +} + +void AudioEffectCapture::clear_buffer() { + const int32_t data_left = buffer.data_left(); + buffer.advance_read(data_left); +} + +void AudioEffectCapture::_bind_methods() { + ClassDB::bind_method(D_METHOD("can_get_buffer", "frames"), &AudioEffectCapture::can_get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "frames"), &AudioEffectCapture::get_buffer); + ClassDB::bind_method(D_METHOD("clear_buffer"), &AudioEffectCapture::clear_buffer); + ClassDB::bind_method(D_METHOD("set_buffer_length", "buffer_length_seconds"), &AudioEffectCapture::set_buffer_length); + ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectCapture::get_buffer_length); + ClassDB::bind_method(D_METHOD("get_frames_available"), &AudioEffectCapture::get_frames_available); + ClassDB::bind_method(D_METHOD("get_discarded_frames"), &AudioEffectCapture::get_discarded_frames); + ClassDB::bind_method(D_METHOD("get_buffer_length_frames"), &AudioEffectCapture::get_buffer_length_frames); + ClassDB::bind_method(D_METHOD("get_pushed_frames"), &AudioEffectCapture::get_pushed_frames); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_buffer_length", "get_buffer_length"); +} + +Ref<AudioEffectInstance> AudioEffectCapture::instance() { + if (!buffer_initialized) { + float target_buffer_size = AudioServer::get_singleton()->get_mix_rate() * buffer_length_seconds; + ERR_FAIL_COND_V(target_buffer_size <= 0 || target_buffer_size >= (1 << 27), Ref<AudioEffectInstance>()); + buffer.resize(nearest_shift((int)target_buffer_size)); + buffer_initialized = true; + } + + clear_buffer(); + + Ref<AudioEffectCaptureInstance> ins; + ins.instance(); + ins->base = Ref<AudioEffectCapture>(this); + + return ins; +} + +void AudioEffectCapture::set_buffer_length(float p_buffer_length_seconds) { + ERR_FAIL_COND(buffer_initialized); + + buffer_length_seconds = p_buffer_length_seconds; +} + +float AudioEffectCapture::get_buffer_length() { + return buffer_length_seconds; +} + +int AudioEffectCapture::get_frames_available() const { + ERR_FAIL_COND_V(!buffer_initialized, 0); + return buffer.data_left(); +} + +int64_t AudioEffectCapture::get_discarded_frames() const { + return discarded_frames.get(); +} + +int AudioEffectCapture::get_buffer_length_frames() const { + ERR_FAIL_COND_V(!buffer_initialized, 0); + return buffer.size(); +} + +int64_t AudioEffectCapture::get_pushed_frames() const { + return pushed_frames.get(); +} + +void AudioEffectCaptureInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { + RingBuffer<AudioFrame> &buffer = base->buffer; + + for (int i = 0; i < p_frame_count; i++) { + p_dst_frames[i] = p_src_frames[i]; + } + + if (buffer.space_left() >= p_frame_count) { + // Add incoming audio frames to the IO ring buffer + int32_t ret = buffer.write(p_src_frames, p_frame_count); + ERR_FAIL_COND_MSG(ret != p_frame_count, "Failed to add data to effect capture ring buffer despite sufficient space."); + base->pushed_frames.add(p_frame_count); + } else { + base->discarded_frames.add(p_frame_count); + } +} + +bool AudioEffectCaptureInstance::process_silence() const { + return true; +} diff --git a/modules/gamecenter/game_center.h b/servers/audio/effects/audio_effect_capture.h index 1ac00ca126..81d4ed6b0f 100644 --- a/modules/gamecenter/game_center.h +++ b/servers/audio/effects/audio_effect_capture.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* game_center.h */ +/* audio_effect_capture.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,44 +28,55 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GAME_CENTER_H -#define GAME_CENTER_H +#ifndef AUDIO_EFFECT_CAPTURE_H +#define AUDIO_EFFECT_CAPTURE_H -#include "core/object/class_db.h" +#include "core/config/engine.h" +#include "core/math/audio_frame.h" +#include "core/object/reference.h" +#include "core/templates/vector.h" +#include "servers/audio/audio_effect.h" +#include "servers/audio_server.h" -class GameCenter : public Object { - GDCLASS(GameCenter, Object); +class AudioEffectCapture; - static GameCenter *instance; - static void _bind_methods(); +class AudioEffectCaptureInstance : public AudioEffectInstance { + GDCLASS(AudioEffectCaptureInstance, AudioEffectInstance); + friend class AudioEffectCapture; + Ref<AudioEffectCapture> base; - List<Variant> pending_events; +public: + virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) override; + virtual bool process_silence() const override; +}; - bool authenticated; +class AudioEffectCapture : public AudioEffect { + GDCLASS(AudioEffectCapture, AudioEffect) + friend class AudioEffectCaptureInstance; - void return_connect_error(const char *p_error_description); + RingBuffer<AudioFrame> buffer; + SafeNumeric<uint64_t> discarded_frames; + SafeNumeric<uint64_t> pushed_frames; + float buffer_length_seconds = 0.1f; + bool buffer_initialized = false; -public: - Error authenticate(); - bool is_authenticated(); - - Error post_score(Dictionary p_score); - Error award_achievement(Dictionary p_params); - void reset_achievements(); - void request_achievements(); - void request_achievement_descriptions(); - Error show_game_center(Dictionary p_params); - Error request_identity_verification_signature(); +protected: + static void _bind_methods(); - void game_center_closed(); +public: + virtual Ref<AudioEffectInstance> instance() override; - int get_pending_event_count(); - Variant pop_pending_event(); + void set_buffer_length(float p_buffer_length_seconds); + float get_buffer_length(); - static GameCenter *get_singleton(); + bool can_get_buffer(int p_frames) const; + PackedVector2Array get_buffer(int p_len); + void clear_buffer(); - GameCenter(); - ~GameCenter(); + int get_frames_available() const; + int64_t get_discarded_frames() const; + int get_buffer_length_frames() const; + int64_t get_pushed_frames() const; }; -#endif +#endif // AUDIO_EFFECT_CAPTURE_H diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp index 1542273a24..eb2268aa2e 100644 --- a/servers/audio/effects/audio_effect_chorus.cpp +++ b/servers/audio/effects/audio_effect_chorus.cpp @@ -84,7 +84,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A if (v.cutoff == 0) { continue; } - float auxlp = expf(-2.0 * Math_PI * v.cutoff / mix_rate); + float auxlp = expf(-Math_TAU * v.cutoff / mix_rate); float c1 = 1.0 - auxlp; float c2 = auxlp; AudioFrame h = filter_h[vc]; @@ -104,7 +104,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A float phase = (float)(local_cycles & AudioEffectChorus::CYCLES_MASK) / (float)(1 << AudioEffectChorus::CYCLES_FRAC); - float wave_delay = sinf(phase * 2.0 * Math_PI) * max_depth_frames; + float wave_delay = sinf(phase * Math_TAU) * max_depth_frames; int wave_delay_frames = lrint(floor(wave_delay)); float wave_delay_frac = wave_delay - (float)wave_delay_frames; @@ -309,7 +309,7 @@ void AudioEffectChorus::_bind_methods() { ClassDB::bind_method(D_METHOD("set_dry", "amount"), &AudioEffectChorus::set_dry); ClassDB::bind_method(D_METHOD("get_dry"), &AudioEffectChorus::get_dry); - ADD_PROPERTY(PropertyInfo(Variant::INT, "voice_count", PROPERTY_HINT_RANGE, "1,4,1"), "set_voice_count", "get_voice_count"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "voice_count", PROPERTY_HINT_RANGE, "1,4,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_voice_count", "get_voice_count"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dry", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dry", "get_dry"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wet", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_wet", "get_wet"); diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp index f04ab45ec1..ba50eeb0a3 100644 --- a/servers/audio/effects/audio_effect_delay.cpp +++ b/servers/audio/effects/audio_effect_delay.cpp @@ -75,7 +75,7 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au tap2_vol.r *= CLAMP(1.0 + base->tap_2_pan, 0, 1); // feedback lowpass here - float lpf_c = expf(-2.0 * Math_PI * base->feedback_lowpass / mix_rate); // 0 .. 10khz + float lpf_c = expf(-Math_TAU * base->feedback_lowpass / mix_rate); // 0 .. 10khz float lpf_ic = 1.0 - lpf_c; const AudioFrame *src = p_src_frames; diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index 8f713ace22..06d51776a3 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -36,8 +36,8 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi const float *src = (const float *)p_src_frames; float *dst = (float *)p_dst_frames; - //float lpf_c=expf(-2.0*Math_PI*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE)); - float lpf_c = expf(-2.0 * Math_PI * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate())); + //float lpf_c=expf(-Math_TAU*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE)); + float lpf_c = expf(-Math_TAU * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate())); float lpf_ic = 1.0 - lpf_c; float drive_f = base->drive; @@ -58,7 +58,8 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi switch (base->mode) { case AudioEffectDistortion::MODE_CLIP: { - a = powf(a, 1.0001 - drive_f); + float a_sign = a < 0 ? -1.0f : 1.0f; + a = powf(abs(a), 1.0001 - drive_f) * a_sign; if (a > 1.0) { a = 1.0; } else if (a < (-1.0)) { diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp index 5e4e183ccf..9b70f03a19 100644 --- a/servers/audio/effects/audio_effect_phaser.cpp +++ b/servers/audio/effects/audio_effect_phaser.cpp @@ -38,13 +38,13 @@ void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFra float dmin = base->range_min / (sampling_rate / 2.0); float dmax = base->range_max / (sampling_rate / 2.0); - float increment = 2.f * Math_PI * (base->rate / sampling_rate); + float increment = Math_TAU * (base->rate / sampling_rate); for (int i = 0; i < p_frame_count; i++) { phase += increment; - while (phase >= Math_PI * 2.f) { - phase -= Math_PI * 2.f; + while (phase >= Math_TAU) { + phase -= Math_TAU; } float d = dmin + (dmax - dmin) * ((sin(phase) + 1.f) / 2.f); diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp index e8832c92a3..2015ede81f 100644 --- a/servers/audio/effects/audio_effect_record.cpp +++ b/servers/audio/effects/audio_effect_record.cpp @@ -118,7 +118,7 @@ void AudioEffectRecordInstance::init() { #ifdef NO_THREADS AudioServer::get_singleton()->add_update_callback(&AudioEffectRecordInstance::_update, this); #else - io_thread = Thread::create(_thread_callback, this); + io_thread.start(_thread_callback, this); #endif } @@ -126,9 +126,7 @@ void AudioEffectRecordInstance::finish() { #ifdef NO_THREADS AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this); #else - if (thread_active) { - Thread::wait_to_finish(io_thread); - } + io_thread.wait_to_finish(); #endif } diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h index 14e646e29d..b97ec43946 100644 --- a/servers/audio/effects/audio_effect_record.h +++ b/servers/audio/effects/audio_effect_record.h @@ -48,7 +48,7 @@ class AudioEffectRecordInstance : public AudioEffectInstance { Ref<AudioEffectRecord> base; bool is_recording; - Thread *io_thread; + Thread io_thread; bool thread_active = false; Vector<AudioFrame> ring_buffer; diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp index 7f73f2e880..3f7ab74a74 100644 --- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp +++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp @@ -110,10 +110,11 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames while (p_frame_count) { int to_fill = fft_size * 2 - temporal_fft_pos; to_fill = MIN(to_fill, p_frame_count); + const double to_fill_step = Math_TAU / (double)fft_size; float *fftw = temporal_fft.ptrw(); for (int i = 0; i < to_fill; i++) { //left and right buffers - float window = -0.5 * Math::cos(2.0 * Math_PI * (double)temporal_fft_pos / (double)fft_size) + 0.5; + float window = -0.5 * Math::cos(to_fill_step * (double)temporal_fft_pos) + 0.5; fftw[temporal_fft_pos * 2] = window * p_src_frames->l; fftw[temporal_fft_pos * 2 + 1] = 0; fftw[(temporal_fft_pos + fft_size * 2) * 2] = window * p_src_frames->r; diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp index 2181411b9e..e0c3eb6d3a 100644 --- a/servers/audio/effects/eq.cpp +++ b/servers/audio/effects/eq.cpp @@ -89,8 +89,8 @@ void EQ::recalculate_band_coefficients() { double frq_l = round(frq / pow(2.0, octave_size / 2.0)); double side_gain2 = POW2(Math_SQRT12); - double th = 2.0 * Math_PI * frq / mix_rate; - double th_l = 2.0 * Math_PI * frq_l / mix_rate; + double th = Math_TAU * frq / mix_rate; + double th_l = Math_TAU * frq_l / mix_rate; double c2a = side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) + side_gain2 - POW2(sin(th_l)); diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp index eb96e21659..7df2f99f67 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb.cpp @@ -91,7 +91,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { } if (params.hpf > 0) { - float hpaux = expf(-2.0 * Math_PI * params.hpf * 6000 / params.mix_rate); + float hpaux = expf(-Math_TAU * params.hpf * 6000 / params.mix_rate); float hp_a1 = (1.0 + hpaux) / 2.0; float hp_a2 = -(1.0 + hpaux) / 2.0; float hp_b1 = hpaux; @@ -293,7 +293,7 @@ void Reverb::update_parameters() { float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough) auxdmp *= auxdmp; - c.damp = expf(-2.0 * Math_PI * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz + c.damp = expf(-Math_TAU * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz } } diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 295059a1ea..138cb6e1f8 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -71,13 +71,20 @@ void AudioDriver::update_mix_time(int p_frames) { } } -double AudioDriver::get_time_since_last_mix() const { - return (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; +double AudioDriver::get_time_since_last_mix() { + lock(); + uint64_t last_mix_time = _last_mix_time; + unlock(); + return (OS::get_singleton()->get_ticks_usec() - last_mix_time) / 1000000.0; } -double AudioDriver::get_time_to_next_mix() const { - double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; - double mix_buffer = _last_mix_frames / (double)get_mix_rate(); +double AudioDriver::get_time_to_next_mix() { + lock(); + uint64_t last_mix_time = _last_mix_time; + uint64_t last_mix_frames = _last_mix_frames; + unlock(); + double total = (OS::get_singleton()->get_ticks_usec() - last_mix_time) / 1000000.0; + double mix_buffer = last_mix_frames / (double)get_mix_rate(); return mix_buffer - total; } @@ -181,10 +188,10 @@ int AudioDriverManager::get_driver_count() { } void AudioDriverManager::initialize(int p_driver) { - GLOBAL_DEF_RST("audio/enable_audio_input", false); - GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE); - GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY); - GLOBAL_DEF_RST("audio/output_latency.web", 50); // Safer default output_latency for web. + GLOBAL_DEF_RST("audio/driver/enable_input", false); + GLOBAL_DEF_RST("audio/driver/mix_rate", DEFAULT_MIX_RATE); + GLOBAL_DEF_RST("audio/driver/output_latency", DEFAULT_OUTPUT_LATENCY); + GLOBAL_DEF_RST("audio/driver/output_latency.web", 50); // Safer default output_latency for web. int failed_driver = -1; @@ -394,6 +401,7 @@ void AudioServer::_mix_step() { for (int k = 0; k < bus->channels.size(); k++) { if (!bus->channels[k].active) { + bus->channels.write[k].peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB); continue; } @@ -427,7 +435,7 @@ void AudioServer::_mix_step() { } } - bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + 0.0000000001), Math::linear2db(peak.r + 0.0000000001)); + bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + AUDIO_PEAK_OFFSET), Math::linear2db(peak.r + AUDIO_PEAK_OFFSET)); if (!bus->channels[k].used) { //see if any audio is contained, because channel was not used @@ -931,9 +939,9 @@ void AudioServer::init_channels_and_buffers() { } void AudioServer::init() { - channel_disable_threshold_db = GLOBAL_DEF_RST("audio/channel_disable_threshold_db", -60.0); - channel_disable_frames = float(GLOBAL_DEF_RST("audio/channel_disable_time", 2.0)) * get_mix_rate(); - ProjectSettings::get_singleton()->set_custom_property_info("audio/channel_disable_time", PropertyInfo(Variant::FLOAT, "audio/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); + channel_disable_threshold_db = GLOBAL_DEF_RST("audio/buses/channel_disable_threshold_db", -60.0); + channel_disable_frames = float(GLOBAL_DEF_RST("audio/buses/channel_disable_time", 2.0)) * get_mix_rate(); + ProjectSettings::get_singleton()->set_custom_property_info("audio/buses/channel_disable_time", PropertyInfo(Variant::FLOAT, "audio/buses/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); buffer_size = 1024; //hardcoded for now init_channels_and_buffers(); @@ -950,7 +958,7 @@ void AudioServer::init() { set_edited(false); //avoid editors from thinking this was edited #endif - GLOBAL_DEF_RST("audio/video_delay_compensation_ms", 0); + GLOBAL_DEF_RST("audio/video/video_delay_compensation_ms", 0); } void AudioServer::update() { @@ -1027,7 +1035,7 @@ void AudioServer::update() { } void AudioServer::load_default_bus_layout() { - String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); + String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); if (ResourceLoader::exists(layout_path)) { Ref<AudioBusLayout> default_layout = ResourceLoader::load(layout_path); diff --git a/servers/audio_server.h b/servers/audio_server.h index 631fef0f65..a1a373e1ca 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -70,8 +70,8 @@ protected: #endif public: - double get_time_since_last_mix() const; //useful for video -> audio sync - double get_time_to_next_mix() const; + double get_time_since_last_mix(); //useful for video -> audio sync + double get_time_to_next_mix(); enum SpeakerMode { SPEAKER_MODE_STEREO, @@ -199,7 +199,7 @@ private: last_mix_with_audio = 0; used = false; active = false; - peak_volume = AudioFrame(0, 0); + peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB); } }; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 29c1c9fc60..2fa333cc05 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -477,7 +477,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("enable_for_stealing_focus", "process_id"), &DisplayServer::enable_for_stealing_focus); - ClassDB::bind_method(D_METHOD("native_video_play", "path", "volume", "audio_track", "subtitle_track"), &DisplayServer::native_video_play); + ClassDB::bind_method(D_METHOD("native_video_play", "path", "volume", "audio_track", "subtitle_track", "screen"), &DisplayServer::native_video_play); ClassDB::bind_method(D_METHOD("native_video_is_playing"), &DisplayServer::native_video_is_playing); ClassDB::bind_method(D_METHOD("native_video_stop"), &DisplayServer::native_video_stop); ClassDB::bind_method(D_METHOD("native_video_pause"), &DisplayServer::native_video_pause); @@ -504,6 +504,11 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_native_icon", "filename"), &DisplayServer::set_native_icon); ClassDB::bind_method(D_METHOD("set_icon", "image"), &DisplayServer::set_icon); + ClassDB::bind_method(D_METHOD("tablet_get_driver_count"), &DisplayServer::tablet_get_driver_count); + ClassDB::bind_method(D_METHOD("tablet_get_driver_name", "idx"), &DisplayServer::tablet_get_driver_name); + ClassDB::bind_method(D_METHOD("tablet_get_current_driver"), &DisplayServer::tablet_get_current_driver); + ClassDB::bind_method(D_METHOD("tablet_set_current_driver", "name"), &DisplayServer::tablet_set_current_driver); + BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU); BIND_ENUM_CONSTANT(FEATURE_SUBWINDOWS); BIND_ENUM_CONSTANT(FEATURE_TOUCHSCREEN); diff --git a/servers/display_server.h b/servers/display_server.h index fc34a2a228..3aab572120 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -83,7 +83,7 @@ protected: static DisplayServerCreate server_create_functions[MAX_SERVERS]; static int server_create_count; - friend class RenderingServerDefault; + friend class RendererViewport; virtual void _set_use_vsync(bool p_enable); public: @@ -340,6 +340,11 @@ public: virtual String keyboard_get_layout_language(int p_index) const; virtual String keyboard_get_layout_name(int p_index) const; + virtual int tablet_get_driver_count() const { return 1; }; + virtual String tablet_get_driver_name(int p_driver) const { return "default"; }; + virtual String tablet_get_current_driver() const { return "default"; }; + virtual void tablet_set_current_driver(const String &p_driver){}; + virtual void process_events() = 0; virtual void force_process_and_drop_events(); diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 2939b4b99f..2db3961f41 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -61,7 +61,7 @@ private: Variant metadata; bool disabled; bool one_way_collision; - float one_way_collision_margin; + real_t one_way_collision_margin; Shape() { disabled = false; one_way_collision = false; @@ -153,7 +153,7 @@ public: return shapes[p_idx].disabled; } - _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision, float p_margin) { + _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision, real_t p_margin) { CRASH_BAD_INDEX(p_idx, shapes.size()); shapes.write[p_idx].one_way_collision = p_one_way_collision; shapes.write[p_idx].one_way_collision_margin = p_margin; @@ -163,7 +163,7 @@ public: return shapes[p_idx].one_way_collision; } - _FORCE_INLINE_ float get_shape_one_way_collision_margin(int p_idx) const { + _FORCE_INLINE_ real_t get_shape_one_way_collision_margin(int p_idx) const { CRASH_BAD_INDEX(p_idx, shapes.size()); return shapes[p_idx].one_way_collision_margin; } diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index 3558848dac..c7b556deba 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -55,6 +55,14 @@ * SOFTWARE. */ +void Joint2DSW::copy_settings_from(Joint2DSW *p_joint) { + set_self(p_joint->get_self()); + set_max_force(p_joint->get_max_force()); + set_bias(p_joint->get_bias()); + set_max_bias(p_joint->get_max_bias()); + disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies()); +} + static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) { real_t value = 0; @@ -197,15 +205,6 @@ PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p } } -PinJoint2DSW::~PinJoint2DSW() { - if (A) { - A->remove_constraint(this, 0); - } - if (B) { - B->remove_constraint(this, 1); - } -} - ////////////////////////////////////////////// ////////////////////////////////////////////// ////////////////////////////////////////////// @@ -338,11 +337,6 @@ GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_ B->add_constraint(this, 1); } -GrooveJoint2DSW::~GrooveJoint2DSW() { - A->remove_constraint(this, 0); - B->remove_constraint(this, 1); -} - ////////////////////////////////////////////// ////////////////////////////////////////////// ////////////////////////////////////////////// @@ -434,8 +428,3 @@ DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Ve A->add_constraint(this, 0); B->add_constraint(this, 1); } - -DampedSpringJoint2DSW::~DampedSpringJoint2DSW() { - A->remove_constraint(this, 0); - B->remove_constraint(this, 1); -} diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h index 53e436b539..628de972ae 100644 --- a/servers/physics_2d/joints_2d_sw.h +++ b/servers/physics_2d/joints_2d_sw.h @@ -49,12 +49,26 @@ public: _FORCE_INLINE_ void set_max_bias(real_t p_bias) { max_bias = p_bias; } _FORCE_INLINE_ real_t get_max_bias() const { return max_bias; } - virtual PhysicsServer2D::JointType get_type() const = 0; + virtual bool setup(real_t p_step) { return false; } + virtual void solve(real_t p_step) {} + + void copy_settings_from(Joint2DSW *p_joint); + + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_MAX; } Joint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) : Constraint2DSW(p_body_ptr, p_body_count) { bias = 0; max_force = max_bias = 3.40282e+38; }; + + virtual ~Joint2DSW() { + for (int i = 0; i < get_body_count(); i++) { + Body2DSW *body = get_body_ptr()[i]; + if (body) { + body->remove_constraint(this, i); + } + } + }; }; class PinJoint2DSW : public Joint2DSW { @@ -76,7 +90,7 @@ class PinJoint2DSW : public Joint2DSW { real_t softness; public: - virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_PIN; } + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_PIN; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); @@ -85,7 +99,6 @@ public: real_t get_param(PhysicsServer2D::PinJointParam p_param) const; PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b = nullptr); - ~PinJoint2DSW(); }; class GrooveJoint2DSW : public Joint2DSW { @@ -113,13 +126,12 @@ class GrooveJoint2DSW : public Joint2DSW { bool correct; public: - virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_GROOVE; } + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_GROOVE; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, Body2DSW *p_body_a, Body2DSW *p_body_b); - ~GrooveJoint2DSW(); }; class DampedSpringJoint2DSW : public Joint2DSW { @@ -146,7 +158,7 @@ class DampedSpringJoint2DSW : public Joint2DSW { real_t v_coef; public: - virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_DAMPED_SPRING; } + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_DAMPED_SPRING; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); @@ -155,7 +167,6 @@ public: real_t get_param(PhysicsServer2D::DampedSpringParam p_param) const; DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b); - ~DampedSpringJoint2DSW(); }; #endif // JOINTS_2D_SW_H diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index c4e2489bef..1040437ca7 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -667,7 +667,7 @@ void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo body->set_shape_as_disabled(p_shape_idx, p_disabled); } -void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) { +void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); @@ -958,7 +958,7 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } -int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) { +int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -985,6 +985,24 @@ PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { /* JOINT API */ +RID PhysicsServer2DSW::joint_create() { + Joint2DSW *joint = memnew(Joint2DSW); + RID joint_rid = joint_owner.make_rid(joint); + joint->set_self(joint_rid); + return joint_rid; +} + +void PhysicsServer2DSW::joint_clear(RID p_joint) { + Joint2DSW *joint = joint_owner.getornull(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + Joint2DSW *empty_joint = memnew(Joint2DSW); + empty_joint->copy_settings_from(joint); + + joint_owner.replace(p_joint, empty_joint); + memdelete(joint); + } +} + void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { Joint2DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); @@ -1048,52 +1066,63 @@ bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) return joint->is_disabled_collisions_between_bodies(); } -RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b) { +void PhysicsServer2DSW::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) { Body2DSW *A = body_owner.getornull(p_body_a); - ERR_FAIL_COND_V(!A, RID()); + ERR_FAIL_COND(!A); Body2DSW *B = nullptr; if (body_owner.owns(p_body_b)) { B = body_owner.getornull(p_body_b); - ERR_FAIL_COND_V(!B, RID()); + ERR_FAIL_COND(!B); } + Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + Joint2DSW *joint = memnew(PinJoint2DSW(p_pos, A, B)); - RID self = joint_owner.make_rid(joint); - joint->set_self(self); - return self; + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); } -RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { +void PhysicsServer2DSW::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { Body2DSW *A = body_owner.getornull(p_body_a); - ERR_FAIL_COND_V(!A, RID()); + ERR_FAIL_COND(!A); Body2DSW *B = body_owner.getornull(p_body_b); - ERR_FAIL_COND_V(!B, RID()); + ERR_FAIL_COND(!B); + + Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(GrooveJoint2DSW(p_a_groove1, p_a_groove2, p_b_anchor, A, B)); - RID self = joint_owner.make_rid(joint); - joint->set_self(self); - return self; + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); } -RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { +void PhysicsServer2DSW::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { Body2DSW *A = body_owner.getornull(p_body_a); - ERR_FAIL_COND_V(!A, RID()); + ERR_FAIL_COND(!A); Body2DSW *B = body_owner.getornull(p_body_b); - ERR_FAIL_COND_V(!B, RID()); + ERR_FAIL_COND(!B); + + Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(DampedSpringJoint2DSW(p_anchor_a, p_anchor_b, A, B)); - RID self = joint_owner.make_rid(joint); - joint->set_self(self); - return self; + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); } void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND(!j); - ERR_FAIL_COND(j->get_type() != JOINT_PIN); + ERR_FAIL_COND(j->get_type() != JOINT_TYPE_PIN); PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j); pin_joint->set_param(p_param, p_value); @@ -1102,7 +1131,7 @@ void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!j, 0); - ERR_FAIL_COND_V(j->get_type() != JOINT_PIN, 0); + ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_PIN, 0); PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j); return pin_joint->get_param(p_param); @@ -1111,7 +1140,7 @@ real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND(!j); - ERR_FAIL_COND(j->get_type() != JOINT_DAMPED_SPRING); + ERR_FAIL_COND(j->get_type() != JOINT_TYPE_DAMPED_SPRING); DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j); dsj->set_param(p_param, p_value); @@ -1120,7 +1149,7 @@ void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringP real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!j, 0); - ERR_FAIL_COND_V(j->get_type() != JOINT_DAMPED_SPRING, 0); + ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_DAMPED_SPRING, 0); DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j); return dsj->get_param(p_param); @@ -1128,7 +1157,7 @@ real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSprin PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const { Joint2DSW *joint = joint_owner.getornull(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_PIN); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); } @@ -1325,7 +1354,7 @@ int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) { PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr; -PhysicsServer2DSW::PhysicsServer2DSW() { +PhysicsServer2DSW::PhysicsServer2DSW(bool p_using_threads) { singletonsw = this; BroadPhase2DSW::create_func = BroadPhase2DHashGrid::_create; //BroadPhase2DSW::create_func=BroadPhase2DBasic::_create; @@ -1334,10 +1363,6 @@ PhysicsServer2DSW::PhysicsServer2DSW() { island_count = 0; active_objects = 0; collision_pairs = 0; -#ifdef NO_THREADS - using_threads = false; -#else - using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2; -#endif + using_threads = p_using_threads; flushing_queries = false; }; diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 3305c0bd3d..65c5df0fce 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -61,11 +61,11 @@ class PhysicsServer2DSW : public PhysicsServer2D { PhysicsDirectBodyState2DSW *direct_state; - mutable RID_PtrOwner<Shape2DSW> shape_owner; - mutable RID_PtrOwner<Space2DSW> space_owner; - mutable RID_PtrOwner<Area2DSW> area_owner; - mutable RID_PtrOwner<Body2DSW> body_owner; - mutable RID_PtrOwner<Joint2DSW> joint_owner; + mutable RID_PtrOwner<Shape2DSW, true> shape_owner; + mutable RID_PtrOwner<Space2DSW, true> space_owner; + mutable RID_PtrOwner<Area2DSW, true> area_owner; + mutable RID_PtrOwner<Body2DSW, true> body_owner; + mutable RID_PtrOwner<Joint2DSW, true> joint_owner; static PhysicsServer2DSW *singletonsw; @@ -191,7 +191,7 @@ public: virtual void body_clear_shapes(RID p_body) override; virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override; - virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) override; + virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) override; virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) override; virtual ObjectID body_get_object_instance_id(RID p_body) const override; @@ -248,22 +248,27 @@ public: virtual void body_set_pickable(RID p_body, bool p_pickable) override; virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; - virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) override; + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override; /* JOINT API */ + virtual RID joint_create() override; + + virtual void joint_clear(RID p_joint) override; + virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value) override; virtual real_t joint_get_param(RID p_joint, JointParam p_param) const override; virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disabled) override; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override; - virtual RID pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b = RID()) override; - virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override; - virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override; + virtual void joint_make_pin(RID p_joint, const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) override; + virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override; + virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override; + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; virtual void damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) override; @@ -287,7 +292,7 @@ public: int get_process_info(ProcessInfo p_info) override; - PhysicsServer2DSW(); + PhysicsServer2DSW(bool p_using_threads = false); ~PhysicsServer2DSW() {} }; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp index 15d875b3b7..790c87cc44 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp @@ -33,7 +33,7 @@ #include "core/os/os.h" void PhysicsServer2DWrapMT::thread_exit() { - exit = true; + exit.set(); } void PhysicsServer2DWrapMT::thread_step(real_t p_delta) { @@ -52,9 +52,9 @@ void PhysicsServer2DWrapMT::thread_loop() { physics_2d_server->init(); - exit = false; - step_thread_up = true; - while (!exit) { + exit.clear(); + step_thread_up.set(); + while (!exit.is_set()) { // flush commands one by one, until exit is requested command_queue.wait_and_flush_one(); } @@ -76,7 +76,7 @@ void PhysicsServer2DWrapMT::step(real_t p_step) { } void PhysicsServer2DWrapMT::sync() { - if (thread) { + if (create_thread) { if (first_frame) { first_frame = false; } else { @@ -97,8 +97,8 @@ void PhysicsServer2DWrapMT::end_sync() { void PhysicsServer2DWrapMT::init() { if (create_thread) { //OS::get_singleton()->release_rendering_thread(); - thread = Thread::create(_thread_callback, this); - while (!step_thread_up) { + thread.start(_thread_callback, this); + while (!step_thread_up.is_set()) { OS::get_singleton()->delay_usec(1000); } } else { @@ -107,37 +107,19 @@ void PhysicsServer2DWrapMT::init() { } void PhysicsServer2DWrapMT::finish() { - if (thread) { + if (thread.is_started()) { command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit); - Thread::wait_to_finish(thread); - memdelete(thread); - - thread = nullptr; + thread.wait_to_finish(); } else { physics_2d_server->finish(); } - - line_shape_free_cached_ids(); - ray_shape_free_cached_ids(); - segment_shape_free_cached_ids(); - circle_shape_free_cached_ids(); - rectangle_shape_free_cached_ids(); - capsule_shape_free_cached_ids(); - convex_polygon_shape_free_cached_ids(); - concave_polygon_shape_free_cached_ids(); - - space_free_cached_ids(); - area_free_cached_ids(); - body_free_cached_ids(); } PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) : command_queue(p_create_thread) { physics_2d_server = p_contained; create_thread = p_create_thread; - thread = nullptr; step_pending = 0; - step_thread_up = false; pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index 9207081a51..3577f706de 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -34,6 +34,7 @@ #include "core/config/project_settings.h" #include "core/os/thread.h" #include "core/templates/command_queue_mt.h" +#include "core/templates/safe_refcount.h" #include "servers/physics_server_2d.h" #ifdef DEBUG_SYNC @@ -52,9 +53,9 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D { Thread::ID server_thread; Thread::ID main_thread; - volatile bool exit; - Thread *thread; - volatile bool step_thread_up; + SafeFlag exit; + Thread thread; + SafeFlag step_thread_up; bool create_thread; Semaphore step_sem; @@ -73,6 +74,8 @@ public: #define ServerName PhysicsServer2D #define ServerNameWrapMT PhysicsServer2DWrapMT #define server_name physics_2d_server +#define WRITE_ACTION + #include "servers/server_wrap_mt_common.h" //FUNC1RID(shape,ShapeType); todo fix @@ -93,7 +96,7 @@ public: FUNC1RC(real_t, shape_get_custom_solver_bias, RID); //these work well, but should be used from the main thread only - bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { + bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count); } @@ -108,18 +111,18 @@ public: FUNC2RC(real_t, space_get_param, RID, SpaceParameter); // this function only works on physics process, errors and returns null otherwise - PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) { + PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->space_get_direct_state(p_space); } FUNC2(space_set_debug_contacts, RID, int); - virtual Vector<Vector2> space_get_contacts(RID p_space) const { + virtual Vector<Vector2> space_get_contacts(RID p_space) const override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>()); return physics_2d_server->space_get_contacts(p_space); } - virtual int space_get_contact_count(RID p_space) const { + virtual int space_get_contact_count(RID p_space) const override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0); return physics_2d_server->space_get_contact_count(p_space); } @@ -189,7 +192,7 @@ public: FUNC2RC(RID, body_get_shape, RID, int); FUNC3(body_set_shape_disabled, RID, int, bool); - FUNC4(body_set_shape_as_one_way_collision, RID, int, bool, float); + FUNC4(body_set_shape_as_one_way_collision, RID, int, bool, real_t); FUNC2(body_remove_shape, RID, int); FUNC1(body_clear_shapes, RID); @@ -244,30 +247,34 @@ public: FUNC4(body_set_force_integration_callback, RID, Object *, const StringName &, const Variant &); - bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) { + bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override { return physics_2d_server->body_collide_shape(p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, r_result_count); } FUNC2(body_set_pickable, RID, bool); - bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) { + bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } - int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) { + int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } // this function only works on physics process, errors and returns null otherwise - PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) { + PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->body_get_direct_state(p_body); } /* JOINT API */ + FUNCRID(joint) + + FUNC1(joint_clear, RID) + FUNC3(joint_set_param, RID, JointParam, real_t); FUNC2RC(real_t, joint_get_param, RID, JointParam); @@ -280,9 +287,9 @@ public: //TODO need to convert this to FUNCRID, but it's a hassle.. - FUNC3R(RID, pin_joint_create, const Vector2 &, RID, RID); - FUNC5R(RID, groove_joint_create, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID); - FUNC4R(RID, damped_spring_joint_create, const Vector2 &, const Vector2 &, RID, RID); + FUNC4(joint_make_pin, RID, const Vector2 &, RID, RID); + FUNC6(joint_make_groove, RID, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID); + FUNC5(joint_make_damped_spring, RID, const Vector2 &, const Vector2 &, RID, RID); FUNC3(pin_joint_set_param, RID, PinJointParam, real_t); FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam); @@ -297,43 +304,28 @@ public: FUNC1(free, RID); FUNC1(set_active, bool); - virtual void init(); - virtual void step(real_t p_step); - virtual void sync(); - virtual void end_sync(); - virtual void flush_queries(); - virtual void finish(); + virtual void init() override; + virtual void step(real_t p_step) override; + virtual void sync() override; + virtual void end_sync() override; + virtual void flush_queries() override; + virtual void finish() override; - virtual bool is_flushing_queries() const { + virtual bool is_flushing_queries() const override { return physics_2d_server->is_flushing_queries(); } - int get_process_info(ProcessInfo p_info) { + int get_process_info(ProcessInfo p_info) override { return physics_2d_server->get_process_info(p_info); } PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread); ~PhysicsServer2DWrapMT(); - template <class T> - static PhysicsServer2D *init_server() { -#ifdef NO_THREADS - return memnew(T); // Always single unsafe when no threads are available. -#else - int tm = GLOBAL_DEF("physics/2d/thread_model", 1); - if (tm == 0) { // single unsafe - return memnew(T); - } else if (tm == 1) { // single safe - return memnew(PhysicsServer2DWrapMT(memnew(T), false)); - } else { // multi threaded - return memnew(PhysicsServer2DWrapMT(memnew(T), true)); - } -#endif - } - #undef ServerNameWrapMT #undef ServerName #undef server_name +#undef WRITE_ACTION }; #ifdef DEBUG_SYNC diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 24c73314d8..6e7e802a8b 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -339,10 +339,10 @@ void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_suppor } bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const { - float x = p_point.x; - float y = p_point.y; - float edge_x = half_extents.x; - float edge_y = half_extents.y; + real_t x = p_point.x; + real_t y = p_point.y; + real_t edge_x = half_extents.x; + real_t edge_y = half_extents.y; return (x >= -edge_x) && (x < edge_x) && (y >= -edge_y) && (y < edge_y); } @@ -590,7 +590,11 @@ real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 } void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { +#ifdef REAL_T_IS_DOUBLE + ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY); +#else ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY); +#endif if (points) { memdelete_arr(points); @@ -829,7 +833,11 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { } void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { +#ifdef REAL_T_IS_DOUBLE + ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY); +#else ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY); +#endif Rect2 aabb; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index ad5dca37e4..4f12248c3e 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -84,6 +84,10 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S int shape_idx = space->intersection_query_subindex_results[i]; + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + Shape2DSW *shape = col_obj->get_shape(shape_idx); Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point); @@ -229,6 +233,10 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; } @@ -272,15 +280,19 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; } - //test initial overlap + //test initial overlap, ignore objects it's inside of. if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { - return false; + continue; } //just do kinematic solving @@ -346,12 +358,17 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & } const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; - int shape_idx = space->intersection_query_subindex_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; } + int shape_idx = space->intersection_query_subindex_results[i]; + + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + cbk.valid_dir = Vector2(); cbk.valid_depth = 0; @@ -376,6 +393,7 @@ struct _RestCallbackData2D { Vector2 best_normal; real_t best_len; Vector2 valid_dir; + real_t valid_depth; real_t min_allowed_depth; }; @@ -385,22 +403,24 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, Vector2 contact_rel = p_point_B - p_point_A; real_t len = contact_rel.length(); - if (len == 0) { + if (len < rd->min_allowed_depth) { return; } - Vector2 normal = contact_rel / len; - - if (rd->valid_dir != Vector2() && rd->valid_dir.dot(normal) > -CMP_EPSILON) { + if (len <= rd->best_len) { return; } - if (len < rd->min_allowed_depth) { - return; - } + Vector2 normal = contact_rel / len; - if (len <= rd->best_len) { - return; + if (rd->valid_dir != Vector2()) { + if (len > rd->valid_depth) { + return; + } + + if (rd->valid_dir.dot(normal) > -CMP_EPSILON) { + return; + } } rd->best_len = len; @@ -433,12 +453,17 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh } const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; - int shape_idx = space->intersection_query_subindex_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; } + int shape_idx = space->intersection_query_subindex_results[i]; + + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + rcd.valid_dir = Vector2(); rcd.object = col_obj; rcd.shape = shape_idx; @@ -644,7 +669,7 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t recover_motion += (b - a) / cbk.amount; - float depth = a.distance_to(b); + real_t depth = a.distance_to(b); if (depth > result.collision_depth) { result.collision_depth = depth; result.collision_point = b; @@ -739,10 +764,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs]; int excluded_shape_pair_count = 0; - float separation_margin = MIN(p_margin, MAX(0.0, p_motion.length() - CMP_EPSILON)); //don't separate by more than the intended motion + real_t motion_length = p_motion.length(); + Vector2 motion_normal = p_motion / motion_length; Transform2D body_transform = p_from; + bool recovered = false; + { //STEP 1, FREE BODY IF STUCK @@ -793,7 +821,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) { cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized(); - float owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx); + real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx); cbk.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work cbk.invalid_by_dir = 0; @@ -804,7 +832,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co Vector2 lv = b->get_linear_velocity(); //compute displacement from linear velocity Vector2 motion = lv * PhysicsDirectBodyState2DSW::singleton->step; - float motion_len = motion.length(); + real_t motion_len = motion.length(); motion.normalize(); cbk.valid_depth += motion_len * MAX(motion.dot(-cbk.valid_dir), 0.0); } @@ -819,7 +847,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co bool did_collide = false; Shape2DSW *against_shape = col_obj->get_shape(shape_idx); - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, separation_margin)) { + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_margin)) { did_collide = cbk.passed > current_passed; //more passed, so collision actually existed } @@ -845,11 +873,20 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } Vector2 recover_motion; - for (int i = 0; i < cbk.amount; i++) { Vector2 a = sr[i * 2 + 0]; Vector2 b = sr[i * 2 + 1]; - recover_motion += (b - a) / cbk.amount; + + // Compute plane on b towards a. + Vector2 n = (a - b).normalized(); + real_t d = n.dot(b); + + // Compute depth on recovered motion. + real_t depth = n.dot(a + recover_motion) - d; + if (depth > 0.0) { + // Only recover if there is penetration. + recover_motion -= n * depth * 0.4; + } } if (recover_motion == Vector2()) { @@ -857,6 +894,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co break; } + recovered = true; + body_transform.elements[2] += recover_motion; body_aabb.position += recover_motion; @@ -929,7 +968,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co //test initial overlap if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { - continue; + Vector2 direction = col_obj_shape_xform.get_axis(1).normalized(); + if (motion_normal.dot(direction) < 0) { + continue; + } } stuck = true; @@ -939,13 +981,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co //just do kinematic solving real_t low = 0; real_t hi = 1; - Vector2 mnormal = p_motion.normalized(); for (int k = 0; k < 8; k++) { //steps should be customizable.. real_t ofs = (low + hi) * 0.5; - Vector2 sep = mnormal; //important optimization for this to work fast enough + Vector2 sep = motion_normal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); if (collided) { @@ -966,7 +1007,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.valid_depth = 10e20; - Vector2 sep = mnormal; //important optimization for this to work fast enough + Vector2 sep = motion_normal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), PhysicsServer2DSW::_shape_col_cbk, &cbk, &sep, 0); if (!collided || cbk.amount == 0) { continue; @@ -997,11 +1038,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } bool collided = false; - if (safe >= 1) { - best_shape = -1; //no best shape with cast, reset to -1 - } - if (safe < 1) { + if (recovered || (safe < 1)) { + if (safe >= 1) { + best_shape = -1; //no best shape with cast, reset to -1 + } + //it collided, let's get the rest info in unsafe advance Transform2D ugt = body_transform; ugt.elements[2] += p_motion * unsafe; @@ -1010,9 +1052,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co rcd.best_len = 0; rcd.best_object = nullptr; rcd.best_shape = 0; - rcd.min_allowed_depth = test_motion_min_contact_depth; - //optimization + // Allowed depth can't be lower than motion length, in order to handle contacts at low speed. + rcd.min_allowed_depth = MIN(motion_length, test_motion_min_contact_depth); + int from_shape = best_shape != -1 ? best_shape : 0; int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); @@ -1060,8 +1103,25 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) { rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized(); + + real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx); + rcd.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work + + if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) { + const Body2DSW *b = static_cast<const Body2DSW *>(col_obj); + if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_RIGID) { + //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction + Vector2 lv = b->get_linear_velocity(); + //compute displacement from linear velocity + Vector2 motion = lv * PhysicsDirectBodyState2DSW::singleton->step; + real_t motion_len = motion.length(); + motion.normalize(); + rcd.valid_depth += motion_len * MAX(motion.dot(-rcd.valid_dir), 0.0); + } + } } else { rcd.valid_dir = Vector2(); + rcd.valid_depth = 0; } rcd.object = col_obj; @@ -1328,7 +1388,7 @@ Space2DSW::Space2DSW() { constraint_bias = 0.2; body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0); - body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI)); + body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", Math::deg2rad(8.0)); body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/2d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h index 41578778f6..8e21003a5f 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/body_3d_sw.h @@ -426,7 +426,7 @@ public: ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3()); return body->contacts[p_contact_idx].local_normal; } - virtual float get_contact_impulse(int p_contact_idx) const override { + virtual real_t get_contact_impulse(int p_contact_idx) const override { return 0.0f; // Only implemented for bullet } virtual int get_contact_local_shape(int p_contact_idx) const override { diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp index b06ade5ed3..293a7e6606 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/collision_object_3d_sw.cpp @@ -43,7 +43,7 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_trans p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); @@ -56,7 +56,7 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) { p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); @@ -68,7 +68,7 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_tr shapes.write[p_index].xform = p_transform; shapes.write[p_index].xform_inv = p_transform.affine_inverse(); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); @@ -77,7 +77,7 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_tr void CollisionObject3DSW::set_shape_as_disabled(int p_idx, bool p_enable) { shapes.write[p_idx].disabled = p_enable; if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } } @@ -106,7 +106,7 @@ void CollisionObject3DSW::remove_shape(int p_index) { shapes.remove(p_index); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index b8e056f1f4..f507cacdc3 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -31,7 +31,38 @@ #include "collision_solver_3d_sat.h" #include "core/math/geometry_3d.h" -#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02 +#include "gjk_epa.h" + +#define fallback_collision_solver gjk_epa_calculate_penetration + +// Cylinder SAT analytic methods and face-circle contact points for cylinder-trimesh and cylinder-box collision are based on ODE colliders. + +/* + * Cylinder-trimesh and Cylinder-box colliders by Alen Ladavac + * Ported to ODE by Nguyen Binh + */ + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ struct _CollectorCallback { CollisionSolver3DSW::CallbackResult callback; @@ -82,6 +113,17 @@ static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point p_callback->call(*p_points_A, closest_B); } +static void _generate_contacts_point_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A != 1); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + Vector3 closest_B = Plane(p_points_B[0], p_points_B[1], p_points_B[2]).project(*p_points_A); + + p_callback->call(*p_points_A, closest_B); +} + static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 2); @@ -128,6 +170,104 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_ p_callback->call(closest_A, closest_B); } +static void _generate_contacts_edge_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A != 2); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + const Vector3 &circle_B_pos = p_points_B[0]; + Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos; + Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos; + + real_t circle_B_radius = circle_B_line_1.length(); + Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized(); + + Plane circle_plane(circle_B_pos, circle_B_normal); + + static const int max_clip = 2; + Vector3 contact_points[max_clip]; + int num_points = 0; + + // Project edge point in circle plane. + const Vector3 &edge_A_1 = p_points_A[0]; + Vector3 proj_point_1 = circle_plane.project(edge_A_1); + + Vector3 dist_vec = proj_point_1 - circle_B_pos; + real_t dist_sq = dist_vec.length_squared(); + + // Point 1 is inside disk, add as contact point. + if (dist_sq <= circle_B_radius * circle_B_radius) { + contact_points[num_points] = edge_A_1; + ++num_points; + } + + const Vector3 &edge_A_2 = p_points_A[1]; + Vector3 proj_point_2 = circle_plane.project(edge_A_2); + + Vector3 dist_vec_2 = proj_point_2 - circle_B_pos; + real_t dist_sq_2 = dist_vec_2.length_squared(); + + // Point 2 is inside disk, add as contact point. + if (dist_sq_2 <= circle_B_radius * circle_B_radius) { + contact_points[num_points] = edge_A_2; + ++num_points; + } + + if (num_points < 2) { + Vector3 line_vec = proj_point_2 - proj_point_1; + real_t line_length_sq = line_vec.length_squared(); + + // Create a quadratic formula of the form ax^2 + bx + c = 0 + real_t a, b, c; + + a = line_length_sq; + b = 2.0 * dist_vec.dot(line_vec); + c = dist_sq - circle_B_radius * circle_B_radius; + + // Solve for t. + real_t sqrtterm = b * b - 4.0 * a * c; + + // If the term we intend to square root is less than 0 then the answer won't be real, + // so the line doesn't intersect. + if (sqrtterm >= 0) { + sqrtterm = Math::sqrt(sqrtterm); + + Vector3 edge_dir = edge_A_2 - edge_A_1; + + real_t fraction_1 = (-b - sqrtterm) / (2.0 * a); + if ((fraction_1 > 0.0) && (fraction_1 < 1.0)) { + Vector3 face_point_1 = edge_A_1 + fraction_1 * edge_dir; + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = face_point_1; + ++num_points; + } + + real_t fraction_2 = (-b + sqrtterm) / (2.0 * a); + if ((fraction_2 > 0.0) && (fraction_2 < 1.0) && !Math::is_equal_approx(fraction_1, fraction_2)) { + Vector3 face_point_2 = edge_A_1 + fraction_2 * edge_dir; + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = face_point_2; + ++num_points; + } + } + } + + // Generate contact points. + for (int i = 0; i < num_points; i++) { + const Vector3 &contact_point_A = contact_points[i]; + + real_t d = circle_plane.distance_to(contact_point_A); + Vector3 closest_B = contact_point_A - circle_plane.normal * d; + + if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) { + continue; + } + + p_callback->call(contact_point_A, closest_B); + } +} + static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 2); @@ -217,36 +357,229 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ } } -static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +static void _generate_contacts_face_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A < 3); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + const Vector3 &circle_B_pos = p_points_B[0]; + Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos; + Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos; + + // Clip face with circle segments. + static const int circle_segments = 8; + Vector3 circle_points[circle_segments]; + + real_t angle_delta = 2.0 * Math_PI / circle_segments; + + for (int i = 0; i < circle_segments; ++i) { + Vector3 point_pos = circle_B_pos; + point_pos += circle_B_line_1 * Math::cos(i * angle_delta); + point_pos += circle_B_line_2 * Math::sin(i * angle_delta); + circle_points[i] = point_pos; + } + + _generate_contacts_face_face(p_points_A, p_point_count_A, circle_points, circle_segments, p_callback); + + // Clip face with circle plane. + Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized(); + + Plane circle_plane(circle_B_pos, circle_B_normal); + + static const int max_clip = 32; + Vector3 contact_points[max_clip]; + int num_points = 0; + + for (int i = 0; i < p_point_count_A; i++) { + int i_n = (i + 1) % p_point_count_A; + + const Vector3 &edge0_A = p_points_A[i]; + const Vector3 &edge1_A = p_points_A[i_n]; + + real_t dist0 = circle_plane.distance_to(edge0_A); + real_t dist1 = circle_plane.distance_to(edge1_A); + + // First point in front of plane, generate contact point. + if (dist0 * circle_plane.d >= 0) { + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = edge0_A; + ++num_points; + } + + // Points on different sides, generate contact point. + if (dist0 * dist1 < 0) { + // calculate intersection + Vector3 rel = edge1_A - edge0_A; + real_t den = circle_plane.normal.dot(rel); + real_t dist = -(circle_plane.normal.dot(edge0_A) - circle_plane.d) / den; + Vector3 inters = edge0_A + rel * dist; + + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = inters; + ++num_points; + } + } + + // Generate contact points. + for (int i = 0; i < num_points; i++) { + const Vector3 &contact_point_A = contact_points[i]; + + real_t d = circle_plane.distance_to(contact_point_A); + Vector3 closest_B = contact_point_A - circle_plane.normal * d; + + if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) { + continue; + } + + p_callback->call(contact_point_A, closest_B); + } +} + +static void _generate_contacts_circle_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A != 3); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + const Vector3 &circle_A_pos = p_points_A[0]; + Vector3 circle_A_line_1 = p_points_A[1] - circle_A_pos; + Vector3 circle_A_line_2 = p_points_A[2] - circle_A_pos; + + real_t circle_A_radius = circle_A_line_1.length(); + Vector3 circle_A_normal = circle_A_line_1.cross(circle_A_line_2).normalized(); + + const Vector3 &circle_B_pos = p_points_B[0]; + Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos; + Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos; + + real_t circle_B_radius = circle_B_line_1.length(); + Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized(); + + static const int max_clip = 4; + Vector3 contact_points[max_clip]; + int num_points = 0; + + Vector3 centers_diff = circle_B_pos - circle_A_pos; + Vector3 norm_proj = circle_A_normal.dot(centers_diff) * circle_A_normal; + Vector3 comp_proj = centers_diff - norm_proj; + real_t proj_dist = comp_proj.length(); + if (!Math::is_zero_approx(proj_dist)) { + comp_proj /= proj_dist; + if ((proj_dist > circle_A_radius - circle_B_radius) && (proj_dist > circle_B_radius - circle_A_radius)) { + // Circles are overlapping, use the 2 points of intersection as contacts. + real_t radius_a_sqr = circle_A_radius * circle_A_radius; + real_t radius_b_sqr = circle_B_radius * circle_B_radius; + real_t d_sqr = proj_dist * proj_dist; + real_t s = (1.0 + (radius_a_sqr - radius_b_sqr) / d_sqr) * 0.5; + real_t h = Math::sqrt(MAX(radius_a_sqr - d_sqr * s * s, 0.0)); + Vector3 midpoint = circle_A_pos + s * comp_proj * proj_dist; + Vector3 h_vec = h * circle_A_normal.cross(comp_proj); + + Vector3 point_A = midpoint + h_vec; + contact_points[num_points] = point_A; + ++num_points; + + point_A = midpoint - h_vec; + contact_points[num_points] = point_A; + ++num_points; + + // Add 2 points from circle A and B along the line between the centers. + point_A = circle_A_pos + comp_proj * circle_A_radius; + contact_points[num_points] = point_A; + ++num_points; + + point_A = circle_B_pos - comp_proj * circle_B_radius - norm_proj; + contact_points[num_points] = point_A; + ++num_points; + } // Otherwise one circle is inside the other one, use 3 arbitrary equidistant points. + } // Otherwise circles are concentric, use 3 arbitrary equidistant points. + + if (num_points == 0) { + // Generate equidistant points. + if (circle_A_radius < circle_B_radius) { + // Circle A inside circle B. + for (int i = 0; i < 3; ++i) { + Vector3 circle_A_point = circle_A_pos; + circle_A_point += circle_A_line_1 * Math::cos(2.0 * Math_PI * i / 3.0); + circle_A_point += circle_A_line_2 * Math::sin(2.0 * Math_PI * i / 3.0); + + contact_points[num_points] = circle_A_point; + ++num_points; + } + } else { + // Circle B inside circle A. + for (int i = 0; i < 3; ++i) { + Vector3 circle_B_point = circle_B_pos; + circle_B_point += circle_B_line_1 * Math::cos(2.0 * Math_PI * i / 3.0); + circle_B_point += circle_B_line_2 * Math::sin(2.0 * Math_PI * i / 3.0); + + Vector3 circle_A_point = circle_B_point - norm_proj; + + contact_points[num_points] = circle_A_point; + ++num_points; + } + } + } + + Plane circle_B_plane(circle_B_pos, circle_B_normal); + + // Generate contact points. + for (int i = 0; i < num_points; i++) { + const Vector3 &contact_point_A = contact_points[i]; + + real_t d = circle_B_plane.distance_to(contact_point_A); + Vector3 closest_B = contact_point_A - circle_B_plane.normal * d; + + if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) { + continue; + } + + p_callback->call(contact_point_A, closest_B); + } +} + +static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, Shape3DSW::FeatureType p_feature_type_A, const Vector3 *p_points_B, int p_point_count_B, Shape3DSW::FeatureType p_feature_type_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 1); ERR_FAIL_COND(p_point_count_B < 1); #endif - static const GenerateContactsFunc generate_contacts_func_table[3][3] = { + static const GenerateContactsFunc generate_contacts_func_table[4][4] = { { _generate_contacts_point_point, _generate_contacts_point_edge, _generate_contacts_point_face, + _generate_contacts_point_circle, }, { nullptr, _generate_contacts_edge_edge, _generate_contacts_face_face, + _generate_contacts_edge_circle, }, { nullptr, nullptr, _generate_contacts_face_face, - } + _generate_contacts_face_circle, + }, + { + nullptr, + nullptr, + nullptr, + _generate_contacts_circle_circle, + }, }; int pointcount_B; int pointcount_A; const Vector3 *points_A; const Vector3 *points_B; + int version_A; + int version_B; - if (p_point_count_A > p_point_count_B) { + if (p_feature_type_A > p_feature_type_B) { //swap p_callback->swap = !p_callback->swap; p_callback->normal = -p_callback->normal; @@ -255,16 +588,17 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po pointcount_A = p_point_count_B; points_A = p_points_B; points_B = p_points_A; + version_A = p_feature_type_B; + version_B = p_feature_type_A; } else { pointcount_B = p_point_count_B; pointcount_A = p_point_count_A; points_A = p_points_A; points_B = p_points_B; + version_A = p_feature_type_A; + version_B = p_feature_type_B; } - int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1; - int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1; - GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B]; ERR_FAIL_COND(!contacts_func); contacts_func(points_A, pointcount_A, points_B, pointcount_B, p_callback); @@ -346,6 +680,17 @@ public: return true; } + static _FORCE_INLINE_ void test_contact_points(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { + SeparatorAxisTest<ShapeA, ShapeB, withMargin> *separator = (SeparatorAxisTest<ShapeA, ShapeB, withMargin> *)p_userdata; + Vector3 axis = (p_point_B - p_point_A); + real_t depth = axis.length(); + + // Filter out bogus directions with a treshold and re-testing axis. + if (separator->best_depth - depth > 0.001) { + separator->test_axis(axis / depth); + } + } + _FORCE_INLINE_ void generate_contacts() { // nothing to do, don't generate if (best_axis == Vector3(0.0, 0.0, 0.0)) { @@ -365,7 +710,8 @@ public: Vector3 supports_A[max_supports]; int support_count_A; - shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A); + Shape3DSW::FeatureType support_type_A; + shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A, support_type_A); for (int i = 0; i < support_count_A; i++) { supports_A[i] = transform_A->xform(supports_A[i]); } @@ -378,7 +724,8 @@ public: Vector3 supports_B[max_supports]; int support_count_B; - shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B); + Shape3DSW::FeatureType support_type_B; + shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B, support_type_B); for (int i = 0; i < support_count_B; i++) { supports_B[i] = transform_B->xform(supports_B[i]); } @@ -393,7 +740,7 @@ public: if (callback->prev_axis) { *callback->prev_axis = best_axis; } - _generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback); + _generate_contacts_from_supports(supports_A, support_count_A, support_type_A, supports_B, support_count_B, support_type_B, callback); callback->collided = true; } @@ -529,6 +876,61 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t template <bool withMargin> static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<SphereShape3DSW, CylinderShape3DSW, withMargin> separator(sphere_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + if (!separator.test_previous_axis()) { + return; + } + + // Cylinder B end caps. + Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1).normalized(); + if (!separator.test_axis(cylinder_B_axis)) { + return; + } + + Vector3 cylinder_diff = p_transform_b.origin - p_transform_a.origin; + + // Cylinder B lateral surface. + if (!separator.test_axis(cylinder_B_axis.cross(cylinder_diff).cross(cylinder_B_axis).normalized())) { + return; + } + + // Closest point to cylinder caps. + const Vector3 &sphere_center = p_transform_a.origin; + Vector3 cyl_axis = p_transform_b.basis.get_axis(1); + Vector3 cap_axis = p_transform_b.basis.get_axis(0); + real_t height_scale = cyl_axis.length(); + real_t cap_dist = cylinder_B->get_height() * 0.5 * height_scale; + cyl_axis /= height_scale; + real_t radius_scale = cap_axis.length(); + real_t cap_radius = cylinder_B->get_radius() * radius_scale; + + for (int i = 0; i < 2; i++) { + Vector3 cap_dir = ((i == 0) ? cyl_axis : -cyl_axis); + Vector3 cap_pos = p_transform_b.origin + cap_dir * cap_dist; + + Vector3 closest_point; + + Vector3 diff = sphere_center - cap_pos; + Vector3 proj = diff - cap_dir.dot(diff) * cap_dir; + + real_t proj_len = proj.length(); + if (Math::is_zero_approx(proj_len)) { + // Point is equidistant to all circle points. + continue; + } + + closest_point = cap_pos + (cap_radius / proj_len) * proj; + + if (!separator.test_axis((closest_point - sphere_center).normalized())) { + return; + } + } + + separator.generate_contacts(); } template <bool withMargin> @@ -739,7 +1141,7 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran // faces of A for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_a.basis.get_axis(i); + Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); if (!separator.test_axis(axis)) { return; @@ -826,6 +1228,115 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran template <bool withMargin> static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<BoxShape3DSW, CylinderShape3DSW, withMargin> separator(box_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + if (!separator.test_previous_axis()) { + return; + } + + // Faces of A. + for (int i = 0; i < 3; i++) { + Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); + + if (!separator.test_axis(axis)) { + return; + } + } + + Vector3 cyl_axis = p_transform_b.basis.get_axis(1).normalized(); + + // Cylinder end caps. + { + if (!separator.test_axis(cyl_axis)) { + return; + } + } + + // Edges of A, cylinder lateral surface. + for (int i = 0; i < 3; i++) { + Vector3 box_axis = p_transform_a.basis.get_axis(i); + Vector3 axis = box_axis.cross(cyl_axis); + if (Math::is_zero_approx(axis.length_squared())) { + continue; + } + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + + // Gather points of A. + Vector3 vertices_A[8]; + Vector3 box_extent = box_A->get_half_extents(); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 2; k++) { + Vector3 extent = box_extent; + extent.x *= (i * 2 - 1); + extent.y *= (j * 2 - 1); + extent.z *= (k * 2 - 1); + Vector3 &point = vertices_A[i * 2 * 2 + j * 2 + k]; + point = p_transform_a.origin; + for (int l = 0; l < 3; l++) { + point += p_transform_a.basis.get_axis(l) * extent[l]; + } + } + } + } + + // Points of A, cylinder lateral surface. + for (int i = 0; i < 8; i++) { + const Vector3 &point = vertices_A[i]; + Vector3 axis = Plane(cyl_axis, 0).project(point).normalized(); + + if (!separator.test_axis(axis)) { + return; + } + } + + // Edges of A, cylinder end caps rim. + int edges_start_A[12] = { 0, 2, 4, 6, 0, 1, 4, 5, 0, 1, 2, 3 }; + int edges_end_A[12] = { 1, 3, 5, 7, 2, 3, 6, 7, 4, 5, 6, 7 }; + + Vector3 cap_axis = cyl_axis * (cylinder_B->get_height() * 0.5); + + for (int i = 0; i < 2; i++) { + Vector3 cap_pos = p_transform_b.origin + ((i == 0) ? cap_axis : -cap_axis); + + for (int e = 0; e < 12; e++) { + const Vector3 &edge_start = vertices_A[edges_start_A[e]]; + const Vector3 &edge_end = vertices_A[edges_end_A[e]]; + + Vector3 edge_dir = (edge_end - edge_start); + edge_dir.normalize(); + + real_t edge_dot = edge_dir.dot(cyl_axis); + if (Math::is_zero_approx(edge_dot)) { + // Edge is perpendicular to cylinder axis. + continue; + } + + // Calculate intersection between edge and circle plane. + Vector3 edge_diff = cap_pos - edge_start; + real_t diff_dot = edge_diff.dot(cyl_axis); + Vector3 intersection = edge_start + edge_dir * diff_dot / edge_dot; + + // Calculate tangent that touches intersection. + Vector3 tangent = (cap_pos - intersection).cross(cyl_axis); + + // Axis is orthogonal both to tangent and edge direction. + Vector3 axis = tangent.cross(edge_dir); + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + } + + separator.generate_contacts(); } template <bool withMargin> @@ -1111,6 +1622,19 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_ template <bool withMargin> static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin> separator(capsule_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; + + // Fallback to generic algorithm to find the best separating axis. + if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) { + return; + } + + separator.generate_contacts(); } template <bool withMargin> @@ -1236,14 +1760,165 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra template <bool withMargin> static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin> separator(cylinder_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + Vector3 cylinder_A_axis = p_transform_a.basis.get_axis(1); + Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1); + + if (!separator.test_previous_axis()) { + return; + } + + // Cylinder A end caps. + if (!separator.test_axis(cylinder_A_axis.normalized())) { + return; + } + + // Cylinder B end caps. + if (!separator.test_axis(cylinder_A_axis.normalized())) { + return; + } + + Vector3 cylinder_diff = p_transform_b.origin - p_transform_a.origin; + + // Cylinder A lateral surface. + if (!separator.test_axis(cylinder_A_axis.cross(cylinder_diff).cross(cylinder_A_axis).normalized())) { + return; + } + + // Cylinder B lateral surface. + if (!separator.test_axis(cylinder_B_axis.cross(cylinder_diff).cross(cylinder_B_axis).normalized())) { + return; + } + + real_t proj = cylinder_A_axis.cross(cylinder_B_axis).cross(cylinder_B_axis).dot(cylinder_A_axis); + if (Math::is_zero_approx(proj)) { + // Parallel cylinders, handle with specific axes only. + // Note: GJKEPA with no margin can lead to degenerate cases in this situation. + separator.generate_contacts(); + return; + } + + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; + + // Fallback to generic algorithm to find the best separating axis. + if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) { + return; + } + + separator.generate_contacts(); } template <bool withMargin> static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); + const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); + + SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(cylinder_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin>::test_contact_points; + + // Fallback to generic algorithm to find the best separating axis. + if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) { + return; + } + + separator.generate_contacts(); } template <bool withMargin> static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); + const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); + + SeparatorAxisTest<CylinderShape3DSW, FaceShape3DSW, withMargin> separator(cylinder_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + if (!separator.test_previous_axis()) { + return; + } + + Vector3 vertex[3] = { + p_transform_b.xform(face_B->vertex[0]), + p_transform_b.xform(face_B->vertex[1]), + p_transform_b.xform(face_B->vertex[2]), + }; + + // Face B normal. + if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) { + return; + } + + Vector3 cyl_axis = p_transform_a.basis.get_axis(1).normalized(); + + // Cylinder end caps. + { + if (!separator.test_axis(cyl_axis)) { + return; + } + } + + // Edges of B, cylinder lateral surface. + for (int i = 0; i < 3; i++) { + Vector3 edge_axis = vertex[i] - vertex[(i + 1) % 3]; + Vector3 axis = edge_axis.cross(cyl_axis); + if (Math::is_zero_approx(axis.length_squared())) { + continue; + } + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + + // Points of B, cylinder lateral surface. + for (int i = 0; i < 3; i++) { + const Vector3 &point = vertex[i]; + Vector3 axis = Plane(cyl_axis, 0).project(point).normalized(); + + if (!separator.test_axis(axis)) { + return; + } + } + + // Edges of B, cylinder end caps rim. + Vector3 cap_axis = cyl_axis * (cylinder_A->get_height() * 0.5); + + for (int i = 0; i < 2; i++) { + Vector3 cap_pos = p_transform_a.origin + ((i == 0) ? cap_axis : -cap_axis); + + for (int j = 0; j < 3; j++) { + const Vector3 &edge_start = vertex[j]; + const Vector3 &edge_end = vertex[(j + 1) % 3]; + Vector3 edge_dir = edge_end - edge_start; + edge_dir.normalize(); + + real_t edge_dot = edge_dir.dot(cyl_axis); + if (Math::is_zero_approx(edge_dot)) { + // Edge is perpendicular to cylinder axis. + continue; + } + + // Calculate intersection between edge and circle plane. + Vector3 edge_diff = cap_pos - edge_start; + real_t diff_dot = edge_diff.dot(cyl_axis); + Vector3 intersection = edge_start + edge_dir * diff_dot / edge_dot; + + // Calculate tangent that touches intersection. + Vector3 tangent = (cap_pos - intersection).cross(cyl_axis); + + // Axis is orthogonal both to tangent and edge direction. + Vector3 axis = tangent.cross(edge_dir); + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + } + + separator.generate_contacts(); } template <bool withMargin> diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp index 1150696b84..fd9ea00d92 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/collision_solver_3d_sw.cpp @@ -46,8 +46,24 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T static const int max_supports = 16; Vector3 supports[max_supports]; int support_count; - - p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count); + Shape3DSW::FeatureType support_type; + p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type); + + if (support_type == Shape3DSW::FEATURE_CIRCLE) { + ERR_FAIL_COND_V(support_count != 3, false); + + Vector3 circle_pos = supports[0]; + Vector3 circle_axis_1 = supports[1] - circle_pos; + Vector3 circle_axis_2 = supports[2] - circle_pos; + + // Use 3 equidistant points on the circle. + for (int i = 0; i < 3; ++i) { + Vector3 vertex_pos = circle_pos; + vertex_pos += circle_axis_1 * Math::cos(2.0 * Math_PI * i / 3.0); + vertex_pos += circle_axis_2 * Math::sin(2.0 * Math_PI * i / 3.0); + supports[i] = vertex_pos; + } + } bool found = false; @@ -265,8 +281,25 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const static const int max_supports = 16; Vector3 supports[max_supports]; int support_count; + Shape3DSW::FeatureType support_type; + + p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type); - p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count); + if (support_type == Shape3DSW::FEATURE_CIRCLE) { + ERR_FAIL_COND_V(support_count != 3, false); + + Vector3 circle_pos = supports[0]; + Vector3 circle_axis_1 = supports[1] - circle_pos; + Vector3 circle_axis_2 = supports[2] - circle_pos; + + // Use 3 equidistant points on the circle. + for (int i = 0; i < 3; ++i) { + Vector3 vertex_pos = circle_pos; + vertex_pos += circle_axis_1 * Math::cos(2.0 * Math_PI * i / 3.0); + vertex_pos += circle_axis_2 * Math::sin(2.0 * Math_PI * i / 3.0); + supports[i] = vertex_pos; + } + } bool collided = false; Vector3 closest; diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index dafd2feb8b..aa7c11eec5 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -64,7 +64,7 @@ GJK-EPA collision solver by Nathanael Presson, 2008 /* GJK */ #define GJK_MAX_ITERATIONS 128 -#define GJK_ACCURARY ((real_t)0.0001) +#define GJK_ACCURACY ((real_t)0.0001) #define GJK_MIN_DISTANCE ((real_t)0.0001) #define GJK_DUPLICATED_EPS ((real_t)0.0001) #define GJK_SIMPLEX2_EPS ((real_t)0.0) @@ -72,10 +72,13 @@ GJK-EPA collision solver by Nathanael Presson, 2008 #define GJK_SIMPLEX4_EPS ((real_t)0.0) /* EPA */ -#define EPA_MAX_VERTICES 64 +#define EPA_MAX_VERTICES 128 #define EPA_MAX_FACES (EPA_MAX_VERTICES*2) #define EPA_MAX_ITERATIONS 255 -#define EPA_ACCURACY ((real_t)0.0001) +// -- GODOT start -- +//#define EPA_ACCURACY ((real_t)0.0001) +#define EPA_ACCURACY ((real_t)0.00001) +// -- GODOT end -- #define EPA_FALLBACK (10*EPA_ACCURACY) #define EPA_PLANE_EPS ((real_t)0.00001) #define EPA_INSIDE_EPS ((real_t)0.01) @@ -237,7 +240,7 @@ struct GJK /* Check for termination */ const real_t omega=vec3_dot(m_ray,w)/rl; alpha=MAX(omega,alpha); - if(((rl-alpha)-(GJK_ACCURARY*rl))<=0) + if(((rl-alpha)-(GJK_ACCURACY*rl))<=0) {/* Return old simplex */ removevertice(m_simplices[m_current]); break; @@ -466,7 +469,7 @@ struct GJK if(ng&&(Math::abs(vl)>GJK_SIMPLEX4_EPS)) { real_t mindist=-1; - real_t subw[3]; + real_t subw[3] = {0.f, 0.f, 0.f}; U subm=0; for(U i=0;i<3;++i) { @@ -512,7 +515,6 @@ struct GJK { Vector3 n; real_t d; - real_t p; sSV* c[3]; sFace* f[3]; sFace* l[2]; @@ -661,8 +663,7 @@ struct GJK remove(m_hull,best); append(m_stock,best); best=findbest(); - if(best->p>=outer.p) { outer=*best; -} + outer=*best; } else { m_status=eStatus::InvalidHull;break; } } else { m_status=eStatus::AccuraryReached;break; } } else { m_status=eStatus::OutOfVertices;break; } @@ -688,24 +689,54 @@ struct GJK } } /* Fallback */ - m_status = eStatus::FallBack; - m_normal = -guess; - const real_t nl=m_normal.length(); - if(nl>0) { - m_normal = m_normal/nl; + m_status = eStatus::FallBack; + m_normal = -guess; + const real_t nl = m_normal.length(); + if (nl > 0) { + m_normal = m_normal/nl; } else { - m_normal = Vector3(1,0,0); -} + m_normal = Vector3(1,0,0); + } m_depth = 0; m_result.rank=1; m_result.c[0]=simplex.c[0]; m_result.p[0]=1; return(m_status); } + + bool getedgedist(sFace* face, sSV* a, sSV* b, real_t& dist) + { + const Vector3 ba = b->w - a->w; + const Vector3 n_ab = vec3_cross(ba, face->n); // Outward facing edge normal direction, on triangle plane + const real_t a_dot_nab = vec3_dot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required + + if (a_dot_nab < 0) { + // Outside of edge a->b + const real_t ba_l2 = ba.length_squared(); + const real_t a_dot_ba = vec3_dot(a->w, ba); + const real_t b_dot_ba = vec3_dot(b->w, ba); + + if (a_dot_ba > 0) { + // Pick distance vertex a + dist = a->w.length(); + } else if (b_dot_ba < 0) { + // Pick distance vertex b + dist = b->w.length(); + } else { + // Pick distance to edge a->b + const real_t a_dot_b = vec3_dot(a->w, b->w); + dist = Math::sqrt(MAX((a->w.length_squared() * b->w.length_squared() - a_dot_b * a_dot_b) / ba_l2, 0.0)); + } + + return true; + } + + return false; + } + sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) { - if(m_stock.root) - { + if (m_stock.root) { sFace* face=m_stock.root; remove(m_stock,face); append(m_hull,face); @@ -716,23 +747,23 @@ struct GJK face->n = vec3_cross(b->w-a->w,c->w-a->w); const real_t l=face->n.length(); const bool v=l>EPA_ACCURACY; - face->p = MIN(MIN( - vec3_dot(a->w,vec3_cross(face->n,a->w-b->w)), - vec3_dot(b->w,vec3_cross(face->n,b->w-c->w))), - vec3_dot(c->w,vec3_cross(face->n,c->w-a->w))) / - (v?l:1); - face->p = face->p>=-EPA_INSIDE_EPS?0:face->p; - if(v) - { - face->d = vec3_dot(a->w,face->n)/l; + if (v) { + if (!(getedgedist(face, a, b, face->d) || + getedgedist(face, b, c, face->d) || + getedgedist(face, c, a, face->d))) { + // Origin projects to the interior of the triangle + // Use distance to triangle plane + face->d = vec3_dot(a->w, face->n) / l; + } face->n /= l; - if(forced||(face->d>=-EPA_PLANE_EPS)) - { + if (forced||(face->d>=-EPA_PLANE_EPS)) { return(face); - } else { m_status=eStatus::NonConvex; -} - } else { m_status=eStatus::Degenerated; -} + } else { + m_status=eStatus::NonConvex; + } + } else { + m_status=eStatus::Degenerated; + } remove(m_hull,face); append(m_stock,face); return(nullptr); @@ -747,15 +778,13 @@ struct GJK { sFace* minf=m_hull.root; real_t mind=minf->d*minf->d; - real_t maxp=minf->p; for(sFace* f=minf->l[1];f;f=f->l[1]) { const real_t sqd=f->d*f->d; - if((f->p>=maxp)&&(sqd<mind)) + if(sqd<mind) { minf=f; mind=sqd; - maxp=f->p; } } return(minf); diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp index 7b10257157..9c4493f4a2 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp @@ -92,9 +92,9 @@ ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Trans m_rbAFrame = rbAFrame; m_rbBFrame = rbBFrame; - m_swingSpan1 = Math_PI / 4.0; - m_swingSpan2 = Math_PI / 4.0; - m_twistSpan = Math_PI * 2; + m_swingSpan1 = Math_TAU / 8.0; + m_swingSpan2 = Math_TAU / 8.0; + m_twistSpan = Math_TAU; m_biasFactor = 0.3f; m_relaxationFactor = 1.0f; diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h index c38edc5737..4e4d4e7f0c 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h @@ -102,7 +102,7 @@ public: bool m_solveSwingLimit; public: - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_CONE_TWIST; } virtual bool setup(real_t p_timestep); virtual void solve(real_t p_timestep); diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp index 7eb49e657b..13b389251f 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp @@ -132,7 +132,7 @@ real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits( real_t oldaccumImpulse = m_accumulatedImpulse; real_t sum = oldaccumImpulse + clippedMotorImpulse; - m_accumulatedImpulse = sum > hi ? real_t(0.) : sum < lo ? real_t(0.) : sum; + m_accumulatedImpulse = sum > hi ? real_t(0.) : (sum < lo ? real_t(0.) : sum); clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse; @@ -201,7 +201,7 @@ real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis( real_t oldNormalImpulse = m_accumulatedImpulse[limit_index]; real_t sum = oldNormalImpulse + normalImpulse; - m_accumulatedImpulse[limit_index] = sum > hi ? real_t(0.) : sum < lo ? real_t(0.) : sum; + m_accumulatedImpulse[limit_index] = sum > hi ? real_t(0.) : (sum < lo ? real_t(0.) : sum); normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; Vector3 impulse_vector = axis_normal_on_a * normalImpulse; diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h index 2ae6fe85fa..d61a033231 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -234,7 +234,7 @@ protected: public: Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_6DOF; } virtual bool setup(real_t p_timestep); virtual void solve(real_t p_timestep); diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h index 028a8b8c72..b6117aa0bc 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.h +++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h @@ -96,7 +96,7 @@ class HingeJoint3DSW : public Joint3DSW { real_t m_appliedImpulse; public: - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_HINGE; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/pin_joint_3d_sw.h index e28fbec6cd..1875983527 100644 --- a/servers/physics_3d/joints/pin_joint_3d_sw.h +++ b/servers/physics_3d/joints/pin_joint_3d_sw.h @@ -74,7 +74,7 @@ class PinJoint3DSW : public Joint3DSW { Vector3 m_pivotInB; public: - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_PIN; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_PIN; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h index 196e60d19d..f52f6ace27 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.h +++ b/servers/physics_3d/joints/slider_joint_3d_sw.h @@ -243,7 +243,7 @@ public: bool setup(real_t p_step); void solve(real_t p_step); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_SLIDER; } }; #endif // SLIDER_JOINT_SW_H diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/joints_3d_sw.h index cad05b6702..225a71aca9 100644 --- a/servers/physics_3d/joints_3d_sw.h +++ b/servers/physics_3d/joints_3d_sw.h @@ -36,10 +36,28 @@ class Joint3DSW : public Constraint3DSW { public: - virtual PhysicsServer3D::JointType get_type() const = 0; + virtual bool setup(real_t p_step) { return false; } + virtual void solve(real_t p_step) {} + + void copy_settings_from(Joint3DSW *p_joint) { + set_self(p_joint->get_self()); + set_priority(p_joint->get_priority()); + disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies()); + } + + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_MAX; } _FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) : Constraint3DSW(p_body_ptr, p_body_count) { } + + virtual ~Joint3DSW() { + for (int i = 0; i < get_body_count(); i++) { + Body3DSW *body = get_body_ptr()[i]; + if (body) { + body->remove_constraint(this); + } + } + } }; #endif // JOINTS_SW_H diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index 274de8411c..6bbef09907 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -43,47 +43,63 @@ #define FLUSH_QUERY_CHECK(m_object) \ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); -RID PhysicsServer3DSW::shape_create(ShapeType p_shape) { - Shape3DSW *shape = nullptr; - switch (p_shape) { - case SHAPE_PLANE: { - shape = memnew(PlaneShape3DSW); - } break; - case SHAPE_RAY: { - shape = memnew(RayShape3DSW); - } break; - case SHAPE_SPHERE: { - shape = memnew(SphereShape3DSW); - } break; - case SHAPE_BOX: { - shape = memnew(BoxShape3DSW); - } break; - case SHAPE_CAPSULE: { - shape = memnew(CapsuleShape3DSW); - } break; - case SHAPE_CYLINDER: { - ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings."); - } break; - case SHAPE_CONVEX_POLYGON: { - shape = memnew(ConvexPolygonShape3DSW); - } break; - case SHAPE_CONCAVE_POLYGON: { - shape = memnew(ConcavePolygonShape3DSW); - } break; - case SHAPE_HEIGHTMAP: { - shape = memnew(HeightMapShape3DSW); - } break; - case SHAPE_CUSTOM: { - ERR_FAIL_V(RID()); - - } break; - } - - RID id = shape_owner.make_rid(shape); - shape->set_self(id); - - return id; -}; +RID PhysicsServer3DSW::plane_shape_create() { + Shape3DSW *shape = memnew(PlaneShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::ray_shape_create() { + Shape3DSW *shape = memnew(RayShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::sphere_shape_create() { + Shape3DSW *shape = memnew(SphereShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::box_shape_create() { + Shape3DSW *shape = memnew(BoxShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::capsule_shape_create() { + Shape3DSW *shape = memnew(CapsuleShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::cylinder_shape_create() { + Shape3DSW *shape = memnew(CylinderShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::convex_polygon_shape_create() { + Shape3DSW *shape = memnew(ConvexPolygonShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::concave_polygon_shape_create() { + Shape3DSW *shape = memnew(ConcavePolygonShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::heightmap_shape_create() { + Shape3DSW *shape = memnew(HeightMapShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::custom_shape_create() { + ERR_FAIL_V(RID()); +} void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) { Shape3DSW *shape = shape_owner.getornull(p_shape); @@ -174,7 +190,7 @@ real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) c PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) { Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, nullptr); - ERR_FAIL_COND_V_MSG(space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); return space->get_direct_state(); } @@ -413,13 +429,6 @@ void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) { area->set_ray_pickable(p_enable); } -bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); - ERR_FAIL_COND_V(!area, false); - - return area->is_ray_pickable(); -} - void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -429,14 +438,8 @@ void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec /* BODY API */ -RID PhysicsServer3DSW::body_create(BodyMode p_mode, bool p_init_sleeping) { +RID PhysicsServer3DSW::body_create() { Body3DSW *body = memnew(Body3DSW); - if (p_mode != BODY_MODE_RIGID) { - body->set_mode(p_mode); - } - if (p_init_sleeping) { - body->set_state(BODY_STATE_SLEEPING, p_init_sleeping); - } RID rid = body_owner.make_rid(body); body->set_self(rid); return rid; @@ -857,12 +860,6 @@ void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) { body->set_ray_pickable(p_enable); } -bool PhysicsServer3DSW::body_is_ray_pickable(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, false); - return body->is_ray_pickable(); -} - bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); @@ -874,7 +871,7 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, co return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, body->get_kinematic_margin(), r_result, p_exclude_raycast_shapes); } -int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) { +int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -886,6 +883,8 @@ int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_t } PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, nullptr); ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); @@ -896,30 +895,52 @@ PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { /* JOINT API */ -RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { +RID PhysicsServer3DSW::joint_create() { + Joint3DSW *joint = memnew(Joint3DSW); + RID rid = joint_owner.make_rid(joint); + joint->set_self(rid); + return rid; +} + +void PhysicsServer3DSW::joint_clear(RID p_joint) { + Joint3DSW *joint = joint_owner.getornull(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + Joint3DSW *empty_joint = memnew(Joint3DSW); + empty_joint->copy_settings_from(joint); + + joint_owner.replace(p_joint, empty_joint); + memdelete(joint); + } +} + +void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(PinJoint3DSW(body_A, p_local_A, body_B, p_local_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_param(p_param, p_value); } @@ -927,7 +948,7 @@ void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); return pin_joint->get_param(p_param); } @@ -935,7 +956,7 @@ real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_pos_a(p_A); } @@ -943,7 +964,7 @@ void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); return pin_joint->get_position_a(); } @@ -951,7 +972,7 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_pos_b(p_B); } @@ -959,55 +980,63 @@ void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); return pin_joint->get_position_b(); } -RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) { +void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + ERR_FAIL_COND(body_A == body_B); + + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_frame_A, p_frame_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } -RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { +void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); hinge_joint->set_param(p_param, p_value); } @@ -1015,7 +1044,7 @@ void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_par real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); return hinge_joint->get_param(p_param); } @@ -1023,7 +1052,7 @@ real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_p void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); hinge_joint->set_flag(p_flag, p_value); } @@ -1031,7 +1060,7 @@ void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); return hinge_joint->get_flag(p_flag); } @@ -1077,34 +1106,38 @@ bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_PIN); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); } -RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(SliderJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); slider_joint->set_param(p_param, p_value); } @@ -1112,35 +1145,39 @@ void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_p real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); return slider_joint->get_param(p_param); } -RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(ConeTwistJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); cone_twist_joint->set_param(p_param, p_value); } @@ -1148,43 +1185,47 @@ void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointPa real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); return cone_twist_joint->get_param(p_param); } -RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + ERR_FAIL_COND(body_A == body_B); + + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(Generic6DOFJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B, true)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); generic_6dof_joint->set_param(p_axis, p_param, p_value); } -real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { +real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); return generic_6dof_joint->get_param(p_axis, p_param); } @@ -1192,15 +1233,15 @@ real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axi void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); } -bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { +bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); return generic_6dof_joint->get_flag(p_axis, p_flag); } @@ -1271,9 +1312,6 @@ void PhysicsServer3DSW::free(RID p_rid) { } else if (joint_owner.owns(p_rid)) { Joint3DSW *joint = joint_owner.getornull(p_rid); - for (int i = 0; i < joint->get_body_count(); i++) { - joint->get_body_ptr()[i]->remove_constraint(joint); - } joint_owner.free(p_rid); memdelete(joint); @@ -1317,6 +1355,10 @@ void PhysicsServer3DSW::step(real_t p_step) { #endif } +void PhysicsServer3DSW::sync() { + doing_sync = true; +}; + void PhysicsServer3DSW::flush_queries() { #ifndef _3D_DISABLED @@ -1370,6 +1412,10 @@ void PhysicsServer3DSW::flush_queries() { #endif }; +void PhysicsServer3DSW::end_sync() { + doing_sync = false; +}; + void PhysicsServer3DSW::finish() { memdelete(stepper); memdelete(direct_state); @@ -1431,14 +1477,15 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 & } } -PhysicsServer3DSW *PhysicsServer3DSW::singleton = nullptr; -PhysicsServer3DSW::PhysicsServer3DSW() { - singleton = this; +PhysicsServer3DSW *PhysicsServer3DSW::singletonsw = nullptr; +PhysicsServer3DSW::PhysicsServer3DSW(bool p_using_threads) { + singletonsw = this; BroadPhase3DSW::create_func = BroadPhaseOctree::_create; island_count = 0; active_objects = 0; collision_pairs = 0; - + using_threads = p_using_threads; active = true; flushing_queries = false; + doing_sync = false; }; diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 9b6b113677..afda161fa8 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -50,6 +50,8 @@ class PhysicsServer3DSW : public PhysicsServer3D { int active_objects; int collision_pairs; + bool using_threads; + bool doing_sync; bool flushing_queries; Step3DSW *stepper; @@ -57,20 +59,20 @@ class PhysicsServer3DSW : public PhysicsServer3D { PhysicsDirectBodyState3DSW *direct_state; - mutable RID_PtrOwner<Shape3DSW> shape_owner; - mutable RID_PtrOwner<Space3DSW> space_owner; - mutable RID_PtrOwner<Area3DSW> area_owner; - mutable RID_PtrOwner<Body3DSW> body_owner; - mutable RID_PtrOwner<Joint3DSW> joint_owner; + mutable RID_PtrOwner<Shape3DSW, true> shape_owner; + mutable RID_PtrOwner<Space3DSW, true> space_owner; + mutable RID_PtrOwner<Area3DSW, true> area_owner; + mutable RID_PtrOwner<Body3DSW, true> body_owner; + mutable RID_PtrOwner<Joint3DSW, true> joint_owner; //void _clear_query(QuerySW *p_query); friend class CollisionObject3DSW; SelfList<CollisionObject3DSW>::List pending_shape_update_list; void _update_shapes(); -public: - static PhysicsServer3DSW *singleton; + static PhysicsServer3DSW *singletonsw; +public: struct CollCbkData { int max; int amount; @@ -79,7 +81,17 @@ public: static void _shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata); - virtual RID shape_create(ShapeType p_shape) override; + virtual RID plane_shape_create() override; + virtual RID ray_shape_create() override; + virtual RID sphere_shape_create() override; + virtual RID box_shape_create() override; + virtual RID capsule_shape_create() override; + virtual RID cylinder_shape_create() override; + virtual RID convex_polygon_shape_create() override; + virtual RID concave_polygon_shape_create() override; + virtual RID heightmap_shape_create() override; + virtual RID custom_shape_create() override; + virtual void shape_set_data(RID p_shape, const Variant &p_data) override; virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) override; @@ -140,7 +152,6 @@ public: virtual Transform area_get_transform(RID p_area) const override; virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; - virtual bool area_is_ray_pickable(RID p_area) const override; virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; @@ -153,7 +164,7 @@ public: /* BODY API */ // create a body of a given type - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) override; + virtual RID body_create() override; virtual void body_set_space(RID p_body, RID p_space) override; virtual RID body_get_space(RID p_body) const override; @@ -232,17 +243,16 @@ public: virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant()) override; virtual void body_set_ray_pickable(RID p_body, bool p_enable) override; - virtual bool body_is_ray_pickable(RID p_body) const override; virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; - virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) override; + virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override; /* SOFT BODY */ - virtual RID soft_body_create(bool p_init_sleeping = false) override { return RID(); } + virtual RID soft_body_create() override { return RID(); } virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) override {} @@ -266,49 +276,52 @@ public: virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const override { return Vector3(); } virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override {} - virtual bool soft_body_is_ray_pickable(RID p_body) const override { return false; } virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) override {} - virtual int soft_body_get_simulation_precision(RID p_body) override { return 0; } + virtual int soft_body_get_simulation_precision(RID p_body) const override { return 0; } virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) override {} - virtual real_t soft_body_get_total_mass(RID p_body) override { return 0.; } + virtual real_t soft_body_get_total_mass(RID p_body) const override { return 0.; } virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override {} - virtual real_t soft_body_get_linear_stiffness(RID p_body) override { return 0.; } + virtual real_t soft_body_get_linear_stiffness(RID p_body) const override { return 0.; } - virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override {} - virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override { return 0.; } + virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override {} + virtual real_t soft_body_get_angular_stiffness(RID p_body) const override { return 0.; } virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override {} - virtual real_t soft_body_get_volume_stiffness(RID p_body) override { return 0.; } + virtual real_t soft_body_get_volume_stiffness(RID p_body) const override { return 0.; } virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override {} - virtual real_t soft_body_get_pressure_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) override {} - virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) override {} - virtual real_t soft_body_get_damping_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_damping_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override {} - virtual real_t soft_body_get_drag_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_drag_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) override {} virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) override {} - virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) override { return Vector3(); } + virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const override { return Vector3(); } virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const override { return Vector3(); } virtual void soft_body_remove_all_pinned_points(RID p_body) override {} virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) override {} - virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) override { return false; } + virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const override { return false; } /* JOINT API */ - virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; + virtual RID joint_create() override; + + virtual void joint_clear(RID p_joint) override; //resets type + + virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; @@ -319,8 +332,8 @@ public: virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override; virtual Vector3 pin_joint_get_local_b(RID p_joint) const override; - virtual RID joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override; - virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override; + virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override; @@ -328,23 +341,23 @@ public: virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override; virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; - virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; - virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) override; - virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) override; + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const override; virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) override; - virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) override; + virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const override; virtual JointType joint_get_type(RID p_joint) const override; @@ -361,14 +374,16 @@ public: virtual void set_active(bool p_active) override; virtual void init() override; virtual void step(real_t p_step) override; + virtual void sync() override; virtual void flush_queries() override; + virtual void end_sync() override; virtual void finish() override; virtual bool is_flushing_queries() const override { return flushing_queries; } int get_process_info(ProcessInfo p_info) override; - PhysicsServer3DSW(); + PhysicsServer3DSW(bool p_using_threads = false); ~PhysicsServer3DSW() {} }; diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.cpp b/servers/physics_3d/physics_server_3d_wrap_mt.cpp new file mode 100644 index 0000000000..f73f67a756 --- /dev/null +++ b/servers/physics_3d/physics_server_3d_wrap_mt.cpp @@ -0,0 +1,140 @@ +/*************************************************************************/ +/* physics_server_3d_wrap_mt.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "physics_server_3d_wrap_mt.h" + +#include "core/os/os.h" + +void PhysicsServer3DWrapMT::thread_exit() { + exit = true; +} + +void PhysicsServer3DWrapMT::thread_step(real_t p_delta) { + physics_3d_server->step(p_delta); + step_sem.post(); +} + +void PhysicsServer3DWrapMT::_thread_callback(void *_instance) { + PhysicsServer3DWrapMT *vsmt = reinterpret_cast<PhysicsServer3DWrapMT *>(_instance); + + vsmt->thread_loop(); +} + +void PhysicsServer3DWrapMT::thread_loop() { + server_thread = Thread::get_caller_id(); + + physics_3d_server->init(); + + exit = false; + step_thread_up = true; + while (!exit) { + // flush commands one by one, until exit is requested + command_queue.wait_and_flush_one(); + } + + command_queue.flush_all(); // flush all + + physics_3d_server->finish(); +} + +/* EVENT QUEUING */ + +void PhysicsServer3DWrapMT::step(real_t p_step) { + if (create_thread) { + command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step); + } else { + command_queue.flush_all(); //flush all pending from other threads + physics_3d_server->step(p_step); + } +} + +void PhysicsServer3DWrapMT::sync() { + if (create_thread) { + if (first_frame) { + first_frame = false; + } else { + step_sem.wait(); //must not wait if a step was not issued + } + } + physics_3d_server->sync(); +} + +void PhysicsServer3DWrapMT::flush_queries() { + physics_3d_server->flush_queries(); +} + +void PhysicsServer3DWrapMT::end_sync() { + physics_3d_server->end_sync(); +} + +void PhysicsServer3DWrapMT::init() { + if (create_thread) { + //OS::get_singleton()->release_rendering_thread(); + thread.start(_thread_callback, this); + while (!step_thread_up) { + OS::get_singleton()->delay_usec(1000); + } + } else { + physics_3d_server->init(); + } +} + +void PhysicsServer3DWrapMT::finish() { + if (thread.is_started()) { + command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit); + thread.wait_to_finish(); + } else { + physics_3d_server->finish(); + } +} + +PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) : + command_queue(p_create_thread) { + physics_3d_server = p_contained; + create_thread = p_create_thread; + step_pending = 0; + step_thread_up = false; + + pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); + + if (!p_create_thread) { + server_thread = Thread::get_caller_id(); + } else { + server_thread = 0; + } + + main_thread = Thread::get_caller_id(); + first_frame = true; +} + +PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() { + memdelete(physics_3d_server); + //finish(); +} diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h new file mode 100644 index 0000000000..f60e1332d5 --- /dev/null +++ b/servers/physics_3d/physics_server_3d_wrap_mt.h @@ -0,0 +1,422 @@ +/*************************************************************************/ +/* physics_server_3d_wrap_mt.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef PHYSICS3DSERVERWRAPMT_H +#define PHYSICS3DSERVERWRAPMT_H + +#include "core/config/project_settings.h" +#include "core/os/thread.h" +#include "core/templates/command_queue_mt.h" +#include "servers/physics_server_3d.h" + +#ifdef DEBUG_SYNC +#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); +#else +#define SYNC_DEBUG +#endif + +class PhysicsServer3DWrapMT : public PhysicsServer3D { + mutable PhysicsServer3D *physics_3d_server; + + mutable CommandQueueMT command_queue; + + static void _thread_callback(void *_instance); + void thread_loop(); + + Thread::ID server_thread; + Thread::ID main_thread; + volatile bool exit = false; + Thread thread; + volatile bool step_thread_up = false; + bool create_thread = false; + + Semaphore step_sem; + int step_pending; + void thread_step(real_t p_delta); + void thread_flush(); + + void thread_exit(); + + bool first_frame = true; + + Mutex alloc_mutex; + int pool_max_size = 0; + +public: +#define ServerName PhysicsServer3D +#define ServerNameWrapMT PhysicsServer3DWrapMT +#define server_name physics_3d_server +#define WRITE_ACTION + +#include "servers/server_wrap_mt_common.h" + + //FUNC1RID(shape,ShapeType); todo fix + FUNCRID(plane_shape) + FUNCRID(ray_shape) + FUNCRID(sphere_shape) + FUNCRID(box_shape) + FUNCRID(capsule_shape) + FUNCRID(cylinder_shape) + FUNCRID(convex_polygon_shape) + FUNCRID(concave_polygon_shape) + FUNCRID(heightmap_shape) + FUNCRID(custom_shape) + + FUNC2(shape_set_data, RID, const Variant &); + FUNC2(shape_set_custom_solver_bias, RID, real_t); + + FUNC2(shape_set_margin, RID, real_t) + FUNC1RC(real_t, shape_get_margin, RID) + + FUNC1RC(ShapeType, shape_get_type, RID); + FUNC1RC(Variant, shape_get_data, RID); + FUNC1RC(real_t, shape_get_custom_solver_bias, RID); +#if 0 + //these work well, but should be used from the main thread only + bool shape_collide(RID p_shape_A, const Transform &p_xform_A, const Vector3 &p_motion_A, RID p_shape_B, const Transform &p_xform_B, const Vector3 &p_motion_B, Vector3 *r_results, int p_result_max, int &r_result_count) { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_3d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count); + } +#endif + /* SPACE API */ + + FUNCRID(space); + FUNC2(space_set_active, RID, bool); + FUNC1RC(bool, space_is_active, RID); + + FUNC3(space_set_param, RID, SpaceParameter, real_t); + FUNC2RC(real_t, space_get_param, RID, SpaceParameter); + + // this function only works on physics process, errors and returns null otherwise + PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); + return physics_3d_server->space_get_direct_state(p_space); + } + + FUNC2(space_set_debug_contacts, RID, int); + virtual Vector<Vector3> space_get_contacts(RID p_space) const override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector3>()); + return physics_3d_server->space_get_contacts(p_space); + } + + virtual int space_get_contact_count(RID p_space) const override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0); + return physics_3d_server->space_get_contact_count(p_space); + } + + /* AREA API */ + + //FUNC0RID(area); + FUNCRID(area); + + FUNC2(area_set_space, RID, RID); + FUNC1RC(RID, area_get_space, RID); + + FUNC2(area_set_space_override_mode, RID, AreaSpaceOverrideMode); + FUNC1RC(AreaSpaceOverrideMode, area_get_space_override_mode, RID); + + FUNC4(area_add_shape, RID, RID, const Transform &, bool); + FUNC3(area_set_shape, RID, int, RID); + FUNC3(area_set_shape_transform, RID, int, const Transform &); + FUNC3(area_set_shape_disabled, RID, int, bool); + + FUNC1RC(int, area_get_shape_count, RID); + FUNC2RC(RID, area_get_shape, RID, int); + FUNC2RC(Transform, area_get_shape_transform, RID, int); + FUNC2(area_remove_shape, RID, int); + FUNC1(area_clear_shapes, RID); + + FUNC2(area_attach_object_instance_id, RID, ObjectID); + FUNC1RC(ObjectID, area_get_object_instance_id, RID); + + FUNC3(area_set_param, RID, AreaParameter, const Variant &); + FUNC2(area_set_transform, RID, const Transform &); + + FUNC2RC(Variant, area_get_param, RID, AreaParameter); + FUNC1RC(Transform, area_get_transform, RID); + + FUNC2(area_set_collision_mask, RID, uint32_t); + FUNC2(area_set_collision_layer, RID, uint32_t); + + FUNC2(area_set_monitorable, RID, bool); + FUNC2(area_set_ray_pickable, RID, bool); + + FUNC3(area_set_monitor_callback, RID, Object *, const StringName &); + FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &); + + /* BODY API */ + + //FUNC2RID(body,BodyMode,bool); + FUNCRID(body) + + FUNC2(body_set_space, RID, RID); + FUNC1RC(RID, body_get_space, RID); + + FUNC2(body_set_mode, RID, BodyMode); + FUNC1RC(BodyMode, body_get_mode, RID); + + FUNC4(body_add_shape, RID, RID, const Transform &, bool); + FUNC3(body_set_shape, RID, int, RID); + FUNC3(body_set_shape_transform, RID, int, const Transform &); + + FUNC1RC(int, body_get_shape_count, RID); + FUNC2RC(Transform, body_get_shape_transform, RID, int); + FUNC2RC(RID, body_get_shape, RID, int); + + FUNC3(body_set_shape_disabled, RID, int, bool); + + FUNC2(body_remove_shape, RID, int); + FUNC1(body_clear_shapes, RID); + + FUNC2(body_attach_object_instance_id, RID, ObjectID); + FUNC1RC(ObjectID, body_get_object_instance_id, RID); + + FUNC2(body_set_enable_continuous_collision_detection, RID, bool); + FUNC1RC(bool, body_is_continuous_collision_detection_enabled, RID); + + FUNC2(body_set_collision_layer, RID, uint32_t); + FUNC1RC(uint32_t, body_get_collision_layer, RID); + + FUNC2(body_set_collision_mask, RID, uint32_t); + FUNC1RC(uint32_t, body_get_collision_mask, RID); + + FUNC2(body_set_user_flags, RID, uint32_t); + FUNC1RC(uint32_t, body_get_user_flags, RID); + + FUNC3(body_set_param, RID, BodyParameter, real_t); + FUNC2RC(real_t, body_get_param, RID, BodyParameter); + + FUNC2(body_set_kinematic_safe_margin, RID, real_t); + FUNC1RC(real_t, body_get_kinematic_safe_margin, RID); + + FUNC3(body_set_state, RID, BodyState, const Variant &); + FUNC2RC(Variant, body_get_state, RID, BodyState); + + FUNC2(body_set_applied_force, RID, const Vector3 &); + FUNC1RC(Vector3, body_get_applied_force, RID); + + FUNC2(body_set_applied_torque, RID, const Vector3 &); + FUNC1RC(Vector3, body_get_applied_torque, RID); + + FUNC2(body_add_central_force, RID, const Vector3 &); + FUNC3(body_add_force, RID, const Vector3 &, const Vector3 &); + FUNC2(body_add_torque, RID, const Vector3 &); + FUNC2(body_apply_torque_impulse, RID, const Vector3 &); + FUNC2(body_apply_central_impulse, RID, const Vector3 &); + FUNC3(body_apply_impulse, RID, const Vector3 &, const Vector3 &); + FUNC2(body_set_axis_velocity, RID, const Vector3 &); + + FUNC3(body_set_axis_lock, RID, BodyAxis, bool); + FUNC2RC(bool, body_is_axis_locked, RID, BodyAxis); + + FUNC2(body_add_collision_exception, RID, RID); + FUNC2(body_remove_collision_exception, RID, RID); + FUNC2S(body_get_collision_exceptions, RID, List<RID> *); + + FUNC2(body_set_max_contacts_reported, RID, int); + FUNC1RC(int, body_get_max_contacts_reported, RID); + + FUNC2(body_set_contacts_reported_depth_threshold, RID, real_t); + FUNC1RC(real_t, body_get_contacts_reported_depth_threshold, RID); + + FUNC2(body_set_omit_force_integration, RID, bool); + FUNC1RC(bool, body_is_omitting_force_integration, RID); + + FUNC4(body_set_force_integration_callback, RID, Object *, const StringName &, const Variant &); + + FUNC2(body_set_ray_pickable, RID, bool); + + bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes); + } + + int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_3d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); + } + + // this function only works on physics process, errors and returns null otherwise + PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); + return physics_3d_server->body_get_direct_state(p_body); + } + + /* SOFT BODY API */ + + FUNCRID(soft_body) + + FUNC2(soft_body_update_rendering_server, RID, class SoftBodyRenderingServerHandler *) + + FUNC2(soft_body_set_space, RID, RID) + FUNC1RC(RID, soft_body_get_space, RID) + + FUNC2(soft_body_set_ray_pickable, RID, bool); + + FUNC2(soft_body_set_collision_layer, RID, uint32_t) + FUNC1RC(uint32_t, soft_body_get_collision_layer, RID) + + FUNC2(soft_body_set_collision_mask, RID, uint32_t) + FUNC1RC(uint32_t, soft_body_get_collision_mask, RID) + + FUNC2(soft_body_add_collision_exception, RID, RID) + FUNC2(soft_body_remove_collision_exception, RID, RID) + FUNC2S(soft_body_get_collision_exceptions, RID, List<RID> *) + + FUNC3(soft_body_set_state, RID, BodyState, const Variant &); + FUNC2RC(Variant, soft_body_get_state, RID, BodyState); + + FUNC2(soft_body_set_transform, RID, const Transform &); + FUNC2RC(Vector3, soft_body_get_vertex_position, RID, int); + + FUNC2(soft_body_set_simulation_precision, RID, int); + FUNC1RC(int, soft_body_get_simulation_precision, RID); + + FUNC2(soft_body_set_total_mass, RID, real_t); + FUNC1RC(real_t, soft_body_get_total_mass, RID); + + FUNC2(soft_body_set_linear_stiffness, RID, real_t); + FUNC1RC(real_t, soft_body_get_linear_stiffness, RID); + + FUNC2(soft_body_set_angular_stiffness, RID, real_t); + FUNC1RC(real_t, soft_body_get_angular_stiffness, RID); + + FUNC2(soft_body_set_volume_stiffness, RID, real_t); + FUNC1RC(real_t, soft_body_get_volume_stiffness, RID); + + FUNC2(soft_body_set_pressure_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_pressure_coefficient, RID); + + FUNC2(soft_body_set_pose_matching_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_pose_matching_coefficient, RID); + + FUNC2(soft_body_set_damping_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_damping_coefficient, RID); + + FUNC2(soft_body_set_drag_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_drag_coefficient, RID); + + FUNC2(soft_body_set_mesh, RID, const REF &); + + FUNC3(soft_body_move_point, RID, int, const Vector3 &); + FUNC2RC(Vector3, soft_body_get_point_global_position, RID, int); + FUNC2RC(Vector3, soft_body_get_point_offset, RID, int); + + FUNC1(soft_body_remove_all_pinned_points, RID); + FUNC3(soft_body_pin_point, RID, int, bool); + FUNC2RC(bool, soft_body_is_point_pinned, RID, int); + + /* JOINT API */ + + FUNCRID(joint) + + FUNC1(joint_clear, RID) + + FUNC5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &) + + FUNC3(pin_joint_set_param, RID, PinJointParam, real_t) + FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam) + + FUNC2(pin_joint_set_local_a, RID, const Vector3 &) + FUNC1RC(Vector3, pin_joint_get_local_a, RID) + + FUNC2(pin_joint_set_local_b, RID, const Vector3 &) + FUNC1RC(Vector3, pin_joint_get_local_b, RID) + + FUNC5(joint_make_hinge, RID, RID, const Transform &, RID, const Transform &) + FUNC7(joint_make_hinge_simple, RID, RID, const Vector3 &, const Vector3 &, RID, const Vector3 &, const Vector3 &) + + FUNC3(hinge_joint_set_param, RID, HingeJointParam, real_t) + FUNC2RC(real_t, hinge_joint_get_param, RID, HingeJointParam) + + FUNC3(hinge_joint_set_flag, RID, HingeJointFlag, bool) + FUNC2RC(bool, hinge_joint_get_flag, RID, HingeJointFlag) + + FUNC5(joint_make_slider, RID, RID, const Transform &, RID, const Transform &) + + FUNC3(slider_joint_set_param, RID, SliderJointParam, real_t) + FUNC2RC(real_t, slider_joint_get_param, RID, SliderJointParam) + + FUNC5(joint_make_cone_twist, RID, RID, const Transform &, RID, const Transform &) + + FUNC3(cone_twist_joint_set_param, RID, ConeTwistJointParam, real_t) + FUNC2RC(real_t, cone_twist_joint_get_param, RID, ConeTwistJointParam) + + FUNC5(joint_make_generic_6dof, RID, RID, const Transform &, RID, const Transform &) + + FUNC4(generic_6dof_joint_set_param, RID, Vector3::Axis, G6DOFJointAxisParam, real_t) + FUNC3RC(real_t, generic_6dof_joint_get_param, RID, Vector3::Axis, G6DOFJointAxisParam) + + FUNC4(generic_6dof_joint_set_flag, RID, Vector3::Axis, G6DOFJointAxisFlag, bool) + FUNC3RC(bool, generic_6dof_joint_get_flag, RID, Vector3::Axis, G6DOFJointAxisFlag) + + FUNC1RC(JointType, joint_get_type, RID); + + FUNC2(joint_set_solver_priority, RID, int); + FUNC1RC(int, joint_get_solver_priority, RID); + + FUNC2(joint_disable_collisions_between_bodies, RID, const bool); + FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID); + + /* MISC */ + + FUNC1(free, RID); + FUNC1(set_active, bool); + + virtual void init() override; + virtual void step(real_t p_step) override; + virtual void sync() override; + virtual void end_sync() override; + virtual void flush_queries() override; + virtual void finish() override; + + virtual bool is_flushing_queries() const override { + return physics_3d_server->is_flushing_queries(); + } + + int get_process_info(ProcessInfo p_info) override { + return physics_3d_server->get_process_info(p_info); + } + + PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread); + ~PhysicsServer3DWrapMT(); + +#undef ServerNameWrapMT +#undef ServerName +#undef server_name +#undef WRITE_ACTION +}; + +#ifdef DEBUG_SYNC +#undef DEBUG_SYNC +#endif +#undef SYNC_DEBUG + +#endif // PHYSICS3DSERVERWRAPMT_H diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index f2adcc1072..5bac4f19b9 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -34,10 +34,12 @@ #include "core/math/quick_hull.h" #include "core/templates/sort_array.h" -#define _POINT_SNAP 0.001953125 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002 #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.9998 +#define _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD 0.002 +#define _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD 0.999 + void Shape3DSW::configure(const AABB &p_aabb) { aabb = p_aabb; configured = true; @@ -50,7 +52,8 @@ void Shape3DSW::configure(const AABB &p_aabb) { Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const { Vector3 res; int amnt; - get_supports(p_normal, 1, &res, amnt); + FeatureType type; + get_supports(p_normal, 1, &res, amnt, type); return res; } @@ -167,16 +170,19 @@ Vector3 RayShape3DSW::get_support(const Vector3 &p_normal) const { } } -void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = Vector3(0, 0, 0); r_supports[1] = Vector3(0, 0, length); } else if (p_normal.z > 0) { r_amount = 1; + r_type = FEATURE_POINT; *r_supports = Vector3(0, 0, length); } else { r_amount = 1; + r_type = FEATURE_POINT; *r_supports = Vector3(0, 0, 0); } } @@ -246,9 +252,10 @@ Vector3 SphereShape3DSW::get_support(const Vector3 &p_normal) const { return p_normal * radius; } -void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { *r_supports = p_normal * radius; r_amount = 1; + r_type = FEATURE_POINT; } bool SphereShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { @@ -261,7 +268,7 @@ bool SphereShape3DSW::intersect_point(const Vector3 &p_point) const { Vector3 SphereShape3DSW::get_closest_point_to(const Vector3 &p_point) const { Vector3 p = p_point; - float l = p.length(); + real_t l = p.length(); if (l < radius) { return p_point; } @@ -312,7 +319,7 @@ Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const { return point; } -void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { static const int next[3] = { 1, 2, 0 }; static const int next2[3] = { 2, 0, 1 }; @@ -325,6 +332,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s bool neg = dot < 0; r_amount = 4; + r_type = FEATURE_FACE; Vector3 point; point[i] = half_extents[i]; @@ -362,6 +370,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; + r_type = FEATURE_EDGE; int i_n = next[i]; int i_n2 = next2[i]; @@ -389,6 +398,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s (p_normal.z < 0) ? -half_extents.z : half_extents.z); r_amount = 1; + r_type = FEATURE_POINT; r_supports[0] = point; } @@ -429,7 +439,7 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { } //check segments - float min_distance = 1e20; + real_t min_distance = 1e20; Vector3 closest_vertex = half_extents * p_point.sign(); Vector3 s[2] = { closest_vertex, @@ -442,7 +452,7 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { Vector3 closest_edge = Geometry3D::get_closest_point_to_segment(p_point, s); - float d = p_point.distance_to(closest_edge); + real_t d = p_point.distance_to(closest_edge); if (d < min_distance) { min_point = closest_edge; min_distance = d; @@ -500,7 +510,7 @@ Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const { return n; } -void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { Vector3 n = p_normal; real_t d = n.z; @@ -512,6 +522,7 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 n *= radius; r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = n; r_supports[0].z += height * 0.5; r_supports[1] = n; @@ -523,6 +534,7 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 n *= radius; n.z += h * 0.5; r_amount = 1; + r_type = FEATURE_POINT; *r_supports = n; } } @@ -642,6 +654,186 @@ CapsuleShape3DSW::CapsuleShape3DSW() { height = radius = 0; } +/********** CYLINDER *************/ + +void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { + Vector3 cylinder_axis = p_transform.basis.get_axis(1).normalized(); + real_t axis_dot = cylinder_axis.dot(p_normal); + + Vector3 local_normal = p_transform.basis.xform_inv(p_normal); + real_t scale = local_normal.length(); + real_t scaled_radius = radius * scale; + real_t scaled_height = height * scale; + + real_t length; + if (Math::abs(axis_dot) > 1.0) { + length = scaled_height * 0.5; + } else { + length = Math::abs(axis_dot * scaled_height * 0.5) + scaled_radius * Math::sqrt(1.0 - axis_dot * axis_dot); + } + + real_t distance = p_normal.dot(p_transform.origin); + + r_min = distance - length; + r_max = distance + length; +} + +Vector3 CylinderShape3DSW::get_support(const Vector3 &p_normal) const { + Vector3 n = p_normal; + real_t h = (n.y > 0) ? height : -height; + real_t s = Math::sqrt(n.x * n.x + n.z * n.z); + if (Math::is_zero_approx(s)) { + n.x = radius; + n.y = h * 0.5; + n.z = 0.0; + } else { + real_t d = radius / s; + n.x = n.x * d; + n.y = h * 0.5; + n.z = n.z * d; + } + + return n; +} + +void CylinderShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { + real_t d = p_normal.y; + if (Math::abs(d) > _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD) { + real_t h = (d > 0) ? height : -height; + + Vector3 n = p_normal; + n.x = 0.0; + n.z = 0.0; + n.y = h * 0.5; + + r_amount = 3; + r_type = FEATURE_CIRCLE; + r_supports[0] = n; + r_supports[1] = n; + r_supports[1].x += radius; + r_supports[2] = n; + r_supports[2].z += radius; + } else if (Math::abs(d) < _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD) { + // make it flat + Vector3 n = p_normal; + n.y = 0.0; + n.normalize(); + n *= radius; + + r_amount = 2; + r_type = FEATURE_EDGE; + r_supports[0] = n; + r_supports[0].y += height * 0.5; + r_supports[1] = n; + r_supports[1].y -= height * 0.5; + } else { + r_amount = 1; + r_type = FEATURE_POINT; + r_supports[0] = get_support(p_normal); + return; + + Vector3 n = p_normal; + real_t h = n.y * Math::sqrt(0.25 * height * height + radius * radius); + if (Math::abs(h) > 1.0) { + // Top or bottom surface. + n.y = (n.y > 0.0) ? height * 0.5 : -height * 0.5; + } else { + // Lateral surface. + n.y = height * 0.5 * h; + } + + real_t s = Math::sqrt(n.x * n.x + n.z * n.z); + if (Math::is_zero_approx(s)) { + n.x = 0.0; + n.z = 0.0; + } else { + real_t scaled_radius = radius / s; + n.x = n.x * scaled_radius; + n.z = n.z * scaled_radius; + } + + r_supports[0] = n; + } +} + +bool CylinderShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { + return Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &r_result, &r_normal, 1); +} + +bool CylinderShape3DSW::intersect_point(const Vector3 &p_point) const { + if (Math::abs(p_point.y) < height * 0.5) { + return Vector3(p_point.x, 0, p_point.z).length() < radius; + } + return false; +} + +Vector3 CylinderShape3DSW::get_closest_point_to(const Vector3 &p_point) const { + if (Math::absf(p_point.y) > height * 0.5) { + // Project point to top disk. + real_t dir = p_point.y > 0.0 ? 1.0 : -1.0; + Vector3 circle_pos(0.0, dir * height * 0.5, 0.0); + Plane circle_plane(circle_pos, Vector3(0.0, dir, 0.0)); + Vector3 proj_point = circle_plane.project(p_point); + + // Clip position. + Vector3 delta_point_1 = proj_point - circle_pos; + real_t dist_point_1 = delta_point_1.length_squared(); + if (!Math::is_zero_approx(dist_point_1)) { + dist_point_1 = Math::sqrt(dist_point_1); + proj_point = circle_pos + delta_point_1 * MIN(dist_point_1, radius) / dist_point_1; + } + + return proj_point; + } else { + Vector3 s[2] = { + Vector3(0, -height * 0.5, 0), + Vector3(0, height * 0.5, 0), + }; + + Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s); + + if (p.distance_to(p_point) < radius) { + return p_point; + } + + return p + (p_point - p).normalized() * radius; + } +} + +Vector3 CylinderShape3DSW::get_moment_of_inertia(real_t p_mass) const { + // use bad AABB approximation + Vector3 extents = get_aabb().size * 0.5; + + return Vector3( + (p_mass / 3.0) * (extents.y * extents.y + extents.z * extents.z), + (p_mass / 3.0) * (extents.x * extents.x + extents.z * extents.z), + (p_mass / 3.0) * (extents.y * extents.y + extents.y * extents.y)); +} + +void CylinderShape3DSW::_setup(real_t p_height, real_t p_radius) { + height = p_height; + radius = p_radius; + configure(AABB(Vector3(-radius, -height * 0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); +} + +void CylinderShape3DSW::set_data(const Variant &p_data) { + Dictionary d = p_data; + ERR_FAIL_COND(!d.has("radius")); + ERR_FAIL_COND(!d.has("height")); + _setup(d["height"], d["radius"]); +} + +Variant CylinderShape3DSW::get_data() const { + Dictionary d; + d["radius"] = radius; + d["height"] = height; + return d; +} + +CylinderShape3DSW::CylinderShape3DSW() { + height = radius = 0; +} + /********** CONVEX POLYGON *************/ void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { @@ -689,7 +881,7 @@ Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const { return vrts[vert_support_idx]; } -void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); @@ -734,6 +926,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve r_supports[j] = vertices[ind[j]]; } r_amount = m; + r_type = FEATURE_FACE; return; } } @@ -743,6 +936,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) { r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = vertices[edges[i].a]; r_supports[1] = vertices[edges[i].b]; return; @@ -751,6 +945,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve r_supports[0] = vertices[vtx]; r_amount = 1; + r_type = FEATURE_POINT; } bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { @@ -839,7 +1034,7 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con return p_point; } - float min_distance = 1e20; + real_t min_distance = 1e20; Vector3 min_point; //check edges @@ -852,7 +1047,7 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con }; Vector3 closest = Geometry3D::get_closest_point_to_segment(p_point, s); - float d = closest.distance_to(p_point); + real_t d = closest.distance_to(p_point); if (d < min_distance) { min_distance = d; min_point = closest; @@ -935,12 +1130,13 @@ Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const { return vertex[vert_support_idx]; } -void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { Vector3 n = p_normal; /** TEST FACE AS SUPPORT **/ if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 3; + r_type = FEATURE_FACE; for (int i = 0; i < 3; i++) { r_supports[i] = vertex[i]; } @@ -974,6 +1170,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = vertex[i]; r_supports[1] = vertex[nx]; return; @@ -981,6 +1178,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ } r_amount = 1; + r_type = FEATURE_POINT; r_supports[0] = vertex[vert_support_idx]; } diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h index 851c0d9443..cafe978abb 100644 --- a/servers/physics_3d/shape_3d_sw.h +++ b/servers/physics_3d/shape_3d_sw.h @@ -67,8 +67,11 @@ protected: void configure(const AABB &p_aabb); public: - enum { - MAX_SUPPORTS = 8 + enum FeatureType { + FEATURE_POINT, + FEATURE_EDGE, + FEATURE_FACE, + FEATURE_CIRCLE, }; virtual real_t get_area() const { return aabb.get_area(); } @@ -85,7 +88,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const = 0; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const = 0; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0; virtual bool intersect_point(const Vector3 &p_point) const = 0; @@ -110,7 +113,7 @@ class ConcaveShape3DSW : public Shape3DSW { public: virtual bool is_concave() const { return true; } typedef void (*Callback)(void *p_userdata, Shape3DSW *p_convex); - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; @@ -129,7 +132,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_PLANE; } virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; @@ -156,7 +159,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_RAY; } virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; @@ -184,7 +187,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -209,7 +212,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -238,7 +241,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -251,6 +254,35 @@ public: CapsuleShape3DSW(); }; +class CylinderShape3DSW : public Shape3DSW { + real_t height; + real_t radius; + + void _setup(real_t p_height, real_t p_radius); + +public: + _FORCE_INLINE_ real_t get_height() const { return height; } + _FORCE_INLINE_ real_t get_radius() const { return radius; } + + virtual real_t get_area() const { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; } + + virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CYLINDER; } + + virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual Vector3 get_support(const Vector3 &p_normal) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; + virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; + virtual bool intersect_point(const Vector3 &p_point) const; + virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; + + virtual Vector3 get_moment_of_inertia(real_t p_mass) const; + + virtual void set_data(const Variant &p_data); + virtual Variant get_data() const; + + CylinderShape3DSW(); +}; + struct ConvexPolygonShape3DSW : public Shape3DSW { Geometry3D::MeshData mesh; @@ -263,7 +295,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -399,7 +431,7 @@ struct FaceShape3DSW : public Shape3DSW { void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -437,7 +469,7 @@ struct MotionShape3DSW : public Shape3DSW { } return support; } - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; } virtual bool intersect_point(const Vector3 &p_point) const { return false; } virtual Vector3 get_closest_point_to(const Vector3 &p_point) const { return p_point; } diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 0395a3339c..c8741dc930 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -181,7 +181,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans return 0; } - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_xform.xform(shape->get_aabb()); @@ -210,6 +210,10 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) { continue; } @@ -232,7 +236,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans } bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); AABB aabb = p_xform.xform(shape->get_aabb()); @@ -265,6 +269,10 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + Vector3 point_A, point_B; Vector3 sep_axis = p_motion.normalized(); @@ -274,11 +282,11 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor continue; } - //test initial overlap + //test initial overlap, ignore objects it's inside of. sep_axis = p_motion.normalized(); if (!CollisionSolver3DSW::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { - return false; + continue; } //just do kinematic solving @@ -340,7 +348,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ return false; } - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_shape_xform.xform(shape->get_aabb()); @@ -365,12 +373,17 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; - int shape_idx = space->intersection_query_subindex_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; } + int shape_idx = space->intersection_query_subindex_results[i]; + + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + if (CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) { collided = true; } @@ -384,6 +397,8 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ struct _RestCallbackData { const CollisionObject3DSW *object; const CollisionObject3DSW *best_object; + int local_shape; + int best_local_shape; int shape; int best_shape; Vector3 best_contact; @@ -409,10 +424,11 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B, rd->best_normal = contact_rel / len; rd->best_object = rd->object; rd->best_shape = rd->shape; + rd->best_local_shape = rd->local_shape; } bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_shape_xform.xform(shape->get_aabb()); @@ -432,12 +448,17 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; - int shape_idx = space->intersection_query_subindex_results[i]; if (p_exclude.has(col_obj->get_self())) { continue; } + int shape_idx = space->intersection_query_subindex_results[i]; + + if (col_obj->is_shape_set_as_disabled(shape_idx)) { + continue; + } + rcd.object = col_obj; rcd.shape = shape_idx; bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); @@ -468,15 +489,15 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap } Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - CollisionObject3DSW *obj = PhysicsServer3DSW::singleton->area_owner.getornull(p_object); + CollisionObject3DSW *obj = PhysicsServer3DSW::singletonsw->area_owner.getornull(p_object); if (!obj) { - obj = PhysicsServer3DSW::singleton->body_owner.getornull(p_object); + obj = PhysicsServer3DSW::singletonsw->body_owner.getornull(p_object); } ERR_FAIL_COND_V(!obj, Vector3()); ERR_FAIL_COND_V(obj->get_space() != space, Vector3()); - float min_distance = 1e20; + real_t min_distance = 1e20; Vector3 min_point; bool shapes_found = false; @@ -492,7 +513,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point)); point = shape_xform.xform(point); - float dist = point.distance_to(p_point); + real_t dist = point.distance_to(p_point); if (dist < min_distance) { min_distance = dist; min_point = point; @@ -651,7 +672,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra recover_motion += (b - a) / cbk.amount; - float depth = a.distance_to(b); + real_t depth = a.distance_to(b); if (depth > result.collision_depth) { result.collision_depth = depth; result.collision_point = b; @@ -739,8 +760,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb)); body_aabb = body_aabb.grow(p_margin); + real_t motion_length = p_motion.length(); + Vector3 motion_normal = p_motion / motion_length; + Transform body_transform = p_from; + bool recovered = false; + { //STEP 1, FREE BODY IF STUCK @@ -791,7 +817,17 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons for (int i = 0; i < cbk.amount; i++) { Vector3 a = sr[i * 2 + 0]; Vector3 b = sr[i * 2 + 1]; - recover_motion += (b - a) / cbk.amount; + + // Compute plane on b towards a. + Vector3 n = (a - b).normalized(); + real_t d = n.dot(b); + + // Compute depth on recovered motion. + real_t depth = n.dot(a + recover_motion) - d; + if (depth > 0.0) { + // Only recover if there is penetration. + recover_motion -= n * depth * 0.4; + } } if (recover_motion == Vector3()) { @@ -799,6 +835,8 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons break; } + recovered = true; + body_transform.origin += recover_motion; body_aabb.position += recover_motion; @@ -848,14 +886,14 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons //test initial overlap, does it collide if going all the way? Vector3 point_A, point_B; - Vector3 sep_axis = p_motion.normalized(); + Vector3 sep_axis = motion_normal; Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { continue; } - sep_axis = p_motion.normalized(); + sep_axis = motion_normal; if (!CollisionSolver3DSW::solve_distance(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { stuck = true; @@ -865,13 +903,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons //just do kinematic solving real_t low = 0; real_t hi = 1; - Vector3 mnormal = p_motion.normalized(); for (int k = 0; k < 8; k++) { //steps should be customizable.. real_t ofs = (low + hi) * 0.5; - Vector3 sep = mnormal; //important optimization for this to work fast enough + Vector3 sep = motion_normal; //important optimization for this to work fast enough mshape.motion = body_shape_xform_inv.basis.xform(p_motion * ofs); @@ -912,16 +949,11 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons } bool collided = false; - if (safe >= 1) { - //not collided - collided = false; - if (r_result) { - r_result->motion = p_motion; - r_result->remainder = Vector3(); - r_result->motion += (body_transform.get_origin() - p_from.get_origin()); + if (recovered || (safe < 1)) { + if (safe >= 1) { + best_shape = -1; //no best shape with cast, reset to -1 } - } else { //it collided, let's get the rest info in unsafe advance Transform ugt = body_transform; ugt.origin += p_motion * unsafe; @@ -930,25 +962,40 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons rcd.best_len = 0; rcd.best_object = nullptr; rcd.best_shape = 0; - rcd.min_allowed_depth = test_motion_min_contact_depth; - Transform body_shape_xform = ugt * p_body->get_shape_transform(best_shape); - Shape3DSW *body_shape = p_body->get_shape(best_shape); + // Allowed depth can't be lower than motion length, in order to handle contacts at low speed. + rcd.min_allowed_depth = MIN(motion_length, test_motion_min_contact_depth); - body_aabb.position += p_motion * unsafe; + int from_shape = best_shape != -1 ? best_shape : 0; + int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); - int amount = _cull_aabb_for_body(p_body, body_aabb); + for (int j = from_shape; j < to_shape; j++) { + if (p_body->is_shape_set_as_disabled(j)) { + continue; + } - for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; - int shape_idx = intersection_query_subindex_results[i]; + Transform body_shape_xform = ugt * p_body->get_shape_transform(j); + Shape3DSW *body_shape = p_body->get_shape(j); - rcd.object = col_obj; - rcd.shape = shape_idx; - bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); - if (!sc) { + if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) { continue; } + + body_aabb.position += p_motion * unsafe; + + int amount = _cull_aabb_for_body(p_body, body_aabb); + + for (int i = 0; i < amount; i++) { + const CollisionObject3DSW *col_obj = intersection_query_results[i]; + int shape_idx = intersection_query_subindex_results[i]; + + rcd.object = col_obj; + rcd.shape = shape_idx; + bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); + if (!sc) { + continue; + } + } } if (rcd.best_len != 0) { @@ -956,7 +1003,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons r_result->collider = rcd.best_object->get_self(); r_result->collider_id = rcd.best_object->get_instance_id(); r_result->collider_shape = rcd.best_shape; - r_result->collision_local_shape = best_shape; + r_result->collision_local_shape = rcd.best_local_shape; r_result->collision_normal = rcd.best_normal; r_result->collision_point = rcd.best_contact; //r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape); @@ -972,17 +1019,15 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons } collided = true; - } else { - if (r_result) { - r_result->motion = p_motion; - r_result->remainder = Vector3(); - r_result->motion += (body_transform.get_origin() - p_from.get_origin()); - } - - collided = false; } } + if (!collided && r_result) { + r_result->motion = p_motion; + r_result->remainder = Vector3(); + r_result->motion += (body_transform.get_origin() - p_from.get_origin()); + } + return collided; } @@ -1211,7 +1256,7 @@ Space3DSW::Space3DSW() { constraint_bias = 0.01; body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_linear", 0.1); - body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI)); + body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg2rad(8.0)); body_time_to_sleep = GLOBAL_DEF("physics/3d/time_before_sleep", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); body_angular_velocity_damp_ratio = 10; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index a6f64f5848..83ebc0c55b 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -42,7 +42,7 @@ void PhysicsDirectBodyState2D::integrate_forces() { real_t av = get_angular_velocity(); - float damp = 1.0 - step * get_total_linear_damp(); + real_t damp = 1.0 - step * get_total_linear_damp(); if (damp < 0) { // reached zero in the given time damp = 0; @@ -168,11 +168,11 @@ Vector2 PhysicsShapeQueryParameters2D::get_motion() const { return motion; } -void PhysicsShapeQueryParameters2D::set_margin(float p_margin) { +void PhysicsShapeQueryParameters2D::set_margin(real_t p_margin) { margin = p_margin; } -float PhysicsShapeQueryParameters2D::get_margin() const { +real_t PhysicsShapeQueryParameters2D::get_margin() const { return margin; } @@ -311,7 +311,7 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) { ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); - float closest_safe, closest_unsafe; + real_t closest_safe, closest_unsafe; bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); if (!res) { return Array(); @@ -517,7 +517,7 @@ PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() { /////////////////////////////////////// -bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { +bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { MotionResult *r = nullptr; if (p_result.is_valid()) { r = p_result->get_result_ptr(); @@ -655,12 +655,16 @@ void PhysicsServer2D::_bind_methods() { /* JOINT API */ + ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer2D::joint_create); + + ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer2D::joint_clear); + ClassDB::bind_method(D_METHOD("joint_set_param", "joint", "param", "value"), &PhysicsServer2D::joint_set_param); ClassDB::bind_method(D_METHOD("joint_get_param", "joint", "param"), &PhysicsServer2D::joint_get_param); - ClassDB::bind_method(D_METHOD("pin_joint_create", "anchor", "body_a", "body_b"), &PhysicsServer2D::pin_joint_create, DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("groove_joint_create", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::groove_joint_create, DEFVAL(RID()), DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("damped_spring_joint_create", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::damped_spring_joint_create, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("joint_make_pin", "joint", "anchor", "body_a", "body_b"), &PhysicsServer2D::joint_make_pin, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("joint_make_groove", "joint", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_groove, DEFVAL(RID()), DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("joint_make_damped_spring", "joint", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_damped_spring, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("damped_spring_joint_set_param", "joint", "param", "value"), &PhysicsServer2D::damped_spring_joint_set_param); ClassDB::bind_method(D_METHOD("damped_spring_joint_get_param", "joint", "param"), &PhysicsServer2D::damped_spring_joint_get_param); @@ -727,9 +731,10 @@ void PhysicsServer2D::_bind_methods() { BIND_ENUM_CONSTANT(BODY_STATE_SLEEPING); BIND_ENUM_CONSTANT(BODY_STATE_CAN_SLEEP); - BIND_ENUM_CONSTANT(JOINT_PIN); - BIND_ENUM_CONSTANT(JOINT_GROOVE); - BIND_ENUM_CONSTANT(JOINT_DAMPED_SPRING); + BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); + BIND_ENUM_CONSTANT(JOINT_TYPE_GROOVE); + BIND_ENUM_CONSTANT(JOINT_TYPE_DAMPED_SPRING); + BIND_ENUM_CONSTANT(JOINT_TYPE_MAX); BIND_ENUM_CONSTANT(JOINT_PARAM_BIAS); BIND_ENUM_CONSTANT(JOINT_PARAM_MAX_BIAS); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index dd38855199..28f22ce06b 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -45,10 +45,10 @@ protected: public: virtual Vector2 get_total_gravity() const = 0; // get gravity vector working on this body space/area - virtual float get_total_linear_damp() const = 0; // get density of this body space/area - virtual float get_total_angular_damp() const = 0; // get density of this body space/area + virtual real_t get_total_linear_damp() const = 0; // get density of this body space/area + virtual real_t get_total_angular_damp() const = 0; // get density of this body space/area - virtual float get_inverse_mass() const = 0; // get the mass + virtual real_t get_inverse_mass() const = 0; // get the mass virtual real_t get_inverse_inertia() const = 0; // get density of this body space virtual void set_linear_velocity(const Vector2 &p_velocity) = 0; @@ -103,7 +103,7 @@ class PhysicsShapeQueryParameters2D : public Reference { RID shape; Transform2D transform; Vector2 motion; - float margin; + real_t margin; Set<RID> exclude; uint32_t collision_mask; @@ -125,8 +125,8 @@ public: void set_motion(const Vector2 &p_motion); Vector2 get_motion() const; - void set_margin(float p_margin); - float get_margin() const; + void set_margin(real_t p_margin); + real_t get_margin() const; void set_collision_mask(int p_collision_mask); int get_collision_mask() const; @@ -182,11 +182,11 @@ public: virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; - virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeRestInfo { Vector2 point; @@ -198,7 +198,7 @@ public: Variant metadata; }; - virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; PhysicsDirectSpaceState2D(); }; @@ -230,7 +230,7 @@ class PhysicsServer2D : public Object { static PhysicsServer2D *singleton; - virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); + virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); protected: static void _bind_methods(); @@ -393,7 +393,7 @@ public: virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const = 0; virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0; - virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, float p_margin = 0) = 0; + virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0) = 0; virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0; virtual void body_clear_shapes(RID p_body) = 0; @@ -431,8 +431,8 @@ public: BODY_PARAM_MAX, }; - virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0; - virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0; + virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) = 0; + virtual real_t body_get_param(RID p_body, BodyParameter p_param) const = 0; //state enum BodyState { @@ -450,15 +450,15 @@ public: virtual void body_set_applied_force(RID p_body, const Vector2 &p_force) = 0; virtual Vector2 body_get_applied_force(RID p_body) const = 0; - virtual void body_set_applied_torque(RID p_body, float p_torque) = 0; - virtual float body_get_applied_torque(RID p_body) const = 0; + virtual void body_set_applied_torque(RID p_body, real_t p_torque) = 0; + virtual real_t body_get_applied_torque(RID p_body) const = 0; virtual void body_add_central_force(RID p_body, const Vector2 &p_force) = 0; virtual void body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0; - virtual void body_add_torque(RID p_body, float p_torque) = 0; + virtual void body_add_torque(RID p_body, real_t p_torque) = 0; virtual void body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) = 0; - virtual void body_apply_torque_impulse(RID p_body, float p_torque) = 0; + virtual void body_apply_torque_impulse(RID p_body, real_t p_torque) = 0; virtual void body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) = 0; virtual void body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) = 0; @@ -471,8 +471,8 @@ public: virtual int body_get_max_contacts_reported(RID p_body) const = 0; //missing remove - virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) = 0; - virtual float body_get_contacts_reported_depth_threshold(RID p_body) const = 0; + virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) = 0; + virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const = 0; virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0; virtual bool body_is_omitting_force_integration(RID p_body) const = 0; @@ -506,10 +506,10 @@ public: } }; - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { - float collision_depth; + real_t collision_depth; Vector2 collision_point; Vector2 collision_normal; Vector2 collider_velocity; @@ -520,14 +520,19 @@ public: Variant collider_metadata; }; - virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0; + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0; /* JOINT API */ + virtual RID joint_create() = 0; + + virtual void joint_clear(RID p_joint) = 0; + enum JointType { - JOINT_PIN, - JOINT_GROOVE, - JOINT_DAMPED_SPRING + JOINT_TYPE_PIN, + JOINT_TYPE_GROOVE, + JOINT_TYPE_DAMPED_SPRING, + JOINT_TYPE_MAX }; enum JointParam { @@ -542,9 +547,9 @@ public: virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0; - virtual RID pin_joint_create(const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0; - virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0; - virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0; + virtual void joint_make_pin(RID p_joint, const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0; + virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0; + virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0; enum PinJointParam { PIN_JOINT_SOFTNESS @@ -576,7 +581,7 @@ public: virtual void set_active(bool p_active) = 0; virtual void init() = 0; - virtual void step(float p_step) = 0; + virtual void step(real_t p_step) = 0; virtual void sync() = 0; virtual void flush_queries() = 0; virtual void end_sync() = 0; diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 27ebe32e50..af25029f04 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -42,13 +42,13 @@ void PhysicsDirectBodyState3D::integrate_forces() { Vector3 av = get_angular_velocity(); - float linear_damp = 1.0 - step * get_total_linear_damp(); + real_t linear_damp = 1.0 - step * get_total_linear_damp(); if (linear_damp < 0) { // reached zero in the given time linear_damp = 0; } - float angular_damp = 1.0 - step * get_total_angular_damp(); + real_t angular_damp = 1.0 - step * get_total_angular_damp(); if (angular_damp < 0) { // reached zero in the given time angular_damp = 0; @@ -128,7 +128,7 @@ void PhysicsDirectBodyState3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleep_state", "is_sleeping"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform"); } PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {} @@ -164,11 +164,11 @@ Transform PhysicsShapeQueryParameters3D::get_transform() const { return transform; } -void PhysicsShapeQueryParameters3D::set_margin(float p_margin) { +void PhysicsShapeQueryParameters3D::set_margin(real_t p_margin) { margin = p_margin; } -float PhysicsShapeQueryParameters3D::get_margin() const { +real_t PhysicsShapeQueryParameters3D::get_margin() const { return margin; } @@ -303,7 +303,7 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) { ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); - float closest_safe = 1.0f, closest_unsafe = 1.0f; + real_t closest_safe = 1.0f, closest_unsafe = 1.0f; bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); if (!res) { return Array(); @@ -398,10 +398,47 @@ void PhysicsShapeQueryResult3D::_bind_methods() { /////////////////////////////////////// +RID PhysicsServer3D::shape_create(ShapeType p_shape) { + switch (p_shape) { + case SHAPE_PLANE: + return plane_shape_create(); + case SHAPE_RAY: + return ray_shape_create(); + case SHAPE_SPHERE: + return sphere_shape_create(); + case SHAPE_BOX: + return box_shape_create(); + case SHAPE_CAPSULE: + return capsule_shape_create(); + case SHAPE_CYLINDER: + return cylinder_shape_create(); + case SHAPE_CONVEX_POLYGON: + return convex_polygon_shape_create(); + case SHAPE_CONCAVE_POLYGON: + return concave_polygon_shape_create(); + case SHAPE_HEIGHTMAP: + return heightmap_shape_create(); + case SHAPE_CUSTOM: + return custom_shape_create(); + default: + return RID(); + } +} + void PhysicsServer3D::_bind_methods() { #ifndef _3D_DISABLED - ClassDB::bind_method(D_METHOD("shape_create", "type"), &PhysicsServer3D::shape_create); + ClassDB::bind_method(D_METHOD("plane_shape_create"), &PhysicsServer3D::plane_shape_create); + ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer3D::ray_shape_create); + ClassDB::bind_method(D_METHOD("sphere_shape_create"), &PhysicsServer3D::sphere_shape_create); + ClassDB::bind_method(D_METHOD("box_shape_create"), &PhysicsServer3D::box_shape_create); + ClassDB::bind_method(D_METHOD("capsule_shape_create"), &PhysicsServer3D::capsule_shape_create); + ClassDB::bind_method(D_METHOD("cylinder_shape_create"), &PhysicsServer3D::cylinder_shape_create); + ClassDB::bind_method(D_METHOD("convex_polygon_shape_create"), &PhysicsServer3D::convex_polygon_shape_create); + ClassDB::bind_method(D_METHOD("concave_polygon_shape_create"), &PhysicsServer3D::concave_polygon_shape_create); + ClassDB::bind_method(D_METHOD("heightmap_shape_create"), &PhysicsServer3D::heightmap_shape_create); + ClassDB::bind_method(D_METHOD("custom_shape_create"), &PhysicsServer3D::custom_shape_create); + ClassDB::bind_method(D_METHOD("shape_set_data", "shape", "data"), &PhysicsServer3D::shape_set_data); ClassDB::bind_method(D_METHOD("shape_get_type", "shape"), &PhysicsServer3D::shape_get_type); @@ -450,9 +487,8 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer3D::area_set_monitorable); ClassDB::bind_method(D_METHOD("area_set_ray_pickable", "area", "enable"), &PhysicsServer3D::area_set_ray_pickable); - ClassDB::bind_method(D_METHOD("area_is_ray_pickable", "area"), &PhysicsServer3D::area_is_ray_pickable); - ClassDB::bind_method(D_METHOD("body_create", "mode", "init_sleeping"), &PhysicsServer3D::body_create, DEFVAL(BODY_MODE_RIGID), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("body_create"), &PhysicsServer3D::body_create); ClassDB::bind_method(D_METHOD("body_set_space", "body", "space"), &PhysicsServer3D::body_set_space); ClassDB::bind_method(D_METHOD("body_get_space", "body"), &PhysicsServer3D::body_get_space); @@ -517,19 +553,22 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "receiver", "method", "userdata"), &PhysicsServer3D::body_set_force_integration_callback, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("body_set_ray_pickable", "body", "enable"), &PhysicsServer3D::body_set_ray_pickable); - ClassDB::bind_method(D_METHOD("body_is_ray_pickable", "body"), &PhysicsServer3D::body_is_ray_pickable); ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer3D::body_get_direct_state); /* JOINT API */ - BIND_ENUM_CONSTANT(JOINT_PIN); - BIND_ENUM_CONSTANT(JOINT_HINGE); - BIND_ENUM_CONSTANT(JOINT_SLIDER); - BIND_ENUM_CONSTANT(JOINT_CONE_TWIST); - BIND_ENUM_CONSTANT(JOINT_6DOF); + ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer3D::joint_create); + ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer3D::joint_clear); + + BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); + BIND_ENUM_CONSTANT(JOINT_TYPE_HINGE); + BIND_ENUM_CONSTANT(JOINT_TYPE_SLIDER); + BIND_ENUM_CONSTANT(JOINT_TYPE_CONE_TWIST); + BIND_ENUM_CONSTANT(JOINT_TYPE_6DOF); + BIND_ENUM_CONSTANT(JOINT_TYPE_MAX); - ClassDB::bind_method(D_METHOD("joint_create_pin", "body_A", "local_A", "body_B", "local_B"), &PhysicsServer3D::joint_create_pin); + ClassDB::bind_method(D_METHOD("joint_make_pin", "joint", "body_A", "local_A", "body_B", "local_B"), &PhysicsServer3D::joint_make_pin); ClassDB::bind_method(D_METHOD("pin_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::pin_joint_set_param); ClassDB::bind_method(D_METHOD("pin_joint_get_param", "joint", "param"), &PhysicsServer3D::pin_joint_get_param); @@ -555,7 +594,7 @@ void PhysicsServer3D::_bind_methods() { BIND_ENUM_CONSTANT(HINGE_JOINT_FLAG_USE_LIMIT); BIND_ENUM_CONSTANT(HINGE_JOINT_FLAG_ENABLE_MOTOR); - ClassDB::bind_method(D_METHOD("joint_create_hinge", "body_A", "hinge_A", "body_B", "hinge_B"), &PhysicsServer3D::joint_create_hinge); + ClassDB::bind_method(D_METHOD("joint_make_hinge", "joint", "body_A", "hinge_A", "body_B", "hinge_B"), &PhysicsServer3D::joint_make_hinge); ClassDB::bind_method(D_METHOD("hinge_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::hinge_joint_set_param); ClassDB::bind_method(D_METHOD("hinge_joint_get_param", "joint", "param"), &PhysicsServer3D::hinge_joint_get_param); @@ -563,7 +602,7 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("hinge_joint_set_flag", "joint", "flag", "enabled"), &PhysicsServer3D::hinge_joint_set_flag); ClassDB::bind_method(D_METHOD("hinge_joint_get_flag", "joint", "flag"), &PhysicsServer3D::hinge_joint_get_flag); - ClassDB::bind_method(D_METHOD("joint_create_slider", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_slider); + ClassDB::bind_method(D_METHOD("joint_make_slider", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_slider); ClassDB::bind_method(D_METHOD("slider_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::slider_joint_set_param); ClassDB::bind_method(D_METHOD("slider_joint_get_param", "joint", "param"), &PhysicsServer3D::slider_joint_get_param); @@ -593,7 +632,7 @@ void PhysicsServer3D::_bind_methods() { BIND_ENUM_CONSTANT(SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING); BIND_ENUM_CONSTANT(SLIDER_JOINT_MAX); - ClassDB::bind_method(D_METHOD("joint_create_cone_twist", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_cone_twist); + ClassDB::bind_method(D_METHOD("joint_make_cone_twist", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_cone_twist); ClassDB::bind_method(D_METHOD("cone_twist_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::cone_twist_joint_set_param); ClassDB::bind_method(D_METHOD("cone_twist_joint_get_param", "joint", "param"), &PhysicsServer3D::cone_twist_joint_get_param); @@ -631,7 +670,7 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("joint_set_solver_priority", "joint", "priority"), &PhysicsServer3D::joint_set_solver_priority); ClassDB::bind_method(D_METHOD("joint_get_solver_priority", "joint"), &PhysicsServer3D::joint_get_solver_priority); - ClassDB::bind_method(D_METHOD("joint_create_generic_6dof", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_generic_6dof); + ClassDB::bind_method(D_METHOD("joint_make_generic_6dof", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_generic_6dof); ClassDB::bind_method(D_METHOD("generic_6dof_joint_set_param", "joint", "axis", "param", "value"), &PhysicsServer3D::generic_6dof_joint_set_param); ClassDB::bind_method(D_METHOD("generic_6dof_joint_get_param", "joint", "axis", "param"), &PhysicsServer3D::generic_6dof_joint_get_param); @@ -718,7 +757,6 @@ void PhysicsServer3D::_bind_methods() { } PhysicsServer3D::PhysicsServer3D() { - ERR_FAIL_COND(singleton != nullptr); singleton = this; } diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 303825f37c..e16857192c 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -44,12 +44,12 @@ protected: public: virtual Vector3 get_total_gravity() const = 0; - virtual float get_total_angular_damp() const = 0; - virtual float get_total_linear_damp() const = 0; + virtual real_t get_total_angular_damp() const = 0; + virtual real_t get_total_linear_damp() const = 0; virtual Vector3 get_center_of_mass() const = 0; virtual Basis get_principal_inertia_axes() const = 0; - virtual float get_inverse_mass() const = 0; // get the mass + virtual real_t get_inverse_mass() const = 0; // get the mass virtual Vector3 get_inverse_inertia() const = 0; // get density of this body space virtual Basis get_inverse_inertia_tensor() const = 0; // get density of this body space @@ -76,7 +76,7 @@ public: virtual Vector3 get_contact_local_position(int p_contact_idx) const = 0; virtual Vector3 get_contact_local_normal(int p_contact_idx) const = 0; - virtual float get_contact_impulse(int p_contact_idx) const = 0; + virtual real_t get_contact_impulse(int p_contact_idx) const = 0; virtual int get_contact_local_shape(int p_contact_idx) const = 0; virtual RID get_contact_collider(int p_contact_idx) const = 0; @@ -103,7 +103,7 @@ class PhysicsShapeQueryParameters3D : public Reference { RES shape_ref; RID shape; Transform transform; - float margin; + real_t margin; Set<RID> exclude; uint32_t collision_mask; @@ -122,8 +122,8 @@ public: void set_transform(const Transform &p_transform); Transform get_transform() const; - void set_margin(float p_margin); - float get_margin() const; + void set_margin(real_t p_margin); + real_t get_margin() const; void set_collision_mask(int p_collision_mask); int get_collision_mask() const; @@ -174,7 +174,7 @@ public: virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) = 0; - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeRestInfo { Vector3 point; @@ -185,11 +185,11 @@ public: Vector3 linear_velocity; //velocity at contact point }; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0; + virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0; - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0; @@ -240,7 +240,19 @@ public: SHAPE_CUSTOM, ///< Server-Implementation based custom shape, calling shape_create() with this value will result in an error }; - virtual RID shape_create(ShapeType p_shape) = 0; + RID shape_create(ShapeType p_shape); + + virtual RID plane_shape_create() = 0; + virtual RID ray_shape_create() = 0; + virtual RID sphere_shape_create() = 0; + virtual RID box_shape_create() = 0; + virtual RID capsule_shape_create() = 0; + virtual RID cylinder_shape_create() = 0; + virtual RID convex_polygon_shape_create() = 0; + virtual RID concave_polygon_shape_create() = 0; + virtual RID heightmap_shape_create() = 0; + virtual RID custom_shape_create() = 0; + virtual void shape_set_data(RID p_shape, const Variant &p_data) = 0; virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) = 0; @@ -344,7 +356,6 @@ public: virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0; virtual void area_set_ray_pickable(RID p_area, bool p_enable) = 0; - virtual bool area_is_ray_pickable(RID p_area) const = 0; /* BODY API */ @@ -357,7 +368,7 @@ public: BODY_MODE_CHARACTER }; - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) = 0; + virtual RID body_create() = 0; virtual void body_set_space(RID p_body, RID p_space) = 0; virtual RID body_get_space(RID p_body) const = 0; @@ -404,8 +415,8 @@ public: BODY_PARAM_MAX, }; - virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0; - virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0; + virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) = 0; + virtual real_t body_get_param(RID p_body, BodyParameter p_param) const = 0; virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) = 0; virtual real_t body_get_kinematic_safe_margin(RID p_body) const = 0; @@ -459,8 +470,8 @@ public: virtual int body_get_max_contacts_reported(RID p_body) const = 0; //missing remove - virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) = 0; - virtual float body_get_contacts_reported_depth_threshold(RID p_body) const = 0; + virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) = 0; + virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const = 0; virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0; virtual bool body_is_omitting_force_integration(RID p_body) const = 0; @@ -468,7 +479,6 @@ public: virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant()) = 0; virtual void body_set_ray_pickable(RID p_body, bool p_enable) = 0; - virtual bool body_is_ray_pickable(RID p_body) const = 0; // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0; @@ -495,7 +505,7 @@ public: virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { - float collision_depth; + real_t collision_depth; Vector3 collision_point; Vector3 collision_normal; Vector3 collider_velocity; @@ -506,11 +516,11 @@ public: Variant collider_metadata; }; - virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0; + virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0; /* SOFT BODY */ - virtual RID soft_body_create(bool p_init_sleeping = false) = 0; + virtual RID soft_body_create() = 0; virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) = 0; @@ -536,55 +546,59 @@ public: virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const = 0; virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) = 0; - virtual bool soft_body_is_ray_pickable(RID p_body) const = 0; virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) = 0; - virtual int soft_body_get_simulation_precision(RID p_body) = 0; + virtual int soft_body_get_simulation_precision(RID p_body) const = 0; virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) = 0; - virtual real_t soft_body_get_total_mass(RID p_body) = 0; + virtual real_t soft_body_get_total_mass(RID p_body) const = 0; virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) = 0; - virtual real_t soft_body_get_linear_stiffness(RID p_body) = 0; + virtual real_t soft_body_get_linear_stiffness(RID p_body) const = 0; - virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) = 0; - virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) = 0; + virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) = 0; + virtual real_t soft_body_get_angular_stiffness(RID p_body) const = 0; virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) = 0; - virtual real_t soft_body_get_volume_stiffness(RID p_body) = 0; + virtual real_t soft_body_get_volume_stiffness(RID p_body) const = 0; virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) = 0; - virtual real_t soft_body_get_pressure_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_pressure_coefficient(RID p_body) const = 0; virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) = 0; - virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) const = 0; virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) = 0; - virtual real_t soft_body_get_damping_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_damping_coefficient(RID p_body) const = 0; virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) = 0; - virtual real_t soft_body_get_drag_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_drag_coefficient(RID p_body) const = 0; virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) = 0; - virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) = 0; + virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const = 0; virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const = 0; virtual void soft_body_remove_all_pinned_points(RID p_body) = 0; virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) = 0; - virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) = 0; + virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const = 0; /* JOINT API */ enum JointType { - JOINT_PIN, - JOINT_HINGE, - JOINT_SLIDER, - JOINT_CONE_TWIST, - JOINT_6DOF + JOINT_TYPE_PIN, + JOINT_TYPE_HINGE, + JOINT_TYPE_SLIDER, + JOINT_TYPE_CONE_TWIST, + JOINT_TYPE_6DOF, + JOINT_TYPE_MAX, }; + virtual RID joint_create() = 0; + + virtual void joint_clear(RID p_joint) = 0; + virtual JointType joint_get_type(RID p_joint) const = 0; virtual void joint_set_solver_priority(RID p_joint, int p_priority) = 0; @@ -593,7 +607,7 @@ public: virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0; - virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0; + virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0; enum PinJointParam { PIN_JOINT_BIAS, @@ -601,8 +615,8 @@ public: PIN_JOINT_IMPULSE_CLAMP }; - virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) = 0; - virtual float pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0; + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) = 0; + virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0; virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) = 0; virtual Vector3 pin_joint_get_local_a(RID p_joint) const = 0; @@ -628,11 +642,11 @@ public: HINGE_JOINT_FLAG_MAX }; - virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0; - virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0; + virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0; - virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) = 0; - virtual float hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const = 0; + virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) = 0; + virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const = 0; virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) = 0; virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const = 0; @@ -665,10 +679,10 @@ public: }; - virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A - virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) = 0; - virtual float slider_joint_get_param(RID p_joint, SliderJointParam p_param) const = 0; + virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) = 0; + virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const = 0; enum ConeTwistJointParam { CONE_TWIST_JOINT_SWING_SPAN, @@ -679,10 +693,10 @@ public: CONE_TWIST_MAX }; - virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A - virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) = 0; - virtual float cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const = 0; + virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) = 0; + virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const = 0; enum G6DOFJointAxisParam { G6DOF_JOINT_LINEAR_LOWER_LIMIT, @@ -720,13 +734,13 @@ public: G6DOF_JOINT_FLAG_MAX }; - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A - virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, float p_value) = 0; - virtual float generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) = 0; + virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) = 0; + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const = 0; virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) = 0; - virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) = 0; + virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const = 0; /* QUERY API */ @@ -741,8 +755,10 @@ public: virtual void set_active(bool p_active) = 0; virtual void init() = 0; - virtual void step(float p_step) = 0; + virtual void step(real_t p_step) = 0; + virtual void sync() = 0; virtual void flush_queries() = 0; + virtual void end_sync() = 0; virtual void finish() = 0; virtual bool is_flushing_queries() const = 0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 58bcdf5802..deb230c4fb 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -36,6 +36,7 @@ #include "audio/audio_effect.h" #include "audio/audio_stream.h" #include "audio/effects/audio_effect_amplify.h" +#include "audio/effects/audio_effect_capture.h" #include "audio/effects/audio_effect_chorus.h" #include "audio/effects/audio_effect_compressor.h" #include "audio/effects/audio_effect_delay.h" @@ -60,6 +61,7 @@ #include "physics_2d/physics_server_2d_sw.h" #include "physics_2d/physics_server_2d_wrap_mt.h" #include "physics_3d/physics_server_3d_sw.h" +#include "physics_3d/physics_server_3d_wrap_mt.h" #include "physics_server_2d.h" #include "physics_server_3d.h" #include "rendering/renderer_compositor.h" @@ -75,11 +77,19 @@ ShaderTypes *shader_types = nullptr; PhysicsServer3D *_createGodotPhysics3DCallback() { - return memnew(PhysicsServer3DSW); + bool using_threads = GLOBAL_GET("physics/3d/run_on_thread"); + + PhysicsServer3D *physics_server = memnew(PhysicsServer3DSW(using_threads)); + + return memnew(PhysicsServer3DWrapMT(physics_server, using_threads)); } PhysicsServer2D *_createGodotPhysics2DCallback() { - return PhysicsServer2DWrapMT::init_server<PhysicsServer2DSW>(); + bool using_threads = GLOBAL_GET("physics/2d/run_on_thread"); + + PhysicsServer2D *physics_server = memnew(PhysicsServer2DSW(using_threads)); + + return memnew(PhysicsServer2DWrapMT(physics_server, using_threads)); } static bool has_server_feature_callback(const String &p_feature) { @@ -94,6 +104,16 @@ static bool has_server_feature_callback(const String &p_feature) { void preregister_server_types() { shader_types = memnew(ShaderTypes); + + GLOBAL_DEF("internationalization/rendering/text_driver", ""); + String text_driver_options; + for (int i = 0; i < TextServerManager::get_interface_count(); i++) { + if (i > 0) { + text_driver_options += ","; + } + text_driver_options += TextServerManager::get_interface_name(i); + } + ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options)); } void register_server_types() { @@ -166,6 +186,8 @@ void register_server_types() { ClassDB::register_class<AudioEffectRecord>(); ClassDB::register_class<AudioEffectSpectrumAnalyzer>(); ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>(); + + ClassDB::register_class<AudioEffectCapture>(); } ClassDB::register_virtual_class<RenderingDevice>(); diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 2d2847e6ca..e34bc9acb8 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -97,7 +97,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2 } } -void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item> &canvas_item_owner) { +void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item, true> &canvas_item_owner) { do { ysort_owner->ysort_children_count = -1; ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr; @@ -356,12 +356,12 @@ bool RendererCanvasCull::was_sdf_used() { return sdf_used; } -RID RendererCanvasCull::canvas_create() { +RID RendererCanvasCull::canvas_allocate() { + return canvas_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_initialize(RID p_rid) { Canvas *canvas = memnew(Canvas); - ERR_FAIL_COND_V(!canvas, RID()); - RID rid = canvas_owner.make_rid(canvas); - - return rid; + canvas_owner.initialize_rid(p_rid, canvas); } void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { @@ -393,11 +393,12 @@ void RendererCanvasCull::canvas_set_parent(RID p_canvas, RID p_parent, float p_s canvas->parent_scale = p_scale; } -RID RendererCanvasCull::canvas_item_create() { +RID RendererCanvasCull::canvas_item_allocate() { + return canvas_item_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_item_initialize(RID p_rid) { Item *canvas_item = memnew(Item); - ERR_FAIL_COND_V(!canvas_item, RID()); - - return canvas_item_owner.make_rid(canvas_item); + canvas_item_owner.initialize_rid(p_rid, canvas_item); } void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) { @@ -721,8 +722,10 @@ void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, static const int circle_points = 64; points.resize(circle_points); + const real_t circle_point_step = Math_TAU / circle_points; + for (int i = 0; i < circle_points; i++) { - float angle = (i / float(circle_points)) * 2 * Math_PI; + float angle = i * circle_point_step; points.write[i].x = Math::cos(angle) * p_radius; points.write[i].y = Math::sin(angle) * p_radius; points.write[i] += p_pos; @@ -1073,10 +1076,13 @@ void RendererCanvasCull::canvas_item_set_canvas_group_mode(RID p_item, RS::Canva } } -RID RendererCanvasCull::canvas_light_create() { +RID RendererCanvasCull::canvas_light_allocate() { + return canvas_light_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_light_initialize(RID p_rid) { RendererCanvasRender::Light *clight = memnew(RendererCanvasRender::Light); clight->light_internal = RSG::canvas_render->light_create(); - return canvas_light_owner.make_rid(clight); + return canvas_light_owner.initialize_rid(p_rid, clight); } void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { @@ -1266,10 +1272,13 @@ void RendererCanvasCull::canvas_light_set_shadow_smooth(RID p_light, float p_smo clight->shadow_smooth = p_smooth; } -RID RendererCanvasCull::canvas_light_occluder_create() { +RID RendererCanvasCull::canvas_light_occluder_allocate() { + return canvas_light_occluder_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_light_occluder_initialize(RID p_rid) { RendererCanvasRender::LightOccluderInstance *occluder = memnew(RendererCanvasRender::LightOccluderInstance); - return canvas_light_occluder_owner.make_rid(occluder); + return canvas_light_occluder_owner.initialize_rid(p_rid, occluder); } void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { @@ -1347,10 +1356,13 @@ void RendererCanvasCull::canvas_light_occluder_set_light_mask(RID p_occluder, in occluder->light_mask = p_mask; } -RID RendererCanvasCull::canvas_occluder_polygon_create() { +RID RendererCanvasCull::canvas_occluder_polygon_allocate() { + return canvas_light_occluder_polygon_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_occluder_polygon_initialize(RID p_rid) { LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon); occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create(); - return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); + return canvas_light_occluder_polygon_owner.initialize_rid(p_rid, occluder_poly); } void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { @@ -1391,8 +1403,11 @@ void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) { RSG::canvas_render->set_shadow_texture_size(p_size); } -RID RendererCanvasCull::canvas_texture_create() { - return RSG::storage->canvas_texture_create(); +RID RendererCanvasCull::canvas_texture_allocate() { + return RSG::storage->canvas_texture_allocate(); +} +void RendererCanvasCull::canvas_texture_initialize(RID p_rid) { + RSG::storage->canvas_texture_initialize(p_rid); } void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 7496a413ee..b71f8e5a9a 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -101,9 +101,9 @@ public: } }; - RID_PtrOwner<LightOccluderPolygon> canvas_light_occluder_polygon_owner; + RID_PtrOwner<LightOccluderPolygon, true> canvas_light_occluder_polygon_owner; - RID_PtrOwner<RendererCanvasRender::LightOccluderInstance> canvas_light_occluder_owner; + RID_PtrOwner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner; struct Canvas : public RendererViewport::CanvasBase { Set<RID> viewports; @@ -148,9 +148,9 @@ public: } }; - mutable RID_PtrOwner<Canvas> canvas_owner; - RID_PtrOwner<Item> canvas_item_owner; - RID_PtrOwner<RendererCanvasRender::Light> canvas_light_owner; + mutable RID_PtrOwner<Canvas, true> canvas_owner; + RID_PtrOwner<Item, true> canvas_item_owner; + RID_PtrOwner<RendererCanvasRender::Light, true> canvas_light_owner; bool disable_scale; bool sdf_used = false; @@ -168,13 +168,17 @@ public: bool was_sdf_used(); - RID canvas_create(); + RID canvas_allocate(); + void canvas_initialize(RID p_rid); + void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring); void canvas_set_modulate(RID p_canvas, const Color &p_color); void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale); void canvas_set_disable_scale(bool p_disable); - RID canvas_item_create(); + RID canvas_item_allocate(); + void canvas_item_initialize(RID p_rid); + void canvas_item_set_parent(RID p_item, RID p_parent); void canvas_item_set_visible(RID p_item, bool p_visible); @@ -222,7 +226,9 @@ public: void canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false); - RID canvas_light_create(); + RID canvas_light_allocate(); + void canvas_light_initialize(RID p_rid); + void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode); void canvas_light_attach_to_canvas(RID p_light, RID p_canvas); void canvas_light_set_enabled(RID p_light, bool p_enabled); @@ -246,7 +252,9 @@ public: void canvas_light_set_shadow_color(RID p_light, const Color &p_color); void canvas_light_set_shadow_smooth(RID p_light, float p_smooth); - RID canvas_light_occluder_create(); + RID canvas_light_occluder_allocate(); + void canvas_light_occluder_initialize(RID p_rid); + void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas); void canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled); void canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon); @@ -254,14 +262,18 @@ public: void canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform); void canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask); - RID canvas_occluder_polygon_create(); + RID canvas_occluder_polygon_allocate(); + void canvas_occluder_polygon_initialize(RID p_rid); + void canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed); void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode); void canvas_set_shadow_texture_size(int p_size); - RID canvas_texture_create(); + RID canvas_texture_allocate(); + void canvas_texture_initialize(RID p_rid); + void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture); void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess); diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp new file mode 100644 index 0000000000..0fdd864d47 --- /dev/null +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -0,0 +1,555 @@ +/*************************************************************************/ +/* cluster_builder_rd.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "cluster_builder_rd.h" +#include "servers/rendering/rendering_device.h" +#include "servers/rendering/rendering_server_globals.h" + +ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() { + RD::VertexFormatID vertex_format; + + { + Vector<RD::VertexAttribute> attributes; + { + RD::VertexAttribute va; + va.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; + va.stride = sizeof(float) * 3; + attributes.push_back(va); + } + vertex_format = RD::get_singleton()->vertex_format_create(attributes); + } + + { + Vector<String> versions; + versions.push_back(""); + cluster_render.cluster_render_shader.initialize(versions); + cluster_render.shader_version = cluster_render.cluster_render_shader.version_create(); + cluster_render.shader = cluster_render.cluster_render_shader.version_get_shader(cluster_render.shader_version, 0); + cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, RD::get_singleton()->framebuffer_format_create_empty(), vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState(), 0); + RD::PipelineMultisampleState ms; + ms.sample_count = RD::TEXTURE_SAMPLES_4; + cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, RD::get_singleton()->framebuffer_format_create_empty(), vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), ms, RD::PipelineDepthStencilState(), RD::PipelineColorBlendState(), 0); + } + { + Vector<String> versions; + versions.push_back(""); + cluster_store.cluster_store_shader.initialize(versions); + cluster_store.shader_version = cluster_store.cluster_store_shader.version_create(); + cluster_store.shader = cluster_store.cluster_store_shader.version_get_shader(cluster_store.shader_version, 0); + cluster_store.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_store.shader); + } + { + Vector<String> versions; + versions.push_back(""); + cluster_debug.cluster_debug_shader.initialize(versions); + cluster_debug.shader_version = cluster_debug.cluster_debug_shader.version_create(); + cluster_debug.shader = cluster_debug.cluster_debug_shader.version_get_shader(cluster_debug.shader_version, 0); + cluster_debug.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_debug.shader); + } + + { // SPHERE + static const uint32_t icosphere_vertex_count = 42; + static const float icosphere_vertices[icosphere_vertex_count * 3] = { + 0, 0, -1, 0.7236073, -0.5257253, -0.4472195, -0.276388, -0.8506492, -0.4472199, -0.8944262, 0, -0.4472156, -0.276388, 0.8506492, -0.4472199, 0.7236073, 0.5257253, -0.4472195, 0.276388, -0.8506492, 0.4472199, -0.7236073, -0.5257253, 0.4472195, -0.7236073, 0.5257253, 0.4472195, 0.276388, 0.8506492, 0.4472199, 0.8944262, 0, 0.4472156, 0, 0, 1, -0.1624555, -0.4999952, -0.8506544, 0.4253227, -0.3090114, -0.8506542, 0.2628688, -0.8090116, -0.5257377, 0.8506479, 0, -0.5257359, 0.4253227, 0.3090114, -0.8506542, -0.5257298, 0, -0.8506517, -0.6881894, -0.4999969, -0.5257362, -0.1624555, 0.4999952, -0.8506544, -0.6881894, 0.4999969, -0.5257362, 0.2628688, 0.8090116, -0.5257377, 0.9510579, -0.3090126, 0, 0.9510579, 0.3090126, 0, 0, -1, 0, 0.5877856, -0.8090167, 0, -0.9510579, -0.3090126, 0, -0.5877856, -0.8090167, 0, -0.5877856, 0.8090167, 0, -0.9510579, 0.3090126, 0, 0.5877856, 0.8090167, 0, 0, 1, 0, 0.6881894, -0.4999969, 0.5257362, -0.2628688, -0.8090116, 0.5257377, -0.8506479, 0, 0.5257359, -0.2628688, 0.8090116, 0.5257377, 0.6881894, 0.4999969, 0.5257362, 0.1624555, -0.4999952, 0.8506544, 0.5257298, 0, 0.8506517, -0.4253227, -0.3090114, 0.8506542, -0.4253227, 0.3090114, 0.8506542, 0.1624555, 0.4999952, 0.8506544 + }; + static const uint32_t icosphere_triangle_count = 80; + static const uint32_t icosphere_triangle_indices[icosphere_triangle_count * 3] = { + 0, 13, 12, 1, 13, 15, 0, 12, 17, 0, 17, 19, 0, 19, 16, 1, 15, 22, 2, 14, 24, 3, 18, 26, 4, 20, 28, 5, 21, 30, 1, 22, 25, 2, 24, 27, 3, 26, 29, 4, 28, 31, 5, 30, 23, 6, 32, 37, 7, 33, 39, 8, 34, 40, 9, 35, 41, 10, 36, 38, 38, 41, 11, 38, 36, 41, 36, 9, 41, 41, 40, 11, 41, 35, 40, 35, 8, 40, 40, 39, 11, 40, 34, 39, 34, 7, 39, 39, 37, 11, 39, 33, 37, 33, 6, 37, 37, 38, 11, 37, 32, 38, 32, 10, 38, 23, 36, 10, 23, 30, 36, 30, 9, 36, 31, 35, 9, 31, 28, 35, 28, 8, 35, 29, 34, 8, 29, 26, 34, 26, 7, 34, 27, 33, 7, 27, 24, 33, 24, 6, 33, 25, 32, 6, 25, 22, 32, 22, 10, 32, 30, 31, 9, 30, 21, 31, 21, 4, 31, 28, 29, 8, 28, 20, 29, 20, 3, 29, 26, 27, 7, 26, 18, 27, 18, 2, 27, 24, 25, 6, 24, 14, 25, 14, 1, 25, 22, 23, 10, 22, 15, 23, 15, 5, 23, 16, 21, 5, 16, 19, 21, 19, 4, 21, 19, 20, 4, 19, 17, 20, 17, 3, 20, 17, 18, 3, 17, 12, 18, 12, 2, 18, 15, 16, 5, 15, 13, 16, 13, 0, 16, 12, 14, 2, 12, 13, 14, 13, 1, 14 + }; + + Vector<uint8_t> vertex_data; + vertex_data.resize(sizeof(float) * icosphere_vertex_count * 3); + copymem(vertex_data.ptrw(), icosphere_vertices, vertex_data.size()); + + sphere_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data); + + Vector<uint8_t> index_data; + index_data.resize(sizeof(uint32_t) * icosphere_triangle_count * 3); + copymem(index_data.ptrw(), icosphere_triangle_indices, index_data.size()); + + sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data); + + Vector<RID> buffers; + buffers.push_back(sphere_vertex_buffer); + + sphere_vertex_array = RD::get_singleton()->vertex_array_create(icosphere_vertex_count, vertex_format, buffers); + + sphere_index_array = RD::get_singleton()->index_array_create(sphere_index_buffer, 0, icosphere_triangle_count * 3); + + float min_d = 1e20; + for (uint32_t i = 0; i < icosphere_triangle_count; i++) { + Vector3 vertices[3]; + for (uint32_t j = 0; j < 3; j++) { + uint32_t index = icosphere_triangle_indices[i * 3 + j]; + for (uint32_t k = 0; k < 3; k++) { + vertices[j][k] = icosphere_vertices[index * 3 + k]; + } + } + Plane p(vertices[0], vertices[1], vertices[2]); + min_d = MIN(Math::abs(p.d), min_d); + } + sphere_overfit = 1.0 / min_d; + } + + { // CONE + static const uint32_t cone_vertex_count = 99; + static const float cone_vertices[cone_vertex_count * 3] = { + 0, 1, -1, 0.1950903, 0.9807853, -1, 0.3826835, 0.9238795, -1, 0.5555703, 0.8314696, -1, 0.7071068, 0.7071068, -1, 0.8314697, 0.5555702, -1, 0.9238795, 0.3826834, -1, 0.9807853, 0.1950903, -1, 1, 0, -1, 0.9807853, -0.1950902, -1, 0.9238796, -0.3826833, -1, 0.8314697, -0.5555702, -1, 0.7071068, -0.7071068, -1, 0.5555702, -0.8314697, -1, 0.3826833, -0.9238796, -1, 0.1950901, -0.9807853, -1, -3.25841e-7, -1, -1, -0.1950907, -0.9807852, -1, -0.3826839, -0.9238793, -1, -0.5555707, -0.8314693, -1, -0.7071073, -0.7071063, -1, -0.83147, -0.5555697, -1, -0.9238799, -0.3826827, -1, 0, 0, 0, -0.9807854, -0.1950894, -1, -1, 9.65599e-7, -1, -0.9807851, 0.1950913, -1, -0.9238791, 0.3826845, -1, -0.8314689, 0.5555713, -1, -0.7071059, 0.7071077, -1, -0.5555691, 0.8314704, -1, -0.3826821, 0.9238801, -1, -0.1950888, 0.9807856, -1 + }; + static const uint32_t cone_triangle_count = 62; + static const uint32_t cone_triangle_indices[cone_triangle_count * 3] = { + 0, 23, 1, 1, 23, 2, 2, 23, 3, 3, 23, 4, 4, 23, 5, 5, 23, 6, 6, 23, 7, 7, 23, 8, 8, 23, 9, 9, 23, 10, 10, 23, 11, 11, 23, 12, 12, 23, 13, 13, 23, 14, 14, 23, 15, 15, 23, 16, 16, 23, 17, 17, 23, 18, 18, 23, 19, 19, 23, 20, 20, 23, 21, 21, 23, 22, 22, 23, 24, 24, 23, 25, 25, 23, 26, 26, 23, 27, 27, 23, 28, 28, 23, 29, 29, 23, 30, 30, 23, 31, 31, 23, 32, 32, 23, 0, 7, 15, 24, 32, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 3, 6, 7, 3, 7, 8, 9, 9, 10, 7, 10, 11, 7, 11, 12, 15, 12, 13, 15, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 24, 20, 21, 24, 21, 22, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 1, 3, 15, 17, 24, 17, 19, 24, 24, 26, 32, 26, 28, 32, 28, 30, 32, 32, 3, 7, 7, 11, 15, 32, 7, 24 + }; + + Vector<uint8_t> vertex_data; + vertex_data.resize(sizeof(float) * cone_vertex_count * 3); + copymem(vertex_data.ptrw(), cone_vertices, vertex_data.size()); + + cone_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data); + + Vector<uint8_t> index_data; + index_data.resize(sizeof(uint32_t) * cone_triangle_count * 3); + copymem(index_data.ptrw(), cone_triangle_indices, index_data.size()); + + cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data); + + Vector<RID> buffers; + buffers.push_back(cone_vertex_buffer); + + cone_vertex_array = RD::get_singleton()->vertex_array_create(cone_vertex_count, vertex_format, buffers); + + cone_index_array = RD::get_singleton()->index_array_create(cone_index_buffer, 0, cone_triangle_count * 3); + + float min_d = 1e20; + for (uint32_t i = 0; i < cone_triangle_count; i++) { + Vector3 vertices[3]; + int32_t zero_index = -1; + for (uint32_t j = 0; j < 3; j++) { + uint32_t index = cone_triangle_indices[i * 3 + j]; + for (uint32_t k = 0; k < 3; k++) { + vertices[j][k] = cone_vertices[index * 3 + k]; + } + if (vertices[j] == Vector3()) { + zero_index = j; + } + } + + if (zero_index != -1) { + Vector3 a = vertices[(zero_index + 1) % 3]; + Vector3 b = vertices[(zero_index + 2) % 3]; + Vector3 c = a + Vector3(0, 0, 1); + Plane p(a, b, c); + min_d = MIN(Math::abs(p.d), min_d); + } + } + cone_overfit = 1.0 / min_d; + } + + { // BOX + static const uint32_t box_vertex_count = 8; + static const float box_vertices[box_vertex_count * 3] = { + -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1 + }; + static const uint32_t box_triangle_count = 12; + static const uint32_t box_triangle_indices[box_triangle_count * 3] = { + 1, 2, 0, 3, 6, 2, 7, 4, 6, 5, 0, 4, 6, 0, 2, 3, 5, 7, 1, 3, 2, 3, 7, 6, 7, 5, 4, 5, 1, 0, 6, 4, 0, 3, 1, 5 + }; + + Vector<uint8_t> vertex_data; + vertex_data.resize(sizeof(float) * box_vertex_count * 3); + copymem(vertex_data.ptrw(), box_vertices, vertex_data.size()); + + box_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data); + + Vector<uint8_t> index_data; + index_data.resize(sizeof(uint32_t) * box_triangle_count * 3); + copymem(index_data.ptrw(), box_triangle_indices, index_data.size()); + + box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data); + + Vector<RID> buffers; + buffers.push_back(box_vertex_buffer); + + box_vertex_array = RD::get_singleton()->vertex_array_create(box_vertex_count, vertex_format, buffers); + + box_index_array = RD::get_singleton()->index_array_create(box_index_buffer, 0, box_triangle_count * 3); + } +} +ClusterBuilderSharedDataRD::~ClusterBuilderSharedDataRD() { + RD::get_singleton()->free(sphere_vertex_buffer); + RD::get_singleton()->free(sphere_index_buffer); + RD::get_singleton()->free(cone_vertex_buffer); + RD::get_singleton()->free(cone_index_buffer); + RD::get_singleton()->free(box_vertex_buffer); + RD::get_singleton()->free(box_index_buffer); + + cluster_render.cluster_render_shader.version_free(cluster_render.shader_version); + cluster_store.cluster_store_shader.version_free(cluster_store.shader_version); + cluster_debug.cluster_debug_shader.version_free(cluster_debug.shader_version); +} + +///////////////////////////// + +void ClusterBuilderRD::_clear() { + if (cluster_buffer.is_null()) { + return; //nothing to clear + } + RD::get_singleton()->free(cluster_buffer); + RD::get_singleton()->free(cluster_render_buffer); + RD::get_singleton()->free(element_buffer); + cluster_buffer = RID(); + cluster_render_buffer = RID(); + element_buffer = RID(); + + memfree(render_elements); + + render_elements = nullptr; + render_element_max = 0; + render_element_count = 0; + + RD::get_singleton()->free(framebuffer); + framebuffer = RID(); + + cluster_render_uniform_set = RID(); + cluster_store_uniform_set = RID(); +} + +void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer) { + ERR_FAIL_COND(p_max_elements == 0); + ERR_FAIL_COND(p_screen_size.x < 1); + ERR_FAIL_COND(p_screen_size.y < 1); + + _clear(); + + screen_size = p_screen_size; + + cluster_screen_size.width = (p_screen_size.width - 1) / cluster_size + 1; + cluster_screen_size.height = (p_screen_size.height - 1) / cluster_size + 1; + + max_elements_by_type = p_max_elements; + if (max_elements_by_type % 32) { //need to be 32 aligned + max_elements_by_type += 32 - (max_elements_by_type % 32); + } + + cluster_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (max_elements_by_type / 32 + 32) * ELEMENT_TYPE_MAX * 4; + + render_element_max = max_elements_by_type * ELEMENT_TYPE_MAX; + + uint32_t element_tag_bits_size = render_element_max / 32; + uint32_t element_tag_depth_bits_size = render_element_max; + cluster_render_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (element_tag_bits_size + element_tag_depth_bits_size) * 4; // tag bits (element was used) and tag depth (depth range in which it was used) + + cluster_render_buffer = RD::get_singleton()->storage_buffer_create(cluster_render_buffer_size); + cluster_buffer = RD::get_singleton()->storage_buffer_create(cluster_buffer_size); + + render_elements = (RenderElementData *)memalloc(sizeof(RenderElementData *) * render_element_max); + render_element_count = 0; + + element_buffer = RD::get_singleton()->storage_buffer_create(sizeof(RenderElementData) * render_element_max); + + uint32_t div_value = 1 << divisor; + if (use_msaa) { + framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value, RD::TEXTURE_SAMPLES_4); + } else { + framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value); + } + + { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 1; + u.ids.push_back(state_uniform); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.ids.push_back(element_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 3; + u.ids.push_back(cluster_render_buffer); + uniforms.push_back(u); + } + + cluster_render_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_render.shader, 0); + } + + { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 1; + u.ids.push_back(cluster_render_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.ids.push_back(cluster_buffer); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 3; + u.ids.push_back(element_buffer); + uniforms.push_back(u); + } + + cluster_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_store.shader, 0); + } + + if (p_color_buffer.is_valid()) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 1; + u.ids.push_back(cluster_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 2; + u.ids.push_back(p_color_buffer); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 3; + u.ids.push_back(p_depth_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 4; + u.ids.push_back(p_depth_buffer_sampler); + uniforms.push_back(u); + } + + debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_debug.shader, 0); + } else { + debug_uniform_set = RID(); + } +} + +void ClusterBuilderRD::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) { + view_xform = p_view_transform.affine_inverse(); + projection = p_cam_projection; + z_near = projection.get_z_near(); + z_far = projection.get_z_far(); + orthogonal = p_cam_projection.is_orthogonal(); + adjusted_projection = projection; + if (!orthogonal) { + adjusted_projection.adjust_perspective_znear(0.0001); + } + + CameraMatrix correction; + correction.set_depth_correction(p_flip_y); + projection = correction * projection; + adjusted_projection = correction * adjusted_projection; + + //reset counts + render_element_count = 0; + for (uint32_t i = 0; i < ELEMENT_TYPE_MAX; i++) { + cluster_count_by_type[i] = 0; + } +} + +void ClusterBuilderRD::bake_cluster() { + RENDER_TIMESTAMP(">Bake Cluster"); + + RD::get_singleton()->draw_command_begin_label("Bake Light Cluster"); + + //clear cluster buffer + RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); + + if (render_element_count > 0) { + //clear render buffer + RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size, RD::BARRIER_MASK_RASTER); + + { //fill state uniform + + StateUniform state; + + RendererStorageRD::store_camera(adjusted_projection, state.projection); + state.inv_z_far = 1.0 / z_far; + state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size); + state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less + + state.cluster_screen_width = cluster_screen_size.x; + state.cluster_depth_offset = (render_element_max / 32); + state.cluster_data_size = state.cluster_depth_offset + render_element_max; + + RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); + } + + //update instances + + RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); + + RENDER_TIMESTAMP("Render Elements"); + + //render elements + { + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD); + ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {}; + + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shared->cluster_render.shader_pipelines[use_msaa ? ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_MSAA : ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_NORMAL]); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, cluster_render_uniform_set, 0); + + for (uint32_t i = 0; i < render_element_count;) { + push_constant.base_index = i; + switch (render_elements[i].type) { + case ELEMENT_TYPE_OMNI_LIGHT: { + RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array); + RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array); + } break; + case ELEMENT_TYPE_SPOT_LIGHT: { + RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array); + RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array); + } break; + case ELEMENT_TYPE_DECAL: + case ELEMENT_TYPE_REFLECTION_PROBE: { + RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->box_vertex_array); + RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->box_index_array); + } break; + } + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterRender::PushConstant)); + + uint32_t instances = 1; +#if 0 + for (uint32_t j = i+1; j < element_count; j++) { + if (elements[i].type!=elements[j].type) { + break; + } + instances++; + } +#endif + RD::get_singleton()->draw_list_draw(draw_list, true, instances); + i += instances; + } + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE); + } + //store elements + RENDER_TIMESTAMP("Pack Elements"); + + { + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_store.shader_pipeline); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cluster_store_uniform_set, 0); + + ClusterBuilderSharedDataRD::ClusterStore::PushConstant push_constant; + push_constant.cluster_render_data_size = render_element_max / 32 + render_element_max; + push_constant.max_render_element_count_div_32 = render_element_max / 32; + push_constant.cluster_screen_size[0] = cluster_screen_size.x; + push_constant.cluster_screen_size[1] = cluster_screen_size.y; + push_constant.render_element_count_div_32 = render_element_count > 0 ? (render_element_count - 1) / 32 + 1 : 0; + push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32; + push_constant.pad1 = 0; + push_constant.pad2 = 0; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterStore::PushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1); + + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); + } + } else { + RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); + } + RENDER_TIMESTAMP("<Bake Cluster"); + RD::get_singleton()->draw_command_end_label(); +} + +void ClusterBuilderRD::debug(ElementType p_element) { + ERR_FAIL_COND(debug_uniform_set.is_null()); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_debug.shader_pipeline); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0); + + ClusterBuilderSharedDataRD::ClusterDebug::PushConstant push_constant; + push_constant.screen_size[0] = screen_size.x; + push_constant.screen_size[1] = screen_size.y; + push_constant.cluster_screen_size[0] = cluster_screen_size.x; + push_constant.cluster_screen_size[1] = cluster_screen_size.y; + push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size); + push_constant.cluster_type = p_element; + push_constant.orthogonal = orthogonal; + push_constant.z_far = z_far; + push_constant.z_near = z_near; + push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterDebug::PushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1); + + RD::get_singleton()->compute_list_end(); +} + +RID ClusterBuilderRD::get_cluster_buffer() const { + return cluster_buffer; +} + +uint32_t ClusterBuilderRD::get_cluster_size() const { + return cluster_size; +} + +uint32_t ClusterBuilderRD::get_max_cluster_elements() const { + return max_elements_by_type; +} + +void ClusterBuilderRD::set_shared(ClusterBuilderSharedDataRD *p_shared) { + shared = p_shared; +} + +ClusterBuilderRD::ClusterBuilderRD() { + state_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(StateUniform)); +} + +ClusterBuilderRD::~ClusterBuilderRD() { + _clear(); + RD::get_singleton()->free(state_uniform); +} diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h new file mode 100644 index 0000000000..dc1707b534 --- /dev/null +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -0,0 +1,378 @@ +/*************************************************************************/ +/* cluster_builder_rd.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CLUSTER_BUILDER_RD_H +#define CLUSTER_BUILDER_RD_H + +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" +#include "servers/rendering/renderer_rd/shaders/cluster_debug.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/cluster_render.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/cluster_store.glsl.gen.h" + +class ClusterBuilderSharedDataRD { + friend class ClusterBuilderRD; + + RID sphere_vertex_buffer; + RID sphere_vertex_array; + RID sphere_index_buffer; + RID sphere_index_array; + float sphere_overfit = 0.0; //because an icosphere is not a perfect sphere, we need to enlarge it to cover the sphere area + + RID cone_vertex_buffer; + RID cone_vertex_array; + RID cone_index_buffer; + RID cone_index_array; + float cone_overfit = 0.0; //because an cone mesh is not a perfect sphere, we need to enlarge it to cover the actual cone area + + RID box_vertex_buffer; + RID box_vertex_array; + RID box_index_buffer; + RID box_index_array; + + enum Divisor { + DIVISOR_1, + DIVISOR_2, + DIVISOR_4, + }; + + struct ClusterRender { + struct PushConstant { + uint32_t base_index; + uint32_t pad0; + uint32_t pad1; + uint32_t pad2; + }; + + ClusterRenderShaderRD cluster_render_shader; + RID shader_version; + RID shader; + enum PipelineVersion { + PIPELINE_NORMAL, + PIPELINE_MSAA, + PIPELINE_MAX + }; + + RID shader_pipelines[PIPELINE_MAX]; + } cluster_render; + + struct ClusterStore { + struct PushConstant { + uint32_t cluster_render_data_size; // how much data for a single cluster takes + uint32_t max_render_element_count_div_32; //divided by 32 + uint32_t cluster_screen_size[2]; + uint32_t render_element_count_div_32; //divided by 32 + uint32_t max_cluster_element_count_div_32; //divided by 32 + uint32_t pad1; + uint32_t pad2; + }; + + ClusterStoreShaderRD cluster_store_shader; + RID shader_version; + RID shader; + RID shader_pipeline; + } cluster_store; + + struct ClusterDebug { + struct PushConstant { + uint32_t screen_size[2]; + uint32_t cluster_screen_size[2]; + + uint32_t cluster_shift; + uint32_t cluster_type; + float z_near; + float z_far; + + uint32_t orthogonal; + uint32_t max_cluster_element_count_div_32; + uint32_t pad1; + uint32_t pad2; + }; + + ClusterDebugShaderRD cluster_debug_shader; + RID shader_version; + RID shader; + RID shader_pipeline; + } cluster_debug; + +public: + ClusterBuilderSharedDataRD(); + ~ClusterBuilderSharedDataRD(); +}; + +class ClusterBuilderRD { +public: + enum LightType { + LIGHT_TYPE_OMNI, + LIGHT_TYPE_SPOT + }; + + enum BoxType { + BOX_TYPE_REFLECTION_PROBE, + BOX_TYPE_DECAL, + }; + + enum ElementType { + ELEMENT_TYPE_OMNI_LIGHT, + ELEMENT_TYPE_SPOT_LIGHT, + ELEMENT_TYPE_DECAL, + ELEMENT_TYPE_REFLECTION_PROBE, + ELEMENT_TYPE_MAX, + + }; + +private: + ClusterBuilderSharedDataRD *shared = nullptr; + + struct RenderElementData { + uint32_t type; //0-4 + uint32_t touches_near; + uint32_t touches_far; + uint32_t original_index; + float transform_inv[12]; //transposed transform for less space + float scale[3]; + uint32_t pad; + }; + + uint32_t cluster_count_by_type[ELEMENT_TYPE_MAX] = {}; + uint32_t max_elements_by_type = 0; + + RenderElementData *render_elements = nullptr; + uint32_t render_element_count = 0; + uint32_t render_element_max = 0; + + Transform view_xform; + CameraMatrix adjusted_projection; + CameraMatrix projection; + float z_far = 0; + float z_near = 0; + bool orthogonal = false; + + enum Divisor { + DIVISOR_1, + DIVISOR_2, + DIVISOR_4, + }; + + uint32_t cluster_size = 32; + bool use_msaa = true; + Divisor divisor = DIVISOR_4; + + Size2i screen_size; + Size2i cluster_screen_size; + + RID framebuffer; + RID cluster_render_buffer; //used for creating + RID cluster_buffer; //used for rendering + RID element_buffer; //used for storing, to hint element touches far plane or near plane + uint32_t cluster_render_buffer_size = 0; + uint32_t cluster_buffer_size = 0; + + RID cluster_render_uniform_set; + RID cluster_store_uniform_set; + + //persistent data + + void _clear(); + + struct StateUniform { + float projection[16]; + float inv_z_far; + uint32_t screen_to_clusters_shift; // shift to obtain coordinates in block indices + uint32_t cluster_screen_width; // + uint32_t cluster_data_size; // how much data for a single cluster takes + uint32_t cluster_depth_offset; + uint32_t pad0; + uint32_t pad1; + uint32_t pad2; + }; + + RID state_uniform; + + RID debug_uniform_set; + +public: + void setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer); + + void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y); + + _FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) { + if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) { + return; //max number elements reached + } + if (p_type == LIGHT_TYPE_SPOT && cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT] == max_elements_by_type) { + return; //max number elements reached + } + + RenderElementData &e = render_elements[render_element_count]; + + Transform xform = view_xform * p_transform; + + float radius = xform.basis.get_uniform_scale(); + if (radius > 0.98 || radius < 1.02) { + xform.basis.orthonormalize(); + } + + radius *= p_radius; + + if (p_type == LIGHT_TYPE_OMNI) { + radius *= shared->sphere_overfit; // overfit icosphere + + //omni + float depth = -xform.origin.z; + if (orthogonal) { + e.touches_near = (depth - radius) < z_near; + } else { + //contains camera inside light + float radius2 = radius * shared->sphere_overfit; // overfit again for outer size (camera may be outside actual sphere but behind an icosphere vertex) + e.touches_near = xform.origin.length_squared() < radius2 * radius2; + } + + e.touches_far = (depth + radius) > z_far; + e.scale[0] = radius; + e.scale[1] = radius; + e.scale[2] = radius; + e.type = ELEMENT_TYPE_OMNI_LIGHT; + e.original_index = cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]; + + RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv); + + cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]++; + + } else { + //spot + radius *= shared->cone_overfit; // overfit icosphere + + real_t len = Math::tan(Math::deg2rad(p_spot_aperture)) * radius; + //approximate, probably better to use a cone support function + float max_d = -1e20; + float min_d = 1e20; +#define CONE_MINMAX(m_x, m_y) \ + { \ + float d = -xform.xform(Vector3(len * m_x, len * m_y, -radius)).z; \ + min_d = MIN(d, min_d); \ + max_d = MAX(d, max_d); \ + } + + CONE_MINMAX(1, 1); + CONE_MINMAX(-1, 1); + CONE_MINMAX(-1, -1); + CONE_MINMAX(1, -1); + + if (orthogonal) { + e.touches_near = min_d < z_near; + } else { + //contains camera inside light + Plane base_plane(xform.origin, -xform.basis.get_axis(Vector3::AXIS_Z)); + float dist = base_plane.distance_to(Vector3()); + if (dist >= 0 && dist < radius) { + //inside, check angle + float angle = Math::rad2deg(Math::acos((-xform.origin.normalized()).dot(-xform.basis.get_axis(Vector3::AXIS_Z)))); + e.touches_near = angle < p_spot_aperture * 1.05; //overfit aperture a little due to cone overfit + } else { + e.touches_near = false; + } + } + + e.touches_far = max_d > z_far; + + e.scale[0] = len * shared->cone_overfit; + e.scale[1] = len * shared->cone_overfit; + e.scale[2] = radius; + + e.type = ELEMENT_TYPE_SPOT_LIGHT; + e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; //use omni since they share index + + RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv); + + cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]++; + } + + render_element_count++; + } + + _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform &p_transform, const Vector3 &p_half_extents) { + if (p_box_type == BOX_TYPE_DECAL && cluster_count_by_type[ELEMENT_TYPE_DECAL] == max_elements_by_type) { + return; //max number elements reached + } + if (p_box_type == BOX_TYPE_REFLECTION_PROBE && cluster_count_by_type[ELEMENT_TYPE_REFLECTION_PROBE] == max_elements_by_type) { + return; //max number elements reached + } + + RenderElementData &e = render_elements[render_element_count]; + Transform xform = view_xform * p_transform; + + //extract scale and scale the matrix by it, makes things simpler + Vector3 scale = p_half_extents; + for (uint32_t i = 0; i < 3; i++) { + float s = xform.basis.elements[i].length(); + scale[i] *= s; + xform.basis.elements[i] /= s; + }; + + float box_depth = Math::abs(xform.basis.xform_inv(Vector3(0, 0, -1)).dot(scale)); + float depth = -xform.origin.z; + + if (orthogonal) { + e.touches_near = depth - box_depth < z_near; + } else { + //contains camera inside box + Vector3 inside = xform.xform_inv(Vector3(0, 0, 0)).abs(); + e.touches_near = inside.x < scale.x && inside.y < scale.y && inside.z < scale.z; + } + + e.touches_far = depth + box_depth > z_far; + + e.scale[0] = scale.x; + e.scale[1] = scale.y; + e.scale[2] = scale.z; + + e.type = (p_box_type == BOX_TYPE_DECAL) ? ELEMENT_TYPE_DECAL : ELEMENT_TYPE_REFLECTION_PROBE; + e.original_index = cluster_count_by_type[e.type]; + + RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv); + + cluster_count_by_type[e.type]++; + render_element_count++; + } + + void bake_cluster(); + void debug(ElementType p_element); + + RID get_cluster_buffer() const; + uint32_t get_cluster_size() const; + uint32_t get_max_cluster_elements() const; + + void set_shared(ClusterBuilderSharedDataRD *p_shared); + + ClusterBuilderRD(); + ~ClusterBuilderRD(); +}; + +#endif // CLUSTER_BUILDER_H diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 6e1d61ff94..bc304aedd8 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -299,15 +299,12 @@ void EffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const copy.push_constant.target[0] = p_rect.position.x; copy.push_constant.target[1] = p_rect.position.y; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -322,15 +319,12 @@ void EffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, copy.push_constant.target[1] = 0; copy.push_constant.camera_z_far = p_lod; - int32_t x_groups = (p_panorama_size.width - 1) / 8 + 1; - int32_t y_groups = (p_panorama_size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -349,15 +343,12 @@ void EffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_ copy.push_constant.camera_z_far = p_z_far; copy.push_constant.camera_z_near = p_z_near; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -374,15 +365,12 @@ void EffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, copy.push_constant.target[0] = p_rect.position.x; copy.push_constant.target[1] = p_rect.position.y; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -400,14 +388,11 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i copy.push_constant.set_color[2] = p_color.b; copy.push_constant.set_color[3] = p_color.a; - int32_t x_groups = (p_region.size.width - 1) / 8 + 1; - int32_t y_groups = (p_region.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -420,8 +405,6 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back copy.push_constant.section[2] = p_region.size.width; copy.push_constant.section[3] = p_region.size.height; - int32_t x_groups = (p_region.size.width - 1) / 8 + 1; - int32_t y_groups = (p_region.size.height - 1) / 8 + 1; //HORIZONTAL RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]); @@ -431,7 +414,7 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL; RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -442,7 +425,7 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back copy.push_constant.flags = base_flags; RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -452,9 +435,6 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; uint32_t base_flags = 0; - int32_t x_groups = (p_size.width + 7) / 8; - int32_t y_groups = (p_size.height + 7) / 8; - copy.push_constant.section[2] = p_size.x; copy.push_constant.section[3] = p_size.y; @@ -479,16 +459,13 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; - int32_t y_groups = (p_screen_size.height - 1) / 8 + 1; - { //scale color and depth to half ssr_scale.push_constant.camera_z_far = p_camera.get_z_far(); ssr_scale.push_constant.camera_z_near = p_camera.get_z_near(); @@ -506,7 +483,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); } @@ -547,7 +524,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R } RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); } if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { @@ -585,7 +562,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -600,7 +577,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); } RD::get_singleton()->compute_list_end(); @@ -609,9 +586,6 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; - int32_t y_groups = (p_screen_size.height - 1) / 8 + 1; - Plane p = p_camera.xform4(Plane(1, 0, -1, 1)); p.normal /= p.d; float unit_size = p.normal.x; @@ -635,7 +609,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -646,7 +620,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept sss.push_constant.vertical = true; RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -690,39 +664,33 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S copy.push_constant.section[2] = p_size.width; copy.push_constant.section[3] = p_size.height; - int32_t x_groups = (p_size.width - 1) / 8 + 1; - int32_t y_groups = (p_size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } -void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { +void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) { CopyToDPPushConstant push_constant; - push_constant.screen_size[0] = p_rect.size.x; - push_constant.screen_size[1] = p_rect.size.y; - push_constant.dest_offset[0] = p_rect.position.x; - push_constant.dest_offset[1] = p_rect.position.y; - push_constant.bias = p_bias; + push_constant.screen_rect[0] = p_rect.position.x; + push_constant.screen_rect[1] = p_rect.position.y; + push_constant.screen_rect[2] = p_rect.size.width; + push_constant.screen_rect[3] = p_rect.size.height; push_constant.z_far = p_z_far; push_constant.z_near = p_z_near; push_constant.z_flip = p_dp_flip; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER); } void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { @@ -807,10 +775,7 @@ void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_ RD::get_singleton()->compute_list_set_push_constant(compute_list, &luminance_reduce.push_constant, sizeof(LuminanceReducePushConstant)); - int32_t x_groups = (luminance_reduce.push_constant.source_size[0] - 1) / 8 + 1; - int32_t y_groups = (luminance_reduce.push_constant.source_size[1] - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, luminance_reduce.push_constant.source_size[0], luminance_reduce.push_constant.source_size[1], 1); luminance_reduce.push_constant.source_size[0] = MAX(luminance_reduce.push_constant.source_size[0] / 8, 1); luminance_reduce.push_constant.source_size[1] = MAX(luminance_reduce.push_constant.source_size[1] / 8, 1); @@ -851,14 +816,12 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_texture), 1); - int32_t x_groups = (p_base_texture_size.x - 1) / 8 + 1; - int32_t y_groups = (p_base_texture_size.y - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x; bokeh.push_constant.size[1] = p_base_texture_size.y; RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { @@ -875,8 +838,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); - x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; - y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; bokeh.push_constant.half_size = true; @@ -890,7 +851,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //third pass @@ -906,7 +867,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); RD::get_singleton()->compute_list_add_barrier(compute_list); if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { @@ -917,8 +878,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture2), 1); - x_groups = (p_base_texture_size.x - 1) / 8 + 1; - y_groups = (p_base_texture_size.y - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x; bokeh.push_constant.size[1] = p_base_texture_size.y; bokeh.push_constant.half_size = false; @@ -926,7 +885,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1); } } else { //circle @@ -944,15 +903,13 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); - x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; - y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; bokeh.push_constant.half_size = true; RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //circle is just one pass, then upscale @@ -964,8 +921,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1); - x_groups = (p_base_texture_size.x - 1) / 8 + 1; - y_groups = (p_base_texture_size.y - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x; bokeh.push_constant.size[1] = p_base_texture_size.y; bokeh.push_constant.half_size = false; @@ -973,7 +928,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1); } RD::get_singleton()->compute_list_end(); @@ -998,20 +953,20 @@ void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 2); RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant)); - int x_groups = ((p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = ((p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; + Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)); - RD::get_singleton()->compute_list_dispatch(p_compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1); } RD::get_singleton()->compute_list_add_barrier(p_compute_list); } void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &p_depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - + RD::get_singleton()->draw_command_begin_label("SSAO"); /* FIRST PASS */ // Downsample and deinterleave the depth buffer. { + RD::get_singleton()->draw_command_begin_label("Downsample Depth"); if (p_invalidate_uniform_sets) { Vector<RD::Uniform> uniforms; { @@ -1074,16 +1029,17 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep } RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant)); - int x_groups = (MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = (MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; + Size2i size(MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)), MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1))); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->draw_command_end_label(); // Downsample SSAO } /* SECOND PASS */ // Sample SSAO { + RD::get_singleton()->draw_command_begin_label("Gather Samples"); ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; @@ -1184,6 +1140,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep } if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) { + RD::get_singleton()->draw_command_begin_label("Generate Importance Map"); ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; ssao.importance_map_push_constant.intensity = p_settings.intensity; @@ -1192,21 +1149,19 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]); gather_ssao(compute_list, p_ao_pong_slices, p_settings, true); //generate importance map - int x_groups = (p_settings.quarter_screen_size.x - 1) / 8 + 1; - int y_groups = (p_settings.quarter_screen_size.y - 1) / 8 + 1; RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //process importance map A RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map_pong), 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //process Importance Map B RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]); @@ -1214,21 +1169,24 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.counter_uniform_set, 2); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_ADAPTIVE]); + RD::get_singleton()->draw_command_end_label(); // Importance Map } else { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]); } gather_ssao(compute_list, p_ao_slices, p_settings, false); + RD::get_singleton()->draw_command_end_label(); // Gather SSAO } // /* THIRD PASS */ // // Blur // { + RD::get_singleton()->draw_command_begin_label("Edge Aware Blur"); ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness; ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; @@ -1268,22 +1226,22 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep } RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant)); - int x_groups = ((p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = ((p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + Size2i size(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1); } if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) { RD::get_singleton()->compute_list_add_barrier(compute_list); } } + RD::get_singleton()->draw_command_end_label(); // Blur } /* FOURTH PASS */ // Interleave buffers // back to full size { + RD::get_singleton()->draw_command_begin_label("Interleave Buffers"); ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness; ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x; ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y; @@ -1307,17 +1265,15 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant)); - int x_groups = (p_settings.full_screen_size.x - 1) / 8 + 1; - int y_groups = (p_settings.full_screen_size.y - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->draw_command_end_label(); // Interleave } - - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->draw_command_end_label(); //SSAO + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); //wait for upcoming transfer int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, false); + RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier } void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) { @@ -1330,12 +1286,9 @@ void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_normal), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_roughness), 1); - int x_groups = (p_size.x - 1) / 8 + 1; - int y_groups = (p_size.y - 1) / 8 + 1; - RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness_limiter.push_constant, sizeof(RoughnessLimiterPushConstant)); //not used but set anyway - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.x, p_size.y, 1); RD::get_singleton()->compute_list_end(); } @@ -1448,7 +1401,7 @@ void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_ RD::get_singleton()->draw_list_draw(draw_list, true); } -void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) { +void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { ResolvePushConstant push_constant; push_constant.screen_size[0] = p_screen_size.x; push_constant.screen_size[1] = p_screen_size.y; @@ -1465,54 +1418,9 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) { - uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 }; - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_source_shadow, p_dest_shadow), 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); -} -void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) { - uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 }; - - switch (p_filter) { - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED: - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW: { - push_constant[5] = 0; - } break; - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM: { - push_constant[5] = 9; - } break; - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH: { - push_constant[5] = 18; - } break; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_FILTER]); - if (p_vertical) { - push_constant[6] = 1; - push_constant[7] = 0; - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_shadow, p_backing_shadow), 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); - } - if (p_vertical && p_horizontal) { - RD::get_singleton()->compute_list_add_barrier(compute_list); - } - if (p_horizontal) { - push_constant[6] = 0; - push_constant[7] = 1; - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_backing_shadow, p_shadow), 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); - } + RD::get_singleton()->compute_list_end(p_barrier); } void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { @@ -1678,8 +1586,12 @@ EffectsRD::EffectsRD() { cube_to_dp.shader.initialize(copy_modes); cube_to_dp.shader_version = cube_to_dp.shader.version_create(); - - cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0)); + RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0); + RD::PipelineDepthStencilState dss; + dss.enable_depth_test = true; + dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS; + dss.enable_depth_write = true; + cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); } { @@ -1776,7 +1688,7 @@ EffectsRD::EffectsRD() { } } - RD::get_singleton()->buffer_update(ssao.gather_constants_buffer, 0, sizeof(SSAOGatherConstants), &gather_constants, false); + RD::get_singleton()->buffer_update(ssao.gather_constants_buffer, 0, sizeof(SSAOGatherConstants), &gather_constants); } { Vector<String> ssao_modes; @@ -1795,7 +1707,8 @@ EffectsRD::EffectsRD() { } ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t)); int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, false); + RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero); + RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter"); Vector<RD::Uniform> uniforms; { @@ -1806,6 +1719,7 @@ EffectsRD::EffectsRD() { uniforms.push_back(u); } ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2); + RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set"); } { Vector<String> ssao_modes; @@ -1834,7 +1748,7 @@ EffectsRD::EffectsRD() { ssao.interleave_shader_version = ssao.interleave_shader.version_create(); for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) { ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE)); - + RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i)); pipeline++; } } @@ -1867,7 +1781,7 @@ EffectsRD::EffectsRD() { { // Initialize cubemap filter - filter.use_high_quality = GLOBAL_GET("rendering/quality/reflections/fast_filter_high_quality"); + filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality"); Vector<String> cubemap_filter_modes; cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n"); @@ -1883,10 +1797,10 @@ EffectsRD::EffectsRD() { if (filter.use_high_quality) { filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs)); - RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0], false); + RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]); } else { filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs)); - RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0], false); + RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]); } Vector<RD::Uniform> uniforms; @@ -2005,20 +1919,6 @@ EffectsRD::EffectsRD() { } { - Vector<String> shadow_reduce_modes; - shadow_reduce_modes.push_back("\n#define MODE_REDUCE\n"); - shadow_reduce_modes.push_back("\n#define MODE_FILTER\n"); - - shadow_reduce.shader.initialize(shadow_reduce_modes); - - shadow_reduce.shader_version = shadow_reduce.shader.version_create(); - - for (int i = 0; i < SHADOW_REDUCE_MAX; i++) { - shadow_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(shadow_reduce.shader.version_get_shader(shadow_reduce.shader_version, i)); - } - } - - { Vector<String> sort_modes; sort_modes.push_back("\n#define MODE_SORT_BLOCK\n"); sort_modes.push_back("\n#define MODE_SORT_STEP\n"); @@ -2039,12 +1939,14 @@ EffectsRD::EffectsRD() { sampler.max_lod = 0; default_sampler = RD::get_singleton()->sampler_create(sampler); + RD::get_singleton()->set_resource_name(default_sampler, "Default Linear Sampler"); sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler.max_lod = 1e20; default_mipmap_sampler = RD::get_singleton()->sampler_create(sampler); + RD::get_singleton()->set_resource_name(default_mipmap_sampler, "Default MipMap Sampler"); { //create index array for copy shaders Vector<uint8_t> pv; @@ -2104,5 +2006,4 @@ EffectsRD::~EffectsRD() { ssr_scale.shader.version_free(ssr_scale.shader_version); sss.shader.version_free(sss.shader_version); tonemap.shader.version_free(tonemap.shader_version); - shadow_reduce.shader.version_free(shadow_reduce.shader_version); } diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index e2cdd0c3d8..1ba25e301b 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -46,7 +46,6 @@ #include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h" @@ -234,18 +233,17 @@ class EffectsRD { } luminance_reduce; struct CopyToDPPushConstant { - int32_t screen_size[2]; - int32_t dest_offset[2]; - float bias; float z_far; float z_near; uint32_t z_flip; + uint32_t pad; + float screen_rect[4]; }; struct CoptToDP { CubeToDpShaderRD shader; RID shader_version; - RID pipeline; + PipelineCacheRD pipeline; } cube_to_dp; struct BokehPushConstant { @@ -598,18 +596,6 @@ class EffectsRD { RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels } resolve; - enum ShadowReduceMode { - SHADOW_REDUCE_REDUCE, - SHADOW_REDUCE_FILTER, - SHADOW_REDUCE_MAX - }; - - struct ShadowReduce { - ShadowReduceShaderRD shader; - RID shader_version; - RID pipelines[SHADOW_REDUCE_MAX]; - } shadow_reduce; - enum SortMode { SORT_MODE_BLOCK, SORT_MODE_STEP, @@ -687,7 +673,7 @@ public: void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); - void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip); + void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); @@ -764,10 +750,7 @@ public: void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection); void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); - void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples); - - void reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RenderingDevice::ComputeListID compute_list); - void filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RS::EnvVolumetricFogShadowFilter p_filter, RenderingDevice::ComputeListID compute_list, bool p_vertical = true, bool p_horizontal = true); + void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void sort_buffer(RID p_uniform_set, int p_size); diff --git a/servers/rendering/renderer_rd/light_cluster_builder.cpp b/servers/rendering/renderer_rd/light_cluster_builder.cpp deleted file mode 100644 index bb807ca4ca..0000000000 --- a/servers/rendering/renderer_rd/light_cluster_builder.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************/ -/* light_cluster_builder.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "light_cluster_builder.h" - -void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection) { - view_xform = p_view_transform; - projection = p_cam_projection; - z_near = -projection.get_z_near(); - z_far = -projection.get_z_far(); - - //reset counts - light_count = 0; - refprobe_count = 0; - decal_count = 0; - item_count = 0; - sort_id_count = 0; -} - -void LightClusterBuilder::bake_cluster() { - float slice_depth = (z_near - z_far) / depth; - - uint8_t *cluster_dataw = cluster_data.ptrw(); - Cell *cluster_data_ptr = (Cell *)cluster_dataw; - //clear the cluster - zeromem(cluster_data_ptr, (width * height * depth * sizeof(Cell))); - - /* Step 1, create cell positions and count them */ - - for (uint32_t i = 0; i < item_count; i++) { - const Item &item = items[i]; - - int from_slice = Math::floor((z_near - (item.aabb.position.z + item.aabb.size.z)) / slice_depth); - int to_slice = Math::floor((z_near - item.aabb.position.z) / slice_depth); - - if (from_slice >= (int)depth || to_slice < 0) { - continue; //sorry no go - } - - from_slice = MAX(0, from_slice); - to_slice = MIN((int)depth - 1, to_slice); - - for (int j = from_slice; j <= to_slice; j++) { - Vector3 min = item.aabb.position; - Vector3 max = item.aabb.position + item.aabb.size; - - float limit_near = MIN((z_near - slice_depth * j), max.z); - float limit_far = MAX((z_near - slice_depth * (j + 1)), min.z); - - max.z = limit_near; - min.z = limit_near; - - Vector3 proj_min = projection.xform(min); - Vector3 proj_max = projection.xform(max); - - int near_from_x = int(Math::floor((proj_min.x * 0.5 + 0.5) * width)); - int near_from_y = int(Math::floor((-proj_max.y * 0.5 + 0.5) * height)); - int near_to_x = int(Math::floor((proj_max.x * 0.5 + 0.5) * width)); - int near_to_y = int(Math::floor((-proj_min.y * 0.5 + 0.5) * height)); - - max.z = limit_far; - min.z = limit_far; - - proj_min = projection.xform(min); - proj_max = projection.xform(max); - - int far_from_x = int(Math::floor((proj_min.x * 0.5 + 0.5) * width)); - int far_from_y = int(Math::floor((-proj_max.y * 0.5 + 0.5) * height)); - int far_to_x = int(Math::floor((proj_max.x * 0.5 + 0.5) * width)); - int far_to_y = int(Math::floor((-proj_min.y * 0.5 + 0.5) * height)); - - //print_line(itos(j) + " near - " + Vector2i(near_from_x, near_from_y) + " -> " + Vector2i(near_to_x, near_to_y)); - //print_line(itos(j) + " far - " + Vector2i(far_from_x, far_from_y) + " -> " + Vector2i(far_to_x, far_to_y)); - - int from_x = MIN(near_from_x, far_from_x); - int from_y = MIN(near_from_y, far_from_y); - int to_x = MAX(near_to_x, far_to_x); - int to_y = MAX(near_to_y, far_to_y); - - if (from_x >= (int)width || to_x < 0 || from_y >= (int)height || to_y < 0) { - continue; - } - - int sx = MAX(0, from_x); - int sy = MAX(0, from_y); - int dx = MIN((int)width - 1, to_x); - int dy = MIN((int)height - 1, to_y); - - //print_line(itos(j) + " - " + Vector2i(sx, sy) + " -> " + Vector2i(dx, dy)); - - for (int x = sx; x <= dx; x++) { - for (int y = sy; y <= dy; y++) { - uint32_t offset = j * (width * height) + y * width + x; - - if (unlikely(sort_id_count == sort_id_max)) { - sort_id_max = nearest_power_of_2_templated(sort_id_max + 1); - sort_ids = (SortID *)memrealloc(sort_ids, sizeof(SortID) * sort_id_max); - if (ids.size()) { - ids.resize(sort_id_max); - RD::get_singleton()->free(items_buffer); - items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * sort_id_max); - } - } - - sort_ids[sort_id_count].cell_index = offset; - sort_ids[sort_id_count].item_index = item.index; - sort_ids[sort_id_count].item_type = item.type; - - sort_id_count++; - - //for now, only count - cluster_data_ptr[offset].item_pointers[item.type]++; - //print_line("at offset " + itos(offset) + " value: " + itos(cluster_data_ptr[offset].item_pointers[item.type])); - } - } - } - } - - /* Step 2, Assign pointers (and reset counters) */ - - uint32_t offset = 0; - for (uint32_t i = 0; i < (width * height * depth); i++) { - for (int j = 0; j < ITEM_TYPE_MAX; j++) { - uint32_t count = cluster_data_ptr[i].item_pointers[j]; //save count - cluster_data_ptr[i].item_pointers[j] = offset; //replace count by pointer - offset += count; //increase offset by count; - } - } - - //print_line("offset: " + itos(offset)); - /* Step 3, Place item lists */ - - uint32_t *ids_ptr = ids.ptrw(); - - for (uint32_t i = 0; i < sort_id_count; i++) { - const SortID &id = sort_ids[i]; - Cell &cell = cluster_data_ptr[id.cell_index]; - uint32_t pointer = cell.item_pointers[id.item_type] & POINTER_MASK; - uint32_t counter = cell.item_pointers[id.item_type] >> COUNTER_SHIFT; - ids_ptr[pointer + counter] = id.item_index; - - cell.item_pointers[id.item_type] = pointer | ((counter + 1) << COUNTER_SHIFT); - } - - RD::get_singleton()->texture_update(cluster_texture, 0, cluster_data, true); - RD::get_singleton()->buffer_update(items_buffer, 0, offset * sizeof(uint32_t), ids_ptr, true); -} - -void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth) { - if (width == p_width && height == p_height && depth == p_depth) { - return; - } - if (cluster_texture.is_valid()) { - RD::get_singleton()->free(cluster_texture); - } - - width = p_width; - height = p_height; - depth = p_depth; - - cluster_data.resize(width * height * depth * sizeof(Cell)); - - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32G32B32A32_UINT; - tf.texture_type = RD::TEXTURE_TYPE_3D; - tf.width = width; - tf.height = height; - tf.depth = depth; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - - cluster_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } -} - -RID LightClusterBuilder::get_cluster_texture() const { - return cluster_texture; -} - -RID LightClusterBuilder::get_cluster_indices_buffer() const { - return items_buffer; -} - -LightClusterBuilder::LightClusterBuilder() { - //initialize accumulators to something - lights = (LightData *)memalloc(sizeof(LightData) * 1024); - light_max = 1024; - - refprobes = (OrientedBoxData *)memalloc(sizeof(OrientedBoxData) * 1024); - refprobe_max = 1024; - - decals = (OrientedBoxData *)memalloc(sizeof(OrientedBoxData) * 1024); - decal_max = 1024; - - items = (Item *)memalloc(sizeof(Item) * 1024); - item_max = 1024; - - sort_ids = (SortID *)memalloc(sizeof(SortID) * 1024); - ids.resize(2014); - items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 1024); - item_max = 1024; -} - -LightClusterBuilder::~LightClusterBuilder() { - if (cluster_data.size()) { - RD::get_singleton()->free(cluster_texture); - } - - if (lights) { - memfree(lights); - } - if (refprobes) { - memfree(refprobes); - } - if (decals) { - memfree(decals); - } - if (items) { - memfree(items); - } - if (sort_ids) { - memfree(sort_ids); - RD::get_singleton()->free(items_buffer); - } -} diff --git a/servers/rendering/renderer_rd/light_cluster_builder.h b/servers/rendering/renderer_rd/light_cluster_builder.h deleted file mode 100644 index 8f77ece6f5..0000000000 --- a/servers/rendering/renderer_rd/light_cluster_builder.h +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************/ -/* light_cluster_builder.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef LIGHT_CLUSTER_BUILDER_H -#define LIGHT_CLUSTER_BUILDER_H - -#include "servers/rendering/renderer_rd/renderer_storage_rd.h" - -class LightClusterBuilder { -public: - enum LightType { - LIGHT_TYPE_OMNI, - LIGHT_TYPE_SPOT - }; - - enum ItemType { - ITEM_TYPE_OMNI_LIGHT, - ITEM_TYPE_SPOT_LIGHT, - ITEM_TYPE_REFLECTION_PROBE, - ITEM_TYPE_DECAL, - ITEM_TYPE_MAX //should always be 4 - }; - - enum { - COUNTER_SHIFT = 20, //one million total ids - POINTER_MASK = (1 << COUNTER_SHIFT) - 1, - COUNTER_MASK = 0xfff // 4096 items per cell - }; - -private: - struct LightData { - float position[3]; - uint32_t type; - float radius; - float spot_aperture; - uint32_t pad[2]; - }; - - uint32_t light_count = 0; - uint32_t light_max = 0; - LightData *lights = nullptr; - - struct OrientedBoxData { - float position[3]; - uint32_t pad; - float x_axis[3]; - uint32_t pad2; - float y_axis[3]; - uint32_t pad3; - float z_axis[3]; - uint32_t pad4; - }; - - uint32_t refprobe_count = 0; - uint32_t refprobe_max = 0; - OrientedBoxData *refprobes = nullptr; - - uint32_t decal_count = 0; - uint32_t decal_max = 0; - OrientedBoxData *decals = nullptr; - - struct Item { - AABB aabb; - ItemType type; - uint32_t index; - }; - - Item *items = nullptr; - uint32_t item_count = 0; - uint32_t item_max = 0; - - uint32_t width = 0; - uint32_t height = 0; - uint32_t depth = 0; - - struct Cell { - uint32_t item_pointers[ITEM_TYPE_MAX]; - }; - - Vector<uint8_t> cluster_data; - RID cluster_texture; - - struct SortID { - uint32_t cell_index; - uint32_t item_index; - ItemType item_type; - }; - - SortID *sort_ids = nullptr; - Vector<uint32_t> ids; - uint32_t sort_id_count = 0; - uint32_t sort_id_max = 0; - RID items_buffer; - - Transform view_xform; - CameraMatrix projection; - float z_far = 0; - float z_near = 0; - - _FORCE_INLINE_ void _add_item(const AABB &p_aabb, ItemType p_type, uint32_t p_index) { - if (unlikely(item_count == item_max)) { - item_max = nearest_power_of_2_templated(item_max + 1); - items = (Item *)memrealloc(items, sizeof(Item) * item_max); - } - - Item &item = items[item_count]; - item.aabb = p_aabb; - item.index = p_index; - item.type = p_type; - item_count++; - } - -public: - void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection); - - _FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) { - if (unlikely(light_count == light_max)) { - light_max = nearest_power_of_2_templated(light_max + 1); - lights = (LightData *)memrealloc(lights, sizeof(LightData) * light_max); - } - - LightData &ld = lights[light_count]; - ld.type = p_type; - ld.position[0] = p_transform.origin.x; - ld.position[1] = p_transform.origin.y; - ld.position[2] = p_transform.origin.z; - ld.radius = p_radius; - ld.spot_aperture = p_spot_aperture; - - Transform xform = view_xform * p_transform; - - ld.radius *= xform.basis.get_uniform_scale(); - - AABB aabb; - - switch (p_type) { - case LIGHT_TYPE_OMNI: { - aabb.position = xform.origin; - aabb.size = Vector3(ld.radius, ld.radius, ld.radius); - aabb.position -= aabb.size; - aabb.size *= 2.0; - - _add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count); - } break; - case LIGHT_TYPE_SPOT: { - float r = ld.radius; - real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r; - - aabb.position = xform.origin; - aabb.expand_to(xform.xform(Vector3(len, len, -r))); - aabb.expand_to(xform.xform(Vector3(-len, len, -r))); - aabb.expand_to(xform.xform(Vector3(-len, -len, -r))); - aabb.expand_to(xform.xform(Vector3(len, -len, -r))); - _add_item(aabb, ITEM_TYPE_SPOT_LIGHT, light_count); - } break; - } - - light_count++; - } - - _FORCE_INLINE_ void add_reflection_probe(const Transform &p_transform, const Vector3 &p_half_extents) { - if (unlikely(refprobe_count == refprobe_max)) { - refprobe_max = nearest_power_of_2_templated(refprobe_max + 1); - refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max); - } - - Transform xform = view_xform * p_transform; - - OrientedBoxData &rp = refprobes[refprobe_count]; - Vector3 origin = xform.origin; - rp.position[0] = origin.x; - rp.position[1] = origin.y; - rp.position[2] = origin.z; - - Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x; - rp.x_axis[0] = x_axis.x; - rp.x_axis[1] = x_axis.y; - rp.x_axis[2] = x_axis.z; - - Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y; - rp.y_axis[0] = y_axis.x; - rp.y_axis[1] = y_axis.y; - rp.y_axis[2] = y_axis.z; - - Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z; - rp.z_axis[0] = z_axis.x; - rp.z_axis[1] = z_axis.y; - rp.z_axis[2] = z_axis.z; - - AABB aabb; - - aabb.position = origin + x_axis + y_axis + z_axis; - aabb.expand_to(origin + x_axis + y_axis - z_axis); - aabb.expand_to(origin + x_axis - y_axis + z_axis); - aabb.expand_to(origin + x_axis - y_axis - z_axis); - aabb.expand_to(origin - x_axis + y_axis + z_axis); - aabb.expand_to(origin - x_axis + y_axis - z_axis); - aabb.expand_to(origin - x_axis - y_axis + z_axis); - aabb.expand_to(origin - x_axis - y_axis - z_axis); - - _add_item(aabb, ITEM_TYPE_REFLECTION_PROBE, refprobe_count); - - refprobe_count++; - } - - _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) { - if (unlikely(decal_count == decal_max)) { - decal_max = nearest_power_of_2_templated(decal_max + 1); - decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max); - } - - Transform xform = view_xform * p_transform; - - OrientedBoxData &dc = decals[decal_count]; - - Vector3 origin = xform.origin; - dc.position[0] = origin.x; - dc.position[1] = origin.y; - dc.position[2] = origin.z; - - Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x; - dc.x_axis[0] = x_axis.x; - dc.x_axis[1] = x_axis.y; - dc.x_axis[2] = x_axis.z; - - Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y; - dc.y_axis[0] = y_axis.x; - dc.y_axis[1] = y_axis.y; - dc.y_axis[2] = y_axis.z; - - Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z; - dc.z_axis[0] = z_axis.x; - dc.z_axis[1] = z_axis.y; - dc.z_axis[2] = z_axis.z; - - AABB aabb; - - aabb.position = origin + x_axis + y_axis + z_axis; - aabb.expand_to(origin + x_axis + y_axis - z_axis); - aabb.expand_to(origin + x_axis - y_axis + z_axis); - aabb.expand_to(origin + x_axis - y_axis - z_axis); - aabb.expand_to(origin - x_axis + y_axis + z_axis); - aabb.expand_to(origin - x_axis + y_axis - z_axis); - aabb.expand_to(origin - x_axis - y_axis + z_axis); - aabb.expand_to(origin - x_axis - y_axis - z_axis); - - _add_item(aabb, ITEM_TYPE_DECAL, decal_count); - - decal_count++; - } - - void bake_cluster(); - - void setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth); - - RID get_cluster_texture() const; - RID get_cluster_indices_buffer() const; - - LightClusterBuilder(); - ~LightClusterBuilder(); -}; - -#endif // LIGHT_CLUSTER_BUILDER_H diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 5b3c3c703f..7d6e2fa8e4 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1367,7 +1367,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p } if (light_count > 0) { - RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0], true); + RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0]); } { @@ -1421,7 +1421,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p //print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale)); state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5); - RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true); + RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer); } { //default filter/repeat @@ -1622,7 +1622,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); } - Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); + Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; @@ -2506,7 +2506,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { actions.renames["FRAGCOORD"] = "gl_FragCoord"; actions.renames["POINT_COORD"] = "gl_PointCoord"; - actions.renames["LIGHT_POSITION"] = "light_pos"; + actions.renames["LIGHT_POSITION"] = "light_position"; actions.renames["LIGHT_COLOR"] = "light_color"; actions.renames["LIGHT_ENERGY"] = "light_energy"; actions.renames["LIGHT"] = "light"; @@ -2695,9 +2695,10 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET); } - default_canvas_texture = storage->canvas_texture_create(); + default_canvas_texture = storage->canvas_texture_allocate(); + storage->canvas_texture_initialize(default_canvas_texture); - state.shadow_texture_size = GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"); + state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size"); //create functions for shader and material storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_shader_funcs); @@ -2706,9 +2707,14 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { state.time = 0; { - default_canvas_group_shader = storage->shader_create(); + default_canvas_group_shader = storage->shader_allocate(); + storage->shader_initialize(default_canvas_group_shader); + storage->shader_set_code(default_canvas_group_shader, "shader_type canvas_item; \nvoid fragment() {\n\tvec4 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0); if (c.a > 0.0001) c.rgb/=c.a; COLOR *= c; \n}\n"); - default_canvas_group_material = storage->material_create(); + + default_canvas_group_material = storage->material_allocate(); + storage->material_initialize(default_canvas_group_material); + storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp index 1d07741296..a57dee7314 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp @@ -453,7 +453,7 @@ void RendererSceneRenderForward::MaterialData::update_parameters(const Map<Strin //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); - RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); + RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER); } uint32_t tex_uniform_count = shader_data->texture_uniforms.size(); @@ -583,19 +583,6 @@ void RendererSceneRenderForward::RenderBufferDataForward::ensure_specular() { } } -void RendererSceneRenderForward::RenderBufferDataForward::ensure_gi() { - if (!reflection_buffer.is_valid()) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.width = width; - tf.height = height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - - reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } -} - void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() { if (!giprobe_buffer.is_valid()) { RD::TextureFormat tf; @@ -633,16 +620,6 @@ void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() { } void RendererSceneRenderForward::RenderBufferDataForward::clear() { - if (ambient_buffer != RID() && ambient_buffer != color) { - RD::get_singleton()->free(ambient_buffer); - ambient_buffer = RID(); - } - - if (reflection_buffer != RID() && reflection_buffer != specular) { - RD::get_singleton()->free(reflection_buffer); - reflection_buffer = RID(); - } - if (giprobe_buffer != RID()) { RD::get_singleton()->free(giprobe_buffer); giprobe_buffer = RID(); @@ -833,16 +810,26 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); - float old_offset[2] = { 0, 0 }; + SceneState::PushConstant push_constant; + + if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { + push_constant.uv_offset = Math::make_half_float(p_params->uv_offset.y) << 16; + push_constant.uv_offset |= Math::make_half_float(p_params->uv_offset.x); + } else { + push_constant.uv_offset = 0; + } for (uint32_t i = p_from_element; i < p_to_element; i++) { const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i]; + const RenderElementInfo &element_info = p_params->element_info[i]; + + push_constant.base_index = i + p_params->element_offset; RID material_uniform_set; ShaderData *shader; void *mesh_surface; - if (shadow_pass) { + if (shadow_pass || p_params->pass_mode == PASS_MODE_DEPTH) { //regular depth pass can use these too material_uniform_set = surf->material_uniform_set_shadow; shader = surf->shader_shadow; mesh_surface = surf->surface_shadow; @@ -857,13 +844,6 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList continue; } - if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { - old_offset[0] = surf->owner->push_constant.lightmap_uv_scale[0]; - old_offset[1] = surf->owner->push_constant.lightmap_uv_scale[1]; - surf->owner->push_constant.lightmap_uv_scale[0] = p_params->uv_offset.x; - surf->owner->push_constant.lightmap_uv_scale[1] = p_params->uv_offset.y; - } - //find cull variant ShaderData::CullVariant cull_variant; @@ -885,16 +865,16 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList switch (p_params->pass_mode) { case PASS_MODE_COLOR: case PASS_MODE_COLOR_TRANSPARENT: { - if (surf->sort.uses_lightmap) { + if (element_info.uses_lightmap) { shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS; - } else if (surf->sort.uses_forward_gi) { + } else if (element_info.uses_forward_gi) { shader_version = SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI; } else { shader_version = SHADER_VERSION_COLOR_PASS; } } break; case PASS_MODE_COLOR_SPECULAR: { - if (surf->sort.uses_lightmap) { + if (element_info.uses_lightmap) { shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR; } else { shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR; @@ -936,31 +916,7 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format); } - if (p_params->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(mesh_surface)) { - //lod - Vector3 support_min = surf->owner->transformed_aabb.get_support(-p_params->lod_plane.normal); - Vector3 support_max = surf->owner->transformed_aabb.get_support(p_params->lod_plane.normal); - - float distance_min = p_params->lod_plane.distance_to(support_min); - float distance_max = p_params->lod_plane.distance_to(support_max); - - float distance = 0.0; - - if (distance_min * distance_max < 0.0) { - //crossing plane - distance = 0.0; - } else if (distance_min >= 0.0) { - distance = distance_min; - } else if (distance_max <= 0.0) { - distance = -distance_max; - } - - index_array_rd = storage->mesh_surface_get_index_array_with_lod(mesh_surface, surf->owner->lod_model_scale * surf->owner->lod_bias, distance * p_params->lod_distance_multiplier, p_params->screen_lod_threshold); - - } else { - //no lod - index_array_rd = storage->mesh_surface_get_index_array(mesh_surface); - } + index_array_rd = storage->mesh_surface_get_index_array(mesh_surface, element_info.lod_index); if (prev_vertex_array_rd != vertex_array_rd) { RD::get_singleton()->draw_list_bind_vertex_array(draw_list, vertex_array_rd); @@ -997,14 +953,11 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList prev_material_uniform_set = material_uniform_set; } - RD::get_singleton()->draw_list_set_push_constant(draw_list, &surf->owner->push_constant, sizeof(GeometryInstanceForward::PushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), surf->owner->instance_count); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant)); - if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { - surf->owner->push_constant.lightmap_uv_scale[0] = old_offset[0]; - surf->owner->push_constant.lightmap_uv_scale[1] = old_offset[1]; - } + uint32_t instance_count = surf->owner->instance_count > 1 ? surf->owner->instance_count : element_info.repeat; + RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); + i += element_info.repeat - 1; //skip equal elements } } @@ -1062,16 +1015,16 @@ void RendererSceneRenderForward::_render_list_with_threads(RenderListParameters thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures); RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RendererSceneRenderForward::_render_list_thread_function, p_params); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->draw_list_end(p_params->barrier); } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures); _render_list(draw_list, fb_format, p_params, 0, p_params->element_count); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->draw_list_end(p_params->barrier); } } -void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { +void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; @@ -1099,8 +1052,18 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren scene_state.ubo.penumbra_shadow_samples = penumbra_shadow_samples_get(); scene_state.ubo.soft_shadow_samples = soft_shadow_samples_get(); - scene_state.ubo.screen_pixel_size[0] = p_screen_pixel_size.x; - scene_state.ubo.screen_pixel_size[1] = p_screen_pixel_size.y; + Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); + scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; + scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y; + + scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_cluster_size); + scene_state.ubo.max_cluster_element_count_div_32 = p_max_cluster_elements / 32; + { + uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_cluster_size + 1; + uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_cluster_size + 1; + scene_state.ubo.cluster_type_size = cluster_screen_width * cluster_screen_height * (scene_state.ubo.max_cluster_element_count_div_32 + 32); + scene_state.ubo.cluster_width = cluster_screen_width; + } if (p_shadow_atlas.is_valid()) { Vector2 sas = shadow_atlas_get_size(p_shadow_atlas); @@ -1300,22 +1263,120 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount(); scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit(); - RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true); + if (p_index >= (int)scene_state.uniform_buffers.size()) { + uint32_t from = scene_state.uniform_buffers.size(); + scene_state.uniform_buffers.resize(p_index + 1); + render_pass_uniform_sets.resize(p_index + 1); + for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { + scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); + } + } + RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER); } -void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi) { - scene_state.used_sss = false; - scene_state.used_screen_texture = false; - scene_state.used_normal_texture = false; - scene_state.used_depth_texture = false; +void RendererSceneRenderForward::_update_instance_data_buffer(RenderListType p_render_list) { + if (scene_state.instance_data[p_render_list].size() > 0) { + if (scene_state.instance_buffer[p_render_list] == RID() || scene_state.instance_buffer_size[p_render_list] < scene_state.instance_data[p_render_list].size()) { + if (scene_state.instance_buffer[p_render_list] != RID()) { + RD::get_singleton()->free(scene_state.instance_buffer[p_render_list]); + } + uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), scene_state.instance_data[p_render_list].size())); + scene_state.instance_buffer[p_render_list] = RD::get_singleton()->storage_buffer_create(new_size * sizeof(SceneState::InstanceData)); + scene_state.instance_buffer_size[p_render_list] = new_size; + } + RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER); + } +} +void RendererSceneRenderForward::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) { + RenderList *rl = &render_list[p_render_list]; + uint32_t element_total = p_max_elements >= 0 ? uint32_t(p_max_elements) : rl->elements.size(); + + scene_state.instance_data[p_render_list].resize(p_offset + element_total); + rl->element_info.resize(p_offset + element_total); + + uint32_t repeats = 0; + GeometryInstanceSurfaceDataCache *prev_surface = nullptr; + for (uint32_t i = 0; i < element_total; i++) { + GeometryInstanceSurfaceDataCache *surface = rl->elements[i + p_offset]; + GeometryInstanceForward *inst = surface->owner; + + SceneState::InstanceData &instance_data = scene_state.instance_data[p_render_list][i + p_offset]; + + if (inst->store_transform_cache) { + RendererStorageRD::store_transform(inst->transform, instance_data.transform); + } else { + RendererStorageRD::store_transform(Transform(), instance_data.transform); + } + + instance_data.flags = inst->flags_cache; + instance_data.gi_offset = inst->gi_offset_cache; + instance_data.layer_mask = inst->layer_mask; + instance_data.instance_uniforms_ofs = uint32_t(inst->shader_parameters_offset); + instance_data.lightmap_uv_scale[0] = inst->lightmap_uv_scale.position.x; + instance_data.lightmap_uv_scale[1] = inst->lightmap_uv_scale.position.y; + instance_data.lightmap_uv_scale[2] = inst->lightmap_uv_scale.size.x; + instance_data.lightmap_uv_scale[3] = inst->lightmap_uv_scale.size.y; + + bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); + + if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2) { + //this element is the same as the previous one, count repeats to draw it using instancing + repeats++; + } else { + if (repeats > 0) { + for (uint32_t j = 1; j <= repeats; j++) { + rl->element_info[p_offset + i - j].repeat = j; + } + } + repeats = 1; + } + + RenderElementInfo &element_info = rl->element_info[p_offset + i]; + + element_info.lod_index = surface->sort.lod_index; + element_info.uses_forward_gi = surface->sort.uses_forward_gi; + element_info.uses_lightmap = surface->sort.uses_lightmap; + + if (cant_repeat) { + prev_surface = nullptr; + } else { + prev_surface = surface; + } + } + + if (repeats > 0) { + for (uint32_t j = 1; j <= repeats; j++) { + rl->element_info[p_offset + element_total - j].repeat = j; + } + } + + if (p_update_buffer) { + _update_instance_data_buffer(p_render_list); + } +} + +void RendererSceneRenderForward::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) { + if (p_render_list == RENDER_LIST_OPAQUE) { + scene_state.used_sss = false; + scene_state.used_screen_texture = false; + scene_state.used_normal_texture = false; + scene_state.used_depth_texture = false; + } + uint32_t lightmap_captures_used = 0; Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); near_plane.d += p_cam_projection.get_z_near(); float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near(); - uint32_t lightmap_captures_used = 0; + RenderList *rl = &render_list[p_render_list]; _update_dirty_geometry_instances(); - render_list.clear(); + + if (!p_append) { + rl->clear(); + if (p_render_list == RENDER_LIST_OPAQUE) { + render_list[RENDER_LIST_ALPHA].clear(); //opaque fills alpha too + } + } //fill list @@ -1331,7 +1392,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst bool uses_lightmap = false; bool uses_gi = false; - if (p_pass_mode == PASS_MODE_COLOR) { + if (p_render_list == RENDER_LIST_OPAQUE) { //setup GI if (inst->lightmap_instance.is_valid()) { @@ -1343,15 +1404,15 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst } } if (lightmap_cull_index >= 0) { - inst->push_constant.gi_offset &= 0xFFFF; - inst->push_constant.gi_offset |= lightmap_cull_index; + inst->gi_offset_cache = inst->lightmap_slice_index << 16; + inst->gi_offset_cache |= lightmap_cull_index; flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP; if (scene_state.lightmap_has_sh[lightmap_cull_index]) { flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP; } uses_lightmap = true; } else { - inst->push_constant.gi_offset = 0xFFFFFFFF; + inst->gi_offset_cache = 0xFFFFFFFF; } } else if (inst->lightmap_sh) { @@ -1365,7 +1426,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst lcd.sh[j * 4 + 3] = src_capture[j].a; } flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE; - inst->push_constant.gi_offset = lightmap_captures_used; + inst->gi_offset_cache = lightmap_captures_used; lightmap_captures_used++; uses_lightmap = true; } @@ -1392,18 +1453,19 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst SWAP(probe0_index, probe1_index); } - inst->push_constant.gi_offset = probe0_index | (probe1_index << 16); + inst->gi_offset_cache = probe0_index | (probe1_index << 16); + flags |= INSTANCE_DATA_FLAG_USE_GIPROBE; uses_gi = true; } else { if (p_using_sdfgi && inst->can_sdfgi) { flags |= INSTANCE_DATA_FLAG_USE_SDFGI; uses_gi = true; } - inst->push_constant.gi_offset = 0xFFFFFFFF; + inst->gi_offset_cache = 0xFFFFFFFF; } } } - inst->push_constant.flags = flags; + inst->flags_cache = flags; GeometryInstanceSurfaceDataCache *surf = inst->surface_caches; @@ -1411,12 +1473,39 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst surf->sort.uses_forward_gi = 0; surf->sort.uses_lightmap = 0; + // LOD + + if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) { + //lod + Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal); + Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal); + + float distance_min = p_lod_plane.distance_to(lod_support_min); + float distance_max = p_lod_plane.distance_to(lod_support_max); + + float distance = 0.0; + + if (distance_min * distance_max < 0.0) { + //crossing plane + distance = 0.0; + } else if (distance_min >= 0.0) { + distance = distance_min; + } else if (distance_max <= 0.0) { + distance = -distance_max; + } + + surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold); + } else { + surf->sort.lod_index = 0; + } + + // ADD Element if (p_pass_mode == PASS_MODE_COLOR) { if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) { - render_list.add_element(surf); + rl->add_element(surf); } if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) { - render_list.add_alpha_element(surf); + render_list[RENDER_LIST_ALPHA].add_element(surf); if (uses_gi) { surf->sort.uses_forward_gi = 1; } @@ -1441,11 +1530,11 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) { if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) { - render_list.add_element(surf); + rl->add_element(surf); } } else { if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) { - render_list.add_element(surf); + rl->add_element(surf); } } @@ -1455,8 +1544,8 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst } } - if (lightmap_captures_used) { - RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true); + if (p_render_list == RENDER_LIST_OPAQUE && lightmap_captures_used) { + RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, RD::BARRIER_MASK_RASTER); } } @@ -1485,29 +1574,21 @@ void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<RID> &p_light scene_state.lightmaps_used++; } if (scene_state.lightmaps_used > 0) { - RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, true); + RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, RD::BARRIER_MASK_RASTER); } } -void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) { +void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) { RenderBufferDataForward *render_buffer = nullptr; if (p_render_buffer.is_valid()) { render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer); } //first of all, make a new render pass - render_pass++; - //fill up ubo RENDER_TIMESTAMP("Setup 3D Scene"); - if (p_reflection_probe.is_valid()) { - scene_state.ubo.reflection_multiplier = 0.0; - } else { - scene_state.ubo.reflection_multiplier = 1.0; - } - float lod_distance_multiplier = p_cam_projection.get_lod_multiplier(); Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); @@ -1520,9 +1601,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); scene_state.ubo.viewport_size[0] = vp_he.x; scene_state.ubo.viewport_size[1] = vp_he.y; - scene_state.ubo.directional_light_count = p_directional_light_count; + scene_state.ubo.directional_light_count = 0; - Size2 screen_pixel_size; Size2i screen_size; RID opaque_framebuffer; RID opaque_specular_framebuffer; @@ -1537,8 +1617,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf bool using_giprobe = false; if (render_buffer) { - screen_pixel_size.width = 1.0 / render_buffer->width; - screen_pixel_size.height = 1.0 / render_buffer->height; screen_size.x = render_buffer->width; screen_size.y = render_buffer->height; @@ -1546,7 +1624,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf if (!low_end && p_gi_probes.size() > 0) { using_giprobe = true; - render_buffer->ensure_gi(); } if (!p_environment.is_valid() && using_giprobe) { @@ -1556,7 +1633,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf if (environment_is_sdfgi_enabled(p_environment)) { depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also giprobe using_sdfgi = true; - render_buffer->ensure_gi(); } else { depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } @@ -1595,8 +1671,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf alpha_framebuffer = opaque_framebuffer; } else if (p_reflection_probe.is_valid()) { uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe); - screen_pixel_size.width = 1.0 / resolution; - screen_pixel_size.height = 1.0 / resolution; screen_size.x = resolution; screen_size.y = resolution; @@ -1611,13 +1685,21 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf ERR_FAIL(); //bug? } + RD::get_singleton()->draw_command_begin_label("Render Setup"); + _setup_lightmaps(p_lightmaps, p_cam_transform); _setup_giprobes(p_gi_probes); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe); + _fill_render_list(RENDER_LIST_OPAQUE, p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + render_list[RENDER_LIST_OPAQUE].sort_by_key(); + render_list[RENDER_LIST_ALPHA].sort_by_depth(); + _fill_instance_data(RENDER_LIST_OPAQUE); + _fill_instance_data(RENDER_LIST_ALPHA); + + RD::get_singleton()->draw_command_end_label(); bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED; @@ -1677,6 +1759,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf // setup sky if used for ambient, reflections, or background if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); + RD::get_singleton()->draw_command_begin_label("Setup Sky"); CameraMatrix projection = p_cam_projection; if (p_reflection_probe.is_valid()) { CameraMatrix correction; @@ -1694,55 +1777,77 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf // do not try to draw sky if invalid draw_sky = false; } + RD::get_singleton()->draw_command_end_label(); } } else { clear_color = p_default_bg_color; } - render_list.sort_by_key(false); - bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION; bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES; - bool depth_pre_pass = !low_end && depth_framebuffer.is_valid(); bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment); bool continue_depth = false; if (depth_pre_pass) { //depth pre pass - RENDER_TIMESTAMP("Render Depth Pre-Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + bool needs_pre_resolve = _needs_post_prepass_render(using_sdfgi || using_giprobe); + if (needs_pre_resolve) { + RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)"); + } else { + RENDER_TIMESTAMP("Render Depth Pre-Pass"); + } + if (needs_pre_resolve) { + //pre clear the depth framebuffer, as AMD (and maybe others?) use compute for it, and barrier other compute shaders. + RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear); + RD::get_singleton()->draw_list_end(); + //start compute processes here, so they run at the same time as depth pre-pass + _post_prepass_render(using_sdfgi || using_giprobe); + } + + RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass"); + + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); bool finish_depth = using_ssao || using_sdfgi || using_giprobe; - RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); - _render_list_with_threads(&render_list_params, depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); + + RD::get_singleton()->draw_command_end_label(); + + if (needs_pre_resolve) { + _pre_resolve_render(using_sdfgi || using_giprobe); + } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { RENDER_TIMESTAMP("Resolve Depth Pre-Pass"); + RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass"); if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) { + if (needs_pre_resolve) { + RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); + } static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 }; storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_giprobe ? render_buffer->giprobe_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_giprobe ? render_buffer->giprobe_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]); } else if (finish_depth) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true); + RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); } + RD::get_singleton()->draw_command_end_label(); } continue_depth = !finish_depth; } - if (using_ssao) { - _process_ssao(p_render_buffer, p_environment, render_buffer->normal_roughness_buffer, p_cam_projection); - } + _pre_opaque_render(using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID()); - if (using_sdfgi || using_giprobe) { - _process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes); - } + RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); + + scene_state.ubo.directional_light_count = _get_render_state_directional_light_count(); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid()); + _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid()); RENDER_TIMESTAMP("Render Opaque Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probes, p_lightmaps); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss; bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; @@ -1763,10 +1868,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf } RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; - RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); - - _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE); @@ -1774,6 +1877,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf } } + RD::get_singleton()->draw_command_end_label(); + if (debug_giprobes) { //debug giprobes bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); @@ -1783,9 +1888,11 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf dc.set_depth_correction(true); CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); + RD::get_singleton()->draw_command_begin_label("Debug GIProbes"); for (int i = 0; i < (int)p_gi_probes.size(); i++) { _debug_giprobe(p_gi_probes[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0); } + RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_list_end(); } @@ -1798,7 +1905,9 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf dc.set_depth_correction(true); CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); + RD::get_singleton()->draw_command_begin_label("Debug SDFGI"); _debug_sdfgi_probes(p_render_buffer, draw_list, opaque_framebuffer, cm); + RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_list_end(); } @@ -1811,30 +1920,35 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf correction.set_depth_correction(true); projection = correction * p_cam_projection; } - + RD::get_singleton()->draw_command_begin_label("Draw Sky"); _draw_sky(can_continue_color, can_continue_depth, opaque_framebuffer, p_environment, projection, p_cam_transform); + RD::get_singleton()->draw_command_end_label(); } if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); + RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color); if (using_separate_specular) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true); + RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular); } } if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true); + RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); } if (using_separate_specular) { if (using_sss) { RENDER_TIMESTAMP("Sub Surface Scattering"); + RD::get_singleton()->draw_command_begin_label("Process Sub Surface Scattering"); _process_sss(p_render_buffer, p_cam_projection); + RD::get_singleton()->draw_command_end_label(); } if (using_ssr) { RENDER_TIMESTAMP("Screen Space Reflection"); + RD::get_singleton()->draw_command_begin_label("Process Screen Space Reflections"); _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); + RD::get_singleton()->draw_command_end_label(); } else { //just mix specular back RENDER_TIMESTAMP("Merge Specular"); @@ -1844,30 +1958,44 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf RENDER_TIMESTAMP("Render Transparent Pass"); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); + + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); - render_list.sort_by_reverse_depth_and_priority(true); + _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); { - RenderListParameters render_list_params(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } + RD::get_singleton()->draw_command_end_label(); + + RD::get_singleton()->draw_command_begin_label("Resolve"); + if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); + RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color); } -} -void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) { - RENDER_TIMESTAMP("Setup Rendering Shadow"); + RD::get_singleton()->draw_command_end_label(); +} +void RendererSceneRenderForward::_render_shadow_begin() { + scene_state.shadow_passes.clear(); + RD::get_singleton()->draw_command_begin_label("Shadow Setup"); _update_render_base_uniform_set(); - render_pass++; + render_list[RENDER_LIST_SECONDARY].clear(); + scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); +} +void RendererSceneRenderForward::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { + uint32_t shadow_pass_index = scene_state.shadow_passes.size(); + + SceneState::ShadowPass shadow_pass; scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar, false, p_use_pancake); + _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { p_screen_lod_threshold = 0.0; @@ -1875,72 +2003,116 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; - _fill_render_list(p_instances, pass_mode, p_projection, p_transform); + uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, false, false, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true); + uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; + render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); + _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false); + + { + //regular forward for now + bool flip_cull = p_use_dp_flip; + if (p_flip_y) { + flip_cull = !flip_cull; + } - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + shadow_pass.element_from = render_list_from; + shadow_pass.element_count = render_list_size; + shadow_pass.flip_cull = flip_cull; + shadow_pass.pass_mode = pass_mode; - RENDER_TIMESTAMP("Render Shadow"); + shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete + shadow_pass.camera_plane = p_camera_plane; + shadow_pass.screen_lod_threshold = p_screen_lod_threshold; + shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier; - render_list.sort_by_key(false); + shadow_pass.framebuffer = p_framebuffer; + shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE); + shadow_pass.final_depth_action = p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE; + shadow_pass.rect = p_rect; - { - //regular forward for now - RenderListParameters render_list_params(render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); - _render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); + scene_state.shadow_passes.push_back(shadow_pass); } } +void RendererSceneRenderForward::_render_shadow_process() { + _update_instance_data_buffer(RENDER_LIST_SECONDARY); + //render shadows one after the other, so this can be done un-barriered and the driver can optimize (as well as allow us to run compute at the same time) + + for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { + //render passes need to be configured after instance buffer is done, since they need the latest version + SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>(), false, i); + } + + RD::get_singleton()->draw_command_end_label(); +} +void RendererSceneRenderForward::_render_shadow_end(uint32_t p_barrier) { + RD::get_singleton()->draw_command_begin_label("Shadow Render"); + + for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { + SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); + _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); + } + + if (p_barrier != RD::BARRIER_MASK_NO_BARRIER) { + RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, p_barrier); + } + RD::get_singleton()->draw_command_end_label(); +} + void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup Render Collider Heightfield"); - _update_render_base_uniform_set(); - - render_pass++; + RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false); + _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false); PassMode pass_mode = PASS_MODE_SHADOW; - _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); - RENDER_TIMESTAMP("Render Collider Heightield"); - - render_list.sort_by_key(false); + RENDER_TIMESTAMP("Render Collider Heightfield"); { //regular forward for now - RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, pass_mode, true, rp_uniform_set); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, true, rp_uniform_set); _render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); } + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering Material"); - _update_render_base_uniform_set(); + RD::get_singleton()->draw_command_begin_label("Render Material"); - render_pass++; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; - scene_state.ubo.material_uv2_mode = true; + scene_state.ubo.material_uv2_mode = false; - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); RENDER_TIMESTAMP("Render Material"); - render_list.sort_by_key(false); - { - RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -1952,31 +2124,33 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); } + + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); - _update_render_base_uniform_set(); + RD::get_singleton()->draw_command_begin_label("Render UV2"); - render_pass++; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = true; - _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform()); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); RENDER_TIMESTAMP("Render Material"); - render_list.sort_by_key(false); - { - RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, true); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, true); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -2012,23 +2186,24 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance * RD::get_singleton()->draw_list_end(); } + + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { RENDER_TIMESTAMP("Render SDFGI"); + RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); + _update_render_base_uniform_set(); RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers); ERR_FAIL_COND(!render_buffer); - render_pass++; - PassMode pass_mode = PASS_MODE_SDF; - _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform()); - render_list.sort_by_key(false); - - RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); Vector3 half_extents = p_bounds.size * 0.5; Vector3 center = p_bounds.position + half_extents; @@ -2079,7 +2254,9 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto RendererStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds); - _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); + + RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); Map<Size2i, RID>::Element *E = sdfgi_framebuffer_size_cache.find(fb_size); if (!E) { @@ -2087,9 +2264,11 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto E = sdfgi_framebuffer_size_cache.insert(fb_size, fb); } - RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, false); _render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs); } + + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_base_uniforms_changed() { @@ -2141,50 +2320,49 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 3; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffer); + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(get_omni_light_buffer()); uniforms.push_back(u); } - { RD::Uniform u; - u.binding = 5; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_positional_light_buffer()); + u.ids.push_back(get_spot_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 6; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 7; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 10; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 11; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 12; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); @@ -2192,7 +2370,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 13; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); u.ids.push_back(decal_atlas); @@ -2200,7 +2378,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 14; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_decal_buffer()); uniforms.push_back(u); @@ -2208,35 +2386,8 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 15; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(get_cluster_builder_texture()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 16; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_cluster_builder_indices_buffer()); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.binding = 17; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - if (directional_shadow_get_texture().is_valid()) { - u.ids.push_back(directional_shadow_get_texture()); - } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); - } - uniforms.push_back(u); - } - - { - RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 18; + u.binding = 12; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2244,7 +2395,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { if (!low_end) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 19; + u.binding = 13; u.ids.push_back(sdfgi_get_ubo()); uniforms.push_back(u); } @@ -2253,10 +2404,9 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } } -RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps) { - if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) { - RD::get_singleton()->free(render_pass_uniform_set); - } +RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) { + //there should always be enough uniform buffers for render passes, otherwise bugs + ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID()); RenderBufferDataForward *rb = nullptr; if (p_render_buffers.is_valid()) { @@ -2268,6 +2418,24 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff Vector<RD::Uniform> uniforms; { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.ids.push_back(scene_state.uniform_buffers[p_index]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + RID instance_buffer = scene_state.instance_buffer[p_render_list]; + if (instance_buffer == RID()) { + instance_buffer = default_vec4_xform_buffer; // any buffer will do since its not used + } + u.ids.push_back(instance_buffer); + uniforms.push_back(u); + } + { RID radiance_texture; if (p_radiance_texture.is_valid()) { radiance_texture = p_radiance_texture; @@ -2275,7 +2443,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; - u.binding = 0; + u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(radiance_texture); uniforms.push_back(u); @@ -2284,7 +2452,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); RD::Uniform u; - u.binding = 1; + u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { u.ids.push_back(ref_texture); @@ -2296,7 +2464,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 2; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; if (p_shadow_atlas.is_valid()) { @@ -2310,7 +2478,18 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 3; + u.binding = 5; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { + u.ids.push_back(directional_shadow_get_texture()); + } else { + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + } + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); @@ -2329,7 +2508,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 4; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2350,7 +2529,16 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 5; + u.binding = 8; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer; + u.ids.push_back(cb); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); @@ -2358,17 +2546,18 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 6; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } + if (!low_end) { { RD::Uniform u; - u.binding = 7; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL); u.ids.push_back(texture); @@ -2377,7 +2566,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 8; + u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID(); RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2387,24 +2576,26 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 9; + u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb && rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); + RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID(); + RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 10; + u.binding = 14; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb && rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); + RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID(); + RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 11; + u.binding = 15; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID t; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { @@ -2417,7 +2608,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 12; + u.binding = 16; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers)); @@ -2428,14 +2619,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 13; + u.binding = 17; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 14; + u.binding = 18; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = RID(); if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) { @@ -2451,8 +2642,16 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } } - render_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET); - return render_pass_uniform_set; + if (p_index >= (int)render_pass_uniform_sets.size()) { + render_pass_uniform_sets.resize(p_index + 1); + } + + if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) { + RD::get_singleton()->free(render_pass_uniform_sets[p_index]); + } + + render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET); + return render_pass_uniform_sets[p_index]; } RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) { @@ -2463,10 +2662,24 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed Vector<RD::Uniform> uniforms; { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.ids.push_back(scene_state.uniform_buffers[0]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); + uniforms.push_back(u); + } + { // No radiance texture. RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RD::Uniform u; - u.binding = 0; + u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(radiance_texture); uniforms.push_back(u); @@ -2476,7 +2689,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed // No reflection atlas. RID ref_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); RD::Uniform u; - u.binding = 1; + u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(ref_texture); uniforms.push_back(u); @@ -2485,7 +2698,17 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No shadow atlas. RD::Uniform u; - u.binding = 2; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + u.ids.push_back(texture); + uniforms.push_back(u); + } + + { + // No directional shadow atlas. + RD::Uniform u; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); @@ -2495,7 +2718,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No Lightmaps RD::Uniform u; - u.binding = 3; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); @@ -2509,7 +2732,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No GIProbes RD::Uniform u; - u.binding = 4; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2519,33 +2742,43 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed uniforms.push_back(u); } + + { + RD::Uniform u; + u.binding = 8; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + RID cb = default_vec4_xform_buffer; + u.ids.push_back(cb); + uniforms.push_back(u); + } + // actual sdfgi stuff { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 5; + u.binding = 9; u.ids.push_back(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 6; + u.binding = 10; u.ids.push_back(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 7; + u.binding = 11; u.ids.push_back(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 8; + u.binding = 12; u.ids.push_back(p_geom_facing_texture); uniforms.push_back(u); } @@ -2569,18 +2802,6 @@ RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_ return rb->normal_roughness_buffer; } -RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) { - RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers); - - return rb->ambient_buffer; -} - -RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) { - RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers); - - return rb->reflection_buffer; -} - RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr; void RendererSceneRenderForward::set_time(double p_time, double p_step) { @@ -2650,10 +2871,17 @@ void RendererSceneRenderForward::_geometry_instance_add_surface_with_material(Ge } MaterialData *material_shadow = nullptr; - //void *surface_shadow = nullptr; + void *surface_shadow = nullptr; if (!p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; material_shadow = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); + + RID shadow_mesh = storage->mesh_get_shadow_mesh(p_mesh); + + if (shadow_mesh.is_valid()) { + surface_shadow = storage->mesh_get_surface(shadow_mesh, p_surface); + } + } else { material_shadow = p_material; } @@ -2675,7 +2903,8 @@ void RendererSceneRenderForward::_geometry_instance_add_surface_with_material(Ge //shadow sdcache->shader_shadow = material_shadow->shader_data; sdcache->material_uniform_set_shadow = material_shadow->uniform_set; - sdcache->surface_shadow = sdcache->surface; //when adding special shadow meshes, will use this + + sdcache->surface_shadow = surface_shadow ? surface_shadow : sdcache->surface; sdcache->owner = ginstance; @@ -2687,10 +2916,11 @@ void RendererSceneRenderForward::_geometry_instance_add_surface_with_material(Ge sdcache->sort.sort_key1 = 0; sdcache->sort.sort_key2 = 0; - sdcache->sort.surface_type = ginstance->data->base_type; - sdcache->sort.material_id = p_material_id; + sdcache->sort.surface_index = p_surface; + sdcache->sort.material_id_low = p_material_id & 0x3FFF; + sdcache->sort.material_id_hi = p_material_id >> 14; sdcache->sort.shader_id = p_shader_id; - sdcache->sort.geometry_id = p_mesh.get_local_index(); + sdcache->sort.geometry_id = p_mesh.get_local_index(); //only meshes can repeat anyway sdcache->sort.uses_forward_gi = ginstance->can_sdfgi; sdcache->sort.priority = p_material->priority; } @@ -2820,11 +3050,6 @@ void RendererSceneRenderForward::_geometry_instance_update(GeometryInstance *p_g //Fill push constant - ginstance->push_constant.instance_uniforms_ofs = ginstance->data->shader_parameters_offset >= 0 ? ginstance->data->shader_parameters_offset : 0; - ginstance->push_constant.layer_mask = ginstance->data->layer_mask; - ginstance->push_constant.flags = 0; - ginstance->push_constant.gi_offset = 0xFFFFFFFF; //disabled - bool store_transform = true; if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { @@ -2881,21 +3106,10 @@ void RendererSceneRenderForward::_geometry_instance_update(GeometryInstance *p_g } } - if (store_transform) { - RendererStorageRD::store_transform(ginstance->data->transform, ginstance->push_constant.transform); - } else { - RendererStorageRD::store_transform(Transform(), ginstance->push_constant.transform); - } - + ginstance->store_transform_cache = store_transform; ginstance->can_sdfgi = false; - if (lightmap_instance_is_valid(ginstance->lightmap_instance)) { - ginstance->push_constant.gi_offset = ginstance->data->lightmap_slice_index << 16; - ginstance->push_constant.lightmap_uv_scale[0] = ginstance->data->lightmap_uv_scale.position.x; - ginstance->push_constant.lightmap_uv_scale[1] = ginstance->data->lightmap_uv_scale.position.y; - ginstance->push_constant.lightmap_uv_scale[2] = ginstance->data->lightmap_uv_scale.size.width; - ginstance->push_constant.lightmap_uv_scale[3] = ginstance->data->lightmap_uv_scale.size.height; - } else if (!low_end) { + if (!lightmap_instance_is_valid(ginstance->lightmap_instance) && !low_end) { if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) { ginstance->can_sdfgi = true; } @@ -2985,8 +3199,7 @@ void RendererSceneRenderForward::geometry_instance_set_mesh_instance(GeometryIns void RendererSceneRenderForward::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - RendererStorageRD::store_transform(p_transform, ginstance->push_constant.transform); - ginstance->data->transform = p_transform; + ginstance->transform = p_transform; ginstance->mirror = p_transform.basis.determinant() < 0; ginstance->data->aabb = p_aabb; ginstance->transformed_aabb = p_transformed_aabb; @@ -3021,8 +3234,8 @@ void RendererSceneRenderForward::geometry_instance_set_use_lightmap(GeometryInst GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); ginstance->lightmap_instance = p_lightmap_instance; - ginstance->data->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->data->lightmap_slice_index = p_lightmap_slice_index; + ginstance->lightmap_uv_scale = p_lightmap_uv_scale; + ginstance->lightmap_slice_index = p_lightmap_slice_index; _geometry_instance_mark_dirty(ginstance); } void RendererSceneRenderForward::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { @@ -3045,7 +3258,7 @@ void RendererSceneRenderForward::geometry_instance_set_lightmap_capture(Geometry void RendererSceneRenderForward::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - ginstance->data->shader_parameters_offset = p_offset; + ginstance->shader_parameters_offset = p_offset; _geometry_instance_mark_dirty(ginstance); } void RendererSceneRenderForward::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { @@ -3059,8 +3272,7 @@ void RendererSceneRenderForward::geometry_instance_set_cast_double_sided_shadows void RendererSceneRenderForward::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - ginstance->data->layer_mask = p_layer_mask; - ginstance->push_constant.layer_mask = p_layer_mask; + ginstance->layer_mask = p_layer_mask; } void RendererSceneRenderForward::geometry_instance_free(GeometryInstance *p_geometry_instance) { @@ -3092,7 +3304,7 @@ void RendererSceneRenderForward::geometry_instance_pair_decal_instances(Geometry Transform RendererSceneRenderForward::geometry_instance_get_transform(GeometryInstance *p_instance) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance); ERR_FAIL_COND_V(!ginstance, Transform()); - return ginstance->data->transform; + return ginstance->transform; } AABB RendererSceneRenderForward::geometry_instance_get_aabb(GeometryInstance *p_instance) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance); @@ -3317,7 +3529,7 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor actions.render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions.render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; - bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley"); + bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley"); if (!force_lambert) { actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; @@ -3329,7 +3541,7 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n"; - bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx"); + bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); if (!force_blinn) { actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; @@ -3355,23 +3567,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; actions.global_buffer_array_variable = "global_variables.data"; - actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs"; + actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs"; shader.compiler.initialize(actions); } - //render list - render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)128000); - render_list.init(); - render_pass = 0; - - scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); - { //default material and shader - default_shader = storage->shader_create(); + default_shader = storage->shader_allocate(); + storage->shader_initialize(default_shader); storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n"); - default_material = storage->material_create(); + default_material = storage->material_allocate(); + storage->material_initialize(default_material); storage->material_set_shader(default_material, default_shader); MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); @@ -3382,14 +3589,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor } { - overdraw_material_shader = storage->shader_create(); + overdraw_material_shader = storage->shader_allocate(); + storage->shader_initialize(overdraw_material_shader); storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }"); - overdraw_material = storage->material_create(); + overdraw_material = storage->material_allocate(); + storage->material_initialize(overdraw_material); storage->material_set_shader(overdraw_material, overdraw_material_shader); - wireframe_material_shader = storage->shader_create(); + wireframe_material_shader = storage->shader_allocate(); + storage->shader_initialize(wireframe_material_shader); storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }"); - wireframe_material = storage->material_create(); + wireframe_material = storage->material_allocate(); + storage->material_initialize(wireframe_material); storage->material_set_shader(wireframe_material, wireframe_material_shader); } @@ -3413,15 +3624,17 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor shadow_sampler = RD::get_singleton()->sampler_create(sampler); } - render_list_thread_threshold = GLOBAL_GET("rendering/forward_renderer/threaded_render_minimum_instances"); + render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances"); } RendererSceneRenderForward::~RendererSceneRenderForward() { directional_shadow_atlas_set_size(0); //clear base uniform set if still valid - if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) { - RD::get_singleton()->free(render_pass_uniform_set); + for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) { + if (render_pass_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[i])) { + RD::get_singleton()->free(render_pass_uniform_sets[i]); + } } if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) { @@ -3440,9 +3653,16 @@ RendererSceneRenderForward::~RendererSceneRenderForward() { storage->free(default_material); { - RD::get_singleton()->free(scene_state.uniform_buffer); + for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) { + RD::get_singleton()->free(scene_state.uniform_buffers[i]); + } RD::get_singleton()->free(scene_state.lightmap_buffer); RD::get_singleton()->free(scene_state.lightmap_capture_buffer); + for (uint32_t i = 0; i < RENDER_LIST_MAX; i++) { + if (scene_state.instance_buffer[i] != RID()) { + RD::get_singleton()->free(scene_state.instance_buffer[i]); + } + } memdelete_arr(scene_state.lightmap_captures); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h index 3b5a5ad96f..af78c50fda 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h @@ -50,6 +50,15 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { MAX_GI_PROBES = 8, MAX_LIGHTMAPS = 8, MAX_GI_PROBES_PER_INSTANCE = 2, + INSTANCE_DATA_BUFFER_MIN_SIZE = 4096 + }; + + enum RenderListType { + RENDER_LIST_OPAQUE, //used for opaque objects + RENDER_LIST_ALPHA, //used for transparent objects + RENDER_LIST_SECONDARY, //used for shadows and other objects + RENDER_LIST_MAX + }; /* Scene Shader */ @@ -213,9 +222,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RID normal_roughness_buffer; RID giprobe_buffer; - RID ambient_buffer; - RID reflection_buffer; - RS::ViewportMSAA msaa; RD::TextureSamples texture_samples; @@ -236,7 +242,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RID render_sdfgi_uniform_set; void ensure_specular(); - void ensure_gi(); void ensure_giprobe(); void clear(); virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa); @@ -249,7 +254,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RID shadow_sampler; RID render_base_uniform_set; - RID render_pass_uniform_set; + LocalVector<RID> render_pass_uniform_sets; RID sdfgi_pass_uniform_set; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -258,12 +263,61 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb); virtual void _render_buffers_uniform_set_changed(RID p_render_buffers); virtual RID _render_buffers_get_normal_texture(RID p_render_buffers); - virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers); - virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers); void _update_render_base_uniform_set(); RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture); - RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0); + + enum PassMode { + PASS_MODE_COLOR, + PASS_MODE_COLOR_SPECULAR, + PASS_MODE_COLOR_TRANSPARENT, + PASS_MODE_SHADOW, + PASS_MODE_SHADOW_DP, + PASS_MODE_DEPTH, + PASS_MODE_DEPTH_NORMAL_ROUGHNESS, + PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE, + PASS_MODE_DEPTH_MATERIAL, + PASS_MODE_SDF, + }; + + struct GeometryInstanceSurfaceDataCache; + struct RenderElementInfo; + + struct RenderListParameters { + GeometryInstanceSurfaceDataCache **elements = nullptr; + RenderElementInfo *element_info = nullptr; + int element_count = 0; + bool reverse_cull = false; + PassMode pass_mode = PASS_MODE_COLOR; + bool no_gi = false; + RID render_pass_uniform_set; + bool force_wireframe = false; + Vector2 uv_offset; + Plane lod_plane; + float lod_distance_multiplier = 0.0; + float screen_lod_threshold = 0.0; + RD::FramebufferFormatID framebuffer_format = 0; + uint32_t element_offset = 0; + uint32_t barrier = RD::BARRIER_MASK_ALL; + + RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { + elements = p_elements; + element_info = p_element_info; + element_count = p_element_count; + reverse_cull = p_reverse_cull; + pass_mode = p_pass_mode; + no_gi = p_no_gi; + render_pass_uniform_set = p_render_pass_uniform_set; + force_wireframe = p_force_wireframe; + uv_offset = p_uv_offset; + lod_plane = p_lod_plane; + lod_distance_multiplier = p_lod_distance_multiplier; + screen_lod_threshold = p_screen_lod_threshold; + element_offset = p_element_offset; + barrier = p_barrier; + } + }; struct LightmapData { float normal_xform[12]; @@ -300,6 +354,11 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { float viewport_size[2]; float screen_pixel_size[2]; + uint32_t cluster_shift; + uint32_t cluster_width; + uint32_t cluster_type_size; + uint32_t max_cluster_element_count_div_32; + float directional_penumbra_shadow_kernel[128]; //32 vec4s float directional_soft_shadow_kernel[128]; float penumbra_shadow_kernel[128]; @@ -368,9 +427,24 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { uint32_t pancake_shadows; }; + struct PushConstant { + uint32_t base_index; // + uint32_t uv_offset; //packed + uint32_t pad[2]; + }; + + struct InstanceData { + float transform[16]; + uint32_t flags; + uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables + uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index) + uint32_t layer_mask; + float lightmap_uv_scale[4]; + }; + UBO ubo; - RID uniform_buffer; + LocalVector<RID> uniform_buffers; LightmapData lightmaps[MAX_LIGHTMAPS]; RID lightmap_ids[MAX_LIGHTMAPS]; @@ -379,6 +453,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { uint32_t max_lightmaps; RID lightmap_buffer; + RID instance_buffer[RENDER_LIST_MAX]; + uint32_t instance_buffer_size[RENDER_LIST_MAX] = { 0, 0, 0 }; + LocalVector<InstanceData> instance_data[RENDER_LIST_MAX]; + LightmapCaptureData *lightmap_captures; uint32_t max_lightmap_captures; RID lightmap_capture_buffer; @@ -391,10 +469,29 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { bool used_depth_texture = false; bool used_sss = false; + struct ShadowPass { + uint32_t element_from; + uint32_t element_count; + bool flip_cull; + PassMode pass_mode; + + RID rp_uniform_set; + Plane camera_plane; + float lod_distance_multiplier; + float screen_lod_threshold; + + RID framebuffer; + RD::InitialAction initial_depth_action; + RD::FinalAction final_depth_action; + Rect2i rect; + }; + + LocalVector<ShadowPass> shadow_passes; + } scene_state; static RendererSceneRenderForward *singleton; - uint64_t render_pass; + double time; RID default_shader; RID default_material; @@ -408,51 +505,15 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RID default_vec4_xform_buffer; RID default_vec4_xform_uniform_set; - enum PassMode { - PASS_MODE_COLOR, - PASS_MODE_COLOR_SPECULAR, - PASS_MODE_COLOR_TRANSPARENT, - PASS_MODE_SHADOW, - PASS_MODE_SHADOW_DP, - PASS_MODE_DEPTH, - PASS_MODE_DEPTH_NORMAL_ROUGHNESS, - PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE, - PASS_MODE_DEPTH_MATERIAL, - PASS_MODE_SDF, - }; - - void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false); + void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); void _setup_giprobes(const PagedArray<RID> &p_giprobes); void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform); - struct GeometryInstanceSurfaceDataCache; - - struct RenderListParameters { - GeometryInstanceSurfaceDataCache **elements = nullptr; - int element_count = 0; - bool reverse_cull = false; - PassMode pass_mode = PASS_MODE_COLOR; - bool no_gi = false; - RID render_pass_uniform_set; - bool force_wireframe = false; - Vector2 uv_offset; - Plane lod_plane; - float lod_distance_multiplier = 0.0; - float screen_lod_threshold = 0.0; - RD::FramebufferFormatID framebuffer_format = 0; - RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) { - elements = p_elements; - element_count = p_element_count; - reverse_cull = p_reverse_cull; - pass_mode = p_pass_mode; - no_gi = p_no_gi; - render_pass_uniform_set = p_render_pass_uniform_set; - force_wireframe = p_force_wireframe; - uv_offset = p_uv_offset; - lod_plane = p_lod_plane; - lod_distance_multiplier = p_lod_distance_multiplier; - screen_lod_threshold = p_screen_lod_threshold; - } + struct RenderElementInfo { + uint32_t repeat : 22; + uint32_t uses_lightmap : 1; + uint32_t uses_forward_gi : 1; + uint32_t lod_index : 8; }; template <PassMode p_pass_mode> @@ -466,7 +527,9 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { uint32_t render_list_thread_threshold = 500; - void _fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false); + void _update_instance_data_buffer(RenderListType p_render_list); + void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); + void _fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false); Map<Size2i, RID> sdfgi_framebuffer_size_cache; @@ -494,14 +557,17 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { union { struct { - uint32_t geometry_id; - uint32_t material_id; - uint32_t shader_id; - uint32_t surface_type : 4; - uint32_t uses_forward_gi : 1; //set during addition - uint32_t uses_lightmap : 1; //set during addition - uint32_t depth_layer : 4; //set during addition - uint32_t priority : 8; + uint64_t lod_index : 8; + uint64_t surface_index : 10; + uint64_t geometry_id : 32; + uint64_t material_id_low : 14; + + uint64_t material_id_hi : 18; + uint64_t shader_id : 32; + uint64_t uses_forward_gi : 1; + uint64_t uses_lightmap : 1; + uint64_t depth_layer : 4; + uint64_t priority : 8; }; struct { uint64_t sort_key1; @@ -533,20 +599,20 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { float lod_model_scale = 1.0; AABB transformed_aabb; //needed for LOD float depth = 0; - struct PushConstant { - float transform[16]; - uint32_t flags; - uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables - uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index) - uint32_t layer_mask; - float lightmap_uv_scale[4]; - } push_constant; + uint32_t gi_offset_cache = 0; + uint32_t flags_cache = 0; + bool store_transform_cache = true; + int32_t shader_parameters_offset = -1; + uint32_t lightmap_slice_index; + Rect2 lightmap_uv_scale; + uint32_t layer_mask = 1; RID transforms_uniform_set; uint32_t instance_count = 0; RID mesh_instance; bool can_sdfgi = false; //used during setup uint32_t base_flags = 0; + Transform transform; RID gi_probes[MAX_GI_PROBES_PER_INSTANCE]; RID lightmap_instance; GeometryInstanceLightmapSH *lightmap_sh = nullptr; @@ -559,21 +625,14 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RS::InstanceType base_type; RID skeleton; - - uint32_t layer_mask = 1; - Vector<RID> surface_materials; RID material_override; - Transform transform; AABB aabb; - int32_t shader_parameters_offset = -1; bool use_dynamic_gi = false; bool use_baked_light = false; bool cast_double_sided_shaodows = false; bool mirror = false; - Rect2 lightmap_uv_scale; - uint32_t lightmap_slice_index = 0; bool dirty_dependencies = false; RendererStorage::DependencyTracker dependency_tracker; @@ -605,16 +664,12 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { /* Render List */ struct RenderList { - int max_elements; - - GeometryInstanceSurfaceDataCache **elements = nullptr; - - int element_count; - int alpha_element_count; + LocalVector<GeometryInstanceSurfaceDataCache *> elements; + LocalVector<RenderElementInfo> element_info; void clear() { - element_count = 0; - alpha_element_count = 0; + elements.clear(); + element_info.clear(); } //should eventually be replaced by radix @@ -625,13 +680,14 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { } }; - void sort_by_key(bool p_alpha) { + void sort_by_key() { SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + sorter.sort(elements.ptr(), elements.size()); + } + + void sort_by_key_range(uint32_t p_from, uint32_t p_size) { + SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter; + sorter.sort(elements.ptr() + p_from, p_size); } struct SortByDepth { @@ -640,14 +696,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { } }; - void sort_by_depth(bool p_alpha) { //used for shadows + void sort_by_depth() { //used for shadows SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + sorter.sort(elements.ptr(), elements.size()); } struct SortByReverseDepthAndPriority { @@ -659,50 +711,24 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + sorter.sort(elements.ptr(), elements.size()); } _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) { - if (element_count + alpha_element_count >= max_elements) { - return; - } - elements[element_count] = p_element; - element_count++; - } - - _FORCE_INLINE_ void add_alpha_element(GeometryInstanceSurfaceDataCache *p_element) { - if (element_count + alpha_element_count >= max_elements) { - return; - } - int idx = max_elements - alpha_element_count - 1; - elements[idx] = p_element; - alpha_element_count++; - } - - void init() { - element_count = 0; - alpha_element_count = 0; - elements = memnew_arr(GeometryInstanceSurfaceDataCache *, max_elements); - } - - RenderList() { - max_elements = 0; - } - - ~RenderList() { - memdelete_arr(elements); + elements.push_back(p_element); } }; - RenderList render_list; + RenderList render_list[RENDER_LIST_MAX]; protected: - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold); - virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0); + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold); + + virtual void _render_shadow_begin(); + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); + virtual void _render_shadow_process(); + virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL); + virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 188bcde8d7..15e963f6e4 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -183,13 +183,11 @@ void RendererSceneRenderRD::_create_reflection_importance_sample(ReflectionData void RendererSceneRenderRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) { for (int i = p_start; i < p_end; i++) { - for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) { - for (int k = 0; k < 6; k++) { - RID view = rd.layers[i].mipmaps[j].views[k]; - RID texture = rd.layers[i].mipmaps[j + 1].views[k]; - Size2i size = rd.layers[i].mipmaps[j + 1].size; - storage->get_effects()->make_mipmap(view, texture, size); - } + for (int j = 0; j < rd.layers[i].views.size() - 1; j++) { + RID view = rd.layers[i].views[j]; + RID texture = rd.layers[i].views[j + 1]; + Size2i size = rd.layers[i].mipmaps[j + 1].size; + storage->get_effects()->cubemap_downsample(view, texture, size); } } } @@ -669,6 +667,13 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment u.ids.push_back(rb->sdfgi->lightprobe_texture); uniforms.push_back(u); } + { + RD::Uniform u; + u.binding = 11; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.ids.push_back(rb->sdfgi->occlusion_texture); + uniforms.push_back(u); + } cascade.sdf_direct_light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, 0), 0); } @@ -951,7 +956,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment sdfgi->cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 0); } - sdfgi->uses_multibounce = env->sdfgi_use_multibounce; + sdfgi->bounce_feedback = env->sdfgi_bounce_feedback; sdfgi->energy = env->sdfgi_energy; sdfgi->normal_bias = env->sdfgi_normal_bias; sdfgi->probe_bias = env->sdfgi_probe_bias; @@ -964,7 +969,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment //check for updates - sdfgi->uses_multibounce = env->sdfgi_use_multibounce; + sdfgi->bounce_feedback = env->sdfgi_bounce_feedback; sdfgi->energy = env->sdfgi_energy; sdfgi->normal_bias = env->sdfgi_normal_bias; sdfgi->probe_bias = env->sdfgi_probe_bias; @@ -1150,150 +1155,72 @@ void RendererSceneRenderRD::_sdfgi_update_cascades(RID p_render_buffers) { cascade_data[i].pad = 0; } - RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, true); + RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); } -void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) { +void RendererSceneRenderRD::_sdfgi_update_light(RID p_render_buffers, RID p_environment) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { return; } - Environment *env = environment_owner.getornull(p_environment); - - RENDER_TIMESTAMP(">SDFGI Update Probes"); - - /* Update Cascades UBO */ - _sdfgi_update_cascades(p_render_buffers); - /* Update Dynamic Lights Buffer */ - - RENDER_TIMESTAMP("Update Lights"); - - /* Update dynamic lights */ - - { - int32_t cascade_light_count[SDFGI::MAX_CASCADES]; - - for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { - SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; - - SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS]; - uint32_t idx = 0; - for (uint32_t j = 0; j < (uint32_t)p_directional_lights.size(); j++) { - if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { - break; - } - - LightInstance *li = light_instance_owner.getornull(p_directional_lights[j]); - ERR_CONTINUE(!li); - if (storage->light_directional_is_sky_only(li->light)) { - continue; - } + RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light"); - Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); - dir.y *= rb->sdfgi->y_mult; - dir.normalize(); - lights[idx].direction[0] = dir.x; - lights[idx].direction[1] = dir.y; - lights[idx].direction[2] = dir.z; - Color color = storage->light_get_color(li->light); - color = color.to_linear(); - lights[idx].color[0] = color.r; - lights[idx].color[1] = color.g; - lights[idx].color[2] = color.b; - lights[idx].type = RS::LIGHT_DIRECTIONAL; - lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); - lights[idx].has_shadow = storage->light_has_shadow(li->light); - - idx++; - } - - AABB cascade_aabb; - cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + cascade.position)) * cascade.cell_size; - cascade_aabb.size = Vector3(1, 1, 1) * rb->sdfgi->cascade_size * cascade.cell_size; - - for (uint32_t j = 0; j < p_positional_light_count; j++) { - if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { - break; - } + /* Update dynamic light */ - LightInstance *li = light_instance_owner.getornull(p_positional_light_instances[j]); - ERR_CONTINUE(!li); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_DYNAMIC]); - uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light); - if (i > max_sdfgi_cascade) { - continue; - } + SDGIShader::DirectLightPushConstant push_constant; - if (!cascade_aabb.intersects(li->aabb)) { - continue; - } + push_constant.grid_size[0] = rb->sdfgi->cascade_size; + push_constant.grid_size[1] = rb->sdfgi->cascade_size; + push_constant.grid_size[2] = rb->sdfgi->cascade_size; + push_constant.max_cascades = rb->sdfgi->cascades.size(); + push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; + push_constant.bounce_feedback = rb->sdfgi->bounce_feedback; + push_constant.y_mult = rb->sdfgi->y_mult; + push_constant.use_occlusion = rb->sdfgi->uses_occlusion; - Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); - //faster to not do this here - //dir.y *= rb->sdfgi->y_mult; - //dir.normalize(); - lights[idx].direction[0] = dir.x; - lights[idx].direction[1] = dir.y; - lights[idx].direction[2] = dir.z; - Vector3 pos = li->transform.origin; - pos.y *= rb->sdfgi->y_mult; - lights[idx].position[0] = pos.x; - lights[idx].position[1] = pos.y; - lights[idx].position[2] = pos.z; - Color color = storage->light_get_color(li->light); - color = color.to_linear(); - lights[idx].color[0] = color.r; - lights[idx].color[1] = color.g; - lights[idx].color[2] = color.b; - lights[idx].type = storage->light_get_type(li->light); - lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); - lights[idx].has_shadow = storage->light_has_shadow(li->light); - lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); - lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); - lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)); - lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { + SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; + push_constant.light_count = rb->sdfgi->cascade_dynamic_light_count[i]; + push_constant.cascade = i; - idx++; - } + if (rb->sdfgi->cascades[i].all_dynamic_lights_dirty || sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) { + push_constant.process_offset = 0; + push_constant.process_increment = 1; + } else { + static uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = { + 1, 2, 4, 8, 16 + }; - if (idx > 0) { - RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, true); - } + uint32_t frames_to_update = frames_to_update_table[sdfgi_frames_to_update_light]; - cascade_light_count[i] = idx; + push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update; + push_constant.process_increment = frames_to_update; } + rb->sdfgi->cascades[i].all_dynamic_lights_dirty = false; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_DYNAMIC]); - - SDGIShader::DirectLightPushConstant push_constant; - - push_constant.grid_size[0] = rb->sdfgi->cascade_size; - push_constant.grid_size[1] = rb->sdfgi->cascade_size; - push_constant.grid_size[2] = rb->sdfgi->cascade_size; - push_constant.max_cascades = rb->sdfgi->cascades.size(); - push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; - push_constant.multibounce = rb->sdfgi->uses_multibounce; - push_constant.y_mult = rb->sdfgi->y_mult; - - push_constant.process_offset = 0; - push_constant.process_increment = 1; - - for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { - SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; - push_constant.light_count = cascade_light_count[i]; - push_constant.cascade = i; + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant)); + RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0); + } + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); + RD::get_singleton()->draw_command_end_label(); +} - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant)); - RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0); - } - RD::get_singleton()->compute_list_end(); +void RendererSceneRenderRD::_sdfgi_update_probes(RID p_render_buffers, RID p_environment) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(rb == nullptr); + if (rb->sdfgi == nullptr) { + return; } - RENDER_TIMESTAMP("Raytrace"); + RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes"); + + Environment *env = environment_owner.getornull(p_environment); SDGIShader::IntegratePushConstant push_constant; push_constant.grid_size[1] = rb->sdfgi->cascade_size; @@ -1303,7 +1230,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; push_constant.history_index = rb->sdfgi->render_pass % rb->sdfgi->history_size; push_constant.history_size = rb->sdfgi->history_size; - static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 8, 16, 32, 64, 96, 128 }; + static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 }; push_constant.ray_count = ray_count[sdfgi_ray_count]; push_constant.ray_bias = rb->sdfgi->probe_bias; push_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count; @@ -1362,7 +1289,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi rb->sdfgi->render_pass++; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_PROCESS]); int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR; @@ -1376,14 +1303,47 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1); } - RD::get_singleton()->compute_list_add_barrier(compute_list); //wait until done + //end later after raster to avoid barriering on layout changes + //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); + + RD::get_singleton()->draw_command_end_label(); +} + +void RendererSceneRenderRD::_sdfgi_store_probes(RID p_render_buffers) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(rb == nullptr); + if (rb->sdfgi == nullptr) { + return; + } + + RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE); + RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes"); + + SDGIShader::IntegratePushConstant push_constant; + push_constant.grid_size[1] = rb->sdfgi->cascade_size; + push_constant.grid_size[2] = rb->sdfgi->cascade_size; + push_constant.grid_size[0] = rb->sdfgi->cascade_size; + push_constant.max_cascades = rb->sdfgi->cascades.size(); + push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; + push_constant.history_index = rb->sdfgi->render_pass % rb->sdfgi->history_size; + push_constant.history_size = rb->sdfgi->history_size; + static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 }; + push_constant.ray_count = ray_count[sdfgi_ray_count]; + push_constant.ray_bias = rb->sdfgi->probe_bias; + push_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count; + push_constant.image_size[1] = rb->sdfgi->probe_axis_count; + push_constant.store_ambient_texture = false; + + push_constant.sky_mode = 0; + push_constant.y_mult = rb->sdfgi->y_mult; // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces RENDER_TIMESTAMP("Average Probes"); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]); //convert to octahedral to store @@ -1393,20 +1353,22 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { push_constant.cascade = i; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[i].integrate_uniform_set, 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1); } - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); - RENDER_TIMESTAMP("<SDFGI Update Probes"); + RD::get_singleton()->draw_command_end_label(); } - void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used) { r_gi_probes_used = 0; RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); + RD::get_singleton()->draw_command_begin_label("GIProbes Setup"); + RID gi_probe_buffer = render_buffers_get_gi_probe_buffer(p_render_buffers); GI::GIProbeData gi_probe_data[RenderBuffers::MAX_GIPROBES]; @@ -1490,56 +1452,25 @@ void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transfor } if (p_gi_probes.size() > 0) { - RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, true); + RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, RD::BARRIER_MASK_COMPUTE); } -} -void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) { - RENDER_TIMESTAMP("Render GI"); + RD::get_singleton()->draw_command_end_label(); +} +void RendererSceneRenderRD::_pre_process_gi(RID p_render_buffers, const Transform &p_transform) { + // Do the required buffer transfers and setup before the depth-pre pass, this way GI can + // run in parallel during depth-pre pass and shadow rendering. RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); - Environment *env = environment_owner.getornull(p_environment); - - GI::PushConstant push_constant; - push_constant.screen_size[0] = rb->width; - push_constant.screen_size[1] = rb->height; - push_constant.z_near = p_projection.get_z_near(); - push_constant.z_far = p_projection.get_z_far(); - push_constant.orthogonal = p_projection.is_orthogonal(); - push_constant.proj_info[0] = -2.0f / (rb->width * p_projection.matrix[0][0]); - push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]); - push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0]; - push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1]; - push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()); - push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH; - push_constant.use_sdfgi = rb->sdfgi != nullptr; + /* Update Cascades UBO */ - if (env) { - push_constant.ao_color[0] = env->ao_color.r; - push_constant.ao_color[1] = env->ao_color.g; - push_constant.ao_color[2] = env->ao_color.b; - } else { - push_constant.ao_color[0] = 0; - push_constant.ao_color[1] = 0; - push_constant.ao_color[2] = 0; - } + if (rb->sdfgi) { + /* Update general SDFGI Buffer */ - push_constant.cam_rotation[0] = p_transform.basis[0][0]; - push_constant.cam_rotation[1] = p_transform.basis[1][0]; - push_constant.cam_rotation[2] = p_transform.basis[2][0]; - push_constant.cam_rotation[3] = 0; - push_constant.cam_rotation[4] = p_transform.basis[0][1]; - push_constant.cam_rotation[5] = p_transform.basis[1][1]; - push_constant.cam_rotation[6] = p_transform.basis[2][1]; - push_constant.cam_rotation[7] = 0; - push_constant.cam_rotation[8] = p_transform.basis[0][2]; - push_constant.cam_rotation[9] = p_transform.basis[1][2]; - push_constant.cam_rotation[10] = p_transform.basis[2][2]; - push_constant.cam_rotation[11] = 0; + _sdfgi_update_cascades(p_render_buffers); - if (rb->sdfgi) { GI::SDFGIData sdfgi_data; sdfgi_data.grid_size[0] = rb->sdfgi->cascade_size; @@ -1606,9 +1537,172 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough c.to_cell = 1.0 / rb->sdfgi->cascades[i].cell_size; } - RD::get_singleton()->buffer_update(gi.sdfgi_ubo, 0, sizeof(GI::SDFGIData), &sdfgi_data, true); + RD::get_singleton()->buffer_update(gi.sdfgi_ubo, 0, sizeof(GI::SDFGIData), &sdfgi_data, RD::BARRIER_MASK_COMPUTE); + + /* Update dynamic lights in SDFGI cascades */ + + for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { + SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; + + SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS]; + uint32_t idx = 0; + for (uint32_t j = 0; j < (uint32_t)render_state.sdfgi_update_data->directional_lights->size(); j++) { + if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { + break; + } + + LightInstance *li = light_instance_owner.getornull(render_state.sdfgi_update_data->directional_lights->get(j)); + ERR_CONTINUE(!li); + + if (storage->light_directional_is_sky_only(li->light)) { + continue; + } + + Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); + dir.y *= rb->sdfgi->y_mult; + dir.normalize(); + lights[idx].direction[0] = dir.x; + lights[idx].direction[1] = dir.y; + lights[idx].direction[2] = dir.z; + Color color = storage->light_get_color(li->light); + color = color.to_linear(); + lights[idx].color[0] = color.r; + lights[idx].color[1] = color.g; + lights[idx].color[2] = color.b; + lights[idx].type = RS::LIGHT_DIRECTIONAL; + lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); + lights[idx].has_shadow = storage->light_has_shadow(li->light); + + idx++; + } + + AABB cascade_aabb; + cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + cascade.position)) * cascade.cell_size; + cascade_aabb.size = Vector3(1, 1, 1) * rb->sdfgi->cascade_size * cascade.cell_size; + + for (uint32_t j = 0; j < render_state.sdfgi_update_data->positional_light_count; j++) { + if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { + break; + } + + LightInstance *li = light_instance_owner.getornull(render_state.sdfgi_update_data->positional_light_instances[j]); + ERR_CONTINUE(!li); + + uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light); + if (i > max_sdfgi_cascade) { + continue; + } + + if (!cascade_aabb.intersects(li->aabb)) { + continue; + } + + Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); + //faster to not do this here + //dir.y *= rb->sdfgi->y_mult; + //dir.normalize(); + lights[idx].direction[0] = dir.x; + lights[idx].direction[1] = dir.y; + lights[idx].direction[2] = dir.z; + Vector3 pos = li->transform.origin; + pos.y *= rb->sdfgi->y_mult; + lights[idx].position[0] = pos.x; + lights[idx].position[1] = pos.y; + lights[idx].position[2] = pos.z; + Color color = storage->light_get_color(li->light); + color = color.to_linear(); + lights[idx].color[0] = color.r; + lights[idx].color[1] = color.g; + lights[idx].color[2] = color.b; + lights[idx].type = storage->light_get_type(li->light); + lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); + lights[idx].has_shadow = storage->light_has_shadow(li->light); + lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); + lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); + lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE))); + lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + + idx++; + } + + if (idx > 0) { + RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, RD::BARRIER_MASK_COMPUTE); + } + + rb->sdfgi->cascade_dynamic_light_count[i] = idx; + } + } +} + +void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) { + RD::get_singleton()->draw_command_begin_label("GI Render"); + + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(rb == nullptr); + Environment *env = environment_owner.getornull(p_environment); + + if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != gi.half_resolution) { + if (rb->ambient_buffer.is_valid()) { + RD::get_singleton()->free(rb->ambient_buffer); + RD::get_singleton()->free(rb->reflection_buffer); + } + + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = rb->width; + tf.height = rb->height; + if (gi.half_resolution) { + tf.width >>= 1; + tf.height >>= 1; + } + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->using_half_size_gi = gi.half_resolution; + + _render_buffers_uniform_set_changed(p_render_buffers); + } + + GI::PushConstant push_constant; + + push_constant.screen_size[0] = rb->width; + push_constant.screen_size[1] = rb->height; + push_constant.z_near = p_projection.get_z_near(); + push_constant.z_far = p_projection.get_z_far(); + push_constant.orthogonal = p_projection.is_orthogonal(); + push_constant.proj_info[0] = -2.0f / (rb->width * p_projection.matrix[0][0]); + push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]); + push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0]; + push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1]; + push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()); + push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH; + + bool use_sdfgi = rb->sdfgi != nullptr; + bool use_giprobes = push_constant.max_giprobes > 0; + + if (env) { + push_constant.ao_color[0] = env->ao_color.r; + push_constant.ao_color[1] = env->ao_color.g; + push_constant.ao_color[2] = env->ao_color.b; + } else { + push_constant.ao_color[0] = 0; + push_constant.ao_color[1] = 0; + push_constant.ao_color[2] = 0; } + push_constant.cam_rotation[0] = p_transform.basis[0][0]; + push_constant.cam_rotation[1] = p_transform.basis[1][0]; + push_constant.cam_rotation[2] = p_transform.basis[2][0]; + push_constant.cam_rotation[3] = 0; + push_constant.cam_rotation[4] = p_transform.basis[0][1]; + push_constant.cam_rotation[5] = p_transform.basis[1][1]; + push_constant.cam_rotation[6] = p_transform.basis[2][1]; + push_constant.cam_rotation[7] = 0; + push_constant.cam_rotation[8] = p_transform.basis[0][2]; + push_constant.cam_rotation[9] = p_transform.basis[1][2]; + push_constant.cam_rotation[10] = p_transform.basis[2][2]; + push_constant.cam_rotation[11] = 0; + if (rb->gi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) { Vector<RD::Uniform> uniforms; { @@ -1693,7 +1787,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(p_ambient_buffer); + u.ids.push_back(rb->ambient_buffer); uniforms.push_back(u); } @@ -1701,7 +1795,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(p_reflection_buffer); + u.ids.push_back(rb->reflection_buffer); uniforms.push_back(u); } @@ -1765,16 +1859,33 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough rb->gi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi.shader.version_get_shader(gi.shader_version, 0), 0); } - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi.pipelines[0]); + GI::Mode mode; + + if (rb->using_half_size_gi) { + mode = (use_sdfgi && use_giprobes) ? GI::MODE_HALF_RES_COMBINED : (use_sdfgi ? GI::MODE_HALF_RES_SDFGI : GI::MODE_HALF_RES_GIPROBE); + } else { + mode = (use_sdfgi && use_giprobes) ? GI::MODE_COMBINED : (use_sdfgi ? GI::MODE_SDFGI : GI::MODE_GIPROBE); + } + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GI::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1); - RD::get_singleton()->compute_list_end(); + + if (rb->using_half_size_gi) { + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1); + } else { + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1); + } + //do barrier later to allow oeverlap + //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time + RD::get_singleton()->draw_command_end_label(); } -RID RendererSceneRenderRD::sky_create() { - return sky_owner.make_rid(Sky()); +RID RendererSceneRenderRD::sky_allocate() { + return sky_owner.allocate_rid(); +} +void RendererSceneRenderRD::sky_initialize(RID p_rid) { + sky_owner.initialize_rid(p_rid, Sky()); } void RendererSceneRenderRD::_sky_invalidate(Sky *p_sky) { @@ -2288,7 +2399,7 @@ void RendererSceneRenderRD::_setup_sky(RID p_environment, RID p_render_buffers, } if (light_data_dirty) { - RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true); + RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights); RendererSceneRenderRD::SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights; sky_scene_state.last_frame_directional_lights = sky_scene_state.directional_lights; @@ -2340,7 +2451,7 @@ void RendererSceneRenderRD::_setup_sky(RID p_environment, RID p_render_buffers, sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; sky_scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment); - RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo, true); + RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } void RendererSceneRenderRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { @@ -2798,8 +2909,11 @@ RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_sky_material_fun return material_data; } -RID RendererSceneRenderRD::environment_create() { - return environment_owner.make_rid(Environment()); +RID RendererSceneRenderRD::environment_allocate() { + return environment_owner.allocate_rid(); +} +void RendererSceneRenderRD::environment_initialize(RID p_rid) { + environment_owner.initialize_rid(p_rid, Environment()); } void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { @@ -2973,7 +3087,7 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) glow_high_quality = p_enable; } -void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { +void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -2985,7 +3099,7 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS:: env->sdfgi_cascades = p_cascades; env->sdfgi_min_cell_size = p_min_cell_size; env->sdfgi_use_occlusion = p_use_occlusion; - env->sdfgi_use_multibounce = p_use_multibounce; + env->sdfgi_bounce_feedback = p_bounce_feedback; env->sdfgi_read_sky_light = p_read_sky; env->sdfgi_energy = p_energy; env->sdfgi_normal_bias = p_normal_bias; @@ -3051,7 +3165,7 @@ float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) c return env->fog_aerial_perspective; } -void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) { +void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3065,8 +3179,9 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena env->volumetric_fog_light_energy = p_light_energy; env->volumetric_fog_length = p_length; env->volumetric_fog_detail_spread = p_detail_spread; - env->volumetric_fog_shadow_filter = p_shadow_filter; env->volumetric_fog_gi_inject = p_gi_inject; + env->volumetric_fog_temporal_reprojection = p_temporal_reprojection; + env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; } void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { @@ -3077,25 +3192,6 @@ void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_siz void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) { volumetric_fog_filter_active = p_enable; } -void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) { - p_shrink_size = nearest_power_of_2_templated(p_shrink_size); - if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) { - return; - } - - _clear_shadow_shrink_stages(directional_shadow.shrink_stages); -} -void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) { - p_shrink_size = nearest_power_of_2_templated(p_shrink_size); - if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) { - return; - } - - for (uint32_t i = 0; i < shadow_atlas_owner.get_rid_count(); i++) { - ShadowAtlas *sa = shadow_atlas_owner.get_ptr_by_index(i); - _clear_shadow_shrink_stages(sa->shrink_stages); - } -} void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { sdfgi_ray_count = p_ray_count; @@ -3104,6 +3200,9 @@ void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGI void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) { sdfgi_frames_to_converge = p_frames; } +void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) { + sdfgi_frames_to_update_light = p_update; +} void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { Environment *env = environment_owner.getornull(p_env); @@ -3230,8 +3329,12 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba RID RendererSceneRenderRD::reflection_atlas_create() { ReflectionAtlas ra; - ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count"); - ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size"); + ra.count = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_count"); + ra.size = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_size"); + + ra.cluster_builder = memnew(ClusterBuilderRD); + ra.cluster_builder->set_shared(&cluster_builder_shared); + ra.cluster_builder->setup(Size2i(ra.size, ra.size), max_cluster_elements, RID(), RID(), RID()); return reflection_atlas_owner.make_rid(ra); } @@ -3244,6 +3347,8 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref return; //no changes } + ra->cluster_builder->setup(Size2i(ra->size, ra->size), max_cluster_elements, RID(), RID(), RID()); + ra->size = p_reflection_size; ra->count = p_reflection_count; @@ -3253,7 +3358,6 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref ra->reflection = RID(); RD::get_singleton()->free(ra->depth_buffer); ra->depth_buffer = RID(); - for (int i = 0; i < ra->reflections.size(); i++) { _clear_reflection_data(ra->reflections.write[i].data); if (ra->reflections[i].owner.is_null()) { @@ -3510,13 +3614,28 @@ RID RendererSceneRenderRD::shadow_atlas_create() { return shadow_atlas_owner.make_rid(ShadowAtlas()); } -void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) { +void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) { + if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) { + RD::TextureFormat tf; + tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT; + tf.width = shadow_atlas->size; + tf.height = shadow_atlas->size; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + Vector<RID> fb_tex; + fb_tex.push_back(shadow_atlas->depth); + shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex); + } +} + +void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); - if (p_size == shadow_atlas->size) { + if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) { return; } @@ -3524,7 +3643,6 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) { if (shadow_atlas->depth.is_valid()) { RD::get_singleton()->free(shadow_atlas->depth); shadow_atlas->depth = RID(); - _clear_shadow_shrink_stages(shadow_atlas->shrink_stages); } for (int i = 0; i < 4; i++) { //clear subdivisions @@ -3543,16 +3661,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) { shadow_atlas->shadow_owners.clear(); shadow_atlas->size = p_size; - - if (shadow_atlas->size) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = shadow_atlas->size; - tf.height = shadow_atlas->size; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - - shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } + shadow_atlas->use_16_bits = p_size; } void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { @@ -3807,10 +3916,24 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i return false; } -void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) { +void RendererSceneRenderRD::_update_directional_shadow_atlas() { + if (directional_shadow.depth.is_null() && directional_shadow.size > 0) { + RD::TextureFormat tf; + tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT; + tf.width = directional_shadow.size; + tf.height = directional_shadow.size; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + Vector<RID> fb_tex; + fb_tex.push_back(directional_shadow.depth); + directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex); + } +} +void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) { p_size = nearest_power_of_2_templated(p_size); - if (directional_shadow.size == p_size) { + if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) { return; } @@ -3818,21 +3941,9 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) { if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); - _clear_shadow_shrink_stages(directional_shadow.shrink_stages); directional_shadow.depth = RID(); + _base_uniforms_changed(); } - - if (p_size > 0) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = p_size; - tf.height = p_size; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - - directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } - - _base_uniforms_changed(); } void RendererSceneRenderRD::set_directional_shadow_count(int p_count) { @@ -3886,8 +3997,11 @@ int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance ////////////////////////////////////////////////// -RID RendererSceneRenderRD::camera_effects_create() { - return camera_effects_owner.make_rid(CameraEffects()); +RID RendererSceneRenderRD::camera_effects_allocate() { + return camera_effects_owner.allocate_rid(); +} +void RendererSceneRenderRD::camera_effects_initialize(RID p_rid) { + camera_effects_owner.initialize_rid(p_rid, CameraEffects()); } void RendererSceneRenderRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { @@ -3952,11 +4066,7 @@ void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_inst LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); - if (storage->light_get_type(light_instance->light) != RS::LIGHT_DIRECTIONAL) { - p_pass = 0; - } - - ERR_FAIL_INDEX(p_pass, 4); + ERR_FAIL_INDEX(p_pass, 6); light_instance->shadow_transform[p_pass].camera = p_projection; light_instance->shadow_transform[p_pass].transform = p_transform; @@ -4002,29 +4112,6 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap return &shadow_cubemaps[p_size]; } -RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) { - if (!shadow_maps.has(p_size)) { - ShadowMap sm; - { - RD::TextureFormat tf; - tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; - tf.width = p_size.width; - tf.height = p_size.height; - tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - - sm.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } - - Vector<RID> fbtex; - fbtex.push_back(sm.depth); - sm.fb = RD::get_singleton()->framebuffer_create(fbtex); - - shadow_maps[p_size] = sm; - } - - return &shadow_maps[p_size]; -} - ////////////////////////// RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { @@ -4125,7 +4212,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins gi_probe->texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->texture_clear(gi_probe->texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1, false); + RD::get_singleton()->texture_clear(gi_probe->texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1); { int total_elements = 0; @@ -4416,7 +4503,10 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins } } - dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT], 0); + dmap.uniform_set = RD::get_singleton()->uniform_set_create( + uniforms, + giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)], + 0); } gi_probe->dynamic_maps.push_back(dmap); @@ -4434,7 +4524,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins if (gi_probe->has_dynamic_object_data) { //if it has dynamic object data, it needs to be cleared - RD::get_singleton()->texture_clear(gi_probe->texture, Color(0, 0, 0, 0), 0, gi_probe->mipmaps.size(), 0, 1, true); + RD::get_singleton()->texture_clear(gi_probe->texture, Color(0, 0, 0, 0), 0, gi_probe->mipmaps.size(), 0, 1); } uint32_t light_count = 0; @@ -4466,8 +4556,8 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins l.color[1] = color.g; l.color[2] = color.b; - l.spot_angle_radians = Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)); - l.spot_attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); + l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); Transform xform = light_instance_get_base_transform(light_instance); @@ -4485,7 +4575,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins l.has_shadow = storage->light_has_shadow(light); } - RD::get_singleton()->buffer_update(gi_probe_lights_uniform, 0, sizeof(GIProbeLight) * light_count, gi_probe_lights, true); + RD::get_singleton()->buffer_update(gi_probe_lights_uniform, 0, sizeof(GIProbeLight) * light_count, gi_probe_lights); } } @@ -4850,7 +4940,16 @@ void RendererSceneRenderRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw } giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_debug_shader_version_shaders[0], 0); - RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, giprobe_debug_shader_version_pipelines[p_emission ? GI_PROBE_DEBUG_EMISSION : p_lighting ? (gi_probe->has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT) : GI_PROBE_DEBUG_COLOR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); + + int giprobe_debug_pipeline = GI_PROBE_DEBUG_COLOR; + if (p_emission) { + giprobe_debug_pipeline = GI_PROBE_DEBUG_EMISSION; + } else if (p_lighting) { + giprobe_debug_pipeline = gi_probe->has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT; + } + RD::get_singleton()->draw_list_bind_render_pipeline( + p_draw_list, + giprobe_debug_shader_version_pipelines[giprobe_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, giprobe_debug_uniform_set, 0); RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant)); RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36); @@ -4877,7 +4976,7 @@ void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawLi push_constant.band_power = 4; push_constant.sections_in_band = ((band_points / 2) - 1); push_constant.band_mask = band_points - 2; - push_constant.section_arc = (Math_PI * 2.0) / float(push_constant.sections_in_band); + push_constant.section_arc = Math_TAU / float(push_constant.sections_in_band); push_constant.y_mult = rb->sdfgi->y_mult; uint32_t total_points = push_constant.sections_in_band * band_points; @@ -5098,9 +5197,6 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { RD::get_singleton()->free(rb->luminance.reduce[i]); } - for (int i = 0; i < rb->luminance.reduce.size(); i++) { - RD::get_singleton()->free(rb->luminance.reduce[i]); - } rb->luminance.reduce.clear(); if (rb->luminance.current.is_valid()) { @@ -5141,6 +5237,13 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { RD::get_singleton()->free(rb->ssr.normal_scaled); rb->ssr.normal_scaled = RID(); } + + if (rb->ambient_buffer.is_valid()) { + RD::get_singleton()->free(rb->ambient_buffer); + RD::get_singleton()->free(rb->reflection_buffer); + rb->ambient_buffer = RID(); + rb->reflection_buffer = RID(); + } } void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { @@ -5273,9 +5376,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen tf.array_layers = 4; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; rb->ssao.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rb->ssao.depth, "SSAO Depth"); for (uint32_t i = 0; i < tf.mipmaps; i++) { RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.depth, 0, i, RD::TEXTURE_SLICE_2D_ARRAY); rb->ssao.depth_slices.push_back(slice); + RD::get_singleton()->set_resource_name(rb->ssao.depth_slices[i], "SSAO Depth Mip " + itos(i) + " "); } } @@ -5288,9 +5393,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen tf.array_layers = 4; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; rb->ssao.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved, "SSAO De-interleaved Array"); for (uint32_t i = 0; i < 4; i++) { RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_deinterleaved, i, 0); rb->ssao.ao_deinterleaved_slices.push_back(slice); + RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved_slices[i], "SSAO De-interleaved Array Layer " + itos(i) + " "); } } @@ -5303,9 +5410,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen tf.array_layers = 4; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; rb->ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rb->ssao.ao_pong, "SSAO De-interleaved Array Pong"); for (uint32_t i = 0; i < 4; i++) { RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_pong, i, 0); rb->ssao.ao_pong_slices.push_back(slice); + RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved_slices[i], "SSAO De-interleaved Array Layer " + itos(i) + " Pong"); } } @@ -5316,7 +5425,9 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen tf.height = half_height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; rb->ssao.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rb->ssao.importance_map[0], "SSAO Importance Map"); rb->ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rb->ssao.importance_map[1], "SSAO Importance Map Pong"); } { RD::TextureFormat tf; @@ -5325,6 +5436,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen tf.height = rb->height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; rb->ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rb->ssao.ao_final, "SSAO Final"); _render_buffers_uniform_set_changed(p_render_buffers); } ssao_using_half_size = ssao_half_size; @@ -5540,10 +5652,10 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); } - if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && _render_buffers_get_ambient_texture(p_render_buffers).is_valid()) { + if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); - RID ambient_texture = _render_buffers_get_ambient_texture(p_render_buffers); - RID reflection_texture = _render_buffers_get_reflection_texture(p_render_buffers); + RID ambient_texture = rb->ambient_buffer; + RID reflection_texture = rb->reflection_buffer; effects->copy_to_fb_rect(ambient_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture); } } @@ -5699,7 +5811,7 @@ void RendererSceneRenderRD::_sdfgi_debug_draw(RID p_render_buffers, const Camera RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DebugPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1); RD::get_singleton()->compute_list_end(); Size2 rtsize = storage->render_target_get_size(rb->render_target); @@ -5735,6 +5847,17 @@ RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() { return default_giprobe_buffer; } +RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND_V(!rb, RID()); + return rb->ambient_buffer; +} +RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND_V(!rb, RID()); + return rb->reflection_buffer; +} + uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const { const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); @@ -5872,6 +5995,11 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p rb->msaa = p_msaa; rb->screen_space_aa = p_screen_space_aa; rb->use_debanding = p_use_debanding; + if (rb->cluster_builder == nullptr) { + rb->cluster_builder = memnew(ClusterBuilderRD); + } + rb->cluster_builder->set_shared(&cluster_builder_shared); + _free_render_buffer_data(rb); { @@ -5912,6 +6040,12 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa); _render_buffers_uniform_set_changed(p_render_buffers); + + rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture); +} + +void RendererSceneRenderRD::gi_set_use_half_resolution(bool p_enable) { + gi.half_resolution = p_enable; } void RendererSceneRenderRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) { @@ -6022,17 +6156,34 @@ RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_g } void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment) { + cluster.reflection_count = 0; + for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) { - RID rpi = p_reflections[i]; + if (cluster.reflection_count == cluster.max_reflections) { + break; + } - if (i >= cluster.max_reflections) { - reflection_probe_instance_set_render_index(rpi, 0); //invalid, but something needs to be set + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflections[i]); + if (!rpi) { continue; } - reflection_probe_instance_set_render_index(rpi, i); + cluster.reflection_sort[cluster.reflection_count].instance = rpi; + cluster.reflection_sort[cluster.reflection_count].depth = -p_camera_inverse_transform.xform(rpi->transform.origin).z; + cluster.reflection_count++; + } - RID base_probe = reflection_probe_instance_get_probe(rpi); + if (cluster.reflection_count > 0) { + SortArray<Cluster::InstanceSort<ReflectionProbeInstance>> sort_array; + sort_array.sort(cluster.reflection_sort, cluster.reflection_count); + } + + for (uint32_t i = 0; i < cluster.reflection_count; i++) { + ReflectionProbeInstance *rpi = cluster.reflection_sort[i].instance; + + rpi->render_index = i; + + RID base_probe = rpi->probe; Cluster::ReflectionData &reflection_ubo = cluster.reflections[i]; @@ -6041,7 +6192,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti reflection_ubo.box_extents[0] = extents.x; reflection_ubo.box_extents[1] = extents.y; reflection_ubo.box_extents[2] = extents.z; - reflection_ubo.index = reflection_probe_instance_get_atlas_index(rpi); + reflection_ubo.index = rpi->atlas_index; Vector3 origin_offset = storage->reflection_probe_get_origin_offset(base_probe); @@ -6050,46 +6201,50 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti reflection_ubo.box_offset[2] = origin_offset.z; reflection_ubo.mask = storage->reflection_probe_get_cull_mask(base_probe); - float intensity = storage->reflection_probe_get_intensity(base_probe); - bool interior = storage->reflection_probe_is_interior(base_probe); - bool box_projection = storage->reflection_probe_is_box_projection(base_probe); + reflection_ubo.intensity = storage->reflection_probe_get_intensity(base_probe); + reflection_ubo.ambient_mode = storage->reflection_probe_get_ambient_mode(base_probe); - reflection_ubo.params[0] = intensity; - reflection_ubo.params[1] = 0; - reflection_ubo.params[2] = interior ? 1.0 : 0.0; - reflection_ubo.params[3] = box_projection ? 1.0 : 0.0; + reflection_ubo.exterior = !storage->reflection_probe_is_interior(base_probe); + reflection_ubo.box_project = storage->reflection_probe_is_box_projection(base_probe); Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).to_linear(); float interior_ambient_energy = storage->reflection_probe_get_ambient_color_energy(base_probe); - uint32_t ambient_mode = storage->reflection_probe_get_ambient_mode(base_probe); reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy; reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy; reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy; - reflection_ubo.ambient_mode = ambient_mode; - Transform transform = reflection_probe_instance_get_transform(rpi); + Transform transform = rpi->transform; Transform proj = (p_camera_inverse_transform * transform).inverse(); RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix); - cluster.builder.add_reflection_probe(transform, extents); + current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, transform, extents); - reflection_probe_instance_set_render_pass(rpi, RSG::rasterizer->get_frame_number()); + rpi->last_pass = RSG::rasterizer->get_frame_number(); } - if (p_reflections.size()) { - RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, MIN(cluster.max_reflections, (unsigned int)p_reflections.size()) * sizeof(ReflectionData), cluster.reflections, true); + if (cluster.reflection_count) { + RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, cluster.reflection_count * sizeof(ReflectionData), cluster.reflections, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } } -void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { - uint32_t light_count = 0; +void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { + Transform inverse_transform = p_camera_transform.affine_inverse(); + r_directional_light_count = 0; r_positional_light_count = 0; sky_scene_state.ubo.directional_light_count = 0; + Plane camera_plane(p_camera_transform.origin, -p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized()); + + cluster.omni_light_count = 0; + cluster.spot_light_count = 0; + for (int i = 0; i < (int)p_lights.size(); i++) { - RID li = p_lights[i]; - RID base = light_instance_get_base_light(li); + LightInstance *li = light_instance_owner.getornull(p_lights[i]); + if (!li) { + continue; + } + RID base = li->light; ERR_CONTINUE(base.is_null()); @@ -6099,7 +6254,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const // Copy to SkyDirectionalLightData if (r_directional_light_count < sky_scene_state.max_directional_lights) { SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count]; - Transform light_transform = light_instance_get_base_transform(li); + Transform light_transform = li->transform; Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); sky_light_data.direction[0] = world_direction.x; @@ -6135,9 +6290,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Cluster::DirectionalLightData &light_data = cluster.directional_lights[r_directional_light_count]; - Transform light_transform = light_instance_get_base_transform(li); + Transform light_transform = li->transform; - Vector3 direction = p_camera_inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized(); + Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized(); light_data.direction[0] = direction.x; light_data.direction[1] = direction.y; @@ -6216,28 +6371,28 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3); light_data.blend_splits = storage->light_directional_get_blend_splits(base); for (int j = 0; j < 4; j++) { - Rect2 atlas_rect = light_instance_get_directional_shadow_atlas_rect(li, j); - CameraMatrix matrix = light_instance_get_shadow_camera(li, j); - float split = light_instance_get_directional_shadow_split(li, MIN(limit, j)); + Rect2 atlas_rect = li->shadow_transform[j].atlas_rect; + CameraMatrix matrix = li->shadow_transform[j].camera; + float split = li->shadow_transform[MIN(limit, j)].split; CameraMatrix bias; bias.set_light_bias(); CameraMatrix rectm; rectm.set_light_atlas_rect(atlas_rect); - Transform modelview = (p_camera_inverse_transform * light_instance_get_shadow_transform(li, j)).inverse(); + Transform modelview = (inverse_transform * li->shadow_transform[j].transform).inverse(); CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; - float bias_scale = light_instance_get_shadow_bias_scale(li, j); + float bias_scale = li->shadow_transform[j].bias_scale; light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale; - light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * light_instance_get_directional_shadow_texel_size(li, j); + light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size; light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale; - light_data.shadow_z_range[j] = light_instance_get_shadow_range(li, j); - light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j); + light_data.shadow_z_range[j] = li->shadow_transform[j].farplane; + light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin; RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]); - Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j); + Vector2 uv_scale = li->shadow_transform[j].uv_scale; uv_scale *= atlas_rect.size; //adapt to atlas size switch (j) { case 0: { @@ -6274,170 +6429,201 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const r_directional_light_count++; } break; - case RS::LIGHT_SPOT: case RS::LIGHT_OMNI: { - if (light_count >= cluster.max_lights) { + if (cluster.omni_light_count >= cluster.max_lights) { continue; } - Transform light_transform = light_instance_get_base_transform(li); + cluster.omni_light_sort[cluster.omni_light_count].instance = li; + cluster.omni_light_sort[cluster.omni_light_count].depth = camera_plane.distance_to(li->transform.origin); + cluster.omni_light_count++; + } break; + case RS::LIGHT_SPOT: { + if (cluster.spot_light_count >= cluster.max_lights) { + continue; + } - Cluster::LightData &light_data = cluster.lights[light_count]; - cluster.lights_instances[light_count] = li; + cluster.spot_light_sort[cluster.spot_light_count].instance = li; + cluster.spot_light_sort[cluster.spot_light_count].depth = camera_plane.distance_to(li->transform.origin); + cluster.spot_light_count++; + } break; + } - float sign = storage->light_is_negative(base) ? -1 : 1; - Color linear_col = storage->light_get_color(base).to_linear(); + li->last_pass = RSG::rasterizer->get_frame_number(); + } - light_data.attenuation_energy[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION)); - light_data.attenuation_energy[1] = Math::make_half_float(sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI); + if (cluster.omni_light_count) { + SortArray<Cluster::InstanceSort<LightInstance>> sorter; + sorter.sort(cluster.omni_light_sort, cluster.omni_light_count); + } - light_data.color_specular[0] = MIN(uint32_t(linear_col.r * 255), 255); - light_data.color_specular[1] = MIN(uint32_t(linear_col.g * 255), 255); - light_data.color_specular[2] = MIN(uint32_t(linear_col.b * 255), 255); - light_data.color_specular[3] = MIN(uint32_t(storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 255), 255); + if (cluster.spot_light_count) { + SortArray<Cluster::InstanceSort<LightInstance>> sorter; + sorter.sort(cluster.spot_light_sort, cluster.spot_light_count); + } - float radius = MAX(0.001, storage->light_get_param(base, RS::LIGHT_PARAM_RANGE)); - light_data.inv_radius = 1.0 / radius; + ShadowAtlas *shadow_atlas = nullptr; - Vector3 pos = p_camera_inverse_transform.xform(light_transform.origin); + if (p_shadow_atlas.is_valid() && p_using_shadows) { + shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + } - light_data.position[0] = pos.x; - light_data.position[1] = pos.y; - light_data.position[2] = pos.z; + for (uint32_t i = 0; i < (cluster.omni_light_count + cluster.spot_light_count); i++) { + uint32_t index = (i < cluster.omni_light_count) ? i : i - (cluster.omni_light_count); + Cluster::LightData &light_data = (i < cluster.omni_light_count) ? cluster.omni_lights[index] : cluster.spot_lights[index]; + RS::LightType type = (i < cluster.omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT; + LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance; + RID base = li->light; - Vector3 direction = p_camera_inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized(); + Transform light_transform = li->transform; - light_data.direction[0] = direction.x; - light_data.direction[1] = direction.y; - light_data.direction[2] = direction.z; + float sign = storage->light_is_negative(base) ? -1 : 1; + Color linear_col = storage->light_get_color(base).to_linear(); - float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION); - light_data.size = size; + float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI; - light_data.cone_attenuation_angle[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION)); - float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE); - light_data.cone_attenuation_angle[1] = Math::make_half_float(Math::cos(Math::deg2rad(spot_angle))); + light_data.color[0] = linear_col.r * energy; + light_data.color[1] = linear_col.g * energy; + light_data.color[2] = linear_col.b * energy; + light_data.specular_amount = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0; - light_data.mask = storage->light_get_cull_mask(base); + float radius = MAX(0.001, storage->light_get_param(base, RS::LIGHT_PARAM_RANGE)); + light_data.inv_radius = 1.0 / radius; - light_data.atlas_rect[0] = 0; - light_data.atlas_rect[1] = 0; - light_data.atlas_rect[2] = 0; - light_data.atlas_rect[3] = 0; + Vector3 pos = inverse_transform.xform(light_transform.origin); - RID projector = storage->light_get_projector(base); + light_data.position[0] = pos.x; + light_data.position[1] = pos.y; + light_data.position[2] = pos.z; - if (projector.is_valid()) { - Rect2 rect = storage->decal_atlas_get_texture_rect(projector); + Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized(); - if (type == RS::LIGHT_SPOT) { - light_data.projector_rect[0] = rect.position.x; - light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped - light_data.projector_rect[2] = rect.size.width; - light_data.projector_rect[3] = -rect.size.height; - } else { - light_data.projector_rect[0] = rect.position.x; - light_data.projector_rect[1] = rect.position.y; - light_data.projector_rect[2] = rect.size.width; - light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half - } - } else { - light_data.projector_rect[0] = 0; - light_data.projector_rect[1] = 0; - light_data.projector_rect[2] = 0; - light_data.projector_rect[3] = 0; - } + light_data.direction[0] = direction.x; + light_data.direction[1] = direction.y; + light_data.direction[2] = direction.z; - if (p_using_shadows && p_shadow_atlas.is_valid() && shadow_atlas_owns_light_instance(p_shadow_atlas, li)) { - // fill in the shadow information + float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); - Color shadow_color = storage->light_get_shadow_color(base); + light_data.size = size; - light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255); - light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255); - light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255); - light_data.shadow_color_enabled[3] = 255; + light_data.inv_spot_attenuation = 1.0f / storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION); + float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE); + light_data.cos_spot_angle = Math::cos(Math::deg2rad(spot_angle)); - if (type == RS::LIGHT_SPOT) { - light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0); - float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0; - shadow_texel_size *= light_instance_get_shadow_texel_size(li, p_shadow_atlas); + light_data.mask = storage->light_get_cull_mask(base); - light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size; + light_data.atlas_rect[0] = 0; + light_data.atlas_rect[1] = 0; + light_data.atlas_rect[2] = 0; + light_data.atlas_rect[3] = 0; - } else { //omni - light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0; - float shadow_texel_size = light_instance_get_shadow_texel_size(li, p_shadow_atlas); - light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space - } + RID projector = storage->light_get_projector(base); - light_data.transmittance_bias = storage->light_get_transmittance_bias(base); + if (projector.is_valid()) { + Rect2 rect = storage->decal_atlas_get_texture_rect(projector); - Rect2 rect = light_instance_get_shadow_atlas_rect(li, p_shadow_atlas); + if (type == RS::LIGHT_SPOT) { + light_data.projector_rect[0] = rect.position.x; + light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped + light_data.projector_rect[2] = rect.size.width; + light_data.projector_rect[3] = -rect.size.height; + } else { + light_data.projector_rect[0] = rect.position.x; + light_data.projector_rect[1] = rect.position.y; + light_data.projector_rect[2] = rect.size.width; + light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half + } + } else { + light_data.projector_rect[0] = 0; + light_data.projector_rect[1] = 0; + light_data.projector_rect[2] = 0; + light_data.projector_rect[3] = 0; + } - light_data.atlas_rect[0] = rect.position.x; - light_data.atlas_rect[1] = rect.position.y; - light_data.atlas_rect[2] = rect.size.width; - light_data.atlas_rect[3] = rect.size.height; + if (shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) { + // fill in the shadow information - light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); - light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base); + light_data.shadow_enabled = true; - if (type == RS::LIGHT_OMNI) { - light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another - Transform proj = (p_camera_inverse_transform * light_transform).inverse(); + if (type == RS::LIGHT_SPOT) { + light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0); + float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0; + shadow_texel_size *= light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); - RendererStorageRD::store_transform(proj, light_data.shadow_matrix); + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size; - if (size > 0.0) { - light_data.soft_shadow_size = size; - } else { - light_data.soft_shadow_size = 0.0; - light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF - } + } else { //omni + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0; + float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space + } - } else if (type == RS::LIGHT_SPOT) { - Transform modelview = (p_camera_inverse_transform * light_transform).inverse(); - CameraMatrix bias; - bias.set_light_bias(); + light_data.transmittance_bias = storage->light_get_transmittance_bias(base); - CameraMatrix shadow_mtx = bias * light_instance_get_shadow_camera(li, 0) * modelview; - RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix); + Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas); - if (size > 0.0) { - CameraMatrix cm = light_instance_get_shadow_camera(li, 0); - float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle)); - light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; - } else { - light_data.soft_shadow_size = 0.0; - light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF - } - } + light_data.atlas_rect[0] = rect.position.x; + light_data.atlas_rect[1] = rect.position.y; + light_data.atlas_rect[2] = rect.size.width; + light_data.atlas_rect[3] = rect.size.height; + + light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); + light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base); + + if (type == RS::LIGHT_OMNI) { + light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another + Transform proj = (inverse_transform * light_transform).inverse(); + + RendererStorageRD::store_transform(proj, light_data.shadow_matrix); + + if (size > 0.0) { + light_data.soft_shadow_size = size; } else { - light_data.shadow_color_enabled[3] = 0; + light_data.soft_shadow_size = 0.0; + light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF } - light_instance_set_index(li, light_count); + } else if (type == RS::LIGHT_SPOT) { + Transform modelview = (inverse_transform * light_transform).inverse(); + CameraMatrix bias; + bias.set_light_bias(); - cluster.builder.add_light(type == RS::LIGHT_SPOT ? LightClusterBuilder::LIGHT_TYPE_SPOT : LightClusterBuilder::LIGHT_TYPE_OMNI, light_transform, radius, spot_angle); + CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview; + RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix); - light_count++; - r_positional_light_count++; - } break; + if (size > 0.0) { + CameraMatrix cm = li->shadow_transform[0].camera; + float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle)); + light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; + } else { + light_data.soft_shadow_size = 0.0; + light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF + } + } + } else { + light_data.shadow_enabled = false; } - light_instance_set_render_pass(li, RSG::rasterizer->get_frame_number()); + li->light_index = index; - //update UBO for forward rendering, blit to texture for clustered + current_cluster_builder->add_light(type == RS::LIGHT_SPOT ? ClusterBuilderRD::LIGHT_TYPE_SPOT : ClusterBuilderRD::LIGHT_TYPE_OMNI, light_transform, radius, spot_angle); + + r_positional_light_count++; + } + + //update without barriers + if (cluster.omni_light_count) { + RD::get_singleton()->buffer_update(cluster.omni_light_buffer, 0, sizeof(Cluster::LightData) * cluster.omni_light_count, cluster.omni_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } - if (light_count) { - RD::get_singleton()->buffer_update(cluster.light_buffer, 0, sizeof(Cluster::LightData) * light_count, cluster.lights, true); + if (cluster.spot_light_count) { + RD::get_singleton()->buffer_update(cluster.spot_light_buffer, 0, sizeof(Cluster::LightData) * cluster.spot_light_count, cluster.spot_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } if (r_directional_light_count) { - RD::get_singleton()->buffer_update(cluster.directional_light_buffer, 0, sizeof(Cluster::DirectionalLightData) * r_directional_light_count, cluster.directional_lights, true); + RD::get_singleton()->buffer_update(cluster.directional_light_buffer, 0, sizeof(Cluster::DirectionalLightData) * r_directional_light_count, cluster.directional_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } } @@ -6446,18 +6632,26 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0)); uv_xform.origin = Vector3(-1.0, 0.0, -1.0); - uint32_t decal_count = MIN((uint32_t)p_decals.size(), cluster.max_decals); - int idx = 0; + uint32_t decal_count = p_decals.size(); + + cluster.decal_count = 0; + for (uint32_t i = 0; i < decal_count; i++) { - RID di = p_decals[i]; - RID decal = decal_instance_get_base(di); + if (cluster.decal_count == cluster.max_decals) { + break; + } - Transform xform = decal_instance_get_transform(di); + DecalInstance *di = decal_instance_owner.getornull(p_decals[i]); + if (!di) { + continue; + } + RID decal = di->decal; - float fade = 1.0; + Transform xform = di->transform; + + real_t distance = -p_camera_inverse_xform.xform(xform.origin).z; if (storage->decal_is_distance_fade_enabled(decal)) { - real_t distance = -p_camera_inverse_xform.xform(xform.origin).z; float fade_begin = storage->decal_get_distance_fade_begin(decal); float fade_length = storage->decal_get_distance_fade_length(decal); @@ -6465,18 +6659,43 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const if (distance > fade_begin + fade_length) { continue; // do not use this decal, its invisible } + } + } + + cluster.decal_sort[cluster.decal_count].instance = di; + cluster.decal_sort[cluster.decal_count].depth = distance; + cluster.decal_count++; + } + + if (cluster.decal_count > 0) { + SortArray<Cluster::InstanceSort<DecalInstance>> sort_array; + sort_array.sort(cluster.decal_sort, cluster.decal_count); + } + + for (uint32_t i = 0; i < cluster.decal_count; i++) { + DecalInstance *di = cluster.decal_sort[i].instance; + RID decal = di->decal; + + Transform xform = di->transform; + float fade = 1.0; + if (storage->decal_is_distance_fade_enabled(decal)) { + real_t distance = -p_camera_inverse_xform.xform(xform.origin).z; + float fade_begin = storage->decal_get_distance_fade_begin(decal); + float fade_length = storage->decal_get_distance_fade_length(decal); + + if (distance > fade_begin) { fade = 1.0 - (distance - fade_begin) / fade_length; } } - Cluster::DecalData &dd = cluster.decals[idx]; + Cluster::DecalData &dd = cluster.decals[i]; Vector3 decal_extents = storage->decal_get_extents(decal); Transform scale_xform; scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z)); - Transform to_decal_xform = (p_camera_inverse_xform * decal_instance_get_transform(di) * scale_xform * uv_xform).affine_inverse(); + Transform to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse(); RendererStorageRD::store_transform(to_decal_xform, dd.xform); Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized(); @@ -6561,19 +6780,18 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const dd.upper_fade = storage->decal_get_upper_fade(decal); dd.lower_fade = storage->decal_get_lower_fade(decal); - cluster.builder.add_decal(xform, decal_extents); - - idx++; + current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, xform, decal_extents); } - if (idx > 0) { - RD::get_singleton()->buffer_update(cluster.decal_buffer, 0, sizeof(Cluster::DecalData) * idx, cluster.decals, true); + if (cluster.decal_count > 0) { + RD::get_singleton()->buffer_update(cluster.decal_buffer, 0, sizeof(Cluster::DecalData) * cluster.decal_count, cluster.decals, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } } void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { ERR_FAIL_COND(!rb->volumetric_fog); + RD::get_singleton()->free(rb->volumetric_fog->prev_light_density_map); RD::get_singleton()->free(rb->volumetric_fog->light_density_map); RD::get_singleton()->free(rb->volumetric_fog->fog_map); @@ -6595,49 +6813,6 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { rb->volumetric_fog = nullptr; } -void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) { - //create fog mipmaps - uint32_t fog_texture_size = p_target_size; - uint32_t base_texture_size = p_base_size; - - ShadowShrinkStage first; - first.size = base_texture_size; - first.texture = p_base; - shrink_stages.push_back(first); //put depth first in case we dont find smaller ones - - while (fog_texture_size < base_texture_size) { - base_texture_size = MAX(base_texture_size / 8, fog_texture_size); - - ShadowShrinkStage s; - s.size = base_texture_size; - - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = base_texture_size; - tf.height = base_texture_size; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; - - if (base_texture_size == fog_texture_size) { - s.filter_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; - } - - s.texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - - shrink_stages.push_back(s); - } -} - -void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) { - for (int i = 1; i < shrink_stages.size(); i++) { - RD::get_singleton()->free(shrink_stages[i].texture); - if (shrink_stages[i].filter_texture.is_valid()) { - RD::get_singleton()->free(shrink_stages[i].filter_texture); - } - } - shrink_stages.clear(); -} - void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -6660,6 +6835,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e return; } + RENDER_TIMESTAMP(">Volumetric Fog"); + if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { //required volumetric fog but not existing, create rb->volumetric_fog = memnew(VolumetricFog); @@ -6673,11 +6850,16 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e tf.height = target_height; tf.depth = volumetric_fog_depth; tf.texture_type = RD::TEXTURE_TYPE_3D; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + + rb->volumetric_fog->prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->texture_clear(rb->volumetric_fog->prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); _render_buffers_uniform_set_changed(p_render_buffers); @@ -6694,162 +6876,6 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG); } - //update directional shadow - - if (p_use_directional_shadows) { - if (directional_shadow.shrink_stages.is_empty()) { - if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { - //invalidate uniform set, we will need a new one - RD::get_singleton()->free(rb->volumetric_fog->uniform_set); - rb->volumetric_fog->uniform_set = RID(); - } - _allocate_shadow_shrink_stages(directional_shadow.depth, directional_shadow.size, directional_shadow.shrink_stages, volumetric_fog_directional_shadow_shrink); - } - - if (directional_shadow.shrink_stages.size() > 1) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - for (int i = 1; i < directional_shadow.shrink_stages.size(); i++) { - int32_t src_size = directional_shadow.shrink_stages[i - 1].size; - int32_t dst_size = directional_shadow.shrink_stages[i].size; - Rect2i r(0, 0, src_size, src_size); - int32_t shrink_limit = 8 / (src_size / dst_size); - - storage->get_effects()->reduce_shadow(directional_shadow.shrink_stages[i - 1].texture, directional_shadow.shrink_stages[i].texture, Size2i(src_size, src_size), r, shrink_limit, compute_list); - RD::get_singleton()->compute_list_add_barrier(compute_list); - if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && directional_shadow.shrink_stages[i].filter_texture.is_valid()) { - Rect2i rf(0, 0, dst_size, dst_size); - storage->get_effects()->filter_shadow(directional_shadow.shrink_stages[i].texture, directional_shadow.shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), rf, env->volumetric_fog_shadow_filter, compute_list); - } - } - RD::get_singleton()->compute_list_end(); - } - } - - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); - - if (shadow_atlas) { - //shrink shadows that need to be shrunk - - bool force_shrink_shadows = false; - - if (shadow_atlas->shrink_stages.is_empty()) { - if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { - //invalidate uniform set, we will need a new one - RD::get_singleton()->free(rb->volumetric_fog->uniform_set); - rb->volumetric_fog->uniform_set = RID(); - } - _allocate_shadow_shrink_stages(shadow_atlas->depth, shadow_atlas->size, shadow_atlas->shrink_stages, volumetric_fog_positional_shadow_shrink); - force_shrink_shadows = true; - } - - if (rb->volumetric_fog->last_shadow_filter != env->volumetric_fog_shadow_filter) { - //if shadow filter changed, invalidate caches - rb->volumetric_fog->last_shadow_filter = env->volumetric_fog_shadow_filter; - force_shrink_shadows = true; - } - - cluster.lights_shadow_rect_cache_count = 0; - - for (int i = 0; i < p_positional_light_count; i++) { - if (cluster.lights[i].shadow_color_enabled[3] > 127) { - RID li = cluster.lights_instances[i]; - - ERR_CONTINUE(!shadow_atlas->shadow_owners.has(li)); - - uint32_t key = shadow_atlas->shadow_owners[li]; - - uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; - uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK; - - ERR_CONTINUE((int)shadow >= shadow_atlas->quadrants[quadrant].shadows.size()); - - ShadowAtlas::Quadrant::Shadow &s = shadow_atlas->quadrants[quadrant].shadows.write[shadow]; - - if (!force_shrink_shadows && s.fog_version == s.version) { - continue; //do not update, no need - } - - s.fog_version = s.version; - - uint32_t quadrant_size = shadow_atlas->size >> 1; - - Rect2i atlas_rect; - - atlas_rect.position.x = (quadrant & 1) * quadrant_size; - atlas_rect.position.y = (quadrant >> 1) * quadrant_size; - - uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision); - atlas_rect.position.x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; - atlas_rect.position.y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; - - atlas_rect.size.x = shadow_size; - atlas_rect.size.y = shadow_size; - - cluster.lights_shadow_rect_cache[cluster.lights_shadow_rect_cache_count] = atlas_rect; - - cluster.lights_shadow_rect_cache_count++; - - if (cluster.lights_shadow_rect_cache_count == cluster.max_lights) { - break; //light limit reached - } - } - } - - if (cluster.lights_shadow_rect_cache_count > 0) { - //there are shadows to be shrunk, try to do them in parallel - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - for (int i = 1; i < shadow_atlas->shrink_stages.size(); i++) { - int32_t base_size = shadow_atlas->shrink_stages[0].size; - int32_t src_size = shadow_atlas->shrink_stages[i - 1].size; - int32_t dst_size = shadow_atlas->shrink_stages[i].size; - - uint32_t rect_divisor = base_size / src_size; - - int32_t shrink_limit = 8 / (src_size / dst_size); - - //shrink in parallel for more performance - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i src_rect = cluster.lights_shadow_rect_cache[j]; - - src_rect.position /= rect_divisor; - src_rect.size /= rect_divisor; - - storage->get_effects()->reduce_shadow(shadow_atlas->shrink_stages[i - 1].texture, shadow_atlas->shrink_stages[i].texture, Size2i(src_size, src_size), src_rect, shrink_limit, compute_list); - } - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && shadow_atlas->shrink_stages[i].filter_texture.is_valid()) { - uint32_t filter_divisor = base_size / dst_size; - - //filter in parallel for more performance - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i dst_rect = cluster.lights_shadow_rect_cache[j]; - - dst_rect.position /= filter_divisor; - dst_rect.size /= filter_divisor; - - storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, true, false); - } - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i dst_rect = cluster.lights_shadow_rect_cache[j]; - - dst_rect.position /= filter_divisor; - dst_rect.size /= filter_divisor; - - storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, false, true); - } - } - } - - RD::get_singleton()->compute_list_end(); - } - } - //update volumetric fog if (rb->volumetric_fog->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { @@ -6861,10 +6887,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) { + ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { - u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture); + u.ids.push_back(shadow_atlas->depth); } uniforms.push_back(u); @@ -6874,10 +6901,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - if (directional_shadow.shrink_stages.size() == 0) { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + if (directional_shadow.depth.is_valid()) { + u.ids.push_back(directional_shadow.depth); } else { - u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); } @@ -6886,23 +6913,22 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(get_positional_light_buffer()); + u.ids.push_back(get_omni_light_buffer()); uniforms.push_back(u); } - { RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; - u.ids.push_back(get_directional_light_buffer()); + u.ids.push_back(get_spot_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 5; - u.ids.push_back(get_cluster_builder_texture()); + u.ids.push_back(get_directional_light_buffer()); uniforms.push_back(u); } @@ -6910,7 +6936,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; - u.ids.push_back(get_cluster_builder_indices_buffer()); + u.ids.push_back(rb->cluster_builder->get_cluster_buffer()); uniforms.push_back(u); } @@ -6970,6 +6996,20 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 14; + u.ids.push_back(volumetric_fog.params_ubo); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 15; + u.ids.push_back(rb->volumetric_fog->prev_light_density_map); + uniforms.push_back(u); + } rb->volumetric_fog->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, 0), 0); @@ -7015,7 +7055,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->length = env->volumetric_fog_length; rb->volumetric_fog->spread = env->volumetric_fog_detail_spread; - VolumetricFogShader::PushConstant push_constant; + VolumetricFogShader::ParamsUBO params; Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); @@ -7031,51 +7071,78 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e fog_near_size = Vector2(); } - push_constant.fog_frustum_size_begin[0] = fog_near_size.x; - push_constant.fog_frustum_size_begin[1] = fog_near_size.y; + params.fog_frustum_size_begin[0] = fog_near_size.x; + params.fog_frustum_size_begin[1] = fog_near_size.y; - push_constant.fog_frustum_size_end[0] = fog_far_size.x; - push_constant.fog_frustum_size_end[1] = fog_far_size.y; + params.fog_frustum_size_end[0] = fog_far_size.x; + params.fog_frustum_size_end[1] = fog_far_size.y; - push_constant.z_near = z_near; - push_constant.z_far = z_far; + params.z_near = z_near; + params.z_far = z_far; - push_constant.fog_frustum_end = fog_end; + params.fog_frustum_end = fog_end; - push_constant.fog_volume_size[0] = rb->volumetric_fog->width; - push_constant.fog_volume_size[1] = rb->volumetric_fog->height; - push_constant.fog_volume_size[2] = rb->volumetric_fog->depth; + params.fog_volume_size[0] = rb->volumetric_fog->width; + params.fog_volume_size[1] = rb->volumetric_fog->height; + params.fog_volume_size[2] = rb->volumetric_fog->depth; - push_constant.directional_light_count = p_directional_light_count; + params.directional_light_count = p_directional_light_count; Color light = env->volumetric_fog_light.to_linear(); - push_constant.light_energy[0] = light.r * env->volumetric_fog_light_energy; - push_constant.light_energy[1] = light.g * env->volumetric_fog_light_energy; - push_constant.light_energy[2] = light.b * env->volumetric_fog_light_energy; - push_constant.base_density = env->volumetric_fog_density; + params.light_energy[0] = light.r * env->volumetric_fog_light_energy; + params.light_energy[1] = light.g * env->volumetric_fog_light_energy; + params.light_energy[2] = light.b * env->volumetric_fog_light_energy; + params.base_density = env->volumetric_fog_density; + + params.detail_spread = env->volumetric_fog_detail_spread; + params.gi_inject = env->volumetric_fog_gi_inject; + + params.cam_rotation[0] = p_cam_transform.basis[0][0]; + params.cam_rotation[1] = p_cam_transform.basis[1][0]; + params.cam_rotation[2] = p_cam_transform.basis[2][0]; + params.cam_rotation[3] = 0; + params.cam_rotation[4] = p_cam_transform.basis[0][1]; + params.cam_rotation[5] = p_cam_transform.basis[1][1]; + params.cam_rotation[6] = p_cam_transform.basis[2][1]; + params.cam_rotation[7] = 0; + params.cam_rotation[8] = p_cam_transform.basis[0][2]; + params.cam_rotation[9] = p_cam_transform.basis[1][2]; + params.cam_rotation[10] = p_cam_transform.basis[2][2]; + params.cam_rotation[11] = 0; + params.filter_axis = 0; + params.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0; + params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; + + Transform to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform; + storage->store_transform(to_prev_cam_view, params.to_prev_view); + + params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; + params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; - push_constant.detail_spread = env->volumetric_fog_detail_spread; - push_constant.gi_inject = env->volumetric_fog_gi_inject; + { + uint32_t cluster_size = rb->cluster_builder->get_cluster_size(); + params.cluster_shift = get_shift_from_power_of_2(cluster_size); - push_constant.cam_rotation[0] = p_cam_transform.basis[0][0]; - push_constant.cam_rotation[1] = p_cam_transform.basis[1][0]; - push_constant.cam_rotation[2] = p_cam_transform.basis[2][0]; - push_constant.cam_rotation[3] = 0; - push_constant.cam_rotation[4] = p_cam_transform.basis[0][1]; - push_constant.cam_rotation[5] = p_cam_transform.basis[1][1]; - push_constant.cam_rotation[6] = p_cam_transform.basis[2][1]; - push_constant.cam_rotation[7] = 0; - push_constant.cam_rotation[8] = p_cam_transform.basis[0][2]; - push_constant.cam_rotation[9] = p_cam_transform.basis[1][2]; - push_constant.cam_rotation[10] = p_cam_transform.basis[2][2]; - push_constant.cam_rotation[11] = 0; - push_constant.filter_axis = 0; - push_constant.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0; + uint32_t cluster_screen_width = (rb->width - 1) / cluster_size + 1; + uint32_t cluster_screen_height = (rb->height - 1) / cluster_size + 1; + params.cluster_type_size = cluster_screen_width * cluster_screen_height * (32 + 32); + params.cluster_width = cluster_screen_width; + params.max_cluster_element_count_div_32 = max_cluster_elements / 32; + + params.screen_size[0] = rb->width; + params.screen_size[1] = rb->height; + } /* Vector2 dssize = directional_shadow_get_size(); push_constant.directional_shadow_pixel_size[0] = 1.0 / dssize.x; push_constant.directional_shadow_pixel_size[1] = 1.0 / dssize.y; */ + + RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog"); + + RENDER_TIMESTAMP("Render Fog"); + RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); bool use_filter = volumetric_fog_filter_active; @@ -7083,93 +7150,212 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[using_sdfgi ? VOLUMETRIC_FOG_SHADER_DENSITY_WITH_SDFGI : VOLUMETRIC_FOG_SHADER_DENSITY]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0); + if (using_sdfgi) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); } - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); + + RD::get_singleton()->draw_command_end_label(); + + RD::get_singleton()->compute_list_end(); - RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->texture_copy(rb->volumetric_fog->light_density_map, rb->volumetric_fog->prev_light_density_map, Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 0, 0, 0, 0); + + compute_list = RD::get_singleton()->compute_list_begin(); if (use_filter) { + RD::get_singleton()->draw_command_begin_label("Filter Fog"); + + RENDER_TIMESTAMP("Filter Fog"); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FILTER]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); - RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->compute_list_end(); + //need restart for buffer update - push_constant.filter_axis = 1; + params.filter_axis = 1; + RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms); + compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FILTER]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set2, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 8, 8, 1); + if (using_sdfgi) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); + } + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->draw_command_end_label(); } + RENDER_TIMESTAMP("Integrate Fog"); + RD::get_singleton()->draw_command_begin_label("Integrate Fog"); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FOG]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1); - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); + + RENDER_TIMESTAMP("<Volumetric Fog"); + RD::get_singleton()->draw_command_end_label(); + + rb->volumetric_fog->prev_cam_transform = p_cam_transform; } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) { - Color clear_color; - if (p_render_buffers.is_valid()) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); - ERR_FAIL_COND(!rb); - clear_color = storage->render_target_get_clear_request_color(rb->render_target); - } else { - clear_color = storage->get_default_clear_color(); +uint32_t RendererSceneRenderRD::_get_render_state_directional_light_count() const { + return render_state.directional_light_count; +} + +bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) { + if (render_state.render_buffers.is_valid()) { + RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); + if (rb->sdfgi != nullptr) { + return true; + } } + return false; +} - //assign render indices to giprobes - for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) { - GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]); - if (giprobe_inst) { - giprobe_inst->render_index = i; +void RendererSceneRenderRD::_post_prepass_render(bool p_use_gi) { + if (render_state.render_buffers.is_valid()) { + if (p_use_gi) { + _sdfgi_update_probes(render_state.render_buffers, render_state.environment); } } +} - const PagedArray<RID> *lights = &p_lights; - const PagedArray<RID> *reflections = &p_reflection_probes; - const PagedArray<RID> *gi_probes = &p_gi_probes; +void RendererSceneRenderRD::_pre_resolve_render(bool p_use_gi) { + if (render_state.render_buffers.is_valid()) { + if (p_use_gi) { + RD::get_singleton()->compute_list_end(); + } + } +} - PagedArray<RID> empty; +void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) { + // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - lights = ∅ - reflections = ∅ - gi_probes = ∅ + if (render_state.render_buffers.is_valid() && p_use_gi) { + _sdfgi_store_probes(render_state.render_buffers); + } + + render_state.cube_shadows.clear(); + render_state.shadows.clear(); + render_state.directional_shadows.clear(); + + Plane camera_plane(render_state.cam_transform.origin, -render_state.cam_transform.basis.get_axis(Vector3::AXIS_Z)); + float lod_distance_multiplier = render_state.cam_projection.get_lod_multiplier(); + + { + for (int i = 0; i < render_state.render_shadow_count; i++) { + LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light); + + if (storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) { + render_state.directional_shadows.push_back(i); + } else if (storage->light_get_type(li->light) == RS::LIGHT_OMNI && storage->light_omni_get_shadow_mode(li->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { + render_state.cube_shadows.push_back(i); + } else { + render_state.shadows.push_back(i); + } + } + + //cube shadows are rendered in their own way + for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) { + _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, true, true, true); + } + + if (render_state.directional_shadows.size()) { + //open the pass for directional shadows + _update_directional_shadow_atlas(); + RD::get_singleton()->draw_list_begin(directional_shadow.fb, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE); + RD::get_singleton()->draw_list_end(); + } + } + + // Render GI + + bool render_shadows = render_state.directional_shadows.size() || render_state.shadows.size(); + bool render_gi = render_state.render_buffers.is_valid() && p_use_gi; + + if (render_shadows && render_gi) { + RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)"); + } else if (render_shadows) { + RENDER_TIMESTAMP("Render Shadows"); + } else if (render_gi) { + RENDER_TIMESTAMP("Render GI"); + } + + //prepare shadow rendering + if (render_shadows) { + _render_shadow_begin(); + + //render directional shadows + for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) { + _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false); + } + //render positional shadows + for (uint32_t i = 0; i < render_state.shadows.size(); i++) { + _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true); + } + + _render_shadow_process(); + } + + //start GI + if (render_gi) { + _process_gi(render_state.render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, render_state.environment, render_state.cam_projection, render_state.cam_transform, *render_state.gi_probes); + } + + //Do shadow rendering (in parallel with GI) + if (render_shadows) { + _render_shadow_end(RD::BARRIER_MASK_NO_BARRIER); + } + + if (render_gi) { + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier + } + + if (render_state.render_buffers.is_valid()) { + if (p_use_ssao) { + _process_ssao(render_state.render_buffers, render_state.environment, p_normal_roughness_buffer, render_state.cam_projection); + } } - cluster.builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster + //full barrier here, we need raster, transfer and compute and it depends from the previous work + RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); + + if (current_cluster_builder) { + current_cluster_builder->begin(render_state.cam_transform, render_state.cam_projection, !render_state.reflection_probe.is_valid()); + } bool using_shadows = true; - if (p_reflection_probe.is_valid()) { - if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_reflection_probe))) { + if (render_state.reflection_probe.is_valid()) { + if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(render_state.reflection_probe))) { using_shadows = false; } } else { //do not render reflections when rendering a reflection probe - _setup_reflections(*reflections, p_cam_transform.affine_inverse(), p_environment); + _setup_reflections(*render_state.reflection_probes, render_state.cam_transform.affine_inverse(), render_state.environment); } uint32_t directional_light_count = 0; uint32_t positional_light_count = 0; - _setup_lights(*lights, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows, directional_light_count, positional_light_count); - _setup_decals(p_decals, p_cam_transform.affine_inverse()); - cluster.builder.bake_cluster(); //bake to cluster + _setup_lights(*render_state.lights, render_state.cam_transform, render_state.shadow_atlas, using_shadows, directional_light_count, positional_light_count); + _setup_decals(*render_state.decals, render_state.cam_transform.affine_inverse()); - uint32_t gi_probe_count = 0; - _setup_giprobes(p_render_buffers, p_cam_transform, *gi_probes, gi_probe_count); + render_state.directional_light_count = directional_light_count; - if (p_render_buffers.is_valid()) { + if (current_cluster_builder) { + current_cluster_builder->bake_cluster(); + } + + if (render_state.render_buffers.is_valid()) { bool directional_shadows = false; for (uint32_t i = 0; i < directional_light_count; i++) { if (cluster.directional_lights[i].shadow_enabled) { @@ -7177,12 +7363,126 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & break; } } - _update_volumetric_fog(p_render_buffers, p_environment, p_cam_projection, p_cam_transform, p_shadow_atlas, directional_light_count, directional_shadows, positional_light_count, gi_probe_count); + _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count); + } +} + +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data) { + //assign render data + { + render_state.render_buffers = p_render_buffers; + render_state.cam_transform = p_cam_transform; + render_state.cam_projection = p_cam_projection; + render_state.cam_ortogonal = p_cam_projection.is_orthogonal(); + render_state.instances = &p_instances; + render_state.lights = &p_lights; + render_state.reflection_probes = &p_reflection_probes; + render_state.gi_probes = &p_gi_probes; + render_state.decals = &p_decals; + render_state.lightmaps = &p_lightmaps; + render_state.environment = p_environment; + render_state.camera_effects = p_camera_effects; + render_state.shadow_atlas = p_shadow_atlas; + render_state.reflection_atlas = p_reflection_atlas; + render_state.reflection_probe = p_reflection_probe; + render_state.reflection_probe_pass = p_reflection_probe_pass; + render_state.screen_lod_threshold = p_screen_lod_threshold; + + render_state.render_shadows = p_render_shadows; + render_state.render_shadow_count = p_render_shadow_count; + render_state.render_sdfgi_regions = p_render_sdfgi_regions; + render_state.render_sdfgi_region_count = p_render_sdfgi_region_count; + render_state.sdfgi_update_data = p_sdfgi_update_data; + } + + PagedArray<RID> empty; + + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { + render_state.lights = ∅ + render_state.reflection_probes = ∅ + render_state.gi_probes = ∅ + } + + //sdfgi first + if (p_render_buffers.is_valid()) { + for (int i = 0; i < render_state.render_sdfgi_region_count; i++) { + _render_sdfgi_region(p_render_buffers, render_state.render_sdfgi_regions[i].region, render_state.render_sdfgi_regions[i].instances); + } + if (render_state.sdfgi_update_data->update_static) { + _render_sdfgi_static_lights(p_render_buffers, render_state.sdfgi_update_data->static_cascade_count, p_sdfgi_update_data->static_cascade_indices, render_state.sdfgi_update_data->static_positional_lights); + } + } + + Color clear_color; + if (p_render_buffers.is_valid()) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(!rb); + clear_color = storage->render_target_get_clear_request_color(rb->render_target); + } else { + clear_color = storage->get_default_clear_color(); + } + + //assign render indices to giprobes + for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) { + GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]); + if (giprobe_inst) { + giprobe_inst->render_index = i; + } } - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, directional_light_count, *gi_probes, p_lightmaps, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold); + if (render_buffers_owner.owns(render_state.render_buffers)) { + RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); + current_cluster_builder = rb->cluster_builder; + } else if (reflection_probe_instance_owner.owns(render_state.reflection_probe)) { + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_state.reflection_probe); + ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas); + if (!ra) { + ERR_PRINT("reflection probe has no reflection atlas! Bug?"); + current_cluster_builder = nullptr; + } else { + current_cluster_builder = ra->cluster_builder; + } + } else { + ERR_PRINT("No cluster builder, bug"); //should never happen, will crash + current_cluster_builder = nullptr; + } if (p_render_buffers.is_valid()) { + _pre_process_gi(p_render_buffers, p_cam_transform); + } + + render_state.gi_probe_count = 0; + if (render_state.render_buffers.is_valid()) { + _setup_giprobes(render_state.render_buffers, render_state.cam_transform, *render_state.gi_probes, render_state.gi_probe_count); + _sdfgi_update_light(render_state.render_buffers, render_state.environment); + } + + render_state.depth_prepass_used = false; + //calls _pre_opaque_render between depth pre-pass and opaque pass + _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, current_cluster_builder->get_cluster_buffer(), current_cluster_builder->get_cluster_size(), current_cluster_builder->get_max_cluster_elements(), p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold); + + if (p_render_buffers.is_valid()) { + if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES) { + ClusterBuilderRD::ElementType elem_type = ClusterBuilderRD::ELEMENT_TYPE_MAX; + switch (debug_draw) { + case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS: + elem_type = ClusterBuilderRD::ELEMENT_TYPE_OMNI_LIGHT; + break; + case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS: + elem_type = ClusterBuilderRD::ELEMENT_TYPE_SPOT_LIGHT; + break; + case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS: + elem_type = ClusterBuilderRD::ELEMENT_TYPE_DECAL; + break; + case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES: + elem_type = ClusterBuilderRD::ELEMENT_TYPE_REFLECTION_PROBE; + break; + default: { + } + } + current_cluster_builder->debug(elem_type); + } + RENDER_TIMESTAMP("Tonemap"); _render_buffers_post_process_and_tonemap(p_render_buffers, p_environment, p_camera_effects, p_cam_projection); @@ -7193,27 +7493,26 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & } } -void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region) { LightInstance *light_instance = light_instance_owner.getornull(p_light); ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; - RID atlas_texture; + uint32_t atlas_size; + RID atlas_fb; bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; - float znear = 0; - float zfar = 0; RID render_fb; RID render_texture; - float bias = 0; - float normal_bias = 0; + float zfar; bool use_pancake = false; - bool use_linear_depth = false; bool render_cubemap = false; bool finalize_cubemap = false; + bool flip_y = false; + CameraMatrix light_projection; Transform light_transform; @@ -7246,7 +7545,6 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.position.x += atlas_rect.size.width; atlas_rect.position.y += atlas_rect.size.height; } - } else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { atlas_rect.size.height /= 2; @@ -7261,15 +7559,11 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size; light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size; - float bias_mult = light_instance->shadow_transform[p_pass].bias_scale; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); - bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult; - normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult; - ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); - render_fb = shadow_map->fb; - render_texture = shadow_map->depth; - atlas_texture = directional_shadow.depth; + render_fb = directional_shadow.fb; + render_texture = RID(); + flip_y = true; } else { //set from shadow atlas @@ -7278,6 +7572,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light)); + _update_shadow_atlas(shadow_atlas); + uint32_t key = shadow_atlas->shadow_owners[p_light]; uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; @@ -7296,11 +7592,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.size.width = shadow_size; atlas_rect.size.height = shadow_size; - atlas_texture = shadow_atlas->depth; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); - bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS); - normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS); if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) { if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { @@ -7309,10 +7602,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p render_fb = cubemap->side_fb[p_pass]; render_texture = cubemap->cubemap; - light_projection = light_instance->shadow_transform[0].camera; - light_transform = light_instance->shadow_transform[0].transform; + light_projection = light_instance->shadow_transform[p_pass].camera; + light_transform = light_instance->shadow_transform[p_pass].transform; render_cubemap = true; finalize_cubemap = p_pass == 5; + atlas_fb = shadow_atlas->fb; + + atlas_size = shadow_atlas->size; + + if (p_pass == 0) { + _render_shadow_begin(); + } } else { light_projection = light_instance->shadow_transform[0].camera; @@ -7323,49 +7623,44 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p using_dual_paraboloid = true; using_dual_paraboloid_flip = p_pass == 1; - - ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); - render_fb = shadow_map->fb; - render_texture = shadow_map->depth; + render_fb = shadow_atlas->fb; + flip_y = true; } } else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) { light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; - ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); - render_fb = shadow_map->fb; - render_texture = shadow_map->depth; + render_fb = shadow_atlas->fb; - znear = light_instance->shadow_transform[0].camera.get_z_near(); - use_linear_depth = true; + flip_y = true; } } if (render_cubemap) { //rendering to cubemap - _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true); if (finalize_cubemap) { + _render_shadow_process(); + _render_shadow_end(); //reblit - atlas_rect.size.height /= 2; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false); - atlas_rect.position.y += atlas_rect.size.height; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true); - } - } else { - //render shadow - - _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); + Rect2 atlas_rect_norm = atlas_rect; + atlas_rect_norm.position.x /= float(atlas_size); + atlas_rect_norm.position.y /= float(atlas_size); + atlas_rect_norm.size.x /= float(atlas_size); + atlas_rect_norm.size.y /= float(atlas_size); + atlas_rect_norm.size.height /= 2; + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false); + atlas_rect_norm.position.y += atlas_rect_norm.size.height; + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true); - //copy to atlas - if (use_linear_depth) { - storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar); - } else { - storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true); + //restore transform so it can be properly used + light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0); } - //does not work from depth to color - //RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true); + } else { + //render shadow + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass); } } @@ -7373,7 +7668,7 @@ void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, co _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region); } -void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) { +void RendererSceneRenderRD::_render_sdfgi_region(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) { //print_line("rendering region " + itos(p_region)); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -7389,16 +7684,18 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con if (cascade_prev != cascade) { //initialize render - RD::get_singleton()->texture_clear(rb->sdfgi->render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1, true); - RD::get_singleton()->texture_clear(rb->sdfgi->render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1, true); - RD::get_singleton()->texture_clear(rb->sdfgi->render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1, true); - RD::get_singleton()->texture_clear(rb->sdfgi->render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1, true); + RD::get_singleton()->texture_clear(rb->sdfgi->render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1); + RD::get_singleton()->texture_clear(rb->sdfgi->render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1); + RD::get_singleton()->texture_clear(rb->sdfgi->render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1); + RD::get_singleton()->texture_clear(rb->sdfgi->render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1); } //print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(rb->sdfgi->cascades[cascade].cell_size)); _render_sdfgi(p_render_buffers, from, size, bounds, p_instances, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing); if (cascade_next != cascade) { + RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade"); + RENDER_TIMESTAMP(">SDFGI Update SDF"); //done rendering! must update SDF //clear dispatch indirect data @@ -7421,6 +7718,9 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.scroll[1] = 0; push_constant.scroll[2] = 0; } + + rb->sdfgi->cascades[cascade].all_dynamic_lights_dirty = true; + push_constant.grid_size = rb->sdfgi->cascade_size; push_constant.cascade = cascade; @@ -7445,7 +7745,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con groups.z = rb->sdfgi->cascade_size - ABS(dirty.z); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z); //no barrier, continue together @@ -7487,7 +7787,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -7495,7 +7795,24 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1); + + RD::get_singleton()->compute_list_add_barrier(compute_list); + + if (rb->sdfgi->bounce_feedback > 0.0) { + //multibounce requires this to be stored so direct light can read from it + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]); + + //convert to octahedral to store + ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE; + ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE; + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1); + } } //ok finally barrier @@ -7504,7 +7821,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con //clear dispatch indirect data uint32_t dispatch_indirct_data[4] = { 0, 0, 0, 0 }; - RD::get_singleton()->buffer_update(rb->sdfgi->cascades[cascade].solid_cell_dispatch_buffer, 0, sizeof(uint32_t) * 4, dispatch_indirct_data, true); + RD::get_singleton()->buffer_update(rb->sdfgi->cascades[cascade].solid_cell_dispatch_buffer, 0, sizeof(uint32_t) * 4, dispatch_indirct_data); RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -7518,7 +7835,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_initialize_half_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); RD::get_singleton()->compute_list_add_barrier(compute_list); //must start with regular jumpflood @@ -7538,7 +7855,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_half_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; @@ -7556,7 +7873,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_half_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; } @@ -7568,7 +7885,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_upscale_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); //run one pass of fullsize jumpflood to fix up half size arctifacts @@ -7578,7 +7895,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[rb->sdfgi->upscale_jfa_uniform_set_index], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); } else { @@ -7588,7 +7905,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_initialize_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -7605,7 +7922,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; @@ -7623,7 +7940,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; } @@ -7670,14 +7987,14 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_STORE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].sdf_store_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_end(); //clear these textures, as they will have previous garbage on next draw - RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1, true); - RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1, true); - RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1, true); + RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); + RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); + RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); #if 0 Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rb->sdfgi->cascades[cascade].sdf, 0); @@ -7707,6 +8024,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con #endif RENDER_TIMESTAMP("<SDFGI Update SDF"); + RD::get_singleton()->draw_command_end_label(); } } @@ -7727,32 +8045,17 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, _render_particle_collider_heightfield(fb, cam_xform, cm, p_instances); } -void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) { +void RendererSceneRenderRD::_render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); ERR_FAIL_COND(!rb->sdfgi); - _sdfgi_update_cascades(p_render_buffers); //need cascades updated for this - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]); - - SDGIShader::DirectLightPushConstant dl_push_constant; - - dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size; - dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size; - dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size; - dl_push_constant.max_cascades = rb->sdfgi->cascades.size(); - dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; - dl_push_constant.multibounce = false; // this is static light, do not multibounce yet - dl_push_constant.y_mult = rb->sdfgi->y_mult; + RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs"); - //all must be processed - dl_push_constant.process_offset = 0; - dl_push_constant.process_increment = 1; + _sdfgi_update_cascades(p_render_buffers); //need cascades updated for this SDGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS]; + uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS]; for (uint32_t i = 0; i < p_cascade_count; i++) { ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size()); @@ -7808,18 +8111,46 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin lights[idx].has_shadow = storage->light_has_shadow(li->light); lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); - lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)); - lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE))); + lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); idx++; } if (idx > 0) { - RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, true); + RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights); } - dl_push_constant.light_count = idx; + + light_count[i] = idx; } + } + /* Static Lights */ + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]); + + SDGIShader::DirectLightPushConstant dl_push_constant; + + dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size; + dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size; + dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size; + dl_push_constant.max_cascades = rb->sdfgi->cascades.size(); + dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; + dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet + dl_push_constant.y_mult = rb->sdfgi->y_mult; + dl_push_constant.use_occlusion = rb->sdfgi->uses_occlusion; + + //all must be processed + dl_push_constant.process_offset = 0; + dl_push_constant.process_increment = 1; + + for (uint32_t i = 0; i < p_cascade_count; i++) { + ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size()); + + SDFGI::Cascade &cc = rb->sdfgi->cascades[p_cascade_indices[i]]; + + dl_push_constant.light_count = light_count[i]; dl_push_constant.cascade = p_cascade_indices[i]; if (dl_push_constant.light_count > 0) { @@ -7830,6 +8161,8 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin } RD::get_singleton()->compute_list_end(); + + RD::get_singleton()->draw_command_end_label(); } bool RendererSceneRenderRD::free(RID p_rid) { @@ -7843,6 +8176,9 @@ bool RendererSceneRenderRD::free(RID p_rid) { if (rb->volumetric_fog) { _volumetric_fog_erase(rb); } + if (rb->cluster_builder) { + memdelete(rb->cluster_builder); + } render_buffers_owner.free(p_rid); } else if (environment_owner.owns(p_rid)) { //not much to delete, just free it @@ -7852,6 +8188,10 @@ bool RendererSceneRenderRD::free(RID p_rid) { camera_effects_owner.free(p_rid); } else if (reflection_atlas_owner.owns(p_rid)) { reflection_atlas_set_size(p_rid, 0, 0); + ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_rid); + if (ra->cluster_builder) { + memdelete(ra->cluster_builder); + } reflection_atlas_owner.free(p_rid); } else if (reflection_probe_instance_owner.owns(p_rid)) { //not much to delete, just free it @@ -8070,20 +8410,17 @@ void RendererSceneRenderRD::sdfgi_set_debug_probe_select(const Vector3 &p_positi RendererSceneRenderRD *RendererSceneRenderRD::singleton = nullptr; -RID RendererSceneRenderRD::get_cluster_builder_texture() { - return cluster.builder.get_cluster_texture(); -} - -RID RendererSceneRenderRD::get_cluster_builder_indices_buffer() { - return cluster.builder.get_cluster_indices_buffer(); -} - RID RendererSceneRenderRD::get_reflection_probe_buffer() { return cluster.reflection_buffer; } -RID RendererSceneRenderRD::get_positional_light_buffer() { - return cluster.light_buffer; +RID RendererSceneRenderRD::get_omni_light_buffer() { + return cluster.omni_light_buffer; +} + +RID RendererSceneRenderRD::get_spot_light_buffer() { + return cluster.spot_light_buffer; } + RID RendererSceneRenderRD::get_directional_light_buffer() { return cluster.directional_light_buffer; } @@ -8099,17 +8436,25 @@ bool RendererSceneRenderRD::is_low_end() const { } RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { + max_cluster_elements = GLOBAL_GET("rendering/limits/cluster_builder/max_clustered_elements"); + storage = p_storage; singleton = this; - roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers"); - sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples"); - sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections"); - // sky_use_cubemap_array = false; + roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers"); + sky_ggx_samples_quality = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples"); + sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections"); + + sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1))); + sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1))); + sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1))); + + directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size"); + directional_shadow.use_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits"); uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); - low_end = GLOBAL_GET("rendering/quality/rd_renderer/use_low_end_renderer"); + low_end = GLOBAL_GET("rendering/driver/rd_renderer/use_low_end_renderer"); if (textures_per_stage < 48) { low_end = true; @@ -8122,7 +8467,7 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { gi_probe_lights = memnew_arr(GIProbeLight, gi_probe_max_lights); gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight)); - gi_probe_quality = RS::GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/quality/gi_probes/quality")), 0, 1)); + gi_probe_quality = RS::GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality")), 0, 1)); String defines = "\n#define MAX_LIGHTS " + itos(gi_probe_max_lights) + "\n"; @@ -8253,9 +8598,14 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { { // default material and shader for sky shader - sky_shader.default_shader = storage->shader_create(); + sky_shader.default_shader = storage->shader_allocate(); + storage->shader_initialize(sky_shader.default_shader); + storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n"); - sky_shader.default_material = storage->material_create(); + + sky_shader.default_material = storage->material_allocate(); + storage->material_initialize(sky_shader.default_material); + storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader); SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY); @@ -8329,9 +8679,13 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { { // Need defaults for using fog with clear color - sky_scene_state.fog_shader = storage->shader_create(); + sky_scene_state.fog_shader = storage->shader_allocate(); + storage->shader_initialize(sky_scene_state.fog_shader); + storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void fragment() { COLOR = clear_color.rgb; } \n"); - sky_scene_state.fog_material = storage->material_create(); + sky_scene_state.fog_material = storage->material_allocate(); + storage->material_initialize(sky_scene_state.fog_material); + storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader); Vector<RD::Uniform> uniforms; @@ -8399,6 +8753,9 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { //calculate tables String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n"; defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n"; + if (sky_use_cubemap_array) { + defines += "\n#define USE_CUBEMAP_ARRAY\n"; + } Vector<String> integrate_modes; integrate_modes.push_back("\n#define MODE_PROCESS\n"); @@ -8433,11 +8790,18 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1); } } + //GK { //calculate tables String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n"; Vector<String> gi_modes; - gi_modes.push_back(""); + gi_modes.push_back("\n#define USE_GIPROBES\n"); + gi_modes.push_back("\n#define USE_SDFGI\n"); + gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBES\n"); + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_GIPROBES\n"); + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n"); + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_GIPROBES\n"); + gi.shader.initialize(gi_modes, defines); gi.shader_version = gi.shader.version_create(); for (int i = 0; i < GI::MODE_MAX; i++) { @@ -8481,31 +8845,33 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES); } - //cluster setup - uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE); + { //decals + cluster.max_decals = max_cluster_elements; + uint32_t decal_buffer_size = cluster.max_decals * sizeof(Cluster::DecalData); + cluster.decals = memnew_arr(Cluster::DecalData, cluster.max_decals); + cluster.decal_sort = memnew_arr(Cluster::InstanceSort<DecalInstance>, cluster.max_decals); + cluster.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); + } { //reflections - uint32_t reflection_buffer_size; - if (uniform_max_size < 65536) { - //Yes, you guessed right, ARM again - reflection_buffer_size = uniform_max_size; - } else { - reflection_buffer_size = 65536; - } - cluster.max_reflections = reflection_buffer_size / sizeof(Cluster::ReflectionData); + cluster.max_reflections = max_cluster_elements; cluster.reflections = memnew_arr(Cluster::ReflectionData, cluster.max_reflections); - cluster.reflection_buffer = RD::get_singleton()->storage_buffer_create(reflection_buffer_size); + cluster.reflection_sort = memnew_arr(Cluster::InstanceSort<ReflectionProbeInstance>, cluster.max_reflections); + cluster.reflection_buffer = RD::get_singleton()->storage_buffer_create(sizeof(Cluster::ReflectionData) * cluster.max_reflections); } { //lights - cluster.max_lights = MIN(1024 * 1024, uniform_max_size) / sizeof(Cluster::LightData); //1mb of lights + cluster.max_lights = max_cluster_elements; + uint32_t light_buffer_size = cluster.max_lights * sizeof(Cluster::LightData); - cluster.lights = memnew_arr(Cluster::LightData, cluster.max_lights); - cluster.light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size); + cluster.omni_lights = memnew_arr(Cluster::LightData, cluster.max_lights); + cluster.omni_light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size); + cluster.omni_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights); + cluster.spot_lights = memnew_arr(Cluster::LightData, cluster.max_lights); + cluster.spot_light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size); + cluster.spot_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights); //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n"; - cluster.lights_instances = memnew_arr(RID, cluster.max_lights); - cluster.lights_shadow_rect_cache = memnew_arr(Rect2i, cluster.max_lights); cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS; uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData); @@ -8513,15 +8879,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { cluster.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size); } - { //decals - cluster.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(Cluster::DecalData); //1mb of decals - uint32_t decal_buffer_size = cluster.max_decals * sizeof(Cluster::DecalData); - cluster.decals = memnew_arr(Cluster::DecalData, cluster.max_decals); - cluster.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); - } - - cluster.builder.setup(16, 8, 24); - if (!low_end) { String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n"; Vector<String> volumetric_fog_modes; @@ -8534,6 +8891,7 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { for (int i = 0; i < VOLUMETRIC_FOG_SHADER_MAX; i++) { volumetric_fog.pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, i)); } + volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO)); } { @@ -8545,37 +8903,34 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { shadow_sampler = RD::get_singleton()->sampler_create(sampler); } - camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape")))); - camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter")); - environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"), GLOBAL_GET("rendering/quality/ssao/adaptive_target"), GLOBAL_GET("rendering/quality/ssao/blur_passes"), GLOBAL_GET("rendering/quality/ssao/fadeout_from"), GLOBAL_GET("rendering/quality/ssao/fadeout_to")); - screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled"); - screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"); - screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit"); - glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0; - glow_high_quality = GLOBAL_GET("rendering/quality/glow/use_high_quality"); - ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality"))); - sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality"))); - sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale"); - sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale"); + camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape")))); + camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_use_jitter")); + environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/environment/ssao/quality"))), GLOBAL_GET("rendering/environment/ssao/half_size"), GLOBAL_GET("rendering/environment/ssao/adaptive_target"), GLOBAL_GET("rendering/environment/ssao/blur_passes"), GLOBAL_GET("rendering/environment/ssao/fadeout_from"), GLOBAL_GET("rendering/environment/ssao/fadeout_to")); + screen_space_roughness_limiter = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/enabled"); + screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount"); + screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit"); + glow_bicubic_upscale = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0; + glow_high_quality = GLOBAL_GET("rendering/environment/glow/use_high_quality"); + ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/environment/screen_space_reflection/roughness_quality"))); + sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_quality"))); + sss_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_scale"); + sss_depth_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale"); directional_penumbra_shadow_kernel = memnew_arr(float, 128); directional_soft_shadow_kernel = memnew_arr(float, 128); penumbra_shadow_kernel = memnew_arr(float, 128); soft_shadow_kernel = memnew_arr(float, 128); - shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality")))); - directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")))); + shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/shadows/soft_shadow_quality")))); + directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_quality")))); - environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth")); - environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter")); - environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink")); - environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); + environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size"), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth")); + environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter")); cull_argument.set_page_pool(&cull_argument_pool); + + gi.half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution"); } RendererSceneRenderRD::~RendererSceneRenderRD() { - for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) { - RD::get_singleton()->free(E->get().depth); - } for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) { RD::get_singleton()->free(E->get().cubemap); } @@ -8599,6 +8954,7 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader); volumetric_fog.shader.version_free(volumetric_fog.shader_version); + RD::get_singleton()->free(volumetric_fog.params_ubo); memdelete_arr(gi_probe_lights); } @@ -8620,15 +8976,19 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { { RD::get_singleton()->free(cluster.directional_light_buffer); - RD::get_singleton()->free(cluster.light_buffer); + RD::get_singleton()->free(cluster.omni_light_buffer); + RD::get_singleton()->free(cluster.spot_light_buffer); RD::get_singleton()->free(cluster.reflection_buffer); RD::get_singleton()->free(cluster.decal_buffer); memdelete_arr(cluster.directional_lights); - memdelete_arr(cluster.lights); - memdelete_arr(cluster.lights_shadow_rect_cache); - memdelete_arr(cluster.lights_instances); + memdelete_arr(cluster.omni_lights); + memdelete_arr(cluster.spot_lights); + memdelete_arr(cluster.omni_light_sort); + memdelete_arr(cluster.spot_light_sort); memdelete_arr(cluster.reflections); + memdelete_arr(cluster.reflection_sort); memdelete_arr(cluster.decals); + memdelete_arr(cluster.decal_sort); } RD::get_singleton()->free(shadow_sampler); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 3f9c117602..e4eaa93212 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -34,7 +34,7 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" -#include "servers/rendering/renderer_rd/light_cluster_builder.h" +#include "servers/rendering/renderer_rd/cluster_builder_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h" @@ -104,13 +104,18 @@ protected: }; virtual RenderBufferData *_create_render_buffer_data() = 0; - void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count); + void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count); void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform); void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment); void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used); - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0; - virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0; + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0; + + virtual void _render_shadow_begin() = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; + virtual void _render_shadow_process() = 0; + virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; + virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; @@ -124,8 +129,6 @@ protected: virtual void _base_uniforms_changed() = 0; virtual void _render_buffers_uniform_set_changed(RID p_render_buffers) = 0; virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0; - virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers) = 0; - virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers) = 0; void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection); void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive); @@ -134,7 +137,15 @@ protected: void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size); void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); - void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes); + void _pre_process_gi(RID p_render_buffers, const Transform &p_transform); + void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes); + + bool _needs_post_prepass_render(bool p_use_gi); + void _post_prepass_render(bool p_use_gi); + void _pre_resolve_render(bool p_use_gi); + + void _pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer); + uint32_t _get_render_state_directional_light_count() const; // needed for a single argument calls (material and uv2) PagedArrayPool<GeometryInstance *> cull_argument_pool; @@ -322,7 +333,7 @@ private: uint32_t sky_ggx_samples_quality; bool sky_use_cubemap_array; - mutable RID_Owner<Sky> sky_owner; + mutable RID_Owner<Sky, true> sky_owner; /* REFLECTION ATLAS */ @@ -341,6 +352,8 @@ private: }; Vector<Reflection> reflections; + + ClusterBuilderRD *cluster_builder = nullptr; }; mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner; @@ -393,10 +406,10 @@ private: float attenuation; float color[3]; - float spot_angle_radians; + float cos_spot_angle; float position[3]; - float spot_attenuation; + float inv_spot_attenuation; float direction[3]; uint32_t has_shadow; @@ -572,17 +585,18 @@ private: uint32_t smallest_subdiv = 0; int size = 0; + bool use_16_bits = false; RID depth; RID fb; //for copying Map<RID, uint32_t> shadow_owners; - - Vector<ShadowShrinkStage> shrink_stages; }; RID_Owner<ShadowAtlas> shadow_atlas_owner; + void _update_shadow_atlas(ShadowAtlas *shadow_atlas); + bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow); RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set @@ -603,17 +617,16 @@ private: struct DirectionalShadow { RID depth; + RID fb; //when renderign direct int light_count = 0; int size = 0; + bool use_16_bits = false; int current_light = 0; - Vector<ShadowShrinkStage> shrink_stages; - } directional_shadow; - void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size); - void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages); + void _update_directional_shadow_atlas(); /* SHADOW CUBEMAPS */ @@ -625,14 +638,6 @@ private: Map<int, ShadowCubemap> shadow_cubemaps; ShadowCubemap *_get_shadow_cubemap(int p_size); - struct ShadowMap { - RID depth; - RID fb; - }; - - Map<Vector2i, ShadowMap> shadow_maps; - ShadowMap *_get_shadow_map(const Size2i &p_size); - void _create_shadow_cubemaps(); /* LIGHT INSTANCE */ @@ -652,7 +657,7 @@ private: RS::LightType light_type = RS::LIGHT_DIRECTIONAL; - ShadowTransform shadow_transform[4]; + ShadowTransform shadow_transform[6]; AABB aabb; RID self; @@ -731,8 +736,9 @@ private: float volumetric_fog_light_energy = 0.0; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - RS::EnvVolumetricFogShadowFilter volumetric_fog_shadow_filter = RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW; float volumetric_fog_gi_inject = 0.0; + bool volumetric_fog_temporal_reprojection = true; + float volumetric_fog_temporal_reprojection_amount = 0.9; /// Glow @@ -772,7 +778,7 @@ private: RS::EnvironmentSDFGICascades sdfgi_cascades; float sdfgi_min_cell_size = 0.2; bool sdfgi_use_occlusion = false; - bool sdfgi_use_multibounce = false; + float sdfgi_bounce_feedback = 0.0; bool sdfgi_read_sky_light = false; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; @@ -803,7 +809,7 @@ private: static uint64_t auto_exposure_counter; - mutable RID_Owner<Environment> environment_owner; + mutable RID_Owner<Environment, true> environment_owner; /* CAMERA EFFECTS */ @@ -829,10 +835,13 @@ private: float sss_scale = 0.05; float sss_depth_scale = 0.01; - mutable RID_Owner<CameraEffects> camera_effects_owner; + mutable RID_Owner<CameraEffects, true> camera_effects_owner; /* RENDER BUFFERS */ + ClusterBuilderSharedDataRD cluster_builder_shared; + ClusterBuilderRD *current_cluster_builder = nullptr; + struct SDFGI; struct VolumetricFog; @@ -858,6 +867,8 @@ private: SDFGI *sdfgi = nullptr; VolumetricFog *volumetric_fog = nullptr; + ClusterBuilderRD *cluster_builder = nullptr; + //built-in textures used for ping pong image processing and blurring struct Blur { RID texture; @@ -897,6 +908,16 @@ private: RID giprobe_textures[MAX_GIPROBES]; RID giprobe_buffer; + + RID ambient_buffer; + RID reflection_buffer; + bool using_half_size_gi = false; + + struct GI { + RID full_buffer; + RID full_dispatch; + RID full_mask; + } gi; }; RID default_giprobe_buffer; @@ -958,6 +979,8 @@ private: RID scroll_occlusion_uniform_set; RID integrate_uniform_set; RID lights_buffer; + + bool all_dynamic_lights_dirty = true; }; //used for rendering (voxelization) @@ -1005,7 +1028,7 @@ private: RID cascades_ubo; bool uses_occlusion = false; - bool uses_multibounce = false; + float bounce_feedback = 0.0; bool reads_sky = false; float energy = 1.0; float normal_bias = 1.1; @@ -1015,10 +1038,18 @@ private: float y_mult = 1.0; uint32_t render_pass = 0; + + int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically }; + void _sdfgi_update_light(RID p_render_buffers, RID p_environment); + void _sdfgi_update_probes(RID p_render_buffers, RID p_environment); + void _sdfgi_store_probes(RID p_render_buffers); + RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16; RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_10_FRAMES; + RS::EnvironmentSDFGIFramesToUpdateLight sdfgi_frames_to_update_light = RS::ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES; + float sdfgi_solid_cell_ratio = 0.25; Vector3 sdfgi_debug_probe_pos; Vector3 sdfgi_debug_probe_dir; @@ -1115,8 +1146,8 @@ private: float attenuation; uint32_t type; - float spot_angle; - float spot_attenuation; + float cos_spot_angle; + float inv_spot_attenuation; float radius; float shadow_color[4]; @@ -1132,9 +1163,9 @@ private: uint32_t process_increment; int32_t probe_axis_size; - uint32_t multibounce; + float bounce_feedback; float y_mult; - uint32_t pad; + uint32_t use_occlusion; }; enum { @@ -1256,23 +1287,28 @@ private: float z_far; float proj_info[4]; - + float ao_color[3]; uint32_t max_giprobes; + uint32_t high_quality_vct; - uint32_t use_sdfgi; uint32_t orthogonal; - - float ao_color[3]; - uint32_t pad; + uint32_t pad[2]; float cam_rotation[12]; }; RID sdfgi_ubo; - enum { - MODE_MAX = 1 + enum Mode { + MODE_GIPROBE, + MODE_SDFGI, + MODE_COMBINED, + MODE_HALF_RES_GIPROBE, + MODE_HALF_RES_SDFGI, + MODE_HALF_RES_COMBINED, + MODE_MAX }; + bool half_resolution = false; GiShaderRD shader; RID shader_version; RID pipelines[MODE_MAX]; @@ -1297,14 +1333,23 @@ private: struct Cluster { /* Scene State UBO */ - struct ReflectionData { //should always be 128 bytes + enum { + REFLECTION_AMBIENT_DISABLED = 0, + REFLECTION_AMBIENT_ENVIRONMENT = 1, + REFLECTION_AMBIENT_COLOR = 2, + }; + + struct ReflectionData { float box_extents[3]; float index; float box_offset[3]; uint32_t mask; - float params[4]; // intensity, 0, interior , boxproject float ambient[3]; // ambient color, + float intensity; + bool exterior; + bool box_project; uint32_t ambient_mode; + uint32_t pad; float local_matrix[16]; // up to here for spot and omni, rest is for directional }; @@ -1313,10 +1358,15 @@ private: float inv_radius; float direction[3]; float size; - uint16_t attenuation_energy[2]; //16 bits attenuation, then energy - uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm) - uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float) - uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm) + + float color[3]; + float attenuation; + + float inv_spot_attenuation; + float cos_spot_angle; + float specular_amount; + uint32_t shadow_enabled; + float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv float shadow_matrix[16]; float shadow_bias; @@ -1380,31 +1430,85 @@ private: float normal_fade; }; + template <class T> + struct InstanceSort { + float depth; + T *instance; + bool operator<(const InstanceSort &p_sort) const { + return depth < p_sort.depth; + } + }; + ReflectionData *reflections; + InstanceSort<ReflectionProbeInstance> *reflection_sort; uint32_t max_reflections; RID reflection_buffer; uint32_t max_reflection_probes_per_instance; + uint32_t reflection_count = 0; DecalData *decals; + InstanceSort<DecalInstance> *decal_sort; uint32_t max_decals; RID decal_buffer; + uint32_t decal_count; + + LightData *omni_lights; + LightData *spot_lights; - LightData *lights; + InstanceSort<LightInstance> *omni_light_sort; + InstanceSort<LightInstance> *spot_light_sort; uint32_t max_lights; - RID light_buffer; - RID *lights_instances; - Rect2i *lights_shadow_rect_cache; - uint32_t lights_shadow_rect_cache_count = 0; + RID omni_light_buffer; + RID spot_light_buffer; + uint32_t omni_light_count = 0; + uint32_t spot_light_count = 0; DirectionalLightData *directional_lights; uint32_t max_directional_lights; RID directional_light_buffer; - LightClusterBuilder builder; - } cluster; + struct RenderState { + RID render_buffers; + Transform cam_transform; + CameraMatrix cam_projection; + bool cam_ortogonal = false; + const PagedArray<GeometryInstance *> *instances = nullptr; + const PagedArray<RID> *lights = nullptr; + const PagedArray<RID> *reflection_probes = nullptr; + const PagedArray<RID> *gi_probes = nullptr; + const PagedArray<RID> *decals = nullptr; + const PagedArray<RID> *lightmaps = nullptr; + RID environment; + RID camera_effects; + RID shadow_atlas; + RID reflection_atlas; + RID reflection_probe; + int reflection_probe_pass = 0; + float screen_lod_threshold = 0.0; + + const RenderShadowData *render_shadows = nullptr; + int render_shadow_count = 0; + const RenderSDFGIData *render_sdfgi_regions = nullptr; + int render_sdfgi_region_count = 0; + const RenderSDFGIUpdateData *sdfgi_update_data = nullptr; + + uint32_t directional_light_count = 0; + uint32_t gi_probe_count = 0; + + LocalVector<int> cube_shadows; + LocalVector<int> shadows; + LocalVector<int> directional_shadows; + + bool depth_prepass_used; + } render_state; + struct VolumetricFog { + enum { + MAX_TEMPORAL_FRAMES = 16 + }; + uint32_t width = 0; uint32_t height = 0; uint32_t depth = 0; @@ -1413,6 +1517,8 @@ private: float spread; RID light_density_map; + RID prev_light_density_map; + RID fog_map; RID uniform_set; RID uniform_set2; @@ -1420,6 +1526,8 @@ private: RID sky_uniform_set; int last_shadow_filter = -1; + + Transform prev_cam_transform; }; enum { @@ -1431,7 +1539,7 @@ private: }; struct VolumetricFogShader { - struct PushConstant { + struct ParamsUBO { float fog_frustum_size_begin[2]; float fog_frustum_size_end[2]; @@ -1449,13 +1557,24 @@ private: float detail_spread; float gi_inject; uint32_t max_gi_probes; - uint32_t pad; + uint32_t cluster_type_size; + + float screen_size[2]; + uint32_t cluster_shift; + uint32_t cluster_width; + + uint32_t max_cluster_element_count_div_32; + uint32_t use_temporal_reprojection; + uint32_t temporal_frame; + float temporal_blend; float cam_rotation[12]; + float to_prev_view[16]; }; VolumetricFogShaderRD shader; + RID params_ubo; RID shader_version; RID pipelines[VOLUMETRIC_FOG_SHADER_MAX]; @@ -1463,9 +1582,7 @@ private: uint32_t volumetric_fog_depth = 128; uint32_t volumetric_fog_size = 128; - bool volumetric_fog_filter_active = false; - uint32_t volumetric_fog_directional_shadow_shrink = 512; - uint32_t volumetric_fog_positional_shadow_shrink = 512; + bool volumetric_fog_filter_active = true; void _volumetric_fog_erase(RenderBuffers *rb); void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count); @@ -1480,8 +1597,13 @@ private: float weight; }; + uint32_t max_cluster_elements = 512; bool low_end = false; + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true); + void _render_sdfgi_region(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances); + void _render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result); + public: virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0; virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; @@ -1489,7 +1611,7 @@ public: /* SHADOW ATLAS API */ RID shadow_atlas_create(); - void shadow_atlas_set_size(RID p_atlas, int p_size); + void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false); void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision); bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version); _FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) { @@ -1510,7 +1632,7 @@ public: return Size2(atlas->size, atlas->size); } - void directional_shadow_atlas_set_size(int p_size); + void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false); int get_directional_light_shadow_size(RID p_light_intance); void set_directional_shadow_count(int p_count); @@ -1529,11 +1651,12 @@ public: virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const; virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const; virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const; - virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count); RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; } /* SKY API */ - RID sky_create(); + virtual RID sky_allocate(); + virtual void sky_initialize(RID p_rid); + void sky_set_radiance_size(RID p_sky, int p_radiance_size); void sky_set_mode(RID p_sky, RS::SkyMode p_mode); void sky_set_material(RID p_sky, RID p_material); @@ -1545,7 +1668,8 @@ public: /* ENVIRONMENT API */ - RID environment_create(); + virtual RID environment_allocate(); + virtual void environment_initialize(RID p_rid); void environment_set_background(RID p_env, RS::EnvironmentBG p_bg); void environment_set_sky(RID p_env, RID p_sky); @@ -1586,12 +1710,10 @@ public: float environment_get_fog_height_density(RID p_env) const; float environment_get_fog_aerial_perspective(RID p_env) const; - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter); + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount); virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth); virtual void environment_set_volumetric_fog_filter_active(bool p_enable); - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size); - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size); void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect); @@ -1602,9 +1724,10 @@ public: bool environment_is_ssr_enabled(RID p_env) const; bool environment_is_sdfgi_enabled(RID p_env) const; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count); virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames); + virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update); void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality); RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const; @@ -1614,7 +1737,8 @@ public: virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size); - virtual RID camera_effects_create(); + virtual RID camera_effects_allocate(); + virtual void camera_effects_initialize(RID p_rid); virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter); virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape); @@ -1903,11 +2027,14 @@ public: */ RID render_buffers_create(); void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding); + void gi_set_use_half_resolution(bool p_enable); RID render_buffers_get_ao_texture(RID p_render_buffers); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); RID render_buffers_get_gi_probe_buffer(RID p_render_buffers); RID render_buffers_get_default_gi_probe_buffer(); + RID render_buffers_get_gi_ambient_texture(RID p_render_buffers); + RID render_buffers_get_gi_reflection_texture(RID p_render_buffers); uint32_t render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const; bool render_buffers_is_sdfgi_enabled(RID p_render_buffers) const; @@ -1928,15 +2055,10 @@ public: float render_buffers_get_volumetric_fog_end(RID p_render_buffers); float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers); - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold); - - void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0); + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr); void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); - void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances); - void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result); - void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances); virtual void set_scene_pass(uint64_t p_pass) { @@ -1988,10 +2110,9 @@ public: virtual void set_time(double p_time, double p_step); - RID get_cluster_builder_texture(); - RID get_cluster_builder_indices_buffer(); RID get_reflection_probe_buffer(); - RID get_positional_light_buffer(); + RID get_omni_light_buffer(); + RID get_spot_light_buffer(); RID get_directional_light_buffer(); RID get_decal_buffer(); int get_max_directional_lights() const; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 1ffc024d42..2a34049675 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -36,6 +36,10 @@ #include "renderer_compositor_rd.h" #include "servers/rendering/shader_language.h" +bool RendererStorageRD::can_create_resources_async() const { + return true; +} + Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { Ref<Image> image = p_image->duplicate(); @@ -535,9 +539,13 @@ Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image return image; } -RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { - ERR_FAIL_COND_V(p_image.is_null(), RID()); - ERR_FAIL_COND_V(p_image->is_empty(), RID()); +RID RendererStorageRD::texture_allocate() { + return texture_owner.allocate_rid(); +} + +void RendererStorageRD::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) { + ERR_FAIL_COND(p_image.is_null()); + ERR_FAIL_COND(p_image->is_empty()); TextureToRDFormat ret_format; Ref<Image> image = _validate_texture_format(p_image, ret_format); @@ -585,13 +593,13 @@ RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { Vector<Vector<uint8_t>> data_slices; data_slices.push_back(data); texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture.is_null()); if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { rd_view.format_override = texture.rd_format_srgb; texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); if (texture.rd_texture_srgb.is_null()) { RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); } } @@ -602,14 +610,14 @@ RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { texture.rd_view = rd_view; texture.is_proxy = false; - return texture_owner.make_rid(texture); + texture_owner.initialize_rid(p_texture, texture); } -RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { - ERR_FAIL_COND_V(p_layers.size() == 0, RID()); +void RendererStorageRD::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { + ERR_FAIL_COND(p_layers.size() == 0); - ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID()); - ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0), RID()); + ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6); + ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0)); TextureToRDFormat ret_format; Vector<Ref<Image>> images; @@ -620,7 +628,7 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay Image::Format valid_format = Image::FORMAT_MAX; for (int i = 0; i < p_layers.size(); i++) { - ERR_FAIL_COND_V(p_layers[i]->is_empty(), RID()); + ERR_FAIL_COND(p_layers[i]->is_empty()); if (i == 0) { valid_width = p_layers[i]->get_width(); @@ -628,10 +636,10 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay valid_format = p_layers[i]->get_format(); valid_mipmaps = p_layers[i]->has_mipmaps(); } else { - ERR_FAIL_COND_V(p_layers[i]->get_width() != valid_width, RID()); - ERR_FAIL_COND_V(p_layers[i]->get_height() != valid_height, RID()); - ERR_FAIL_COND_V(p_layers[i]->get_format() != valid_format, RID()); - ERR_FAIL_COND_V(p_layers[i]->has_mipmaps() != valid_mipmaps, RID()); + ERR_FAIL_COND(p_layers[i]->get_width() != valid_width); + ERR_FAIL_COND(p_layers[i]->get_height() != valid_height); + ERR_FAIL_COND(p_layers[i]->get_format() != valid_format); + ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps); } images.push_back(_validate_texture_format(p_layers[i], ret_format)); @@ -695,13 +703,13 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay data_slices.push_back(data); } texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture.is_null()); if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { rd_view.format_override = texture.rd_format_srgb; texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); if (texture.rd_texture_srgb.is_null()) { RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); } } @@ -712,14 +720,14 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay texture.rd_view = rd_view; texture.is_proxy = false; - return texture_owner.make_rid(texture); + texture_owner.initialize_rid(p_texture, texture); } -RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { - ERR_FAIL_COND_V(p_data.size() == 0, RID()); +void RendererStorageRD::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { + ERR_FAIL_COND(p_data.size() == 0); Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); if (verr != Image::VALIDATE_3D_OK) { - ERR_FAIL_V_MSG(RID(), Image::get_3d_image_validation_error_text(verr)); + ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); } TextureToRDFormat ret_format; @@ -811,13 +819,13 @@ RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, in data_slices.push_back(all_data); //one slice texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture.is_null()); if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { rd_view.format_override = texture.rd_format_srgb; texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); if (texture.rd_texture_srgb.is_null()) { RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); } } @@ -828,12 +836,12 @@ RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, in texture.rd_view = rd_view; texture.is_proxy = false; - return texture_owner.make_rid(texture); + texture_owner.initialize_rid(p_texture, texture); } -RID RendererStorageRD::texture_proxy_create(RID p_base) { +void RendererStorageRD::texture_proxy_initialize(RID p_texture, RID p_base) { Texture *tex = texture_owner.getornull(p_base); - ERR_FAIL_COND_V(!tex, RID()); + ERR_FAIL_COND(!tex); Texture proxy_tex = *tex; proxy_tex.rd_view.format_override = tex->rd_format; @@ -847,11 +855,9 @@ RID RendererStorageRD::texture_proxy_create(RID p_base) { proxy_tex.is_proxy = true; proxy_tex.proxies.clear(); - RID rid = texture_owner.make_rid(proxy_tex); - - tex->proxies.push_back(rid); + texture_owner.initialize_rid(p_texture, proxy_tex); - return rid; + tex->proxies.push_back(p_texture); } void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { @@ -873,7 +879,7 @@ void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_im TextureToRDFormat f; Ref<Image> validated = _validate_texture_format(p_image, f); - RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data(), !p_immediate); + RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data()); } void RendererStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) { @@ -918,7 +924,7 @@ void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image> } } - RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data, true); + RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data); } void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { @@ -961,7 +967,7 @@ void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { } //these two APIs can be used together or in combination with the others. -RID RendererStorageRD::texture_2d_placeholder_create() { +void RendererStorageRD::texture_2d_placeholder_initialize(RID p_texture) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -974,10 +980,10 @@ RID RendererStorageRD::texture_2d_placeholder_create() { } } - return texture_2d_create(image); + texture_2d_initialize(p_texture, image); } -RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) { +void RendererStorageRD::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -1000,10 +1006,10 @@ RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredT } } - return texture_2d_layered_create(images, p_layered_type); + texture_2d_layered_initialize(p_texture, images, p_layered_type); } -RID RendererStorageRD::texture_3d_placeholder_create() { +void RendererStorageRD::texture_3d_placeholder_initialize(RID p_texture) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -1022,7 +1028,7 @@ RID RendererStorageRD::texture_3d_placeholder_create() { images.push_back(image); } - return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images); + texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images); } Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const { @@ -1223,8 +1229,11 @@ RendererStorageRD::CanvasTexture::~CanvasTexture() { clear_sets(); } -RID RendererStorageRD::canvas_texture_create() { - return canvas_texture_owner.make_rid(memnew(CanvasTexture)); +RID RendererStorageRD::canvas_texture_allocate() { + return canvas_texture_owner.allocate_rid(); +} +void RendererStorageRD::canvas_texture_initialize(RID p_rid) { + canvas_texture_owner.initialize_rid(p_rid, memnew(CanvasTexture)); } void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { @@ -1365,12 +1374,15 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas /* SHADER API */ -RID RendererStorageRD::shader_create() { +RID RendererStorageRD::shader_allocate() { + return shader_owner.allocate_rid(); +} +void RendererStorageRD::shader_initialize(RID p_rid) { Shader shader; shader.data = nullptr; shader.type = SHADER_TYPE_MAX; - return shader_owner.make_rid(shader); + shader_owner.initialize_rid(p_rid, shader); } void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { @@ -1510,7 +1522,10 @@ RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID /* COMMON MATERIAL API */ -RID RendererStorageRD::material_create() { +RID RendererStorageRD::material_allocate() { + return material_owner.allocate_rid(); +} +void RendererStorageRD::material_initialize(RID p_rid) { Material material; material.data = nullptr; material.shader = nullptr; @@ -1520,12 +1535,8 @@ RID RendererStorageRD::material_create() { material.uniform_dirty = false; material.texture_dirty = false; material.priority = 0; - RID id = material_owner.make_rid(material); - { - Material *material_ptr = material_owner.getornull(id); - material_ptr->self = id; - } - return id; + material.self = p_rid; + material_owner.initialize_rid(p_rid, material); } void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) { @@ -2399,8 +2410,11 @@ void RendererStorageRD::_update_queued_materials() { /* MESH API */ -RID RendererStorageRD::mesh_create() { - return mesh_owner.make_rid(Mesh()); +RID RendererStorageRD::mesh_allocate() { + return mesh_owner.allocate_rid(); +} +void RendererStorageRD::mesh_initialize(RID p_rid) { + mesh_owner.initialize_rid(p_rid, Mesh()); } void RendererStorageRD::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) { @@ -2609,6 +2623,12 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); + for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) { + Mesh *shadow_owner = E->get(); + shadow_owner->shadow_mesh = RID(); + shadow_owner->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); + } + mesh->material_cache.clear(); } @@ -2824,6 +2844,25 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { return aabb; } +void RendererStorageRD::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { + Mesh *mesh = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND(!mesh); + + Mesh *shadow_mesh = mesh_owner.getornull(mesh->shadow_mesh); + if (shadow_mesh) { + shadow_mesh->shadow_owners.erase(mesh); + } + mesh->shadow_mesh = p_shadow_mesh; + + shadow_mesh = mesh_owner.getornull(mesh->shadow_mesh); + + if (shadow_mesh) { + shadow_mesh->shadow_owners.insert(mesh); + } + + mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); +} + void RendererStorageRD::mesh_clear(RID p_mesh) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); @@ -2871,6 +2910,12 @@ void RendererStorageRD::mesh_clear(RID p_mesh) { } mesh->has_bone_weights = false; mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); + + for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) { + Mesh *shadow_owner = E->get(); + shadow_owner->shadow_mesh = RID(); + shadow_owner->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); + } } bool RendererStorageRD::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) { @@ -3013,7 +3058,7 @@ void RendererStorageRD::update_mesh_instances() { MeshInstance *mi = dirty_mesh_instance_weights.first()->self(); if (mi->blend_weights_buffer.is_valid()) { - RD::get_singleton()->buffer_update(mi->blend_weights_buffer, 0, mi->blend_weights.size() * sizeof(float), mi->blend_weights.ptr(), true); + RD::get_singleton()->buffer_update(mi->blend_weights_buffer, 0, mi->blend_weights.size() * sizeof(float), mi->blend_weights.ptr()); } dirty_mesh_instance_weights.remove(&mi->weight_update_list); mi->weights_dirty = false; @@ -3067,7 +3112,7 @@ void RendererStorageRD::update_mesh_instances() { RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SkeletonShader::PushConstant)); //dispatch without barrier, so all is done at the same time - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1); } mi->dirty = false; @@ -3267,11 +3312,14 @@ void RendererStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surf ////////////////// MULTIMESH -RID RendererStorageRD::multimesh_create() { - return multimesh_owner.make_rid(MultiMesh()); +RID RendererStorageRD::multimesh_allocate() { + return multimesh_owner.allocate_rid(); +} +void RendererStorageRD::multimesh_initialize(RID p_rid) { + multimesh_owner.initialize_rid(p_rid, MultiMesh()); } -void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +void RendererStorageRD::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -3681,7 +3729,7 @@ void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float { const float *r = p_buffer.ptr(); - RD::get_singleton()->buffer_update(multimesh->buffer, 0, p_buffer.size() * sizeof(float), r, false); + RD::get_singleton()->buffer_update(multimesh->buffer, 0, p_buffer.size() * sizeof(float), r); multimesh->buffer_set = true; } @@ -3780,14 +3828,14 @@ void RendererStorageRD::_update_dirty_multimeshes() { if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) { //if there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much - RD::get_singleton()->buffer_update(multimesh->buffer, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data, false); + RD::get_singleton()->buffer_update(multimesh->buffer, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data); } else { //not that many regions? update them all for (uint32_t i = 0; i < visible_region_count; i++) { if (multimesh->data_cache_dirty_regions[i]) { uint64_t offset = i * region_size; uint64_t size = multimesh->stride_cache * multimesh->instances * sizeof(float); - RD::get_singleton()->buffer_update(multimesh->buffer, offset, MIN(region_size, size - offset), &data[i * region_size], false); + RD::get_singleton()->buffer_update(multimesh->buffer, offset, MIN(region_size, size - offset), &data[i * region_size]); } } } @@ -3818,8 +3866,11 @@ void RendererStorageRD::_update_dirty_multimeshes() { /* PARTICLES */ -RID RendererStorageRD::particles_create() { - return particles_owner.make_rid(Particles()); +RID RendererStorageRD::particles_allocate() { + return particles_owner.allocate_rid(); +} +void RendererStorageRD::particles_initialize(RID p_rid) { + particles_owner.initialize_rid(p_rid, Particles()); } void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) { @@ -4478,7 +4529,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta if (sub_emitter && sub_emitter->emission_storage_buffer.is_valid()) { // print_line("updating subemitter buffer"); int32_t zero[4] = { 0, sub_emitter->amount, 0, 0 }; - RD::get_singleton()->buffer_update(sub_emitter->emission_storage_buffer, 0, sizeof(uint32_t) * 4, zero, true); + RD::get_singleton()->buffer_update(sub_emitter->emission_storage_buffer, 0, sizeof(uint32_t) * 4, zero); push_constant.can_emit = true; if (sub_emitter->emitting) { @@ -4496,13 +4547,13 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta } if (p_particles->emission_buffer && p_particles->emission_buffer->particle_count) { - RD::get_singleton()->buffer_update(p_particles->emission_storage_buffer, 0, sizeof(uint32_t) * 4 + sizeof(ParticleEmissionBuffer::Data) * p_particles->emission_buffer->particle_count, p_particles->emission_buffer, true); + RD::get_singleton()->buffer_update(p_particles->emission_storage_buffer, 0, sizeof(uint32_t) * 4 + sizeof(ParticleEmissionBuffer::Data) * p_particles->emission_buffer->particle_count, p_particles->emission_buffer); p_particles->emission_buffer->particle_count = 0; } p_particles->clear = false; - RD::get_singleton()->buffer_update(p_particles->frame_params_buffer, 0, sizeof(ParticlesFrameParams), &frame_params, true); + RD::get_singleton()->buffer_update(p_particles->frame_params_buffer, 0, sizeof(ParticlesFrameParams), &frame_params); ParticlesMaterialData *m = (ParticlesMaterialData *)material_get_data(p_particles->process_material, SHADER_TYPE_PARTICLES); if (!m) { @@ -4524,7 +4575,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); } @@ -4578,7 +4629,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); @@ -4590,7 +4641,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); } @@ -4697,7 +4748,7 @@ void RendererStorageRD::update_particles() { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); } @@ -4953,8 +5004,11 @@ RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_f /* PARTICLES COLLISION API */ -RID RendererStorageRD::particles_collision_create() { - return particles_collision_owner.make_rid(ParticlesCollision()); +RID RendererStorageRD::particles_collision_allocate() { + return particles_collision_owner.allocate_rid(); +} +void RendererStorageRD::particles_collision_initialize(RID p_rid) { + particles_collision_owner.initialize_rid(p_rid, ParticlesCollision()); } RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { @@ -5133,8 +5187,11 @@ void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_ /* SKELETON API */ -RID RendererStorageRD::skeleton_create() { - return skeleton_owner.make_rid(Skeleton()); +RID RendererStorageRD::skeleton_allocate() { + return skeleton_owner.allocate_rid(); +} +void RendererStorageRD::skeleton_initialize(RID p_rid) { + skeleton_owner.initialize_rid(p_rid, Skeleton()); } void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { @@ -5145,7 +5202,7 @@ void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { } } -void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { +void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_COND(p_bones < 0); @@ -5301,7 +5358,7 @@ void RendererStorageRD::_update_dirty_skeletons() { Skeleton *skeleton = skeleton_dirty_list; if (skeleton->size) { - RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr(), false); + RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr()); } skeleton_dirty_list = skeleton->dirty_list; @@ -5319,7 +5376,7 @@ void RendererStorageRD::_update_dirty_skeletons() { /* LIGHT */ -RID RendererStorageRD::light_create(RS::LightType p_type) { +void RendererStorageRD::_light_initialize(RID p_light, RS::LightType p_type) { Light light; light.type = p_type; @@ -5340,10 +5397,31 @@ RID RendererStorageRD::light_create(RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0; + light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; - return light_owner.make_rid(light); + light_owner.initialize_rid(p_light, light); +} + +RID RendererStorageRD::directional_light_allocate() { + return light_owner.allocate_rid(); +} +void RendererStorageRD::directional_light_initialize(RID p_light) { + _light_initialize(p_light, RS::LIGHT_DIRECTIONAL); +} + +RID RendererStorageRD::omni_light_allocate() { + return light_owner.allocate_rid(); +} +void RendererStorageRD::omni_light_initialize(RID p_light) { + _light_initialize(p_light, RS::LIGHT_OMNI); +} + +RID RendererStorageRD::spot_light_allocate() { + return light_owner.allocate_rid(); +} +void RendererStorageRD::spot_light_initialize(RID p_light) { + _light_initialize(p_light, RS::LIGHT_SPOT); } void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) { @@ -5581,8 +5659,11 @@ AABB RendererStorageRD::light_get_aabb(RID p_light) const { /* REFLECTION PROBE */ -RID RendererStorageRD::reflection_probe_create() { - return reflection_probe_owner.make_rid(ReflectionProbe()); +RID RendererStorageRD::reflection_probe_allocate() { + return reflection_probe_owner.allocate_rid(); +} +void RendererStorageRD::reflection_probe_initialize(RID p_reflection_probe) { + reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe()); } void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { @@ -5804,8 +5885,11 @@ float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) return reflection_probe->ambient_color_energy; } -RID RendererStorageRD::decal_create() { - return decal_owner.make_rid(Decal()); +RID RendererStorageRD::decal_allocate() { + return decal_owner.allocate_rid(); +} +void RendererStorageRD::decal_initialize(RID p_decal) { + decal_owner.initialize_rid(p_decal, Decal()); } void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) { @@ -5892,11 +5976,14 @@ AABB RendererStorageRD::decal_get_aabb(RID p_decal) const { return AABB(-decal->extents, decal->extents * 2.0); } -RID RendererStorageRD::gi_probe_create() { - return gi_probe_owner.make_rid(GIProbe()); +RID RendererStorageRD::gi_probe_allocate() { + return gi_probe_owner.allocate_rid(); +} +void RendererStorageRD::gi_probe_initialize(RID p_gi_probe) { + gi_probe_owner.initialize_rid(p_gi_probe, GIProbe()); } -void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { +void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -6245,8 +6332,12 @@ RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { /* LIGHTMAP API */ -RID RendererStorageRD::lightmap_create() { - return lightmap_owner.make_rid(Lightmap()); +RID RendererStorageRD::lightmap_allocate() { + return lightmap_owner.allocate_rid(); +} + +void RendererStorageRD::lightmap_initialize(RID p_lightmap) { + lightmap_owner.initialize_rid(p_lightmap, Lightmap()); } void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { @@ -6449,7 +6540,8 @@ void RendererStorageRD::_clear_render_target(RenderTarget *rt) { void RendererStorageRD::_update_render_target(RenderTarget *rt) { if (rt->texture.is_null()) { //create a placeholder until updated - rt->texture = texture_2d_placeholder_create(); + rt->texture = texture_allocate(); + texture_2d_placeholder_initialize(rt->texture); Texture *tex = texture_owner.getornull(rt->texture); tex->is_render_target = true; } @@ -6949,7 +7041,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0] RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1); /* Process */ @@ -6965,7 +7057,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0); push_constant.stride = stride; RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1); stride /= 2; swap = !swap; RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -6976,7 +7068,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1); RD::get_singleton()->compute_list_end(); } @@ -7340,6 +7432,7 @@ void RendererStorageRD::_update_decal_atlas() { tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB); decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView()); + RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1); { //create the framebuffer @@ -7394,7 +7487,7 @@ void RendererStorageRD::_update_decal_atlas() { prev_texture = mm.texture; } } else { - RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1, false); + RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1); } } } @@ -8160,29 +8253,38 @@ bool RendererStorageRD::free(RID p_rid) { material_owner.free(p_rid); } else if (mesh_owner.owns(p_rid)) { mesh_clear(p_rid); + mesh_set_shadow_mesh(p_rid, RID()); Mesh *mesh = mesh_owner.getornull(p_rid); mesh->dependency.deleted_notify(p_rid); if (mesh->instances.size()) { ERR_PRINT("deleting mesh with active instances"); } + if (mesh->shadow_owners.size()) { + for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) { + Mesh *shadow_owner = E->get(); + shadow_owner->shadow_mesh = RID(); + shadow_owner->dependency.changed_notify(DEPENDENCY_CHANGED_MESH); + } + } mesh_owner.free(p_rid); } else if (mesh_instance_owner.owns(p_rid)) { MeshInstance *mi = mesh_instance_owner.getornull(p_rid); _mesh_instance_clear(mi); mi->mesh->instances.erase(mi->I); mi->I = nullptr; + mesh_instance_owner.free(p_rid); memdelete(mi); } else if (multimesh_owner.owns(p_rid)) { _update_dirty_multimeshes(); - multimesh_allocate(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D); + multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D); MultiMesh *multimesh = multimesh_owner.getornull(p_rid); multimesh->dependency.deleted_notify(p_rid); multimesh_owner.free(p_rid); } else if (skeleton_owner.owns(p_rid)) { _update_dirty_skeletons(); - skeleton_allocate(p_rid, 0); + skeleton_allocate_data(p_rid, 0); Skeleton *skeleton = skeleton_owner.getornull(p_rid); skeleton->dependency.deleted_notify(p_rid); skeleton_owner.free(p_rid); @@ -8200,7 +8302,7 @@ bool RendererStorageRD::free(RID p_rid) { decal->dependency.deleted_notify(p_rid); decal_owner.free(p_rid); } else if (gi_probe_owner.owns(p_rid)) { - gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate + gi_probe_allocate_data(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); gi_probe->dependency.deleted_notify(p_rid); gi_probe_owner.free(p_rid); @@ -8256,11 +8358,11 @@ EffectsRD *RendererStorageRD::get_effects() { } void RendererStorageRD::capture_timestamps_begin() { - RD::get_singleton()->capture_timestamp("Frame Begin", false); + RD::get_singleton()->capture_timestamp("Frame Begin"); } void RendererStorageRD::capture_timestamp(const String &p_name) { - RD::get_singleton()->capture_timestamp(p_name, true); + RD::get_singleton()->capture_timestamp(p_name); } uint32_t RendererStorageRD::get_captured_timestamps_count() const { @@ -8294,7 +8396,7 @@ RendererStorageRD::RendererStorageRD() { static_assert(sizeof(GlobalVariables::Value) == 16); - global_variables.buffer_size = GLOBAL_GET("rendering/high_end/global_shader_variables_buffer_size"); + global_variables.buffer_size = GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size"); global_variables.buffer_size = MAX(4096, global_variables.buffer_size); global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); zeromem(global_variables.buffer_values, sizeof(GlobalVariables::Value) * global_variables.buffer_size); @@ -8562,14 +8664,14 @@ RendererStorageRD::RendererStorageRD() { sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.use_anisotropy = true; - sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level")); + sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/textures/default_filters/anisotropic_filtering_level")); } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: { sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.use_anisotropy = true; - sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level")); + sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/textures/default_filters/anisotropic_filtering_level")); } break; default: { @@ -8739,7 +8841,7 @@ RendererStorageRD::RendererStorageRD() { } } - lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed"); + lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed"); /* Particles */ @@ -8780,7 +8882,7 @@ RendererStorageRD::RendererStorageRD() { actions.renames["RESTART_VELOCITY"] = "restart_velocity"; actions.renames["RESTART_COLOR"] = "restart_color"; actions.renames["RESTART_CUSTOM"] = "restart_custom"; - actions.renames["emit_particle"] = "emit_particle"; + actions.renames["emit_subparticle"] = "emit_subparticle"; actions.renames["COLLIDED"] = "collided"; actions.renames["COLLISION_NORMAL"] = "collision_normal"; actions.renames["COLLISION_DEPTH"] = "collision_depth"; @@ -8806,9 +8908,11 @@ RendererStorageRD::RendererStorageRD() { { // default material and shader for particles shader - particles_shader.default_shader = shader_create(); + particles_shader.default_shader = shader_allocate(); + shader_initialize(particles_shader.default_shader); shader_set_code(particles_shader.default_shader, "shader_type particles; void compute() { COLOR = vec4(1.0); } \n"); - particles_shader.default_material = material_create(); + particles_shader.default_material = material_allocate(); + material_initialize(particles_shader.default_material); material_set_shader(particles_shader.default_material, particles_shader.default_shader); ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RendererStorageRD::SHADER_TYPE_PARTICLES); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 5ef73f0db8..68256dc155 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -95,6 +95,21 @@ public: p_array[11] = 0; } + static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform &p_mtx, float *p_array) { + p_array[0] = p_mtx.basis.elements[0][0]; + p_array[1] = p_mtx.basis.elements[0][1]; + p_array[2] = p_mtx.basis.elements[0][2]; + p_array[3] = p_mtx.origin.x; + p_array[4] = p_mtx.basis.elements[1][0]; + p_array[5] = p_mtx.basis.elements[1][1]; + p_array[6] = p_mtx.basis.elements[1][2]; + p_array[7] = p_mtx.origin.y; + p_array[8] = p_mtx.basis.elements[2][0]; + p_array[9] = p_mtx.basis.elements[2][1]; + p_array[10] = p_mtx.basis.elements[2][2]; + p_array[11] = p_mtx.origin.z; + } + static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { @@ -206,7 +221,7 @@ private: ~CanvasTexture(); }; - RID_PtrOwner<CanvasTexture> canvas_texture_owner; + RID_PtrOwner<CanvasTexture, true> canvas_texture_owner; /* TEXTURE API */ struct Texture { @@ -352,7 +367,7 @@ private: }; ShaderDataRequestFunction shader_data_request_func[SHADER_TYPE_MAX]; - mutable RID_Owner<Shader> shader_owner; + mutable RID_Owner<Shader, true> shader_owner; /* Material */ @@ -374,7 +389,7 @@ private: }; MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX]; - mutable RID_Owner<Material> material_owner; + mutable RID_Owner<Material, true> material_owner; Material *material_update_list; void _material_queue_update(Material *material, bool p_uniform, bool p_texture); @@ -463,10 +478,13 @@ private: List<MeshInstance *> instances; + RID shadow_mesh; + Set<Mesh *> shadow_owners; + Dependency dependency; }; - mutable RID_Owner<Mesh> mesh_owner; + mutable RID_Owner<Mesh, true> mesh_owner; struct MeshInstance { Mesh *mesh; @@ -569,7 +587,7 @@ private: Dependency dependency; }; - mutable RID_Owner<MultiMesh> multimesh_owner; + mutable RID_Owner<MultiMesh, true> multimesh_owner; MultiMesh *multimesh_dirty_list = nullptr; @@ -875,7 +893,7 @@ private: void update_particles(); - mutable RID_Owner<Particles> particles_owner; + mutable RID_Owner<Particles, true> particles_owner; /* Particles Collision */ @@ -897,7 +915,7 @@ private: Dependency dependency; }; - mutable RID_Owner<ParticlesCollision> particles_collision_owner; + mutable RID_Owner<ParticlesCollision, true> particles_collision_owner; struct ParticlesCollisionInstance { RID collision; @@ -927,7 +945,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Skeleton> skeleton_owner; + mutable RID_Owner<Skeleton, true> skeleton_owner; _FORCE_INLINE_ void _skeleton_make_dirty(Skeleton *skeleton); @@ -959,7 +977,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Light> light_owner; + mutable RID_Owner<Light, true> light_owner; /* REFLECTION PROBE */ @@ -982,7 +1000,7 @@ private: Dependency dependency; }; - mutable RID_Owner<ReflectionProbe> reflection_probe_owner; + mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner; /* DECAL */ @@ -1003,7 +1021,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Decal> decal_owner; + mutable RID_Owner<Decal, true> decal_owner; /* GI PROBE */ @@ -1046,7 +1064,7 @@ private: RID giprobe_sdf_shader_version_shader; RID giprobe_sdf_shader_pipeline; - mutable RID_Owner<GIProbe> gi_probe_owner; + mutable RID_Owner<GIProbe, true> gi_probe_owner; /* REFLECTION PROBE */ @@ -1077,7 +1095,7 @@ private: uint64_t lightmap_array_version = 0; - mutable RID_Owner<Lightmap> lightmap_owner; + mutable RID_Owner<Lightmap, true> lightmap_owner; float lightmap_probe_capture_update_speed = 4; @@ -1231,12 +1249,16 @@ private: EffectsRD effects; public: + virtual bool can_create_resources_async() const; + /* TEXTURE API */ - virtual RID texture_2d_create(const Ref<Image> &p_image); - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type); - virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent - virtual RID texture_proxy_create(RID p_base); + virtual RID texture_allocate(); + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image); + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type); + virtual void texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent + virtual void texture_proxy_initialize(RID p_texture, RID p_base); virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate); @@ -1246,9 +1268,9 @@ public: virtual void texture_proxy_update(RID p_texture, RID p_proxy_to); //these two APIs can be used together or in combination with the others. - virtual RID texture_2d_placeholder_create(); - virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type); - virtual RID texture_3d_placeholder_create(); + virtual void texture_2d_placeholder_initialize(RID p_texture); + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type); + virtual void texture_3d_placeholder_initialize(RID p_texture); virtual Ref<Image> texture_2d_get(RID p_texture) const; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const; @@ -1320,7 +1342,8 @@ public: /* CANVAS TEXTURE API */ - virtual RID canvas_texture_create(); + RID canvas_texture_allocate(); + void canvas_texture_initialize(RID p_canvas_texture); virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture); virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess); @@ -1332,7 +1355,8 @@ public: /* SHADER API */ - RID shader_create(); + RID shader_allocate(); + void shader_initialize(RID p_shader); void shader_set_code(RID p_shader, const String &p_code); String shader_get_code(RID p_shader) const; @@ -1347,7 +1371,8 @@ public: /* COMMON MATERIAL API */ - RID material_create(); + RID material_allocate(); + void material_initialize(RID p_material); void material_set_shader(RID p_material, RID p_shader); @@ -1383,7 +1408,8 @@ public: /* MESH API */ - virtual RID mesh_create(); + RID mesh_allocate(); + void mesh_initialize(RID p_mesh); virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count); @@ -1408,6 +1434,7 @@ public: virtual AABB mesh_get_custom_aabb(RID p_mesh) const; virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()); + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh); virtual void mesh_clear(RID p_mesh); @@ -1446,6 +1473,13 @@ public: return mesh->surfaces[p_surface_index]; } + _FORCE_INLINE_ RID mesh_get_shadow_mesh(RID p_mesh) { + Mesh *mesh = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND_V(!mesh, RID()); + + return mesh->shadow_mesh; + } + _FORCE_INLINE_ RS::PrimitiveType mesh_surface_get_primitive(void *p_surface) { Mesh::Surface *surface = reinterpret_cast<Mesh::Surface *>(p_surface); return surface->primitive; @@ -1456,13 +1490,7 @@ public: return s->lod_count > 0; } - _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface) const { - Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); - - return s->index_array; - } - - _FORCE_INLINE_ RID mesh_surface_get_index_array_with_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const { + _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const { Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); int32_t current_lod = -1; @@ -1474,9 +1502,19 @@ public: current_lod = i; } if (current_lod == -1) { + return 0; + } else { + return current_lod + 1; + } + } + + _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface, uint32_t p_lod) const { + Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); + + if (p_lod == 0) { return s->index_array; } else { - return s->lods[current_lod].index_array; + return s->lods[p_lod - 1].index_array; } } @@ -1592,9 +1630,10 @@ public: /* MULTIMESH API */ - RID multimesh_create(); + RID multimesh_allocate(); + void multimesh_initialize(RID p_multimesh); - void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false); + void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false); int multimesh_get_instance_count(RID p_multimesh) const; void multimesh_set_mesh(RID p_multimesh, RID p_mesh); @@ -1658,24 +1697,28 @@ public: /* IMMEDIATE API */ - RID immediate_create() { return RID(); } - void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {} - void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {} - void immediate_normal(RID p_immediate, const Vector3 &p_normal) {} - void immediate_tangent(RID p_immediate, const Plane &p_tangent) {} - void immediate_color(RID p_immediate, const Color &p_color) {} - void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {} - void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {} - void immediate_end(RID p_immediate) {} - void immediate_clear(RID p_immediate) {} - void immediate_set_material(RID p_immediate, RID p_material) {} - RID immediate_get_material(RID p_immediate) const { return RID(); } - AABB immediate_get_aabb(RID p_immediate) const { return AABB(); } + RID immediate_allocate() { return RID(); } + void immediate_initialize(RID p_immediate) {} + + virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {} + virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {} + virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) {} + virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) {} + virtual void immediate_color(RID p_immediate, const Color &p_color) {} + virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {} + virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {} + virtual void immediate_end(RID p_immediate) {} + virtual void immediate_clear(RID p_immediate) {} + virtual void immediate_set_material(RID p_immediate, RID p_material) {} + virtual RID immediate_get_material(RID p_immediate) const { return RID(); } + virtual AABB immediate_get_aabb(RID p_immediate) const { return AABB(); } /* SKELETON API */ - RID skeleton_create(); - void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false); + RID skeleton_allocate(); + void skeleton_initialize(RID p_skeleton); + + void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false); void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform); void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform); int skeleton_get_bone_count(RID p_skeleton) const; @@ -1709,11 +1752,16 @@ public: } /* Light API */ - RID light_create(RS::LightType p_type); + void _light_initialize(RID p_rid, RS::LightType p_type); + + RID directional_light_allocate(); + void directional_light_initialize(RID p_light); - RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); } - RID omni_light_create() { return light_create(RS::LIGHT_OMNI); } - RID spot_light_create() { return light_create(RS::LIGHT_SPOT); } + RID omni_light_allocate(); + void omni_light_initialize(RID p_light); + + RID spot_light_allocate(); + void spot_light_initialize(RID p_light); void light_set_color(RID p_light, const Color &p_color); void light_set_param(RID p_light, RS::LightParam p_param, float p_value); @@ -1816,7 +1864,8 @@ public: /* PROBE API */ - RID reflection_probe_create(); + RID reflection_probe_allocate(); + void reflection_probe_initialize(RID p_reflection_probe); void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode); void reflection_probe_set_intensity(RID p_probe, float p_intensity); @@ -1856,7 +1905,9 @@ public: /* DECAL API */ - virtual RID decal_create(); + RID decal_allocate(); + void decal_initialize(RID p_decal); + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents); virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture); virtual void decal_set_emission_energy(RID p_decal, float p_energy); @@ -1931,9 +1982,10 @@ public: /* GI PROBE API */ - RID gi_probe_create(); + RID gi_probe_allocate(); + void gi_probe_initialize(RID p_gi_probe); - void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); + void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); AABB gi_probe_get_bounds(RID p_gi_probe) const; Vector3i gi_probe_get_octree_size(RID p_gi_probe) const; @@ -1984,7 +2036,8 @@ public: /* LIGHTMAP CAPTURE */ - virtual RID lightmap_create(); + RID lightmap_allocate(); + void lightmap_initialize(RID p_lightmap); virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics); virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds); @@ -2033,7 +2086,8 @@ public: /* PARTICLES */ - RID particles_create(); + RID particles_allocate(); + void particles_initialize(RID p_particles_collision); void particles_set_emitting(RID p_particles, bool p_emitting); void particles_set_amount(RID p_particles, int p_amount); @@ -2111,7 +2165,9 @@ public: /* PARTICLES COLLISION */ - virtual RID particles_collision_create(); + RID particles_collision_allocate(); + void particles_collision_initialize(RID p_particles_collision); + virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type); virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask); virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius); //for spheres diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index e77141b26c..8135d388e1 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -687,7 +687,15 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uint32_t index = p_default_actions.base_varying_index; + List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light; + for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { + if (E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) { + var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(E->key(), E->get())); + fragment_varyings.insert(E->key()); + continue; + } + String vcode; String interp_mode = _interpstr(E->get().interpolation); vcode += _prestr(E->get().precision); @@ -705,6 +713,21 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge index++; } + if (var_frag_to_light.size() > 0) { + String gcode = "\n\nstruct {\n"; + for (List<Pair<StringName, SL::ShaderNode::Varying>>::Element *E = var_frag_to_light.front(); E; E = E->next()) { + gcode += "\t" + _prestr(E->get().second.precision) + _typestr(E->get().second.type) + " " + _mkid(E->get().first); + if (E->get().second.array_size > 0) { + gcode += "["; + gcode += itos(E->get().second.array_size); + gcode += "]"; + } + gcode += ";\n"; + } + gcode += "} frag_to_light;\n"; + r_gen_code.fragment_global += gcode; + } + for (int i = 0; i < pnode->vconstants.size(); i++) { const SL::ShaderNode::Constant &cnode = pnode->vconstants[i]; String gcode; @@ -833,6 +856,19 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; case SL::Node::TYPE_VARIABLE: { SL::VariableNode *vnode = (SL::VariableNode *)p_node; + bool use_fragment_varying = false; + + if (current_func_name != vertex_name) { + if (p_assigning) { + if (shader->varyings.has(vnode->name)) { + use_fragment_varying = true; + } + } else { + if (fragment_varyings.has(vnode->name)) { + use_fragment_varying = true; + } + } + } if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) { *p_actions.write_flag_pointers[vnode->name] = true; @@ -877,7 +913,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } } else { - code = _mkid(vnode->name); //its something else (local var most likely) use as is + if (use_fragment_varying) { + code = "frag_to_light."; + } + code += _mkid(vnode->name); //its something else (local var most likely) use as is } } @@ -962,6 +1001,23 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; case SL::Node::TYPE_ARRAY: { SL::ArrayNode *anode = (SL::ArrayNode *)p_node; + bool use_fragment_varying = false; + + if (current_func_name != vertex_name) { + if (anode->assign_expression != nullptr) { + use_fragment_varying = true; + } else { + if (p_assigning) { + if (shader->varyings.has(anode->name)) { + use_fragment_varying = true; + } + } else { + if (fragment_varyings.has(anode->name)) { + use_fragment_varying = true; + } + } + } + } if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) { *p_actions.write_flag_pointers[anode->name] = true; @@ -984,7 +1040,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (p_default_actions.renames.has(anode->name)) { code = p_default_actions.renames[anode->name]; } else { - code = _mkid(anode->name); + if (use_fragment_varying) { + code = "frag_to_light."; + } + code += _mkid(anode->name); } if (anode->call_expression != nullptr) { @@ -1277,6 +1336,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide used_name_defines.clear(); used_rmode_defines.clear(); used_flag_pointers.clear(); + fragment_varyings.clear(); shader = parser.get_shader(); function = nullptr; @@ -1408,7 +1468,7 @@ ShaderCompilerRD::ShaderCompilerRD() { actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; - bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley"); + bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley"); if (!force_lambert) { actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; @@ -1418,7 +1478,7 @@ ShaderCompilerRD::ShaderCompilerRD() { actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; - bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx"); + bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); if (!force_blinn) { actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h index d127d8e01c..6575829e73 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.h +++ b/servers/rendering/renderer_rd/shader_compiler_rd.h @@ -114,6 +114,7 @@ private: Set<StringName> used_flag_pointers; Set<StringName> used_rmode_defines; Set<StringName> internal_functions; + Set<StringName> fragment_varyings; DefaultIdentifierActions actions; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 2ae22a8a38..e4a39ff813 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -301,6 +301,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { builder.append(compute_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline + builder.append(base_compute_defines.get_data()); builder.append(general_defines.get_data()); builder.append(variant_defines[p_variant].get_data()); @@ -401,7 +402,6 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio builder.append(fragment_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline - builder.append(general_defines.get_data()); builder.append(variant_defines[i].get_data()); for (int j = 0; j < version->custom_defines.size(); j++) { @@ -440,6 +440,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio builder.append(compute_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline + builder.append(base_compute_defines.get_data()); builder.append(general_defines.get_data()); builder.append(variant_defines[i].get_data()); @@ -596,6 +597,22 @@ bool ShaderRD::is_variant_enabled(int p_variant) const { return variants_enabled[p_variant]; } +ShaderRD::ShaderRD() { + // Do not feel forced to use this, in most cases it makes little to no difference. + bool use_32_threads = false; + if (RD::get_singleton()->get_device_vendor_name() == "NVIDIA") { + use_32_threads = true; + } + String base_compute_define_text; + if (use_32_threads) { + base_compute_define_text = "\n#define NATIVE_LOCAL_GROUP_SIZE 32\n#define NATIVE_LOCAL_SIZE_2D_X 8\n#define NATIVE_LOCAL_SIZE_2D_Y 4\n"; + } else { + base_compute_define_text = "\n#define NATIVE_LOCAL_GROUP_SIZE 64\n#define NATIVE_LOCAL_SIZE_2D_X 8\n#define NATIVE_LOCAL_SIZE_2D_Y 8\n"; + } + + base_compute_defines = base_compute_define_text.ascii(); +} + void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) { ERR_FAIL_COND(variant_defines.size()); ERR_FAIL_COND(p_variant_defines.size() == 0); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index a3474c6f93..e0f4dcf2d0 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -99,8 +99,10 @@ class ShaderRD { const char *name; + CharString base_compute_defines; + protected: - ShaderRD() {} + ShaderRD(); void setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name); public: diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub index deaa9668df..c192574ff2 100644 --- a/servers/rendering/renderer_rd/shaders/SCsub +++ b/servers/rendering/renderer_rd/shaders/SCsub @@ -39,8 +39,10 @@ if "RD_GLSL" in env["BUILDERS"]: env.RD_GLSL("sdfgi_debug.glsl") env.RD_GLSL("sdfgi_debug_probes.glsl") env.RD_GLSL("volumetric_fog.glsl") - env.RD_GLSL("shadow_reduce.glsl") env.RD_GLSL("particles.glsl") env.RD_GLSL("particles_copy.glsl") env.RD_GLSL("sort.glsl") env.RD_GLSL("skeleton.glsl") + env.RD_GLSL("cluster_render.glsl") + env.RD_GLSL("cluster_store.glsl") + env.RD_GLSL("cluster_debug.glsl") diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 9c4e95a7c2..3b39edc70e 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -396,7 +396,7 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color); #ifdef LIGHT_SHADER_CODE_USED - shadow_color *= shadow_modulate; + shadow_color.rgb *= shadow_modulate; #endif shadow_color.a *= light_color.a; //respect light alpha @@ -546,7 +546,7 @@ FRAGMENT_SHADER_CODE #ifdef LIGHT_SHADER_CODE_USED vec4 shadow_modulate = vec4(1.0); - light_color = light_compute(light_vertex, direction, normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, true); + light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true); #else if (normal_used) { @@ -563,7 +563,7 @@ FRAGMENT_SHADER_CODE light_color = light_shadow_compute(light_base, light_color, shadow_uv #ifdef LIGHT_SHADER_CODE_USED , - shadow_modulate + shadow_modulate.rgb #endif ); } @@ -605,7 +605,7 @@ FRAGMENT_SHADER_CODE vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height); light_color.rgb *= light_base_color.rgb; - light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, false); + light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false); #else light_color.rgb *= light_base_color.rgb * light_base_color.a; @@ -659,7 +659,7 @@ FRAGMENT_SHADER_CODE light_color = light_shadow_compute(light_base, light_color, shadow_uv #ifdef LIGHT_SHADER_CODE_USED , - shadow_modulate + shadow_modulate.rgb #endif ); } diff --git a/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl index e723468dd8..3a4bf4da07 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl @@ -6,12 +6,18 @@ struct LightData { //this structure needs to be as packed as possible vec3 position; float inv_radius; + vec3 direction; float size; - uint attenuation_energy; //attenuation - uint color_specular; //rgb color, a specular (8 bit unorm) - uint cone_attenuation_angle; // attenuation and angle, (16bit float) - uint shadow_color_enabled; //shadow rgb color, a>0.5 enabled (8bit unorm) + + vec3 color; + float attenuation; + + float cone_attenuation; + float cone_angle; + float specular_amount; + bool shadow_enabled; + vec4 atlas_rect; // rect in the shadow atlas mat4 shadow_matrix; float shadow_bias; @@ -34,9 +40,13 @@ struct ReflectionData { float index; vec3 box_offset; uint mask; - vec4 params; // intensity, 0, interior , boxproject vec3 ambient; // ambient color + float intensity; + bool exterior; + bool box_project; uint ambient_mode; + uint pad; + //0-8 is intensity,8-9 is ambient, mode mat4 local_matrix; // up to here for spot and omni, rest is for directional // notes: for ambientblend, use distance to edge to blend between already existing global environment }; diff --git a/servers/rendering/renderer_rd/shaders/cluster_debug.glsl b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl new file mode 100644 index 0000000000..70a875192c --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl @@ -0,0 +1,115 @@ +#[compute] + +#version 450 + +VERSION_DEFINES + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +const vec3 usage_gradient[33] = vec3[]( // 1 (none) + 32 + vec3(0.14, 0.17, 0.23), + vec3(0.24, 0.44, 0.83), + vec3(0.23, 0.57, 0.84), + vec3(0.22, 0.71, 0.84), + vec3(0.22, 0.85, 0.83), + vec3(0.21, 0.85, 0.72), + vec3(0.21, 0.85, 0.57), + vec3(0.20, 0.85, 0.42), + vec3(0.20, 0.85, 0.27), + vec3(0.27, 0.86, 0.19), + vec3(0.51, 0.85, 0.19), + vec3(0.57, 0.86, 0.19), + vec3(0.62, 0.85, 0.19), + vec3(0.67, 0.86, 0.20), + vec3(0.73, 0.85, 0.20), + vec3(0.78, 0.85, 0.20), + vec3(0.83, 0.85, 0.20), + vec3(0.85, 0.82, 0.20), + vec3(0.85, 0.76, 0.20), + vec3(0.85, 0.81, 0.20), + vec3(0.85, 0.65, 0.20), + vec3(0.84, 0.60, 0.21), + vec3(0.84, 0.56, 0.21), + vec3(0.84, 0.51, 0.21), + vec3(0.84, 0.46, 0.21), + vec3(0.84, 0.41, 0.21), + vec3(0.84, 0.36, 0.21), + vec3(0.84, 0.31, 0.21), + vec3(0.84, 0.27, 0.21), + vec3(0.83, 0.22, 0.22), + vec3(0.83, 0.22, 0.27), + vec3(0.83, 0.22, 0.32), + vec3(1.00, 0.63, 0.70)); +layout(push_constant, binding = 0, std430) uniform Params { + uvec2 screen_size; + uvec2 cluster_screen_size; + + uint cluster_shift; + uint cluster_type; + float z_near; + float z_far; + + bool orthogonal; + uint max_cluster_element_count_div_32; + uint pad1; + uint pad2; +} +params; + +layout(set = 0, binding = 1, std430) buffer restrict readonly ClusterData { + uint data[]; +} +cluster_data; + +layout(rgba16f, set = 0, binding = 2) uniform restrict writeonly image2D screen_buffer; +layout(set = 0, binding = 3) uniform texture2D depth_buffer; +layout(set = 0, binding = 4) uniform sampler depth_buffer_sampler; + +void main() { + uvec2 screen_pos = gl_GlobalInvocationID.xy; + if (any(greaterThanEqual(screen_pos, params.screen_size))) { + return; + } + + uvec2 cluster_pos = screen_pos >> params.cluster_shift; + + uint offset = cluster_pos.y * params.cluster_screen_size.x + cluster_pos.x; + offset += params.cluster_screen_size.x * params.cluster_screen_size.y * params.cluster_type; + offset *= (params.max_cluster_element_count_div_32 + 32); + + //depth buffers generally can't be accessed via image API + float depth = texelFetch(sampler2D(depth_buffer, depth_buffer_sampler), ivec2(screen_pos), 0).r * 2.0 - 1.0; + + if (params.orthogonal) { + depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0; + } else { + depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); + } + depth /= params.z_far; + + uint slice = uint(clamp(floor(depth * 32.0), 0.0, 31.0)); + uint slice_minmax = cluster_data.data[offset + params.max_cluster_element_count_div_32 + slice]; + uint item_min = slice_minmax & 0xFFFF; + uint item_max = slice_minmax >> 16; + + uint item_count = 0; + for (uint i = 0; i < params.max_cluster_element_count_div_32; i++) { + uint slice_bits = cluster_data.data[offset + i]; + while (slice_bits != 0) { + uint bit = findLSB(slice_bits); + uint item = i * 32 + bit; + if ((item >= item_min && item < item_max)) { + item_count++; + } + slice_bits &= ~(1 << bit); + } + } + + item_count = min(item_count, 32); + + vec3 color = usage_gradient[item_count]; + + color = mix(color * 1.2, color * 0.3, float(slice) / 31.0); + + imageStore(screen_buffer, ivec2(screen_pos), vec4(color, 1.0)); +} diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl new file mode 100644 index 0000000000..8723ea78e4 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -0,0 +1,168 @@ +#[vertex] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) in vec3 vertex_attrib; + +layout(location = 0) out float depth_interp; +layout(location = 1) out flat uint element_index; + +layout(push_constant, binding = 0, std430) uniform Params { + uint base_index; + uint pad0; + uint pad1; + uint pad2; +} +params; + +layout(set = 0, binding = 1, std140) uniform State { + mat4 projection; + + float inv_z_far; + uint screen_to_clusters_shift; // shift to obtain coordinates in block indices + uint cluster_screen_width; // + uint cluster_data_size; // how much data for a single cluster takes + + uint cluster_depth_offset; + uint pad0; + uint pad1; + uint pad2; +} +state; + +struct RenderElement { + uint type; //0-4 + bool touches_near; + bool touches_far; + uint original_index; + mat3x4 transform_inv; + vec3 scale; + uint pad; +}; + +layout(set = 0, binding = 2, std430) buffer restrict readonly RenderElements { + RenderElement data[]; +} +render_elements; + +void main() { + element_index = params.base_index + gl_InstanceIndex; + + vec3 vertex = vertex_attrib; + vertex *= render_elements.data[element_index].scale; + + vertex = vec4(vertex, 1.0) * render_elements.data[element_index].transform_inv; + depth_interp = -vertex.z; + + gl_Position = state.projection * vec4(vertex, 1.0); +} + +#[fragment] + +#version 450 + +VERSION_DEFINES + +#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic) && defined(GL_KHR_shader_subgroup_vote) + +#extension GL_KHR_shader_subgroup_ballot : enable +#extension GL_KHR_shader_subgroup_arithmetic : enable +#extension GL_KHR_shader_subgroup_vote : enable + +#define USE_SUBGROUPS +#endif + +layout(location = 0) in float depth_interp; +layout(location = 1) in flat uint element_index; + +layout(set = 0, binding = 1, std140) uniform State { + mat4 projection; + float inv_z_far; + uint screen_to_clusters_shift; // shift to obtain coordinates in block indices + uint cluster_screen_width; // + uint cluster_data_size; // how much data for a single cluster takes + uint cluster_depth_offset; + uint pad0; + uint pad1; + uint pad2; +} +state; + +//cluster data is layout linearly, each cell contains the follow information: +// - list of bits for every element to mark as used, so (max_elem_count/32)*4 uints +// - a uint for each element to mark the depth bits used when rendering (0-31) + +layout(set = 0, binding = 3, std430) buffer restrict ClusterRender { + uint data[]; +} +cluster_render; + +void main() { + //convert from screen to cluster + uvec2 cluster = uvec2(gl_FragCoord.xy) >> state.screen_to_clusters_shift; + + //get linear cluster offset from screen poss + uint cluster_offset = cluster.x + state.cluster_screen_width * cluster.y; + //multiply by data size to position at the beginning of the element list for this cluster + cluster_offset *= state.cluster_data_size; + + //find the current element in the list and plot the bit to mark it as used + uint usage_write_offset = cluster_offset + (element_index >> 5); + uint usage_write_bit = 1 << (element_index & 0x1F); + +#ifdef USE_SUBGROUPS + + uint cluster_thread_group_index; + + if (!gl_HelperInvocation) { + //http://advances.realtimerendering.com/s2017/2017_Sig_Improved_Culling_final.pdf + + uvec4 mask; + + while (true) { + // find the cluster offset of the first active thread + // threads that did break; go inactive and no longer count + uint first = subgroupBroadcastFirst(cluster_offset); + // update the mask for thread that match this cluster + mask = subgroupBallot(first == cluster_offset); + if (first == cluster_offset) { + // This thread belongs to the group of threads that match this offset, + // so exit the loop. + break; + } + } + + cluster_thread_group_index = subgroupBallotExclusiveBitCount(mask); + + if (cluster_thread_group_index == 0) { + atomicOr(cluster_render.data[usage_write_offset], usage_write_bit); + } + } +#else + if (!gl_HelperInvocation) { + atomicOr(cluster_render.data[usage_write_offset], usage_write_bit); + } +#endif + //find the current element in the depth usage list and mark the current depth as used + float unit_depth = depth_interp * state.inv_z_far; + + uint z_bit = clamp(uint(floor(unit_depth * 32.0)), 0, 31); + + uint z_write_offset = cluster_offset + state.cluster_depth_offset + element_index; + uint z_write_bit = 1 << z_bit; + +#ifdef USE_SUBGROUPS + if (!gl_HelperInvocation) { + z_write_bit = subgroupOr(z_write_bit); //merge all Zs + if (cluster_thread_group_index == 0) { + atomicOr(cluster_render.data[z_write_offset], z_write_bit); + } + } +#else + if (!gl_HelperInvocation) { + atomicOr(cluster_render.data[z_write_offset], z_write_bit); + } +#endif +} diff --git a/servers/rendering/renderer_rd/shaders/cluster_store.glsl b/servers/rendering/renderer_rd/shaders/cluster_store.glsl new file mode 100644 index 0000000000..5be0893c4f --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/cluster_store.glsl @@ -0,0 +1,119 @@ +#[compute] + +#version 450 + +VERSION_DEFINES + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout(push_constant, binding = 0, std430) uniform Params { + uint cluster_render_data_size; // how much data for a single cluster takes + uint max_render_element_count_div_32; //divided by 32 + uvec2 cluster_screen_size; + uint render_element_count_div_32; //divided by 32 + + uint max_cluster_element_count_div_32; //divided by 32 + uint pad1; + uint pad2; +} +params; + +layout(set = 0, binding = 1, std430) buffer restrict readonly ClusterRender { + uint data[]; +} +cluster_render; + +layout(set = 0, binding = 2, std430) buffer restrict ClusterStore { + uint data[]; +} +cluster_store; + +struct RenderElement { + uint type; //0-4 + bool touches_near; + bool touches_far; + uint original_index; + mat3x4 transform_inv; + vec3 scale; + uint pad; +}; + +layout(set = 0, binding = 3, std430) buffer restrict readonly RenderElements { + RenderElement data[]; +} +render_elements; + +void main() { + uvec2 pos = gl_GlobalInvocationID.xy; + if (any(greaterThanEqual(pos, params.cluster_screen_size))) { + return; + } + + //counter for each type of render_element + + //base offset for this cluster + uint base_offset = (pos.x + params.cluster_screen_size.x * pos.y); + uint src_offset = base_offset * params.cluster_render_data_size; + + uint render_element_offset = 0; + + //check all render_elements and see which one was written to + while (render_element_offset < params.render_element_count_div_32) { + uint bits = cluster_render.data[src_offset + render_element_offset]; + while (bits != 0) { + //if bits exist, check the render_element + uint index_bit = findLSB(bits); + uint index = render_element_offset * 32 + index_bit; + uint type = render_elements.data[index].type; + + uint z_range_offset = src_offset + params.max_render_element_count_div_32 + index; + uint z_range = cluster_render.data[z_range_offset]; + + //if object was written, z was written, but check just in case + if (z_range != 0) { //should always be > 0 + + uint from_z = findLSB(z_range); + uint to_z = findMSB(z_range) + 1; + + if (render_elements.data[index].touches_near) { + from_z = 0; + } + + if (render_elements.data[index].touches_far) { + to_z = 32; + } + + // find cluster offset in the buffer used for indexing in the renderer + uint dst_offset = (base_offset + type * (params.cluster_screen_size.x * params.cluster_screen_size.y)) * (params.max_cluster_element_count_div_32 + 32); + + uint orig_index = render_elements.data[index].original_index; + //store this index in the Z slices by setting the relevant bit + for (uint i = from_z; i < to_z; i++) { + uint slice_ofs = dst_offset + params.max_cluster_element_count_div_32 + i; + + uint minmax = cluster_store.data[slice_ofs]; + + if (minmax == 0) { + minmax = 0xFFFF; //min 0, max 0xFFFF + } + + uint elem_min = min(orig_index, minmax & 0xFFFF); + uint elem_max = max(orig_index + 1, minmax >> 16); //always store plus one, so zero means range is empty when not written to + + minmax = elem_min | (elem_max << 16); + cluster_store.data[slice_ofs] = minmax; + } + + uint store_word = orig_index >> 5; + uint store_bit = orig_index & 0x1F; + + //store the actual render_element index at the end, so the rendering code can reference it + cluster_store.data[dst_offset + store_word] |= 1 << store_bit; + } + + bits &= ~(1 << index_bit); //clear the bit to continue iterating + } + + render_element_offset++; + } +} diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index 54d67db6c6..c3ac0bee57 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl @@ -1,33 +1,48 @@ -#[compute] +#[vertex] #version 450 VERSION_DEFINES -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +layout(push_constant, binding = 1, std430) uniform Params { + float z_far; + float z_near; + bool z_flip; + uint pad; + vec4 screen_rect; +} +params; + +layout(location = 0) out vec2 uv_interp; + +void main() { + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy; + gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0); +} + +#[fragment] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) in vec2 uv_interp; layout(set = 0, binding = 0) uniform samplerCube source_cube; layout(push_constant, binding = 1, std430) uniform Params { - ivec2 screen_size; - ivec2 offset; - float bias; float z_far; float z_near; bool z_flip; + uint pad; + vec4 screen_rect; } params; -layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer; - void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing - return; - } - - vec2 pixel_size = 1.0 / vec2(params.screen_size); - vec2 uv = (vec2(pos) + 0.5) * pixel_size; + vec2 uv = uv_interp; vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); @@ -65,5 +80,5 @@ void main() { float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); depth = (linear_depth * depth_fix) / params.z_far; - imageStore(depth_buffer, pos + params.offset, vec4(depth)); + gl_FragDepth = depth; } diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index 8011dadc72..92a5682572 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl @@ -97,13 +97,12 @@ layout(push_constant, binding = 0, std430) uniform Params { vec4 proj_info; + vec3 ao_color; uint max_giprobes; + bool high_quality_vct; - bool use_sdfgi; bool orthogonal; - - vec3 ao_color; - uint pad; + uint pad[2]; mat3x4 cam_rotation; } @@ -331,7 +330,7 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o } ambient_light.rgb = diffuse; -#if 1 + if (roughness < 0.2) { vec3 pos_to_uvw = 1.0 / sdfgi.grid_size; vec4 light_accum = vec4(0.0); @@ -363,59 +362,63 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o //ray_pos += ray_dir * (bias / sdfgi.cascades[cascade].to_cell); //bias to avoid self occlusion ray_pos += (ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) + cam_normal * 1.4) * bias / sdfgi.cascades[cascade].to_cell; } - float softness = 0.2 + min(1.0, roughness * 5.0) * 4.0; //approximation to roughness so it does not seem like a hard fade - while (length(ray_pos) < max_distance) { - for (uint i = 0; i < sdfgi.max_cascades; i++) { - if (i >= cascade && length(ray_pos) < radius_sizes[i]) { - cascade = max(i, cascade); //never go down - - vec3 pos = ray_pos - sdfgi.cascades[i].position; - pos *= sdfgi.cascades[i].to_cell * pos_to_uvw; - - float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.1; - - vec4 hit_light = vec4(0.0); - if (distance < softness) { - hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb; - hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy - hit_light.a = clamp(1.0 - (distance / softness), 0.0, 1.0); - hit_light.rgb *= hit_light.a; - } + uint i = 0; + bool found = false; + while (true) { + if (length(ray_pos) >= max_distance || light_accum.a > 0.99) { + break; + } + if (!found && i >= cascade && length(ray_pos) < radius_sizes[i]) { + uint next_i = min(i + 1, sdfgi.max_cascades - 1); + cascade = max(i, cascade); //never go down - distance /= sdfgi.cascades[i].to_cell; + vec3 pos = ray_pos - sdfgi.cascades[i].position; + pos *= sdfgi.cascades[i].to_cell * pos_to_uvw; - if (i < (sdfgi.max_cascades - 1)) { - pos = ray_pos - sdfgi.cascades[i + 1].position; - pos *= sdfgi.cascades[i + 1].to_cell * pos_to_uvw; + float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).r * 255.0 - 1.1; - float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.1; + vec4 hit_light = vec4(0.0); + if (fdistance < softness) { + hit_light.rgb = textureLod(sampler3D(light_cascades[i], linear_sampler), pos, 0.0).rgb; + hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy + hit_light.a = clamp(1.0 - (fdistance / softness), 0.0, 1.0); + hit_light.rgb *= hit_light.a; + } - vec4 hit_light2 = vec4(0.0); - if (distance2 < softness) { - hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb; - hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy - hit_light2.a = clamp(1.0 - (distance2 / softness), 0.0, 1.0); - hit_light2.rgb *= hit_light2.a; - } + fdistance /= sdfgi.cascades[i].to_cell; - float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1]; - float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0); + if (i < (sdfgi.max_cascades - 1)) { + pos = ray_pos - sdfgi.cascades[next_i].position; + pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw; - distance2 /= sdfgi.cascades[i + 1].to_cell; + float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1; - hit_light = mix(hit_light, hit_light2, blend); - distance = mix(distance, distance2, blend); + vec4 hit_light2 = vec4(0.0); + if (fdistance2 < softness) { + hit_light2.rgb = textureLod(sampler3D(light_cascades[next_i], linear_sampler), pos, 0.0).rgb; + hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy + hit_light2.a = clamp(1.0 - (fdistance2 / softness), 0.0, 1.0); + hit_light2.rgb *= hit_light2.a; } - light_accum += hit_light; - ray_pos += ray_dir * distance; - break; + float prev_radius = i == 0 ? 0.0 : radius_sizes[max(0, i - 1)]; + float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0); + + fdistance2 /= sdfgi.cascades[next_i].to_cell; + + hit_light = mix(hit_light, hit_light2, blend); + fdistance = mix(fdistance, fdistance2, blend); } - } - if (light_accum.a > 0.99) { - break; + light_accum += hit_light; + ray_pos += ray_dir * fdistance; + found = true; + } + i++; + if (i == sdfgi.max_cascades) { + i = 0; + found = false; } } @@ -434,8 +437,6 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o } } -#endif - reflection_light.rgb = specular; ambient_light.rgb *= sdfgi.energy; @@ -597,35 +598,24 @@ vec4 fetch_normal_and_roughness(ivec2 pos) { return normal_roughness; } -void main() { - // Pixel being shaded - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing - return; - } - - vec3 vertex = reconstruct_position(pos); - vertex.y = -vertex.y; - +void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 reflection_light) { vec4 normal_roughness = fetch_normal_and_roughness(pos); - vec3 normal = normal_roughness.xyz; - vec4 ambient_light = vec4(0.0), reflection_light = vec4(0.0); + vec3 normal = normal_roughness.xyz; if (normal.length() > 0.5) { //valid normal, can do GI float roughness = normal_roughness.w; - vertex = mat3(params.cam_rotation) * vertex; normal = normalize(mat3(params.cam_rotation) * normal); - vec3 reflection = normalize(reflect(normalize(vertex), normal)); - if (params.use_sdfgi) { - sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light); - } +#ifdef USE_SDFGI + sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light); +#endif - if (params.max_giprobes > 0) { +#ifdef USE_GIPROBES + { uvec2 giprobe_tex = texelFetch(usampler2D(giprobe_buffer, linear_sampler), pos, 0).rg; roughness *= roughness; //find arbitrary tangent and bitangent, then build a matrix @@ -648,16 +638,40 @@ void main() { spec_accum /= blend_accum; } - if (params.use_sdfgi) { - reflection_light = blend_color(spec_accum, reflection_light); - ambient_light = blend_color(amb_accum, ambient_light); - } else { - reflection_light = spec_accum; - ambient_light = amb_accum; - } +#ifdef USE_SDFGI + reflection_light = blend_color(spec_accum, reflection_light); + ambient_light = blend_color(amb_accum, ambient_light); +#else + reflection_light = spec_accum; + ambient_light = amb_accum; +#endif } +#endif + } +} + +void main() { + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + +#ifdef MODE_HALF_RES + pos <<= 1; +#endif + if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing + return; } + vec4 ambient_light = vec4(0.0); + vec4 reflection_light = vec4(0.0); + + vec3 vertex = reconstruct_position(pos); + vertex.y = -vertex.y; + + process_gi(pos, vertex, ambient_light, reflection_light); + +#ifdef MODE_HALF_RES + pos >>= 1; +#endif + imageStore(ambient_buffer, pos, ambient_light); imageStore(reflection_buffer, pos, reflection_light); } diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl index 4f4753d147..b931461b31 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl @@ -51,10 +51,10 @@ struct Light { float attenuation; vec3 color; - float spot_angle_radians; + float cos_spot_angle; vec3 position; - float spot_attenuation; + float inv_spot_attenuation; vec3 direction; bool has_shadow; @@ -233,13 +233,15 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 if (lights.data[light].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(pos - light_pos); - float angle = acos(dot(rel, lights.data[light].direction)); - if (angle > lights.data[light].spot_angle_radians) { + float cos_spot_angle = lights.data[light].cos_spot_angle; + float cos_angle = dot(rel, lights.data[light].direction); + if (cos_angle < cos_spot_angle) { return false; } - float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1); - attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation); + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation); } } diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl index 9c794f1bcc..56b3b7ccb4 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl @@ -43,10 +43,10 @@ struct Light { float attenuation; vec3 color; - float spot_angle_radians; + float cos_spot_angle; vec3 position; - float spot_attenuation; + float inv_spot_attenuation; vec3 direction; bool has_shadow; @@ -146,13 +146,15 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation if (lights.data[light].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(pos - light_pos); - float angle = acos(dot(rel, lights.data[light].direction)); - if (angle > lights.data[light].spot_angle_radians) { + float cos_spot_angle = lights.data[light].cos_spot_angle; + float cos_angle = dot(rel, lights.data[light].direction); + if (cos_angle < cos_spot_angle) { return false; } - float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1); - attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation); + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation); } } diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 926c7ef9fc..cb6d8dc7f6 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -173,7 +173,7 @@ uint hash(uint x) { return x; } -bool emit_particle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) { +bool emit_subparticle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) { if (!params.can_emit) { return false; } diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index 9429a66dc9..e83c4ca93b 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl @@ -58,6 +58,116 @@ void main() { #else +#if 1 + + vec4 group1; + vec4 group2; + vec4 group3; + vec4 group4; + int best_index = 0; + + //2X + group1.x = texelFetch(source_depth, pos, 0).r; + group1.y = texelFetch(source_depth, pos, 1).r; + + //4X + if (params.sample_count >= 4) { + group1.z = texelFetch(source_depth, pos, 2).r; + group1.w = texelFetch(source_depth, pos, 3).r; + } + //8X + if (params.sample_count >= 8) { + group2.x = texelFetch(source_depth, pos, 4).r; + group2.y = texelFetch(source_depth, pos, 5).r; + group2.z = texelFetch(source_depth, pos, 6).r; + group2.w = texelFetch(source_depth, pos, 7).r; + } + //16X + if (params.sample_count >= 16) { + group3.x = texelFetch(source_depth, pos, 8).r; + group3.y = texelFetch(source_depth, pos, 9).r; + group3.z = texelFetch(source_depth, pos, 10).r; + group3.w = texelFetch(source_depth, pos, 11).r; + + group4.x = texelFetch(source_depth, pos, 12).r; + group4.y = texelFetch(source_depth, pos, 13).r; + group4.z = texelFetch(source_depth, pos, 14).r; + group4.w = texelFetch(source_depth, pos, 15).r; + } + + if (params.sample_count == 2) { + best_index = (pos.x & 1) ^ ((pos.y >> 1) & 1); //not much can be done here + } else if (params.sample_count == 4) { + vec4 freq = vec4(equal(group1, vec4(group1.x))); + freq += vec4(equal(group1, vec4(group1.y))); + freq += vec4(equal(group1, vec4(group1.z))); + freq += vec4(equal(group1, vec4(group1.w))); + + float min_f = freq.x; + best_index = 0; + if (freq.y < min_f) { + best_index = 1; + min_f = freq.y; + } + if (freq.z < min_f) { + best_index = 2; + min_f = freq.z; + } + if (freq.w < min_f) { + best_index = 3; + } + } else if (params.sample_count == 8) { + vec4 freq0 = vec4(equal(group1, vec4(group1.x))); + vec4 freq1 = vec4(equal(group2, vec4(group1.x))); + freq0 += vec4(equal(group1, vec4(group1.y))); + freq1 += vec4(equal(group2, vec4(group1.y))); + freq0 += vec4(equal(group1, vec4(group1.z))); + freq1 += vec4(equal(group2, vec4(group1.z))); + freq0 += vec4(equal(group1, vec4(group1.w))); + freq1 += vec4(equal(group2, vec4(group1.w))); + freq0 += vec4(equal(group1, vec4(group2.x))); + freq1 += vec4(equal(group2, vec4(group2.x))); + freq0 += vec4(equal(group1, vec4(group2.y))); + freq1 += vec4(equal(group2, vec4(group2.y))); + freq0 += vec4(equal(group1, vec4(group2.z))); + freq1 += vec4(equal(group2, vec4(group2.z))); + freq0 += vec4(equal(group1, vec4(group2.w))); + freq1 += vec4(equal(group2, vec4(group2.w))); + + float min_f0 = freq0.x; + int best_index0 = 0; + if (freq0.y < min_f0) { + best_index0 = 1; + min_f0 = freq0.y; + } + if (freq0.z < min_f0) { + best_index0 = 2; + min_f0 = freq0.z; + } + if (freq0.w < min_f0) { + best_index0 = 3; + min_f0 = freq0.w; + } + + float min_f1 = freq1.x; + int best_index1 = 4; + if (freq1.y < min_f1) { + best_index1 = 5; + min_f1 = freq1.y; + } + if (freq1.z < min_f1) { + best_index1 = 6; + min_f1 = freq1.z; + } + if (freq1.w < min_f1) { + best_index1 = 7; + min_f1 = freq1.w; + } + + best_index = mix(best_index0, best_index1, min_f0 < min_f1); + } + +#else float depths[16]; int depth_indices[16]; int depth_amount[16]; @@ -91,7 +201,7 @@ void main() { depth_least = depth_amount[j]; } } - +#endif best_depth = texelFetch(source_depth, pos, best_index).r; best_normal_roughness = texelFetch(source_normal_roughness, pos, best_index); #ifdef GIPROBE_RESOLVE diff --git a/servers/rendering/renderer_rd/shaders/scene_forward.glsl b/servers/rendering/renderer_rd/shaders/scene_forward.glsl index 0518976322..1cea9bf8db 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward.glsl @@ -89,12 +89,6 @@ MATERIAL_UNIFORMS } material; #endif -/* clang-format off */ - -VERTEX_SHADER_GLOBALS - -/* clang-format on */ - invariant gl_Position; #ifdef MODE_DUAL_PARABOLOID @@ -103,28 +97,43 @@ layout(location = 8) out float dp_clip; #endif +layout(location = 9) out flat uint instance_index; + +/* clang-format off */ + +VERTEX_SHADER_GLOBALS + +/* clang-format on */ + void main() { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; #endif - mat4 world_matrix = draw_call.transform; + instance_index = draw_call.instance_index; + + bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH); + if (!is_multimesh) { + instance_index += gl_InstanceIndex; + } + + mat4 world_matrix = instances.data[instance_index].transform; mat3 world_normal_matrix; - if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { world_normal_matrix = inverse(mat3(world_matrix)); } else { world_normal_matrix = mat3(world_matrix); } - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH)) { + if (is_multimesh) { //multimesh, instances are for it - uint offset = (draw_call.flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK; + uint offset = (instances.data[instance_index].flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK; offset *= gl_InstanceIndex; mat4 matrix; - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); offset += 2; } else { @@ -132,14 +141,14 @@ void main() { offset += 3; } - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { #ifdef COLOR_USED color_interp *= transforms.data[offset]; #endif offset += 1; } - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { instance_custom = transforms.data[offset]; } @@ -161,7 +170,7 @@ void main() { #endif #if 0 - if (bool(draw_call.flags & INSTANCE_FLAGS_SKELETON)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) { //multimesh, instances are for it uvec2 bones_01 = uvec2(bone_attrib.x & 0xFFFF, bone_attrib.x >> 16) * 3; @@ -194,7 +203,7 @@ void main() { uv2_interp = uv2_attrib; #endif -#ifdef USE_OVERRIDE_POSITION +#ifdef OVERRIDE_POSITION vec4 position; #endif @@ -289,7 +298,7 @@ VERTEX_SHADER_CODE #endif //MODE_RENDER_DEPTH -#ifdef USE_OVERRIDE_POSITION +#ifdef OVERRIDE_POSITION gl_Position = position; #else gl_Position = projection_matrix * vec4(vertex_interp, 1.0); @@ -304,7 +313,8 @@ VERTEX_SHADER_CODE #endif #ifdef MODE_RENDER_MATERIAL if (scene_data.material_uv2_mode) { - gl_Position.xy = (uv2_attrib.xy + draw_call.lightmap_uv_scale.xy) * 2.0 - 1.0; + vec2 uv_offset = unpackHalf2x16(draw_call.uv_offset); + gl_Position.xy = (uv2_attrib.xy + uv_offset) * 2.0 - 1.0; gl_Position.z = 0.00001; gl_Position.w = 1.0; } @@ -350,9 +360,11 @@ layout(location = 8) in float dp_clip; #endif +layout(location = 9) in flat uint instance_index; + //defines to keep compatibility with vertex -#define world_matrix draw_call.transform +#define world_matrix instances.data[instance_index].transform #define projection_matrix scene_data.projection_matrix #if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) @@ -541,7 +553,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, vec3(metallic)); } -void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 shadow_attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity, +void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, vec3 f0, uint orms, float specular_amount, #ifdef LIGHT_BACKLIGHT_USED vec3 backlight, #endif @@ -553,7 +565,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float transmittance_z, #endif #ifdef LIGHT_RIM_USED - float rim, float rim_tint, + float rim, float rim_tint, vec3 rim_color, #endif #ifdef LIGHT_CLEARCOAT_USED float clearcoat, float clearcoat_gloss, @@ -561,6 +573,9 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #ifdef LIGHT_ANISOTROPY_USED vec3 B, vec3 T, float anisotropy, #endif +#ifdef USE_SOFT_SHADOWS + float A, +#endif #ifdef USE_SHADOW_TO_OPACITY inout float alpha, #endif @@ -570,7 +585,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // light is written by the light shader vec3 normal = N; - vec3 albedo = diffuse_color; vec3 light = L; vec3 view = V; @@ -581,7 +595,12 @@ LIGHT_SHADER_CODE /* clang-format on */ #else + +#ifdef USE_SOFT_SHADOWS float NdotL = min(A + dot(N, L), 1.0); +#else + float NdotL = dot(N, L); +#endif float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); float cNdotV = max(NdotV, 0.0); @@ -591,14 +610,25 @@ LIGHT_SHADER_CODE #endif #if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) +#ifdef USE_SOFT_SHADOWS float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); +#else + float cNdotH = clamp(dot(N, H), 0.0, 1.0); +#endif #endif #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) +#ifdef USE_SOFT_SHADOWS float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); +#else + float cLdotH = clamp(dot(L, H), 0.0, 1.0); +#endif #endif + float metallic = unpackUnorm4x8(orms).z; if (metallic < 1.0) { + float roughness = unpackUnorm4x8(orms).y; + #if defined(DIFFUSE_OREN_NAYAR) vec3 diffuse_brdf_NL; #else @@ -608,23 +638,6 @@ LIGHT_SHADER_CODE #if defined(DIFFUSE_LAMBERT_WRAP) // energy conserving lambert wrap shader diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))); - -#elif defined(DIFFUSE_OREN_NAYAR) - - { - // see http://mimosa-pudica.net/improved-oren-nayar.html - float LdotV = dot(L, V); - - float s = LdotV - NdotL * NdotV; - float t = mix(1.0, max(NdotL, NdotV), step(0.0, s)); - - float sigma2 = roughness * roughness; // TODO: this needs checking - vec3 A = 1.0 + sigma2 * (-0.5 / (sigma2 + 0.33) + 0.17 * diffuse_color / (sigma2 + 0.13)); - float B = 0.45 * sigma2 / (sigma2 + 0.09); - - diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI); - } - #elif defined(DIFFUSE_TOON) diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL); @@ -652,15 +665,15 @@ LIGHT_SHADER_CODE diffuse_brdf_NL = cNdotL * (1.0 / M_PI); #endif - diffuse_light += light_color * diffuse_color * shadow_attenuation * diffuse_brdf_NL * attenuation; + diffuse_light += light_color * diffuse_brdf_NL * attenuation; #if defined(LIGHT_BACKLIGHT_USED) - diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; + diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; #endif #if defined(LIGHT_RIM_USED) float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); - diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color; + diffuse_light += rim_light * rim * mix(vec3(1.0), rim_color, rim_tint) * light_color; #endif #ifdef LIGHT_TRANSMITTANCE_USED @@ -678,7 +691,7 @@ LIGHT_SHADER_CODE vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); - diffuse_light += profile * transmittance_color.a * diffuse_color * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI) * attenuation; + diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI); } #else @@ -688,7 +701,7 @@ LIGHT_SHADER_CODE fade = pow(max(0.0, 1.0 - fade), transmittance_curve); fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0); - diffuse_light += diffuse_color * transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade * attenuation; + diffuse_light += transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade; } #endif //SSS_MODE_SKIN @@ -696,6 +709,7 @@ LIGHT_SHADER_CODE #endif //LIGHT_TRANSMITTANCE_USED } + float roughness = unpackUnorm4x8(orms).y; if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely // D @@ -708,7 +722,7 @@ LIGHT_SHADER_CODE blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = blinn; - specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; + specular_light += light_color * intensity * attenuation * specular_amount; #elif defined(SPECULAR_PHONG) @@ -719,7 +733,7 @@ LIGHT_SHADER_CODE phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75); - specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; + specular_light += light_color * intensity * attenuation * specular_amount; #elif defined(SPECULAR_TOON) @@ -728,7 +742,7 @@ LIGHT_SHADER_CODE float mid = 1.0 - roughness; mid *= mid; float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; - diffuse_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection + diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection #elif defined(SPECULAR_DISABLED) // none.. @@ -753,13 +767,12 @@ LIGHT_SHADER_CODE float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx); #endif // F - vec3 f0 = F0(metallic, specular, diffuse_color); float cLdotH5 = SchlickFresnel(cLdotH); vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0); vec3 specular_brdf_NL = cNdotL * D * F * G; - specular_light += specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation; + specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; #endif #if defined(LIGHT_CLEARCOAT_USED) @@ -773,12 +786,12 @@ LIGHT_SHADER_CODE float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; - specular_light += clearcoat_specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation; + specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; #endif } #ifdef USE_SHADOW_TO_OPACITY - alpha = min(alpha, clamp(1.0 - length(shadow_attenuation * attenuation), 0.0, 1.0)); + alpha = min(alpha, clamp(1.0 - attenuation), 0.0, 1.0)); #endif #endif //defined(USE_LIGHT_SHADER_CODE) @@ -786,13 +799,11 @@ LIGHT_SHADER_CODE #ifndef USE_NO_SHADOWS -// Produces cheap white noise, optimized for window-space -// Comes from: https://www.shadertoy.com/view/4djSRW -// Copyright: Dave Hoskins, MIT License +// Interleaved Gradient Noise +// http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare float quick_hash(vec2 pos) { - vec3 p3 = fract(vec3(pos.xyx) * .1031); - p3 += dot(p3, p3.yzx + 33.33); - return fract((p3.x + p3.y) * p3.z); + const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f); + return fract(magic.z * fract(dot(pos, magic.xy))); } float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { @@ -900,68 +911,30 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { return nd * pow(max(distance, 0.0001), -decay); } -void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, -#ifdef LIGHT_BACKLIGHT_USED - vec3 backlight, -#endif -#ifdef LIGHT_TRANSMITTANCE_USED - vec4 transmittance_color, - float transmittance_depth, - float transmittance_curve, - float transmittance_boost, -#endif -#ifdef LIGHT_RIM_USED - float rim, float rim_tint, -#endif -#ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, -#endif -#ifdef LIGHT_ANISOTROPY_USED - vec3 binormal, vec3 tangent, float anisotropy, -#endif -#ifdef USE_SHADOW_TO_OPACITY - inout float alpha, -#endif - inout vec3 diffuse_light, inout vec3 specular_light) { - vec3 light_rel_vec = lights.data[idx].position - vertex; - float light_length = length(light_rel_vec); - vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy); - float omni_attenuation = get_omni_attenuation(light_length, lights.data[idx].inv_radius, attenuation_energy.x); - float light_attenuation = omni_attenuation; - vec3 shadow_attenuation = vec3(1.0); - vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular); - color_specular.rgb *= attenuation_energy.y; - float size_A = 0.0; - - if (lights.data[idx].size > 0.0) { - float t = lights.data[idx].size / max(0.001, light_length); - size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); - } - -#ifdef LIGHT_TRANSMITTANCE_USED - float transmittance_z = transmittance_depth; //no transmittance by default -#endif - +float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { #ifndef USE_NO_SHADOWS - vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled); - if (shadow_color_enabled.w > 0.5) { + if (omni_lights.data[idx].shadow_enabled) { // there is a shadowmap + vec3 light_rel_vec = omni_lights.data[idx].position - vertex; + float light_length = length(light_rel_vec); + vec4 v = vec4(vertex, 1.0); - vec4 splane = (lights.data[idx].shadow_matrix * v); + vec4 splane = (omni_lights.data[idx].shadow_matrix * v); float shadow_len = length(splane.xyz); //need to remember shadow len from here { - vec3 nofs = normal_interp * lights.data[idx].shadow_normal_bias / lights.data[idx].inv_radius; + vec3 nofs = normal_interp * omni_lights.data[idx].shadow_normal_bias / omni_lights.data[idx].inv_radius; nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp)))); v.xyz += nofs; - splane = (lights.data[idx].shadow_matrix * v); + splane = (omni_lights.data[idx].shadow_matrix * v); } float shadow; - if (lights.data[idx].soft_shadow_size > 0.0) { +#ifdef USE_SOFT_SHADOWS + if (omni_lights.data[idx].soft_shadow_size > 0.0) { //soft shadow //find blocker @@ -981,10 +954,10 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); vec3 tangent = normalize(cross(v0, normal)); vec3 bitangent = normalize(cross(tangent, normal)); - float z_norm = shadow_len * lights.data[idx].inv_radius; + float z_norm = shadow_len * omni_lights.data[idx].inv_radius; - tangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale; - bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale; + tangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale; + bitangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; @@ -992,7 +965,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; pos = normalize(pos); - vec4 uv_rect = lights.data[idx].atlas_rect; + vec4 uv_rect = omni_lights.data[idx].atlas_rect; if (pos.z >= 0.0) { pos.z += 1.0; @@ -1020,7 +993,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v tangent *= penumbra; bitangent *= penumbra; - z_norm -= lights.data[idx].inv_radius * lights.data[idx].shadow_bias; + z_norm -= omni_lights.data[idx].inv_radius * omni_lights.data[idx].shadow_bias; shadow = 0.0; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { @@ -1028,7 +1001,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; pos = normalize(pos); - vec4 uv_rect = lights.data[idx].atlas_rect; + vec4 uv_rect = omni_lights.data[idx].atlas_rect; if (pos.z >= 0.0) { pos.z += 1.0; @@ -1051,8 +1024,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v shadow = 1.0; } } else { +#endif splane.xyz = normalize(splane.xyz); - vec4 clamp_rect = lights.data[idx].atlas_rect; + vec4 clamp_rect = omni_lights.data[idx].atlas_rect; if (splane.z >= 0.0) { splane.z += 1.0; @@ -1066,101 +1040,149 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v splane.xy /= splane.z; splane.xy = splane.xy * 0.5 + 0.5; - splane.z = (shadow_len - lights.data[idx].shadow_bias) * lights.data[idx].inv_radius; + splane.z = (shadow_len - omni_lights.data[idx].shadow_bias) * omni_lights.data[idx].inv_radius; splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; splane.w = 1.0; //needed? i think it should be 1 already - shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); + shadow = sample_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); +#ifdef USE_SOFT_SHADOWS } +#endif + + return shadow; + } +#endif + return 1.0; +} + +void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 f0, uint orms, float shadow, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif #ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 clamp_rect = lights.data[idx].atlas_rect; + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, +#endif +#ifdef LIGHT_RIM_USED + float rim, float rim_tint, vec3 rim_color, +#endif +#ifdef LIGHT_CLEARCOAT_USED + float clearcoat, float clearcoat_gloss, +#endif +#ifdef LIGHT_ANISOTROPY_USED + vec3 binormal, vec3 tangent, float anisotropy, +#endif +#ifdef USE_SHADOW_TO_OPACITY + inout float alpha, +#endif + inout vec3 diffuse_light, inout vec3 specular_light) { + vec3 light_rel_vec = omni_lights.data[idx].position - vertex; + float light_length = length(light_rel_vec); + float omni_attenuation = get_omni_attenuation(light_length, omni_lights.data[idx].inv_radius, omni_lights.data[idx].attenuation); + float light_attenuation = omni_attenuation; + vec3 color = omni_lights.data[idx].color; - //redo shadowmapping, but shrink the model a bit to avoid arctifacts - splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); +#ifdef USE_SOFT_SHADOWS + float size_A = 0.0; - shadow_len = length(splane.xyz); - splane = normalize(splane.xyz); + if (omni_lights.data[idx].size > 0.0) { + float t = omni_lights.data[idx].size / max(0.001, light_length); + size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + } +#endif - if (splane.z >= 0.0) { - splane.z += 1.0; +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; //no transmittance by default + transmittance_color.a *= light_attenuation; + { + vec4 clamp_rect = omni_lights.data[idx].atlas_rect; - } else { - splane.z = 1.0 - splane.z; - } + //redo shadowmapping, but shrink the model a bit to avoid arctifacts + vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0)); - splane.xy /= splane.z; - splane.xy = splane.xy * 0.5 + 0.5; - splane.z = shadow_len * lights.data[idx].inv_radius; - splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; - splane.w = 1.0; //needed? i think it should be 1 already + shadow_len = length(splane.xyz); + splane = normalize(splane.xyz); + + if (splane.z >= 0.0) { + splane.z += 1.0; - float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; - transmittance_z = (splane.z - shadow_z) / lights.data[idx].inv_radius; + } else { + splane.z = 1.0 - splane.z; } -#endif - vec3 no_shadow = vec3(1.0); + splane.xy /= splane.z; + splane.xy = splane.xy * 0.5 + 0.5; + splane.z = shadow_len * omni_lights.data[idx].inv_radius; + splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; //needed? i think it should be 1 already - if (lights.data[idx].projector_rect != vec4(0.0)) { - vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; - local_v = normalize(local_v); + float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; + transmittance_z = (splane.z - shadow_z) / omni_lights.data[idx].inv_radius; + } +#endif - vec4 atlas_rect = lights.data[idx].projector_rect; +#if 0 - if (local_v.z >= 0.0) { - local_v.z += 1.0; - atlas_rect.y += atlas_rect.w; + if (omni_lights.data[idx].projector_rect != vec4(0.0)) { + vec3 local_v = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; + local_v = normalize(local_v); - } else { - local_v.z = 1.0 - local_v.z; - } + vec4 atlas_rect = omni_lights.data[idx].projector_rect; - local_v.xy /= local_v.z; - local_v.xy = local_v.xy * 0.5 + 0.5; - vec2 proj_uv = local_v.xy * atlas_rect.zw; + if (local_v.z >= 0.0) { + local_v.z += 1.0; + atlas_rect.y += atlas_rect.w; - vec2 proj_uv_ddx; - vec2 proj_uv_ddy; - { - vec3 local_v_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)).xyz; - local_v_ddx = normalize(local_v_ddx); + } else { + local_v.z = 1.0 - local_v.z; + } - if (local_v_ddx.z >= 0.0) { - local_v_ddx.z += 1.0; - } else { - local_v_ddx.z = 1.0 - local_v_ddx.z; - } + local_v.xy /= local_v.z; + local_v.xy = local_v.xy * 0.5 + 0.5; + vec2 proj_uv = local_v.xy * atlas_rect.zw; - local_v_ddx.xy /= local_v_ddx.z; - local_v_ddx.xy = local_v_ddx.xy * 0.5 + 0.5; + vec2 proj_uv_ddx; + vec2 proj_uv_ddy; + { + vec3 local_v_ddx = (omni_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)).xyz; + local_v_ddx = normalize(local_v_ddx); - proj_uv_ddx = local_v_ddx.xy * atlas_rect.zw - proj_uv; + if (local_v_ddx.z >= 0.0) { + local_v_ddx.z += 1.0; + } else { + local_v_ddx.z = 1.0 - local_v_ddx.z; + } - vec3 local_v_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)).xyz; - local_v_ddy = normalize(local_v_ddy); + local_v_ddx.xy /= local_v_ddx.z; + local_v_ddx.xy = local_v_ddx.xy * 0.5 + 0.5; - if (local_v_ddy.z >= 0.0) { - local_v_ddy.z += 1.0; - } else { - local_v_ddy.z = 1.0 - local_v_ddy.z; - } + proj_uv_ddx = local_v_ddx.xy * atlas_rect.zw - proj_uv; - local_v_ddy.xy /= local_v_ddy.z; - local_v_ddy.xy = local_v_ddy.xy * 0.5 + 0.5; + vec3 local_v_ddy = (omni_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)).xyz; + local_v_ddy = normalize(local_v_ddy); - proj_uv_ddy = local_v_ddy.xy * atlas_rect.zw - proj_uv; + if (local_v_ddy.z >= 0.0) { + local_v_ddy.z += 1.0; + } else { + local_v_ddy.z = 1.0 - local_v_ddy.z; } - vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy); - no_shadow = mix(no_shadow, proj.rgb, proj.a); + local_v_ddy.xy /= local_v_ddy.z; + local_v_ddy.xy = local_v_ddy.xy * 0.5 + 0.5; + + proj_uv_ddy = local_v_ddy.xy * atlas_rect.zw - proj_uv; } - shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow); + vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy); + no_shadow = mix(no_shadow, proj.rgb, proj.a); } -#endif //USE_NO_SHADOWS +#endif + + light_attenuation *= shadow; - light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, + light_compute(normal, normalize(light_rel_vec), eye_vec, color, light_attenuation, f0, orms, omni_lights.data[idx].specular_amount, #ifdef LIGHT_BACKLIGHT_USED backlight, #endif @@ -1172,7 +1194,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v transmittance_z, #endif #ifdef LIGHT_RIM_USED - rim * omni_attenuation, rim_tint, + rim * omni_attenuation, rim_tint, rim_color, #endif #ifdef LIGHT_CLEARCOAT_USED clearcoat, clearcoat_gloss, @@ -1180,6 +1202,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, #endif +#ifdef USE_SOFT_SHADOWS + size_A, +#endif #ifdef USE_SHADOW_TO_OPACITY alpha, #endif @@ -1187,88 +1212,39 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v specular_light); } -void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, -#ifdef LIGHT_BACKLIGHT_USED - vec3 backlight, -#endif -#ifdef LIGHT_TRANSMITTANCE_USED - vec4 transmittance_color, - float transmittance_depth, - float transmittance_curve, - float transmittance_boost, -#endif -#ifdef LIGHT_RIM_USED - float rim, float rim_tint, -#endif -#ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, -#endif -#ifdef LIGHT_ANISOTROPY_USED - vec3 binormal, vec3 tangent, float anisotropy, -#endif -#ifdef USE_SHADOW_TO_OPACITY - inout float alpha, -#endif - inout vec3 diffuse_light, - inout vec3 specular_light) { - vec3 light_rel_vec = lights.data[idx].position - vertex; - float light_length = length(light_rel_vec); - vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy); - float spot_attenuation = get_omni_attenuation(light_length, lights.data[idx].inv_radius, attenuation_energy.x); - vec3 spot_dir = lights.data[idx].direction; - vec2 spot_att_angle = unpackHalf2x16(lights.data[idx].cone_attenuation_angle); - float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y); - float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y)); - spot_attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x); - float light_attenuation = spot_attenuation; - vec3 shadow_attenuation = vec3(1.0); - vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular); - color_specular.rgb *= attenuation_energy.y; - - float size_A = 0.0; - - if (lights.data[idx].size > 0.0) { - float t = lights.data[idx].size / max(0.001, light_length); - size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); - } -/* - if (lights.data[idx].atlas_rect!=vec4(0.0)) { - //use projector texture - } - */ -#ifdef LIGHT_TRANSMITTANCE_USED - float transmittance_z = transmittance_depth; -#endif - +float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { #ifndef USE_NO_SHADOWS - vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled); - if (shadow_color_enabled.w > 0.5) { + if (spot_lights.data[idx].shadow_enabled) { + vec3 light_rel_vec = spot_lights.data[idx].position - vertex; + float light_length = length(light_rel_vec); + vec3 spot_dir = spot_lights.data[idx].direction; //there is a shadowmap vec4 v = vec4(vertex, 1.0); - v.xyz -= spot_dir * lights.data[idx].shadow_bias; + v.xyz -= spot_dir * spot_lights.data[idx].shadow_bias; - float z_norm = dot(spot_dir, -light_rel_vec) * lights.data[idx].inv_radius; + float z_norm = dot(spot_dir, -light_rel_vec) * spot_lights.data[idx].inv_radius; float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map - vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * lights.data[idx].shadow_normal_bias * depth_bias_scale; + vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * spot_lights.data[idx].shadow_normal_bias * depth_bias_scale; normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z v.xyz += normal_bias; //adjust with bias - z_norm = dot(spot_dir, v.xyz - lights.data[idx].position) * lights.data[idx].inv_radius; + z_norm = dot(spot_dir, v.xyz - spot_lights.data[idx].position) * spot_lights.data[idx].inv_radius; float shadow; - vec4 splane = (lights.data[idx].shadow_matrix * v); + vec4 splane = (spot_lights.data[idx].shadow_matrix * v); splane /= splane.w; - if (lights.data[idx].soft_shadow_size > 0.0) { +#ifdef USE_SOFT_SHADOWS + if (spot_lights.data[idx].soft_shadow_size > 0.0) { //soft shadow //find blocker - vec2 shadow_uv = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy; + vec2 shadow_uv = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy; float blocker_count = 0.0; float blocker_average = 0.0; @@ -1281,11 +1257,11 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); } - float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale; - vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw; + float uv_size = spot_lights.data[idx].soft_shadow_size * z_norm * spot_lights.data[idx].soft_shadow_scale; + vec2 clamp_max = spot_lights.data[idx].atlas_rect.xy + spot_lights.data[idx].atlas_rect.zw; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; - suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max); + suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max); float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; if (d < z_norm) { blocker_average += d; @@ -1302,7 +1278,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v shadow = 0.0; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; - suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max); + suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max); shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, z_norm, 1.0)); } @@ -1314,54 +1290,93 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } } else { +#endif //hard shadow - vec4 shadow_uv = vec4(splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy, z_norm, 1.0); + vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0); - shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv); + shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv); +#ifdef USE_SOFT_SHADOWS } +#endif - vec3 no_shadow = vec3(1.0); + return shadow; + } - if (lights.data[idx].projector_rect != vec4(0.0)) { - splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); - splane /= splane.w; +#endif //USE_NO_SHADOWS - vec2 proj_uv = splane.xy * lights.data[idx].projector_rect.zw; + return 1.0; +} - //ensure we have proper mipmaps - vec4 splane_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)); - splane_ddx /= splane_ddx.w; - vec2 proj_uv_ddx = splane_ddx.xy * lights.data[idx].projector_rect.zw - proj_uv; +void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 f0, uint orms, float shadow, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, +#endif +#ifdef LIGHT_RIM_USED + float rim, float rim_tint, vec3 rim_color, +#endif +#ifdef LIGHT_CLEARCOAT_USED + float clearcoat, float clearcoat_gloss, +#endif +#ifdef LIGHT_ANISOTROPY_USED + vec3 binormal, vec3 tangent, float anisotropy, +#endif +#ifdef USE_SHADOW_TO_OPACITY + inout float alpha, +#endif + inout vec3 diffuse_light, + inout vec3 specular_light) { + vec3 light_rel_vec = spot_lights.data[idx].position - vertex; + float light_length = length(light_rel_vec); + float spot_attenuation = get_omni_attenuation(light_length, spot_lights.data[idx].inv_radius, spot_lights.data[idx].attenuation); + vec3 spot_dir = spot_lights.data[idx].direction; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[idx].cone_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[idx].cone_angle)); + spot_attenuation *= 1.0 - pow(spot_rim, spot_lights.data[idx].cone_attenuation); + float light_attenuation = spot_attenuation; + vec3 color = spot_lights.data[idx].color; + float specular_amount = spot_lights.data[idx].specular_amount; - vec4 splane_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)); - splane_ddy /= splane_ddy.w; - vec2 proj_uv_ddy = splane_ddy.xy * lights.data[idx].projector_rect.zw - proj_uv; +#ifdef USE_SOFT_SHADOWS + float size_A = 0.0; - vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + lights.data[idx].projector_rect.xy, proj_uv_ddx, proj_uv_ddy); - no_shadow = mix(no_shadow, proj.rgb, proj.a); - } + if (spot_lights.data[idx].size > 0.0) { + float t = spot_lights.data[idx].size / max(0.001, light_length); + size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + } +#endif - shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow); + /* + if (spot_lights.data[idx].atlas_rect!=vec4(0.0)) { + //use projector texture + } + */ #ifdef LIGHT_TRANSMITTANCE_USED - { - splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); - splane /= splane.w; - splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy; - - float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; - //reconstruct depth - shadow_z /= lights.data[idx].inv_radius; - //distance to light plane - float z = dot(spot_dir, -light_rel_vec); - transmittance_z = z - shadow_z; - } -#endif //LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; + transmittance_color.a *= light_attenuation; + { + splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0)); + splane /= splane.w; + splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy; + + float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; + //reconstruct depth + shadow_z /= spot_lights.data[idx].inv_radius; + //distance to light plane + float z = dot(spot_dir, -light_rel_vec); + transmittance_z = z - shadow_z; } +#endif //LIGHT_TRANSMITTANCE_USED -#endif //USE_NO_SHADOWS + light_attenuation *= shadow; - light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, + light_compute(normal, normalize(light_rel_vec), eye_vec, color, light_attenuation, f0, orms, spot_lights.data[idx].specular_amount, #ifdef LIGHT_BACKLIGHT_USED backlight, #endif @@ -1373,7 +1388,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v transmittance_z, #endif #ifdef LIGHT_RIM_USED - rim * spot_attenuation, rim_tint, + rim * spot_attenuation, rim_tint, rim_color, #endif #ifdef LIGHT_CLEARCOAT_USED clearcoat, clearcoat_gloss, @@ -1381,6 +1396,9 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, #endif +#ifdef USE_SOFT_SHADOW + size_A, +#endif #ifdef USE_SHADOW_TO_OPACITY alpha, #endif @@ -1404,11 +1422,11 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes blend *= blend; blend = max(0.0, 1.0 - blend); - if (reflections.data[ref_index].params.x > 0.0) { // compute reflection + if (reflections.data[ref_index].intensity > 0.0) { // compute reflection vec3 local_ref_vec = (reflections.data[ref_index].local_matrix * vec4(ref_vec, 0.0)).xyz; - if (reflections.data[ref_index].params.w > 0.5) { //box project + if (reflections.data[ref_index].box_project) { //box project vec3 nrdir = normalize(local_ref_vec); vec3 rbmax = (box_extents - local_pos) / nrdir; @@ -1425,11 +1443,11 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb; - if (reflections.data[ref_index].params.z < 0.5) { + if (reflections.data[ref_index].exterior) { reflection.rgb = mix(specular_light, reflection.rgb, blend); } - reflection.rgb *= reflections.data[ref_index].params.x; + reflection.rgb *= reflections.data[ref_index].intensity; //intensity reflection.a = blend; reflection.rgb *= reflection.a; @@ -1448,7 +1466,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes ambient_out.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_amb_vec, reflections.data[ref_index].index), MAX_ROUGHNESS_LOD).rgb; ambient_out.a = blend; - if (reflections.data[ref_index].params.z < 0.5) { //interior + if (reflections.data[ref_index].exterior) { ambient_out.rgb = mix(ambient_light, ambient_out.rgb, blend); } @@ -1459,7 +1477,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes vec4 ambient_out; ambient_out.a = blend; ambient_out.rgb = reflections.data[ref_index].ambient; - if (reflections.data[ref_index].params.z < 0.5) { + if (reflections.data[ref_index].exterior) { ambient_out.rgb = mix(ambient_light, ambient_out.rgb, blend); } ambient_out.rgb *= ambient_out.a; @@ -1762,7 +1780,7 @@ vec4 fog_process(vec3 vertex) { } } - float fog_amount = 1.0 - exp(vertex.z * scene_data.fog_density); + float fog_amount = 1.0 - exp(min(0.0, vertex.z * scene_data.fog_density)); if (abs(scene_data.fog_height_density) > 0.001) { float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y; @@ -1777,7 +1795,43 @@ vec4 fog_process(vec3 vertex) { return vec4(fog_color, fog_amount); } +void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) { + uint item_min_max = cluster_buffer.data[p_offset]; + item_min = item_min_max & 0xFFFF; + item_max = item_min_max >> 16; + ; + + item_from = item_min >> 5; + item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements +} + +uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) { + int local_min = clamp(int(z_min) - int(i) * 32, 0, 31); + int mask_width = min(int(z_max) - int(z_min), 32 - local_min); + return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width); +} + +float blur_shadow(float shadow) { + return shadow; +#if 0 + //disabling for now, will investigate later + float interp_shadow = shadow; + if (gl_HelperInvocation) { + interp_shadow = -4.0; // technically anything below -4 will do but just to make sure + } + + uvec2 fc2 = uvec2(gl_FragCoord.xy); + interp_shadow -= dFdx(interp_shadow) * (float(fc2.x & 1) - 0.5); + interp_shadow -= dFdy(interp_shadow) * (float(fc2.y & 1) - 0.5); + + if (interp_shadow >= 0.0) { + shadow = interp_shadow; + } + return shadow; #endif +} + +#endif //!MODE_RENDER DEPTH void main() { #ifdef MODE_DUAL_PARABOLOID @@ -1805,9 +1859,7 @@ void main() { float clearcoat_gloss = 0.0; float anisotropy = 0.0; vec2 anisotropy_flow = vec2(1.0, 0.0); -#if defined(CUSTOM_FOG_USED) - vec4 custom_fog = vec4(0.0); -#endif + vec4 fog = vec4(0.0); #if defined(CUSTOM_RADIANCE_USED) vec4 custom_radiance = vec4(0.0); #endif @@ -1815,10 +1867,8 @@ void main() { vec4 custom_irradiance = vec4(0.0); #endif -#if defined(AO_USED) float ao = 1.0; float ao_light_affect = 0.0; -#endif float alpha = 1.0; @@ -1956,77 +2006,147 @@ FRAGMENT_SHADER_CODE discard; } #endif + + /////////////////////// FOG ////////////////////// +#ifndef MODE_RENDER_DEPTH + +#ifndef CUSTOM_FOG_USED + // fog must be processed as early as possible and then packed. + // to maximize VGPR usage + // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. + + if (scene_data.fog_enabled) { + fog = fog_process(vertex); + } + +#ifndef LOW_END_MODE + if (scene_data.volumetric_fog_enabled) { + vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z); + if (scene_data.fog_enabled) { + //must use the full blending equation here to blend fogs + vec4 res; + float sa = 1.0 - volumetric_fog.a; + res.a = fog.a * sa + volumetric_fog.a; + if (res.a == 0.0) { + res.rgb = vec3(0.0); + } else { + res.rgb = (fog.rgb * fog.a * sa + volumetric_fog.rgb * volumetric_fog.a) / res.a; + } + fog = res; + } else { + fog = volumetric_fog; + } + } +#endif //!LOW_END_MODE +#endif //!CUSTOM_FOG_USED + + uint fog_rg = packHalf2x16(fog.rg); + uint fog_ba = packHalf2x16(fog.ba); + +#endif //!MODE_RENDER_DEPTH + /////////////////////// DECALS //////////////////////////////// #ifndef MODE_RENDER_DEPTH - uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near))); + uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> scene_data.cluster_shift; + uint cluster_offset = (scene_data.cluster_width * cluster_pos.y + cluster_pos.x) * (scene_data.max_cluster_element_count_div_32 + 32); + + uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0)); + //used for interpolating anything cluster related vec3 vertex_ddx = dFdx(vertex); vec3 vertex_ddy = dFdy(vertex); { // process decals - uint decal_count = cluster_cell.w >> CLUSTER_COUNTER_SHIFT; - uint decal_pointer = cluster_cell.w & CLUSTER_POINTER_MASK; + uint cluster_decal_offset = cluster_offset + scene_data.cluster_type_size * 2; - //do outside for performance and avoiding arctifacts + uint item_min; + uint item_max; + uint item_from; + uint item_to; - for (uint i = 0; i < decal_count; i++) { - uint decal_index = cluster_data.indices[decal_pointer + i]; - if (!bool(decals.data[decal_index].mask & draw_call.layer_mask)) { - continue; //not masked - } + cluster_get_item_range(cluster_decal_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); - vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; - if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { - continue; //out of decal - } +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif - //we need ddx/ddy for mipmaps, so simulate them - vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; - vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_decal_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); +#ifdef USE_SUBGROUPS + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); +#else + uint merged_mask = mask; +#endif - float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); +#ifdef USE_SUBGROUPS + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } +#endif + uint decal_index = 32 * i + bit; - if (decals.data[decal_index].normal_fade > 0.0) { - fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); - } + if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } - if (decals.data[decal_index].albedo_rect != vec4(0.0)) { - //has albedo - vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); - decal_albedo *= decals.data[decal_index].modulate; - decal_albedo.a *= fade; - albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); - - if (decals.data[decal_index].normal_rect != vec4(0.0)) { - vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; - decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software - decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); - //convert to view space, use xzy because y is up - decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; - - normal = normalize(mix(normal, decal_normal, decal_albedo.a)); + vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; + if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { + continue; //out of decal } - if (decals.data[decal_index].orm_rect != vec4(0.0)) { - vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; -#if defined(AO_USED) - ao = mix(ao, decal_orm.r, decal_albedo.a); -#endif - roughness = mix(roughness, decal_orm.g, decal_albedo.a); - metallic = mix(metallic, decal_orm.b, decal_albedo.a); + //we need ddx/ddy for mipmaps, so simulate them + vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; + vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; + + float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); + + if (decals.data[decal_index].normal_fade > 0.0) { + fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); + } + + if (decals.data[decal_index].albedo_rect != vec4(0.0)) { + //has albedo + vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); + decal_albedo *= decals.data[decal_index].modulate; + decal_albedo.a *= fade; + albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); + + if (decals.data[decal_index].normal_rect != vec4(0.0)) { + vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; + decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software + decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); + //convert to view space, use xzy because y is up + decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; + + normal = normalize(mix(normal, decal_normal, decal_albedo.a)); + } + + if (decals.data[decal_index].orm_rect != vec4(0.0)) { + vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; + ao = mix(ao, decal_orm.r, decal_albedo.a); + roughness = mix(roughness, decal_orm.g, decal_albedo.a); + metallic = mix(metallic, decal_orm.b, decal_albedo.a); + } } - } - if (decals.data[decal_index].emission_rect != vec4(0.0)) { - //emission is additive, so its independent from albedo - emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + if (decals.data[decal_index].emission_rect != vec4(0.0)) { + //emission is additive, so its independent from albedo + emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + } } } } + //pack albedo until needed again, saves 2 VGPRs in the meantime + #endif //not render depth /////////////////////// LIGHTING ////////////////////////////// @@ -2094,19 +2214,14 @@ FRAGMENT_SHADER_CODE //radiance - float specular_blob_intensity = 1.0; - -#if defined(SPECULAR_TOON) - specular_blob_intensity *= specular * 2.0; -#endif - +/// GI /// #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #ifdef USE_LIGHTMAP //lightmap - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture - uint index = draw_call.gi_offset; + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture + uint index = instances.data[instance_index].gi_offset; vec3 wnormal = mat3(scene_data.camera_matrix) * normal; const float c1 = 0.429043; @@ -2125,12 +2240,12 @@ FRAGMENT_SHADER_CODE 2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y + 2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z); - } else if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap - bool uses_sh = bool(draw_call.flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP); - uint ofs = draw_call.gi_offset & 0xFFFF; + } else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap + bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP); + uint ofs = instances.data[instance_index].gi_offset & 0xFFFF; vec3 uvw; - uvw.xy = uv2 * draw_call.lightmap_uv_scale.zw + draw_call.lightmap_uv_scale.xy; - uvw.z = float((draw_call.gi_offset >> 16) & 0xFFFF); + uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy; + uvw.z = float((instances.data[instance_index].gi_offset >> 16) & 0xFFFF); if (uses_sh) { uvw.z *= 4.0; //SH textures use 4 times more data @@ -2139,7 +2254,7 @@ FRAGMENT_SHADER_CODE vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb; vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb; - uint idx = draw_call.gi_offset >> 20; + uint idx = instances.data[instance_index].gi_offset >> 20; vec3 n = normalize(lightmaps.data[idx].normal_xform * normal); ambient_light += lm_light_l0 * 0.282095f; @@ -2159,7 +2274,7 @@ FRAGMENT_SHADER_CODE } #elif defined(USE_FORWARD_GI) - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture //make vertex orientation the world one, but still align to camera vec3 cam_pos = mat3(scene_data.camera_matrix) * vertex; @@ -2231,9 +2346,9 @@ FRAGMENT_SHADER_CODE } } - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes - uint index1 = draw_call.gi_offset & 0xFFFF; + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); //find arbitrary tangent and bitangent, then build a matrix vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); @@ -2245,7 +2360,7 @@ FRAGMENT_SHADER_CODE vec4 spec_accum = vec4(0.0); gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); - uint index2 = draw_call.gi_offset >> 16; + uint index2 = instances.data[instance_index].gi_offset >> 16; if (index2 != 0xFFFF) { gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); @@ -2264,19 +2379,19 @@ FRAGMENT_SHADER_CODE } #elif !defined(LOW_END_MODE) - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers - ivec2 coord; + vec2 coord; if (scene_data.gi_upscale_for_msaa) { - ivec2 base_coord = ivec2(gl_FragCoord.xy); - ivec2 closest_coord = base_coord; - float closest_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0).xyz * 2.0 - 1.0); + vec2 base_coord = screen_uv; + vec2 closest_coord = base_coord; + float closest_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0.0).xyz * 2.0 - 1.0); for (int i = 0; i < 4; i++) { - const ivec2 neighbours[4] = ivec2[](ivec2(-1, 0), ivec2(1, 0), ivec2(0, -1), ivec2(0, 1)); - ivec2 neighbour_coord = base_coord + neighbours[i]; - float neighbour_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0).xyz * 2.0 - 1.0); + const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1)); + vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size; + float neighbour_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0.0).xyz * 2.0 - 1.0); if (neighbour_ang > closest_ang) { closest_ang = neighbour_ang; closest_coord = neighbour_coord; @@ -2286,28 +2401,69 @@ FRAGMENT_SHADER_CODE coord = closest_coord; } else { - coord = ivec2(gl_FragCoord.xy); + coord = screen_uv; } - vec4 buffer_ambient = texelFetch(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0); - vec4 buffer_reflection = texelFetch(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0); + vec4 buffer_ambient = textureLod(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0); + vec4 buffer_reflection = textureLod(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0); ambient_light = mix(ambient_light, buffer_ambient.rgb, buffer_ambient.a); specular_light = mix(specular_light, buffer_reflection.rgb, buffer_reflection.a); } #endif +#ifndef LOW_END_MODE + if (scene_data.ssao_enabled) { + float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r; + ao = min(ao, ssao); + ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect); + } +#endif //LOW_END_MODE + { // process reflections vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); - uint reflection_probe_count = cluster_cell.z >> CLUSTER_COUNTER_SHIFT; - uint reflection_probe_pointer = cluster_cell.z & CLUSTER_POINTER_MASK; + uint cluster_reflection_offset = cluster_offset + scene_data.cluster_type_size * 3; - for (uint i = 0; i < reflection_probe_count; i++) { - uint ref_index = cluster_data.indices[reflection_probe_pointer + i]; - reflection_process(ref_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); + uint item_min; + uint item_max; + uint item_from; + uint item_to; + + cluster_get_item_range(cluster_reflection_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif + + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_reflection_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); +#ifdef USE_SUBGROUPS + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); +#else + uint merged_mask = mask; +#endif + + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); +#ifdef USE_SUBGROUPS + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } +#endif + uint reflection_index = 32 * i + bit; + + if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + + reflection_process(reflection_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); + } } if (reflection_accum.a > 0.0) { @@ -2321,6 +2477,16 @@ FRAGMENT_SHADER_CODE #endif } + //finalize ambient light here + ambient_light *= albedo.rgb; + ambient_light *= ao; + + // convert ao to direct light ao + ao = mix(1.0, ao, ao_light_affect); + + //this saves some VGPRs + vec3 f0 = F0(metallic, specular, albedo); + { #if defined(DIFFUSE_TOON) //simplify for toon, as @@ -2338,24 +2504,39 @@ FRAGMENT_SHADER_CODE float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - vec3 f0 = F0(metallic, specular, albedo); specular_light *= env.x * f0 + env.y; #endif } +#endif //GI !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) + +#if !defined(MODE_RENDER_DEPTH) + //this saves some VGPRs + uint orms = packUnorm4x8(vec4(ao, roughness, metallic, specular)); +#endif + +// LIGHTING +#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) + { //directional light - for (uint i = 0; i < scene_data.directional_light_count; i++) { - if (!bool(directional_lights.data[i].mask & draw_call.layer_mask)) { - continue; //not masked + // Do shadow and lighting in two passes to reduce register pressure + uint shadow0 = 0; + uint shadow1 = 0; + + for (uint i = 0; i < 8; i++) { + if (i >= scene_data.directional_light_count) { + break; } - vec3 shadow_attenuation = vec3(1.0); + if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } -#ifdef LIGHT_TRANSMITTANCE_USED - float transmittance_z = transmittance_depth; -#endif + float shadow = 1.0; +#ifdef USE_SOFT_SHADOWS + //version with soft shadows, more expensive if (directional_lights.data[i].shadow_enabled) { float depth_z = -vertex.z; @@ -2369,8 +2550,6 @@ FRAGMENT_SHADER_CODE normal_bias -= light_dir * dot(light_dir, normal_bias); \ m_var.xyz += normal_bias; - float shadow = 0.0; - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { vec4 v = vec4(vertex, 1.0); @@ -2391,19 +2570,6 @@ FRAGMENT_SHADER_CODE shadow_color = directional_lights.data[i].shadow_color1.rgb; -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_z_range.x; - float z = trans_coord.z * directional_lights.data[i].shadow_z_range.x; - - transmittance_z = z - shadow_z; - } -#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); @@ -2423,19 +2589,6 @@ FRAGMENT_SHADER_CODE } shadow_color = directional_lights.data[i].shadow_color2.rgb; -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_z_range.y; - float z = trans_coord.z * directional_lights.data[i].shadow_z_range.y; - - transmittance_z = z - shadow_z; - } -#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); @@ -2455,19 +2608,6 @@ FRAGMENT_SHADER_CODE } shadow_color = directional_lights.data[i].shadow_color3.rgb; -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_z_range.z; - float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z; - - transmittance_z = z - shadow_z; - } -#endif } else { vec4 v = vec4(vertex, 1.0); @@ -2488,20 +2628,6 @@ FRAGMENT_SHADER_CODE } shadow_color = directional_lights.data[i].shadow_color4.rgb; - -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_z_range.w; - float z = trans_coord.z * directional_lights.data[i].shadow_z_range.w; - - transmittance_z = z - shadow_z; - } -#endif } if (directional_lights.data[i].blend_splits) { @@ -2575,130 +2701,407 @@ FRAGMENT_SHADER_CODE shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance - shadow_attenuation = mix(shadow_color, vec3(1.0), shadow); +#undef BIAS_FUNC + } +#else + // Soft shadow disabled version + + if (directional_lights.data[i].shadow_enabled) { + float depth_z = -vertex.z; + + vec4 pssm_coord; + vec3 light_dir = directional_lights.data[i].direction; + vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))); + +#define BIAS_FUNC(m_var, m_idx) \ + m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ + vec3 normal_bias = base_normal_bias * directional_lights.data[i].shadow_normal_bias[m_idx]; \ + normal_bias -= light_dir * dot(light_dir, normal_bias); \ + m_var.xyz += normal_bias; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 0) + + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; + + transmittance_z = z - shadow_z; + } +#endif + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 1) + + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; + + transmittance_z = z - shadow_z; + } +#endif + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 2) + + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; + + transmittance_z = z - shadow_z; + } +#endif + + } else { + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 3) + + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; + + transmittance_z = z - shadow_z; + } +#endif + } + + pssm_coord /= pssm_coord.w; + + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + + if (directional_lights.data[i].blend_splits) { + float pssm_blend; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 1) + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 2) + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 3) + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); + } else { + pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) + } + + pssm_coord /= pssm_coord.w; + + float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + shadow = mix(shadow, shadow2, pssm_blend); + } + + shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance #undef BIAS_FUNC } +#endif + + if (i < 4) { + shadow0 |= uint(clamp(shadow * 255.0, 0.0, 255.0)) << (i * 8); + } else { + shadow1 |= uint(clamp(shadow * 255.0, 0.0, 255.0)) << ((i - 4) * 8); + } + } + + for (uint i = 0; i < 8; i++) { + if (i >= scene_data.directional_light_count) { + break; + } + + if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; + + if (directional_lights.data[i].shadow_enabled) { + float depth_z = -vertex.z; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; + + transmittance_z = z - shadow_z; + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex; + trans_coord /= trans_coord.w; - light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].size, directional_lights.data[i].color * directional_lights.data[i].energy, 1.0, shadow_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity, + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; + + transmittance_z = z - shadow_z; + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; + + transmittance_z = z - shadow_z; + + } else { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; + + transmittance_z = z - shadow_z; + } +#endif + + float shadow = 1.0; + + if (i < 4) { + shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0; + } else { + shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; + } + + blur_shadow(shadow); + + light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_curve, - transmittance_boost, - transmittance_z, + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED - rim, rim_tint, + rim, rim_tint, albedo, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_gloss, #endif #ifdef LIGHT_ANISOTROPY_USED - binormal, tangent, anisotropy, + binormal, tangent, anisotropy, +#endif +#ifdef USE_SOFT_SHADOW + directional_lights.data[i].size, #endif #ifdef USE_SHADOW_TO_OPACITY - alpha, + alpha, #endif - diffuse_light, - specular_light); + diffuse_light, + specular_light); + } } - } - { //omni lights + { //omni lights - uint omni_light_count = cluster_cell.x >> CLUSTER_COUNTER_SHIFT; - uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK; + uint cluster_omni_offset = cluster_offset; - for (uint i = 0; i < omni_light_count; i++) { - uint light_index = cluster_data.indices[omni_light_pointer + i]; + uint item_min; + uint item_max; + uint item_from; + uint item_to; - if (!bool(lights.data[light_index].mask & draw_call.layer_mask)) { - continue; //not masked - } + cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif + + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_omni_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); +#ifdef USE_SUBGROUPS + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); +#else + uint merged_mask = mask; +#endif + + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); +#ifdef USE_SUBGROUPS + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } +#endif + uint light_index = 32 * i + bit; - light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity, + if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + + float shadow = light_process_omni_shadow(light_index, vertex, view); + + shadow = blur_shadow(shadow); + + light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_curve, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED - rim, - rim_tint, + rim, + rim_tint, + albedo, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_gloss, #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, binormal, anisotropy, #endif #ifdef USE_SHADOW_TO_OPACITY - alpha, + alpha, #endif - diffuse_light, specular_light); + diffuse_light, specular_light); + } + } } - } - { //spot lights - uint spot_light_count = cluster_cell.y >> CLUSTER_COUNTER_SHIFT; - uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK; + { //spot lights - for (uint i = 0; i < spot_light_count; i++) { - uint light_index = cluster_data.indices[spot_light_pointer + i]; + uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size; - if (!bool(lights.data[light_index].mask & draw_call.layer_mask)) { - continue; //not masked - } + uint item_min; + uint item_max; + uint item_from; + uint item_to; - light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity, + cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif + + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_spot_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); +#ifdef USE_SUBGROUPS + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); +#else + uint merged_mask = mask; +#endif + + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); +#ifdef USE_SUBGROUPS + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } +#endif + + uint light_index = 32 * i + bit; + + if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + + float shadow = light_process_spot_shadow(light_index, vertex, view); + + shadow = blur_shadow(shadow); + + light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_curve, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED - rim, - rim_tint, + rim, + rim_tint, + albedo, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_gloss, #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, binormal, anisotropy, #endif #ifdef USE_SHADOW_TO_OPACITY - alpha, + alpha, #endif - diffuse_light, specular_light); + diffuse_light, specular_light); + } + } } - } #ifdef USE_SHADOW_TO_OPACITY - alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); + alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); #if defined(ALPHA_SCISSOR_USED) - if (alpha < alpha_scissor) { - discard; - } + if (alpha < alpha_scissor) { + discard; + } #endif // ALPHA_SCISSOR_USED #ifdef USE_OPAQUE_PREPASS - if (alpha < opaque_prepass_threshold) { - discard; - } + if (alpha < opaque_prepass_threshold) { + discard; + } #endif // USE_OPAQUE_PREPASS @@ -2710,173 +3113,149 @@ FRAGMENT_SHADER_CODE #ifdef MODE_RENDER_SDF - { - vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; - ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); - - uint albedo16 = 0x1; //solid flag - albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; - albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6; - albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1; - - imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16)); - - uint facing_bits = 0; - const vec3 aniso_dir[6] = vec3[]( - vec3(1, 0, 0), - vec3(0, 1, 0), - vec3(0, 0, 1), - vec3(-1, 0, 0), - vec3(0, -1, 0), - vec3(0, 0, -1)); - - vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp); - - float closest_dist = -1e20; - - for (uint i = 0; i < 6; i++) { - float d = dot(cam_normal, aniso_dir[i]); - if (d > closest_dist) { - closest_dist = d; - facing_bits = (1 << i); + { + vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; + ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); + + uint albedo16 = 0x1; //solid flag + albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; + albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6; + albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1; + + imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16)); + + uint facing_bits = 0; + const vec3 aniso_dir[6] = vec3[]( + vec3(1, 0, 0), + vec3(0, 1, 0), + vec3(0, 0, 1), + vec3(-1, 0, 0), + vec3(0, -1, 0), + vec3(0, 0, -1)); + + vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp); + + float closest_dist = -1e20; + + for (uint i = 0; i < 6; i++) { + float d = dot(cam_normal, aniso_dir[i]); + if (d > closest_dist) { + closest_dist = d; + facing_bits = (1 << i); + } } - } - imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits + imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits - if (length(emission) > 0.001) { - float lumas[6]; - vec3 light_total = vec3(0); + if (length(emission) > 0.001) { + float lumas[6]; + vec3 light_total = vec3(0); - for (int i = 0; i < 6; i++) { - float strength = max(0.0, dot(cam_normal, aniso_dir[i])); - vec3 light = emission * strength; - light_total += light; - lumas[i] = max(light.r, max(light.g, light.b)); - } + for (int i = 0; i < 6; i++) { + float strength = max(0.0, dot(cam_normal, aniso_dir[i])); + vec3 light = emission * strength; + light_total += light; + lumas[i] = max(light.r, max(light.g, light.b)); + } - float luma_total = max(light_total.r, max(light_total.g, light_total.b)); + float luma_total = max(light_total.r, max(light_total.g, light_total.b)); - uint light_aniso = 0; + uint light_aniso = 0; - for (int i = 0; i < 6; i++) { - light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5); - } + for (int i = 0; i < 6; i++) { + light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5); + } - //compress to RGBE9995 to save space + //compress to RGBE9995 to save space - const float pow2to9 = 512.0f; - const float B = 15.0f; - const float N = 9.0f; - const float LN2 = 0.6931471805599453094172321215; + const float pow2to9 = 512.0f; + const float B = 15.0f; + const float N = 9.0f; + const float LN2 = 0.6931471805599453094172321215; - float cRed = clamp(light_total.r, 0.0, 65408.0); - float cGreen = clamp(light_total.g, 0.0, 65408.0); - float cBlue = clamp(light_total.b, 0.0, 65408.0); + float cRed = clamp(light_total.r, 0.0, 65408.0); + float cGreen = clamp(light_total.g, 0.0, 65408.0); + float cBlue = clamp(light_total.b, 0.0, 65408.0); - float cMax = max(cRed, max(cGreen, cBlue)); + float cMax = max(cRed, max(cGreen, cBlue)); - float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B; + float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B; - float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f); + float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f); - float exps = expp + 1.0f; + float exps = expp + 1.0f; - if (0.0 <= sMax && sMax < pow2to9) { - exps = expp; - } + if (0.0 <= sMax && sMax < pow2to9) { + exps = expp; + } - float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); - float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); - float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); - //store as 8985 to have 2 extra neighbour bits - uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25); + float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); + float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); + float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); + //store as 8985 to have 2 extra neighbour bits + uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25); - imageStore(emission_grid, grid_pos, uvec4(light_rgbe)); - imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso)); + imageStore(emission_grid, grid_pos, uvec4(light_rgbe)); + imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso)); + } } - } #endif #ifdef MODE_RENDER_MATERIAL - albedo_output_buffer.rgb = albedo; - albedo_output_buffer.a = alpha; + albedo_output_buffer.rgb = albedo; + albedo_output_buffer.a = alpha; - normal_output_buffer.rgb = normal * 0.5 + 0.5; - normal_output_buffer.a = 0.0; - depth_output_buffer.r = -vertex.z; + normal_output_buffer.rgb = normal * 0.5 + 0.5; + normal_output_buffer.a = 0.0; + depth_output_buffer.r = -vertex.z; -#if defined(AO_USED) - orm_output_buffer.r = ao; -#else - orm_output_buffer.r = 0.0; -#endif - orm_output_buffer.g = roughness; - orm_output_buffer.b = metallic; - orm_output_buffer.a = sss_strength; + orm_output_buffer.r = ao; + orm_output_buffer.g = roughness; + orm_output_buffer.b = metallic; + orm_output_buffer.a = sss_strength; - emission_output_buffer.rgb = emission; - emission_output_buffer.a = 0.0; + emission_output_buffer.rgb = emission; + emission_output_buffer.a = 0.0; #endif #ifdef MODE_RENDER_NORMAL_ROUGHNESS - normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); + normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); #ifdef MODE_RENDER_GIPROBE - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes - uint index1 = draw_call.gi_offset & 0xFFFF; - uint index2 = draw_call.gi_offset >> 16; - giprobe_buffer.x = index1 & 0xFF; - giprobe_buffer.y = index2 & 0xFF; - } else { - giprobe_buffer.x = 0xFF; - giprobe_buffer.y = 0xFF; - } + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; + uint index2 = instances.data[instance_index].gi_offset >> 16; + giprobe_buffer.x = index1 & 0xFF; + giprobe_buffer.y = index2 & 0xFF; + } else { + giprobe_buffer.x = 0xFF; + giprobe_buffer.y = 0xFF; + } #endif -#endif //MODE_RENDER_NORMAL +#endif //MODE_RENDER_NORMAL_ROUGHNESS //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) #else - specular_light *= scene_data.reflection_multiplier; - ambient_light *= albedo; //ambient must be multiplied by albedo at the end - -//ambient occlusion -#if defined(AO_USED) - -#ifndef LOW_END_MODE - if (scene_data.ssao_enabled && scene_data.ssao_ao_affect > 0.0) { - float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r; - ao = mix(ao, min(ao, ssao), scene_data.ssao_ao_affect); - ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect); - } -#endif //LOW_END_MODE - - ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao); - ao_light_affect = mix(1.0, ao, ao_light_affect); - specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect); - diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect); -#else - -#ifndef LOW_END_MODE - if (scene_data.ssao_enabled) { - float ao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r; - ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao); - float ao_light_affect = mix(1.0, ao, scene_data.ssao_light_affect); - specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect); - diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect); - } -#endif //LOW_END_MODE + // multiply by albedo + diffuse_light *= albedo; // ambient must be multiplied by albedo at the end -#endif // AO_USED + // apply direct light AO + ao = unpackUnorm4x8(orms).x; + specular_light *= ao; + diffuse_light *= ao; - // base color remapping - diffuse_light *= 1.0 - metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point + // apply metallic + metallic = unpackUnorm4x8(orms).z; + diffuse_light *= 1.0 - metallic; ambient_light *= 1.0 - metallic; + //restore fog + fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); + #ifdef MODE_MULTIPLE_RENDER_TARGETS #ifdef MODE_UNSHADED @@ -2892,25 +3271,8 @@ FRAGMENT_SHADER_CODE specular_buffer = vec4(specular_light, metallic); #endif - // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. - if (scene_data.fog_enabled) { - vec4 fog = fog_process(vertex); - diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a); - specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a); - } - -#ifndef LOW_END_MODE - if (scene_data.volumetric_fog_enabled) { - vec4 fog = volumetric_fog_process(screen_uv, -vertex.z); - diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a); - specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a); - } -#endif // LOW_END_MODE - -#if defined(CUSTOM_FOG_USED) - diffuse_buffer.rgb = mix(diffuse_buffer.rgb, custom_fog.rgb, custom_fog.a); - specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), custom_fog.a); -#endif //CUSTOM_FOG_USED + diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a); + specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a); #else //MODE_MULTIPLE_RENDER_TARGETS @@ -2922,22 +3284,10 @@ FRAGMENT_SHADER_CODE #endif //USE_NO_SHADING // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. - if (scene_data.fog_enabled) { - vec4 fog = fog_process(vertex); - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); - } -#ifndef LOW_END_MODE - if (scene_data.volumetric_fog_enabled) { - vec4 fog = volumetric_fog_process(screen_uv, -vertex.z); - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); - } -#endif - -#if defined(CUSTOM_FOG_USED) - frag_color.rgb = mix(frag_color.rgb, custom_fog.rgb, custom_fog.a); -#endif //CUSTOM_FOG_USED + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); + ; #endif //MODE_MULTIPLE_RENDER_TARGETS #endif //MODE_RENDER_DEPTH -} + } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl index 87ce74ba88..d78890fa9e 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl @@ -3,6 +3,15 @@ #define MAX_GI_PROBES 8 +#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic) + +#extension GL_KHR_shader_subgroup_ballot : enable +#extension GL_KHR_shader_subgroup_arithmetic : enable + +#define USE_SUBGROUPS + +#endif + #include "cluster_data_inc.glsl" #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_GIPROBE) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) @@ -12,12 +21,10 @@ #endif layout(push_constant, binding = 0, std430) uniform DrawCall { - mat4 transform; - uint flags; - uint instance_uniforms_ofs; //base offset in global buffer for instance variables - uint gi_offset; //GI information when using lightmapping (VCT or lightmap index) - uint layer_mask; - vec4 lightmap_uv_scale; + uint instance_index; + uint uv_offset; + uint pad0; + uint pad1; } draw_call; @@ -36,91 +43,13 @@ draw_call; #define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT 10 #define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11 -layout(set = 0, binding = 1) uniform sampler material_samplers[12]; - -layout(set = 0, binding = 2) uniform sampler shadow_sampler; - #define SDFGI_MAX_CASCADES 8 -layout(set = 0, binding = 3, std140) uniform SceneData { - mat4 projection_matrix; - mat4 inv_projection_matrix; - - mat4 camera_matrix; - mat4 inv_camera_matrix; - - vec2 viewport_size; - vec2 screen_pixel_size; - - //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted - vec4 directional_penumbra_shadow_kernel[32]; - vec4 directional_soft_shadow_kernel[32]; - vec4 penumbra_shadow_kernel[32]; - vec4 soft_shadow_kernel[32]; - - uint directional_penumbra_shadow_samples; - uint directional_soft_shadow_samples; - uint penumbra_shadow_samples; - uint soft_shadow_samples; - - vec4 ambient_light_color_energy; - - float ambient_color_sky_mix; - bool use_ambient_light; - bool use_ambient_cubemap; - bool use_reflection_cubemap; - - mat3 radiance_inverse_xform; - - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; - - uint directional_light_count; - float dual_paraboloid_side; - float z_far; - float z_near; - - bool ssao_enabled; - float ssao_light_affect; - float ssao_ao_affect; - bool roughness_limiter_enabled; - - float roughness_limiter_amount; - float roughness_limiter_limit; - uvec2 roughness_limiter_pad; - - vec4 ao_color; - - mat4 sdf_to_bounds; - - ivec3 sdf_offset; - bool material_uv2_mode; - - ivec3 sdf_size; - bool gi_upscale_for_msaa; - - bool volumetric_fog_enabled; - float volumetric_fog_inv_length; - float volumetric_fog_detail_spread; - uint volumetric_fog_pad; - - bool fog_enabled; - float fog_density; - float fog_height; - float fog_height_density; - - vec3 fog_light_color; - float fog_sun_scatter; - - float fog_aerial_perspective; - - float time; - float reflection_multiplier; // one normally, zero when rendering reflections +/* Set 1: Base Pass (never changes) */ - bool pancake_shadows; -} +layout(set = 0, binding = 1) uniform sampler material_samplers[12]; -scene_data; +layout(set = 0, binding = 2) uniform sampler shadow_sampler; #define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6) #define INSTANCE_FLAGS_USE_SDFGI (1 << 7) @@ -139,17 +68,22 @@ scene_data; #define INSTANCE_FLAGS_SKELETON (1 << 19) #define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20) -layout(set = 0, binding = 5, std430) restrict readonly buffer Lights { +layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights { + LightData data[]; +} +omni_lights; + +layout(set = 0, binding = 4, std430) restrict readonly buffer SpotLights { LightData data[]; } -lights; +spot_lights; -layout(set = 0, binding = 6) buffer restrict readonly ReflectionProbeData { +layout(set = 0, binding = 5) buffer restrict readonly ReflectionProbeData { ReflectionData data[]; } reflections; -layout(set = 0, binding = 7, std140) uniform DirectionalLights { +layout(set = 0, binding = 6, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } directional_lights; @@ -161,7 +95,7 @@ struct Lightmap { mat3 normal_xform; }; -layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps { +layout(set = 0, binding = 7, std140) restrict readonly buffer Lightmaps { Lightmap data[]; } lightmaps; @@ -170,29 +104,20 @@ struct LightmapCapture { vec4 sh[9]; }; -layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures { +layout(set = 0, binding = 8, std140) restrict readonly buffer LightmapCaptures { LightmapCapture data[]; } lightmap_captures; -layout(set = 0, binding = 12) uniform texture2D decal_atlas; -layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 9) uniform texture2D decal_atlas; +layout(set = 0, binding = 10) uniform texture2D decal_atlas_srgb; -layout(set = 0, binding = 14, std430) restrict readonly buffer Decals { +layout(set = 0, binding = 11, std430) restrict readonly buffer Decals { DecalData data[]; } decals; -layout(set = 0, binding = 15) uniform utexture3D cluster_texture; - -layout(set = 0, binding = 16, std430) restrict readonly buffer ClusterData { - uint indices[]; -} -cluster_data; - -layout(set = 0, binding = 17) uniform texture2D directional_shadow_atlas; - -layout(set = 0, binding = 18, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } global_variables; @@ -206,7 +131,7 @@ struct SDFGIProbeCascadeData { float to_cell; // 1/bounds * grid_size }; -layout(set = 0, binding = 19, std140) uniform SDFGI { +layout(set = 0, binding = 13, std140) uniform SDFGI { vec3 grid_size; uint max_cascades; @@ -236,40 +161,140 @@ sdfgi; #endif //LOW_END_MODE -// decal atlas +/* Set 2: Render Pass (changes per render pass) */ + +layout(set = 1, binding = 0, std140) uniform SceneData { + mat4 projection_matrix; + mat4 inv_projection_matrix; + + mat4 camera_matrix; + mat4 inv_camera_matrix; + + vec2 viewport_size; + vec2 screen_pixel_size; + + uint cluster_shift; + uint cluster_width; + uint cluster_type_size; + uint max_cluster_element_count_div_32; + + //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + vec4 directional_penumbra_shadow_kernel[32]; + vec4 directional_soft_shadow_kernel[32]; + vec4 penumbra_shadow_kernel[32]; + vec4 soft_shadow_kernel[32]; + + uint directional_penumbra_shadow_samples; + uint directional_soft_shadow_samples; + uint penumbra_shadow_samples; + uint soft_shadow_samples; + + vec4 ambient_light_color_energy; + + float ambient_color_sky_mix; + bool use_ambient_light; + bool use_ambient_cubemap; + bool use_reflection_cubemap; + + mat3 radiance_inverse_xform; + + vec2 shadow_atlas_pixel_size; + vec2 directional_shadow_pixel_size; + + uint directional_light_count; + float dual_paraboloid_side; + float z_far; + float z_near; -/* Set 1, Radiance */ + bool ssao_enabled; + float ssao_light_affect; + float ssao_ao_affect; + bool roughness_limiter_enabled; + + float roughness_limiter_amount; + float roughness_limiter_limit; + uvec2 roughness_limiter_pad; + + vec4 ao_color; + + mat4 sdf_to_bounds; + + ivec3 sdf_offset; + bool material_uv2_mode; + + ivec3 sdf_size; + bool gi_upscale_for_msaa; + + bool volumetric_fog_enabled; + float volumetric_fog_inv_length; + float volumetric_fog_detail_spread; + uint volumetric_fog_pad; + + bool fog_enabled; + float fog_density; + float fog_height; + float fog_height_density; + + vec3 fog_light_color; + float fog_sun_scatter; + + float fog_aerial_perspective; + + float time; + float reflection_multiplier; // one normally, zero when rendering reflections + + bool pancake_shadows; +} + +scene_data; + +struct InstanceData { + mat4 transform; + uint flags; + uint instance_uniforms_ofs; //base offset in global buffer for instance variables + uint gi_offset; //GI information when using lightmapping (VCT or lightmap index) + uint layer_mask; + vec4 lightmap_uv_scale; +}; + +layout(set = 1, binding = 1, std430) buffer restrict readonly InstanceDataBuffer { + InstanceData data[]; +} +instances; #ifdef USE_RADIANCE_CUBEMAP_ARRAY -layout(set = 1, binding = 0) uniform textureCubeArray radiance_cubemap; +layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap; #else -layout(set = 1, binding = 0) uniform textureCube radiance_cubemap; +layout(set = 1, binding = 2) uniform textureCube radiance_cubemap; #endif -/* Set 2, Reflection and Shadow Atlases (view dependent) */ +layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas; -layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas; +layout(set = 1, binding = 4) uniform texture2D shadow_atlas; -layout(set = 1, binding = 2) uniform texture2D shadow_atlas; +layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; -layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; +layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; -#ifndef LOW_END_MODE -layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +#ifndef LOW_END_MOD +layout(set = 1, binding = 7) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; #endif -/* Set 3, Render Buffers */ +layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer { + uint data[]; +} +cluster_buffer; #ifdef MODE_RENDER_SDF -layout(r16ui, set = 1, binding = 5) uniform restrict writeonly uimage3D albedo_volume_grid; -layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_grid; -layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_aniso_grid; -layout(r32ui, set = 1, binding = 8) uniform restrict uimage3D geom_facing_grid; +layout(r16ui, set = 1, binding = 9) uniform restrict writeonly uimage3D albedo_volume_grid; +layout(r32ui, set = 1, binding = 10) uniform restrict writeonly uimage3D emission_grid; +layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_aniso_grid; +layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid; //still need to be present for shaders that use it, so remap them to something #define depth_buffer shadow_atlas @@ -278,17 +303,17 @@ layout(r32ui, set = 1, binding = 8) uniform restrict uimage3D geom_facing_grid; #else -layout(set = 1, binding = 5) uniform texture2D depth_buffer; -layout(set = 1, binding = 6) uniform texture2D color_buffer; +layout(set = 1, binding = 9) uniform texture2D depth_buffer; +layout(set = 1, binding = 10) uniform texture2D color_buffer; #ifndef LOW_END_MODE -layout(set = 1, binding = 7) uniform texture2D normal_roughness_buffer; -layout(set = 1, binding = 8) uniform texture2D ao_buffer; -layout(set = 1, binding = 9) uniform texture2D ambient_buffer; -layout(set = 1, binding = 10) uniform texture2D reflection_buffer; -layout(set = 1, binding = 11) uniform texture2DArray sdfgi_lightprobe_texture; -layout(set = 1, binding = 12) uniform texture3D sdfgi_occlusion_cascades; +layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer; +layout(set = 1, binding = 12) uniform texture2D ao_buffer; +layout(set = 1, binding = 13) uniform texture2D ambient_buffer; +layout(set = 1, binding = 14) uniform texture2D reflection_buffer; +layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture; +layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades; struct GIProbeData { mat4 xform; @@ -306,22 +331,22 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 1, binding = 13, std140) uniform GIProbes { +layout(set = 1, binding = 17, std140) uniform GIProbes { GIProbeData data[MAX_GI_PROBES]; } gi_probes; -layout(set = 1, binding = 14) uniform texture3D volumetric_fog_texture; +layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture; #endif // LOW_END_MODE #endif -/* Set 4 Skeleton & Instancing (Multimesh) */ +/* Set 2 Skeleton & Instancing (can change per item) */ layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms { vec4 data[]; } transforms; -/* Set 5 User Material */ +/* Set 3 User Material */ diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl index 813ea29fa1..e4c3f3a84b 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl @@ -97,6 +97,8 @@ void main() { float blend = 0.0; #if 1 + // No interpolation + vec3 inv_dir = 1.0 / ray_dir; float rough = 0.5; @@ -161,114 +163,11 @@ void main() { hit_light *= (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0))); - if (blend > 0.0) { - light = mix(light, hit_light, blend); - blend = 0.0; - } else { - light = hit_light; - - //process blend - float blend_from = (float(params.probe_axis_size - 1) / 2.0) - 2.5; - float blend_to = blend_from + 2.0; - - vec3 cam_pos = params.cam_transform[3].xyz - cascades.data[i].offset; - cam_pos *= cascades.data[i].to_cell; - - pos += ray_dir * min(advance, max_advance); - vec3 inner_pos = pos - cam_pos; - - inner_pos = inner_pos * float(params.probe_axis_size - 1) / params.grid_size.x; - - float len = length(inner_pos); - - inner_pos = abs(normalize(inner_pos)); - len *= max(inner_pos.x, max(inner_pos.y, inner_pos.z)); - - if (len >= blend_from) { - blend = smoothstep(blend_from, blend_to, len); - - pos /= cascades.data[i].to_cell; - pos += cascades.data[i].offset; - ray_pos = pos; - hit = false; //continue trace for blend - - continue; - } - } + light = hit_light; break; } - light = mix(light, vec3(0.0), blend); - -#else - - vec3 inv_dir = 1.0 / ray_dir; - - bool hit = false; - vec4 light_accum = vec4(0.0); - - float blend_size = (params.grid_size.x / float(params.probe_axis_size - 1)) * 0.5; - - float radius_sizes[MAX_CASCADES]; - for (uint i = 0; i < params.max_cascades; i++) { - radius_sizes[i] = (1.0 / cascades.data[i].to_cell) * (params.grid_size.x * 0.5 - blend_size); - } - - float max_distance = radius_sizes[params.max_cascades - 1]; - float advance = 0; - while (advance < max_distance) { - for (uint i = 0; i < params.max_cascades; i++) { - if (advance < radius_sizes[i]) { - vec3 pos = (ray_pos + ray_dir * advance) - cascades.data[i].offset; - pos *= cascades.data[i].to_cell * pos_to_uvw; - - float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.0; - - vec4 hit_light = vec4(0.0); - if (distance < 1.0) { - hit_light.a = max(0.0, 1.0 - distance); - hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb; - hit_light.rgb *= hit_light.a; - } - - distance /= cascades.data[i].to_cell; - - if (i < (params.max_cascades - 1)) { - pos = (ray_pos + ray_dir * advance) - cascades.data[i + 1].offset; - pos *= cascades.data[i + 1].to_cell * pos_to_uvw; - - float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.0; - - vec4 hit_light2 = vec4(0.0); - if (distance2 < 1.0) { - hit_light2.a = max(0.0, 1.0 - distance2); - hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb; - hit_light2.rgb *= hit_light2.a; - } - - float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1]; - float blend = (advance - prev_radius) / (radius_sizes[i] - prev_radius); - - distance2 /= cascades.data[i + 1].to_cell; - - hit_light = mix(hit_light, hit_light2, blend); - distance = mix(distance, distance2, blend); - } - - light_accum += hit_light; - advance += distance; - break; - } - } - - if (light_accum.a > 0.98) { - break; - } - } - - light = light_accum.rgb / light_accum.a; - #endif imageStore(screen_buffer, screen_pos, vec4(linear_to_srgb(light), 1.0)); diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index 30dbf5871f..dc7238abed 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -67,8 +67,8 @@ struct Light { float attenuation; uint type; - float spot_angle; - float spot_attenuation; + float cos_spot_angle; + float inv_spot_attenuation; float radius; vec4 shadow_color; @@ -80,6 +80,7 @@ layout(set = 0, binding = 9, std140) buffer restrict readonly Lights { lights; layout(set = 0, binding = 10) uniform texture2DArray lightprobe_texture; +layout(set = 0, binding = 11) uniform texture3D occlusion_texture; layout(push_constant, binding = 0, std430) uniform Params { vec3 grid_size; @@ -91,9 +92,9 @@ layout(push_constant, binding = 0, std430) uniform Params { uint process_increment; int probe_axis_size; - bool multibounce; + float bounce_feedback; float y_mult; - uint pad; + bool use_occlusion; } params; @@ -125,7 +126,10 @@ void main() { uint voxel_index = uint(gl_GlobalInvocationID.x); //used for skipping voxels every N frames - voxel_index = params.process_offset + voxel_index * params.process_increment; + if (params.process_increment > 1) { + voxel_index *= params.process_increment; + voxel_index += params.process_offset; + } if (voxel_index >= dispatch_data.total_count) { return; @@ -143,10 +147,96 @@ void main() { uint voxel_albedo = process_voxels.data[voxel_index].albedo; vec3 albedo = vec3(uvec3(voxel_albedo >> 10, voxel_albedo >> 5, voxel_albedo) & uvec3(0x1F)) / float(0x1F); - vec3 light_accum[6]; - + vec3 light_accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); uint valid_aniso = (voxel_albedo >> 15) & 0x3F; + const vec3 aniso_dir[6] = vec3[]( + vec3(1, 0, 0), + vec3(0, 1, 0), + vec3(0, 0, 1), + vec3(-1, 0, 0), + vec3(0, -1, 0), + vec3(0, 0, -1)); + + // Add indirect light first, in order to save computation resources +#ifdef MODE_PROCESS_DYNAMIC + if (params.bounce_feedback > 0.001) { + vec3 feedback = (params.bounce_feedback < 1.0) ? (albedo * params.bounce_feedback) : mix(albedo, vec3(1.0), params.bounce_feedback - 1.0); + vec3 pos = (vec3(positioni) + vec3(0.5)) * float(params.probe_axis_size - 1) / params.grid_size; + ivec3 probe_base_pos = ivec3(pos); + + float weight_accum[6] = float[](0, 0, 0, 0, 0, 0); + + ivec3 tex_pos = ivec3(probe_base_pos.xy, int(params.cascade)); + tex_pos.x += probe_base_pos.z * int(params.probe_axis_size); + + tex_pos.xy = tex_pos.xy * (OCT_SIZE + 2) + ivec2(1); + + vec3 base_tex_posf = vec3(tex_pos); + vec2 tex_pixel_size = 1.0 / vec2(ivec2((OCT_SIZE + 2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE + 2) * params.probe_axis_size)); + vec3 probe_uv_offset = vec3(ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx; + + for (uint j = 0; j < 8; j++) { + ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1); + ivec3 probe_posi = probe_base_pos; + probe_posi += offset; + + // Compute weight + + vec3 probe_pos = vec3(probe_posi); + vec3 probe_to_pos = pos - probe_pos; + vec3 probe_dir = normalize(-probe_to_pos); + + // Compute lightprobe texture position + + vec3 trilinear = vec3(1.0) - abs(probe_to_pos); + + for (uint k = 0; k < 6; k++) { + if (bool(valid_aniso & (1 << k))) { + vec3 n = aniso_dir[k]; + float weight = trilinear.x * trilinear.y * trilinear.z * max(0, dot(n, probe_dir)); + + if (weight > 0.0 && params.use_occlusion) { + ivec3 occ_indexv = abs((cascades.data[params.cascade].probe_world_offset + probe_posi) & ivec3(1, 1, 1)) * ivec3(1, 2, 4); + vec4 occ_mask = mix(vec4(0.0), vec4(1.0), equal(ivec4(occ_indexv.x | occ_indexv.y), ivec4(0, 1, 2, 3))); + + vec3 occ_pos = (vec3(positioni) + aniso_dir[k] + vec3(0.5)) / params.grid_size; + occ_pos.z += float(params.cascade); + if (occ_indexv.z != 0) { //z bit is on, means index is >=4, so make it switch to the other half of textures + occ_pos.x += 1.0; + } + occ_pos *= vec3(0.5, 1.0, 1.0 / float(params.max_cascades)); //renormalize + float occlusion = dot(textureLod(sampler3D(occlusion_texture, linear_sampler), occ_pos, 0.0), occ_mask); + + weight *= occlusion; + } + + if (weight > 0.0) { + vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0); + tex_posf.xy *= tex_pixel_size; + + vec3 pos_uvw = tex_posf; + pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy; + pos_uvw.x += float(offset.z) * probe_uv_offset.z; + vec3 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb; + + light_accum[k] += indirect_light * weight; + weight_accum[k] += weight; + } + } + } + } + + for (uint k = 0; k < 6; k++) { + if (weight_accum[k] > 0.0) { + light_accum[k] /= weight_accum[k]; + light_accum[k] *= feedback; + } + } + } + +#endif + { uint rgbe = process_voxels.data[voxel_index].light; @@ -162,18 +252,10 @@ void main() { uint aniso = process_voxels.data[voxel_index].light_aniso; for (uint i = 0; i < 6; i++) { float strength = ((aniso >> (i * 5)) & 0x1F) / float(0x1F); - light_accum[i] = l * strength; + light_accum[i] += l * strength; } } - const vec3 aniso_dir[6] = vec3[]( - vec3(1, 0, 0), - vec3(0, 1, 0), - vec3(0, 0, 1), - vec3(-1, 0, 0), - vec3(0, -1, 0), - vec3(0, 0, -1)); - // Raytrace light vec3 pos_to_uvw = 1.0 / params.grid_size; @@ -203,13 +285,16 @@ void main() { rel_vec.y /= params.y_mult; attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation); - float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction)); - if (angle > lights.data[i].spot_angle) { - attenuation = 0.0; - } else { - float d = clamp(angle / lights.data[i].spot_angle, 0, 1); - attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation); + float cos_spot_angle = lights.data[i].cos_spot_angle; + float cos_angle = dot(-direction, lights.data[i].direction); + + if (cos_angle < cos_spot_angle) { + continue; } + + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation); } break; } @@ -292,65 +377,6 @@ void main() { } } - // Add indirect light - - if (params.multibounce) { - vec3 pos = (vec3(positioni) + vec3(0.5)) * float(params.probe_axis_size - 1) / params.grid_size; - ivec3 probe_base_pos = ivec3(pos); - - vec4 probe_accum[6] = vec4[](vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); - float weight_accum[6] = float[](0, 0, 0, 0, 0, 0); - - ivec3 tex_pos = ivec3(probe_base_pos.xy, int(params.cascade)); - tex_pos.x += probe_base_pos.z * int(params.probe_axis_size); - - tex_pos.xy = tex_pos.xy * (OCT_SIZE + 2) + ivec2(1); - - vec3 base_tex_posf = vec3(tex_pos); - vec2 tex_pixel_size = 1.0 / vec2(ivec2((OCT_SIZE + 2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE + 2) * params.probe_axis_size)); - vec3 probe_uv_offset = (ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx; - - for (uint j = 0; j < 8; j++) { - ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1); - ivec3 probe_posi = probe_base_pos; - probe_posi += offset; - - // Compute weight - - vec3 probe_pos = vec3(probe_posi); - vec3 probe_to_pos = pos - probe_pos; - vec3 probe_dir = normalize(-probe_to_pos); - - // Compute lightprobe texture position - - vec3 trilinear = vec3(1.0) - abs(probe_to_pos); - - for (uint k = 0; k < 6; k++) { - if (bool(valid_aniso & (1 << k))) { - vec3 n = aniso_dir[k]; - float weight = trilinear.x * trilinear.y * trilinear.z * max(0.005, dot(n, probe_dir)); - - vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0); - tex_posf.xy *= tex_pixel_size; - - vec3 pos_uvw = tex_posf; - pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy; - pos_uvw.x += float(offset.z) * probe_uv_offset.z; - vec4 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0); - - probe_accum[k] += indirect_light * weight; - weight_accum[k] += weight; - } - } - } - - for (uint k = 0; k < 6; k++) { - if (weight_accum[k] > 0.0) { - light_accum[k] += probe_accum[k].rgb * albedo / weight_accum[k]; - } - } - } - // Store the light in the light texture float lumas[6]; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index d516ab22c3..007e4c113a 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl @@ -39,8 +39,11 @@ layout(rgba32i, set = 0, binding = 13) uniform restrict iimage2D lightprobe_aver layout(rgba16f, set = 0, binding = 14) uniform restrict writeonly image2DArray lightprobe_ambient_texture; +#ifdef USE_CUBEMAP_ARRAY +layout(set = 1, binding = 0) uniform textureCubeArray sky_irradiance; +#else layout(set = 1, binding = 0) uniform textureCube sky_irradiance; - +#endif layout(set = 1, binding = 1) uniform sampler linear_sampler_mipmaps; #define HISTORY_BITS 10 @@ -136,12 +139,24 @@ uint rgbe_encode(vec3 color) { return (uint(sRed) & 0x1FF) | ((uint(sGreen) & 0x1FF) << 9) | ((uint(sBlue) & 0x1FF) << 18) | ((uint(exps) & 0x1F) << 27); } +struct SH { +#if (SH_SIZE == 16) + float c[48]; +#else + float c[28]; +#endif +}; + +shared SH sh_accum[64]; //8x8 + void main() { ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThanEqual(pos, params.image_size))) { //too large, do nothing return; } + uint probe_index = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 8; + #ifdef MODE_PROCESS float probe_cell_size = float(params.grid_size.x / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell; @@ -154,27 +169,9 @@ void main() { vec3 probe_pos = cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size; vec3 pos_to_uvw = 1.0 / params.grid_size; - vec4 probe_sh_accum[SH_SIZE] = vec4[]( - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0) -#if (SH_SIZE == 16) - , - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0), - vec4(0.0) -#endif - ); + for (uint i = 0; i < SH_SIZE * 3; i++) { + sh_accum[probe_index].c[i] = 0.0; + } // quickly ensure each probe has a different "offset" for the vogel function, based on integer world position uvec3 h3 = hash3(uvec3(params.world_offset + probe_cell)); @@ -195,14 +192,12 @@ void main() { vec3 inv_dir = 1.0 / ray_dir; bool hit = false; - vec3 hit_normal; - vec3 hit_light; - vec3 hit_aniso0; - vec3 hit_aniso1; + uint hit_cascade; float bias = params.ray_bias; vec3 abs_ray_dir = abs(ray_dir); ray_pos += ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) * bias / cascades.data[params.cascade].to_cell; + vec3 uvw; for (uint j = params.cascade; j < params.max_cascades; j++) { //convert to local bounds @@ -221,14 +216,12 @@ void main() { float advance = 0.0; - vec3 uvw; - while (advance < max_advance) { //read how much to advance from SDF uvw = (pos + ray_dir * advance) * pos_to_uvw; float distance = texture(sampler3D(sdf_cascades[j], linear_sampler), uvw).r * 255.0 - 1.0; - if (distance < 0.001) { + if (distance < 0.05) { //consider hit hit = true; break; @@ -238,17 +231,7 @@ void main() { } if (hit) { - const float EPSILON = 0.001; - hit_normal = normalize(vec3( - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r, - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r, - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r)); - - hit_light = texture(sampler3D(light_cascades[j], linear_sampler), uvw).rgb; - vec4 aniso0 = texture(sampler3D(aniso0_cascades[j], linear_sampler), uvw); - hit_aniso0 = aniso0.rgb; - hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[j], linear_sampler), uvw).rg); - + hit_cascade = j; break; } @@ -261,11 +244,32 @@ void main() { vec4 light; if (hit) { - //one liner magic - light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0))); - light.a = 1.0; + //avoid reading different texture from different threads + for (uint j = params.cascade; j < params.max_cascades; j++) { + if (j == hit_cascade) { + const float EPSILON = 0.001; + vec3 hit_normal = normalize(vec3( + texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r, + texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r, + texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r)); + + vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb; + vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw); + vec3 hit_aniso0 = aniso0.rgb; + vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg); + + //one liner magic + light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0))); + light.a = 1.0; + } + } + } else if (params.sky_mode == SKY_MODE_SKY) { +#ifdef USE_CUBEMAP_ARRAY + light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates +#else light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates +#endif light.rgb *= params.sky_energy; light.a = 0.0; @@ -278,33 +282,33 @@ void main() { } vec3 ray_dir2 = ray_dir * ray_dir; - float c[SH_SIZE] = float[]( - - 0.282095, //l0 - 0.488603 * ray_dir.y, //l1n1 - 0.488603 * ray_dir.z, //l1n0 - 0.488603 * ray_dir.x, //l1p1 - 1.092548 * ray_dir.x * ray_dir.y, //l2n2 - 1.092548 * ray_dir.y * ray_dir.z, //l2n1 - 0.315392 * (3.0 * ray_dir2.z - 1.0), //l20 - 1.092548 * ray_dir.x * ray_dir.z, //l2p1 - 0.546274 * (ray_dir2.x - ray_dir2.y) //l2p2 + +#define SH_ACCUM(m_idx, m_value) \ + { \ + vec3 l = light.rgb * (m_value); \ + sh_accum[probe_index].c[m_idx * 3 + 0] += l.r; \ + sh_accum[probe_index].c[m_idx * 3 + 1] += l.g; \ + sh_accum[probe_index].c[m_idx * 3 + 2] += l.b; \ + } + SH_ACCUM(0, 0.282095); //l0 + SH_ACCUM(1, 0.488603 * ray_dir.y); //l1n1 + SH_ACCUM(2, 0.488603 * ray_dir.z); //l1n0 + SH_ACCUM(3, 0.488603 * ray_dir.x); //l1p1 + SH_ACCUM(4, 1.092548 * ray_dir.x * ray_dir.y); //l2n2 + SH_ACCUM(5, 1.092548 * ray_dir.y * ray_dir.z); //l2n1 + SH_ACCUM(6, 0.315392 * (3.0 * ray_dir2.z - 1.0)); //l20 + SH_ACCUM(7, 1.092548 * ray_dir.x * ray_dir.z); //l2p1 + SH_ACCUM(8, 0.546274 * (ray_dir2.x - ray_dir2.y)); //l2p2 #if (SH_SIZE == 16) - , - 0.590043 * ray_dir.y * (3.0f * ray_dir2.x - ray_dir2.y), - 2.890611 * ray_dir.y * ray_dir.x * ray_dir.z, - 0.646360 * ray_dir.y * (-1.0f + 5.0f * ray_dir2.z), - 0.373176 * (5.0f * ray_dir2.z * ray_dir.z - 3.0f * ray_dir.z), - 0.457045 * ray_dir.x * (-1.0f + 5.0f * ray_dir2.z), - 1.445305 * (ray_dir2.x - ray_dir2.y) * ray_dir.z, - 0.590043 * ray_dir.x * (ray_dir2.x - 3.0f * ray_dir2.y) + SH_ACCUM(9, 0.590043 * ray_dir.y * (3.0f * ray_dir2.x - ray_dir2.y)); + SH_ACCUM(10, 2.890611 * ray_dir.y * ray_dir.x * ray_dir.z); + SH_ACCUM(11, 0.646360 * ray_dir.y * (-1.0f + 5.0f * ray_dir2.z)); + SH_ACCUM(12, 0.373176 * (5.0f * ray_dir2.z * ray_dir.z - 3.0f * ray_dir.z)); + SH_ACCUM(13, 0.457045 * ray_dir.x * (-1.0f + 5.0f * ray_dir2.z)); + SH_ACCUM(14, 1.445305 * (ray_dir2.x - ray_dir2.y) * ray_dir.z); + SH_ACCUM(15, 0.590043 * ray_dir.x * (ray_dir2.x - 3.0f * ray_dir2.y)); #endif - ); - - for (uint j = 0; j < SH_SIZE; j++) { - probe_sh_accum[j] += light * c[j]; - } } for (uint i = 0; i < SH_SIZE; i++) { @@ -312,7 +316,7 @@ void main() { ivec3 prev_pos = ivec3(pos.x, pos.y * SH_SIZE + i, int(params.history_index)); ivec2 average_pos = prev_pos.xy; - vec4 value = probe_sh_accum[i] * 4.0 / float(params.ray_count); + vec4 value = vec4(sh_accum[probe_index].c[i * 3 + 0], sh_accum[probe_index].c[i * 3 + 1], sh_accum[probe_index].c[i * 3 + 2], 1.0) * 4.0 / float(params.ray_count); ivec4 ivalue = clamp(ivec4(value * float(1 << HISTORY_BITS)), -32768, 32767); //clamp to 16 bits, so higher values don't break average @@ -344,37 +348,11 @@ void main() { ivec2 oct_pos = (pos / OCT_SIZE) * (OCT_SIZE + 2) + ivec2(1); ivec2 local_pos = pos % OCT_SIZE; - //fill the spherical harmonic - vec4 sh[SH_SIZE]; - - for (uint i = 0; i < SH_SIZE; i++) { - // store in history texture - ivec2 average_pos = sh_pos + ivec2(0, i); - ivec4 average = imageLoad(lightprobe_average_texture, average_pos); - - sh[i] = (vec4(average) / float(params.history_size)) / float(1 << HISTORY_BITS); - } - //compute the octahedral normal for this texel vec3 normal = octahedron_encode(vec2(local_pos) / float(OCT_SIZE)); - /* + // read the spherical harmonic - const float c1 = 0.429043; - const float c2 = 0.511664; - const float c3 = 0.743125; - const float c4 = 0.886227; - const float c5 = 0.247708; - vec4 light = (c1 * sh[8] * (normal.x * normal.x - normal.y * normal.y) + - c3 * sh[6] * normal.z * normal.z + - c4 * sh[0] - - c5 * sh[6] + - 2.0 * c1 * sh[4] * normal.x * normal.y + - 2.0 * c1 * sh[7] * normal.x * normal.z + - 2.0 * c1 * sh[5] * normal.y * normal.z + - 2.0 * c2 * sh[3] * normal.x + - 2.0 * c2 * sh[1] * normal.y + - 2.0 * c2 * sh[2] * normal.z); -*/ + vec3 normal2 = normal * normal; float c[SH_SIZE] = float[]( @@ -426,7 +404,14 @@ void main() { vec3 radiance = vec3(0.0); for (uint i = 0; i < SH_SIZE; i++) { - vec3 m = sh[i].rgb * c[i] * 4.0; + // store in history texture + ivec2 average_pos = sh_pos + ivec2(0, i); + ivec4 average = imageLoad(lightprobe_average_texture, average_pos); + + vec4 sh = (vec4(average) / float(params.history_size)) / float(1 << HISTORY_BITS); + + vec3 m = sh.rgb * c[i] * 4.0; + irradiance += m * l_mult[i]; radiance += m; } @@ -515,13 +500,15 @@ void main() { //can't scroll, must look for position in parent cascade //to global coords - float probe_cell_size = float(params.grid_size.x / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell; + float cell_to_probe = float(params.grid_size.x / float(params.probe_axis_size - 1)); + + float probe_cell_size = cell_to_probe / cascades.data[params.cascade].to_cell; vec3 probe_pos = cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size; //to parent local coords + float probe_cell_size_next = cell_to_probe / cascades.data[params.cascade + 1].to_cell; probe_pos -= cascades.data[params.cascade + 1].offset; - probe_pos *= cascades.data[params.cascade + 1].to_cell; - probe_pos = probe_pos * float(params.probe_axis_size - 1) / float(params.grid_size.x); + probe_pos /= probe_cell_size_next; ivec3 probe_posi = ivec3(probe_pos); //add up all light, no need to use occlusion here, since occlusion will do its work afterwards @@ -574,20 +561,28 @@ void main() { } } else { - // clear and let it re-raytrace, only for the last cascade, which happens very un-often - //scroll + //scroll at the edge of the highest cascade, just copy what is there, + //since its the closest we have anyway + for (uint j = 0; j < params.history_size; j++) { + ivec2 tex_pos; + tex_pos = probe_cell.xy; + tex_pos.x += probe_cell.z * int(params.probe_axis_size); + for (int i = 0; i < SH_SIZE; i++) { // copy from history texture + ivec3 src_pos = ivec3(tex_pos.x, tex_pos.y * SH_SIZE + i, int(j)); ivec3 dst_pos = ivec3(pos.x, pos.y * SH_SIZE + i, int(j)); - imageStore(lightprobe_history_scroll_texture, dst_pos, ivec4(0)); + ivec4 value = imageLoad(lightprobe_history_texture, dst_pos); + imageStore(lightprobe_history_scroll_texture, dst_pos, value); } } for (int i = 0; i < SH_SIZE; i++) { // copy from average texture - ivec2 dst_pos = ivec2(pos.x, pos.y * SH_SIZE + i); - imageStore(lightprobe_average_scroll_texture, dst_pos, ivec4(0)); + ivec2 spos = ivec2(pos.x, pos.y * SH_SIZE + i); + ivec4 average = imageLoad(lightprobe_average_texture, spos); + imageStore(lightprobe_average_scroll_texture, spos, average); } } diff --git a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl deleted file mode 100644 index 29443ae7db..0000000000 --- a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl +++ /dev/null @@ -1,105 +0,0 @@ -#[compute] - -#version 450 - -VERSION_DEFINES - -#define BLOCK_SIZE 8 - -layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; - -#ifdef MODE_REDUCE - -shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE]; -const uint swizzle_table[BLOCK_SIZE] = uint[](0, 4, 2, 6, 1, 5, 3, 7); -const uint unswizzle_table[BLOCK_SIZE] = uint[](0, 0, 0, 1, 0, 2, 1, 3); - -#endif - -layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_depth; -layout(r32f, set = 0, binding = 1) uniform restrict writeonly image2D dst_depth; - -layout(push_constant, binding = 1, std430) uniform Params { - ivec2 source_size; - ivec2 source_offset; - uint min_size; - uint gaussian_kernel_version; - ivec2 filter_dir; -} -params; - -void main() { -#ifdef MODE_REDUCE - - uvec2 pos = gl_LocalInvocationID.xy; - - ivec2 image_offset = params.source_offset; - ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy); - uint dst_t = swizzle_table[pos.y] * BLOCK_SIZE + swizzle_table[pos.x]; - tmp_data[dst_t] = imageLoad(source_depth, min(image_pos, params.source_size - ivec2(1))).r; - ivec2 image_size = params.source_size; - - uint t = pos.y * BLOCK_SIZE + pos.x; - - //neighbours - uint size = BLOCK_SIZE; - - do { - groupMemoryBarrier(); - barrier(); - - size >>= 1; - image_size >>= 1; - image_offset >>= 1; - - if (all(lessThan(pos, uvec2(size)))) { - uint nx = t + size; - uint ny = t + (BLOCK_SIZE * size); - uint nxy = ny + size; - - tmp_data[t] += tmp_data[nx]; - tmp_data[t] += tmp_data[ny]; - tmp_data[t] += tmp_data[nxy]; - tmp_data[t] /= 4.0; - } - - } while (size > params.min_size); - - if (all(lessThan(pos, uvec2(size)))) { - image_pos = ivec2(unswizzle_table[size + pos.x], unswizzle_table[size + pos.y]); - image_pos += image_offset + ivec2(gl_WorkGroupID.xy) * int(size); - - image_size = max(ivec2(1), image_size); //in case image size became 0 - - if (all(lessThan(image_pos, uvec2(image_size)))) { - imageStore(dst_depth, image_pos, vec4(tmp_data[t])); - } - } -#endif - -#ifdef MODE_FILTER - - ivec2 image_pos = params.source_offset + ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(image_pos, params.source_size))) { - return; - } - - ivec2 clamp_min = ivec2(params.source_offset); - ivec2 clamp_max = ivec2(params.source_size) - 1; - - //gaussian kernel, size 9, sigma 4 - const int kernel_size = 9; - const float gaussian_kernel[kernel_size * 3] = float[]( - 0.000229, 0.005977, 0.060598, 0.241732, 0.382928, 0.241732, 0.060598, 0.005977, 0.000229, - 0.028532, 0.067234, 0.124009, 0.179044, 0.20236, 0.179044, 0.124009, 0.067234, 0.028532, - 0.081812, 0.101701, 0.118804, 0.130417, 0.134535, 0.130417, 0.118804, 0.101701, 0.081812); - float accum = 0.0; - for (int i = 0; i < kernel_size; i++) { - ivec2 ofs = clamp(image_pos + params.filter_dir * (i - kernel_size / 2), clamp_min, clamp_max); - accum += imageLoad(source_depth, ofs).r * gaussian_kernel[params.gaussian_kernel_version + i]; - } - - imageStore(dst_depth, image_pos, vec4(accum)); - -#endif -} diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index b19f5a9ad3..680d1045cd 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -100,7 +100,7 @@ void main() { for (uint i = 0; i < params.blend_shape_count; i++) { float w = blend_shape_weights.data[i]; - if (w > 0.0001) { + if (abs(w) > 0.0001) { uint base_offset = (params.vertex_count * i + index) * params.vertex_stride; blend_vertex += uintBitsToFloat(uvec3(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1], src_blend_shapes.data[base_offset + 2])) * w; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index 498a6ddb5b..e7ba8feb80 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl @@ -4,6 +4,15 @@ VERSION_DEFINES +/* Do not use subgroups here, seems there is not much advantage and causes glitches +#extension GL_KHR_shader_subgroup_ballot: enable +#extension GL_KHR_shader_subgroup_arithmetic: enable + +#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic) +#define USE_SUBGROUPS +#endif +*/ + #if defined(MODE_FOG) || defined(MODE_FILTER) layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; @@ -23,22 +32,25 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; layout(set = 0, binding = 1) uniform texture2D shadow_atlas; layout(set = 0, binding = 2) uniform texture2D directional_shadow_atlas; -layout(set = 0, binding = 3, std430) restrict readonly buffer Lights { +layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights { LightData data[]; } -lights; +omni_lights; -layout(set = 0, binding = 4, std140) uniform DirectionalLights { +layout(set = 0, binding = 4, std430) restrict readonly buffer SpotLights { + LightData data[]; +} +spot_lights; + +layout(set = 0, binding = 5, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } directional_lights; -layout(set = 0, binding = 5) uniform utexture3D cluster_texture; - -layout(set = 0, binding = 6, std430) restrict readonly buffer ClusterData { - uint indices[]; +layout(set = 0, binding = 6, std430) buffer restrict readonly ClusterBuffer { + uint data[]; } -cluster_data; +cluster_buffer; layout(set = 0, binding = 7) uniform sampler linear_sampler; @@ -132,7 +144,7 @@ layout(set = 1, binding = 2) uniform texture3D sdfgi_occlusion_texture; #endif //SDFGI -layout(push_constant, binding = 0, std430) uniform Params { +layout(set = 0, binding = 14, std140) uniform Params { vec2 fog_frustum_size_begin; vec2 fog_frustum_size_end; @@ -150,12 +162,24 @@ layout(push_constant, binding = 0, std430) uniform Params { float detail_spread; float gi_inject; uint max_gi_probes; - uint pad; + uint cluster_type_size; + + vec2 screen_size; + uint cluster_shift; + uint cluster_width; + + uint max_cluster_element_count_div_32; + bool use_temporal_reprojection; + uint temporal_frame; + float temporal_blend; mat3x4 cam_rotation; + mat4 to_prev_view; } params; +layout(set = 0, binding = 15) uniform texture3D prev_density_texture; + float get_depth_at_pos(float cell_depth_size, int z) { float d = float(z) * cell_depth_size + cell_depth_size * 0.5; //center of voxels d = pow(d, params.detail_spread); @@ -178,6 +202,42 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { return nd * pow(max(distance, 0.0001), -decay); } +void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) { + uint item_min_max = cluster_buffer.data[p_offset]; + item_min = item_min_max & 0xFFFF; + item_max = item_min_max >> 16; + ; + + item_from = item_min >> 5; + item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements +} + +uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) { + int local_min = clamp(int(z_min) - int(i) * 32, 0, 31); + int mask_width = min(int(z_max) - int(z_min), 32 - local_min); + return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width); +} + +#define TEMPORAL_FRAMES 16 + +const vec3 halton_map[TEMPORAL_FRAMES] = vec3[]( + vec3(0.5, 0.33333333, 0.2), + vec3(0.25, 0.66666667, 0.4), + vec3(0.75, 0.11111111, 0.6), + vec3(0.125, 0.44444444, 0.8), + vec3(0.625, 0.77777778, 0.04), + vec3(0.375, 0.22222222, 0.24), + vec3(0.875, 0.55555556, 0.44), + vec3(0.0625, 0.88888889, 0.64), + vec3(0.5625, 0.03703704, 0.84), + vec3(0.3125, 0.37037037, 0.08), + vec3(0.8125, 0.7037037, 0.28), + vec3(0.1875, 0.14814815, 0.48), + vec3(0.6875, 0.48148148, 0.68), + vec3(0.4375, 0.81481481, 0.88), + vec3(0.9375, 0.25925926, 0.12), + vec3(0.03125, 0.59259259, 0.32)); + void main() { vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size); @@ -193,6 +253,12 @@ void main() { //posf += mix(vec3(0.0),vec3(1.0),0.3) * hash3f(uvec3(pos)) * 2.0 - 1.0; vec3 fog_unit_pos = posf * fog_cell_size + fog_cell_size * 0.5; //center of voxels + + uvec2 screen_pos = uvec2(fog_unit_pos.xy * params.screen_size); + uvec2 cluster_pos = screen_pos >> params.cluster_shift; + uint cluster_offset = (params.cluster_width * cluster_pos.y + cluster_pos.x) * (params.max_cluster_element_count_div_32 + 32); + //positions in screen are too spread apart, no hopes for optimizing with subgroups + fog_unit_pos.z = pow(fog_unit_pos.z, params.detail_spread); vec3 view_pos; @@ -200,6 +266,47 @@ void main() { view_pos.z = -params.fog_frustum_end * fog_unit_pos.z; view_pos.y = -view_pos.y; + vec4 reprojected_density = vec4(0.0); + float reproject_amount = 0.0; + + if (params.use_temporal_reprojection) { + vec3 prev_view = (params.to_prev_view * vec4(view_pos, 1.0)).xyz; + //undo transform into prev view + prev_view.y = -prev_view.y; + //z back to unit size + prev_view.z /= -params.fog_frustum_end; + //xy back to unit size + prev_view.xy /= mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(prev_view.z)); + prev_view.xy = prev_view.xy * 0.5 + 0.5; + //z back to unspread value + prev_view.z = pow(prev_view.z, 1.0 / params.detail_spread); + + if (all(greaterThan(prev_view, vec3(0.0))) && all(lessThan(prev_view, vec3(1.0)))) { + //reprojectinon fits + + reprojected_density = textureLod(sampler3D(prev_density_texture, linear_sampler), prev_view, 0.0); + reproject_amount = params.temporal_blend; + + // Since we can reproject, now we must jitter the current view pos. + // This is done here because cells that can't reproject should not jitter. + + fog_unit_pos = posf * fog_cell_size + fog_cell_size * halton_map[params.temporal_frame]; //center of voxels, offset by halton table + + screen_pos = uvec2(fog_unit_pos.xy * params.screen_size); + cluster_pos = screen_pos >> params.cluster_shift; + cluster_offset = (params.cluster_width * cluster_pos.y + cluster_pos.x) * (params.max_cluster_element_count_div_32 + 32); + //positions in screen are too spread apart, no hopes for optimizing with subgroups + + fog_unit_pos.z = pow(fog_unit_pos.z, params.detail_spread); + + view_pos.xy = (fog_unit_pos.xy * 2.0 - 1.0) * mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(fog_unit_pos.z)); + view_pos.z = -params.fog_frustum_end * fog_unit_pos.z; + view_pos.y = -view_pos.y; + } + } + + uint cluster_z = uint(clamp((abs(view_pos.z) / params.z_far) * 32.0, 0.0, 31.0)); + vec3 total_light = params.light_color; float total_density = params.base_density; @@ -266,108 +373,160 @@ void main() { //compute lights from cluster - vec3 cluster_pos; - cluster_pos.xy = fog_unit_pos.xy; - cluster_pos.z = clamp((abs(view_pos.z) - params.z_near) / (params.z_far - params.z_near), 0.0, 1.0); + { //omni lights - uvec4 cluster_cell = texture(usampler3D(cluster_texture, linear_sampler), cluster_pos); + uint cluster_omni_offset = cluster_offset; - uint omni_light_count = cluster_cell.x >> CLUSTER_COUNTER_SHIFT; - uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK; + uint item_min; + uint item_max; + uint item_from; + uint item_to; - for (uint i = 0; i < omni_light_count; i++) { - uint light_index = cluster_data.indices[omni_light_pointer + i]; + cluster_get_item_range(cluster_omni_offset + params.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); - vec3 light_pos = lights.data[i].position; - float d = distance(lights.data[i].position, view_pos); - vec3 shadow_attenuation = vec3(1.0); +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif + + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_omni_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); +#ifdef USE_SUBGROUPS + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); +#else + uint merged_mask = mask; +#endif + + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); +#ifdef USE_SUBGROUPS + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } +#endif + uint light_index = 32 * i + bit; - if (d * lights.data[i].inv_radius < 1.0) { - vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy); - vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular); + //if (!bool(omni_omni_lights.data[light_index].mask & draw_call.layer_mask)) { + // continue; //not masked + //} - float attenuation = get_omni_attenuation(d, lights.data[i].inv_radius, attenuation_energy.x); + vec3 light_pos = omni_lights.data[light_index].position; + float d = distance(omni_lights.data[light_index].position, view_pos); + float shadow_attenuation = 1.0; - vec3 light = attenuation_energy.y * color_specular.rgb / M_PI; + if (d * omni_lights.data[light_index].inv_radius < 1.0) { + float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation); - vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[i].shadow_color_enabled); + vec3 light = omni_lights.data[light_index].color / M_PI; - if (shadow_color_enabled.a > 0.5) { - //has shadow - vec4 v = vec4(view_pos, 1.0); + if (omni_lights.data[light_index].shadow_enabled) { + //has shadow + vec4 v = vec4(view_pos, 1.0); - vec4 splane = (lights.data[i].shadow_matrix * v); - float shadow_len = length(splane.xyz); //need to remember shadow len from here + vec4 splane = (omni_lights.data[light_index].shadow_matrix * v); + float shadow_len = length(splane.xyz); //need to remember shadow len from here - splane.xyz = normalize(splane.xyz); - vec4 clamp_rect = lights.data[i].atlas_rect; + splane.xyz = normalize(splane.xyz); + vec4 clamp_rect = omni_lights.data[light_index].atlas_rect; - if (splane.z >= 0.0) { - splane.z += 1.0; + if (splane.z >= 0.0) { + splane.z += 1.0; - clamp_rect.y += clamp_rect.w; + clamp_rect.y += clamp_rect.w; - } else { - splane.z = 1.0 - splane.z; - } + } else { + splane.z = 1.0 - splane.z; + } - splane.xy /= splane.z; + splane.xy /= splane.z; - splane.xy = splane.xy * 0.5 + 0.5; - splane.z = shadow_len * lights.data[i].inv_radius; - splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; - splane.w = 1.0; //needed? i think it should be 1 already + splane.xy = splane.xy * 0.5 + 0.5; + splane.z = shadow_len * omni_lights.data[light_index].inv_radius; + splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; //needed? i think it should be 1 already - float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r; - float shadow = exp(min(0.0, (depth - splane.z)) / lights.data[i].inv_radius * lights.data[i].shadow_volumetric_fog_fade); + float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r; - shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + shadow_attenuation = exp(min(0.0, (depth - splane.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade); + } + total_light += light * attenuation * shadow_attenuation; + } } - total_light += light * attenuation * shadow_attenuation; } } - uint spot_light_count = cluster_cell.y >> CLUSTER_COUNTER_SHIFT; - uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK; + { //spot lights - for (uint i = 0; i < spot_light_count; i++) { - uint light_index = cluster_data.indices[spot_light_pointer + i]; + uint cluster_spot_offset = cluster_offset + params.cluster_type_size; - vec3 light_pos = lights.data[i].position; - vec3 light_rel_vec = lights.data[i].position - view_pos; - float d = length(light_rel_vec); - vec3 shadow_attenuation = vec3(1.0); + uint item_min; + uint item_max; + uint item_from; + uint item_to; + + cluster_get_item_range(cluster_spot_offset + params.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); - if (d * lights.data[i].inv_radius < 1.0) { - vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy); - vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular); +#ifdef USE_SUBGROUPS + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); +#endif - float attenuation = get_omni_attenuation(d, lights.data[i].inv_radius, attenuation_energy.x); + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_spot_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); +#ifdef USE_SUBGROUPS + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); +#else + uint merged_mask = mask; +#endif - vec3 spot_dir = lights.data[i].direction; - vec2 spot_att_angle = unpackHalf2x16(lights.data[i].cone_attenuation_angle); - float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y); - float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y)); - attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x); + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); +#ifdef USE_SUBGROUPS + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } +#endif - vec3 light = attenuation_energy.y * color_specular.rgb / M_PI; + //if (!bool(omni_lights.data[light_index].mask & draw_call.layer_mask)) { + // continue; //not masked + //} - vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[i].shadow_color_enabled); + uint light_index = 32 * i + bit; - if (shadow_color_enabled.a > 0.5) { - //has shadow - vec4 v = vec4(view_pos, 1.0); + vec3 light_pos = spot_lights.data[light_index].position; + vec3 light_rel_vec = spot_lights.data[light_index].position - view_pos; + float d = length(light_rel_vec); + float shadow_attenuation = 1.0; - vec4 splane = (lights.data[i].shadow_matrix * v); - splane /= splane.w; + if (d * spot_lights.data[light_index].inv_radius < 1.0) { + float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation); - float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r; - float shadow = exp(min(0.0, (depth - splane.z)) / lights.data[i].inv_radius * lights.data[i].shadow_volumetric_fog_fade); + vec3 spot_dir = spot_lights.data[light_index].direction; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[light_index].cone_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[light_index].cone_angle)); + attenuation *= 1.0 - pow(spot_rim, spot_lights.data[light_index].cone_attenuation); - shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow); - } + vec3 light = spot_lights.data[light_index].color / M_PI; + + if (spot_lights.data[light_index].shadow_enabled) { + //has shadow + vec4 v = vec4(view_pos, 1.0); + + vec4 splane = (spot_lights.data[light_index].shadow_matrix * v); + splane /= splane.w; - total_light += light * attenuation * shadow_attenuation; + float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r; + + shadow_attenuation = exp(min(0.0, (depth - splane.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade); + } + + total_light += light * attenuation * shadow_attenuation; + } + } } } @@ -470,7 +629,11 @@ void main() { #endif - imageStore(density_map, pos, vec4(total_light, total_density)); + vec4 final_density = vec4(total_light, total_density); + + final_density = mix(final_density, reprojected_density, reproject_amount); + + imageStore(density_map, pos, final_density); #endif #ifdef MODE_FOG diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index c483898fed..b546001843 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -36,7 +36,8 @@ class RendererScene { public: - virtual RID camera_create() = 0; + virtual RID camera_allocate() = 0; + virtual void camera_initialize(RID p_rid) = 0; virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0; virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0; @@ -48,7 +49,8 @@ public: virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0; virtual bool is_camera(RID p_camera) const = 0; - virtual RID scenario_create() = 0; + virtual RID scenario_allocate() = 0; + virtual void scenario_initialize(RID p_rid) = 0; virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) = 0; virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0; @@ -58,7 +60,8 @@ public: virtual bool is_scenario(RID p_scenario) const = 0; virtual RID scenario_get_environment(RID p_scenario) = 0; - virtual RID instance_create() = 0; + virtual RID instance_allocate() = 0; + virtual void instance_initialize(RID p_rid) = 0; virtual void instance_set_base(RID p_instance, RID p_base) = 0; virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; @@ -95,11 +98,13 @@ public: virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0; virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0; - virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; /* SKY API */ - virtual RID sky_create() = 0; + virtual RID sky_allocate() = 0; + virtual void sky_initialize(RID p_rid) = 0; + virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; @@ -107,7 +112,8 @@ public: /* ENVIRONMENT API */ - virtual RID environment_create() = 0; + virtual RID environment_allocate() = 0; + virtual void environment_initialize(RID p_rid) = 0; virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; virtual void environment_set_sky(RID p_env, RID p_sky) = 0; @@ -122,12 +128,10 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; @@ -136,10 +140,11 @@ public: virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; + virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0; virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; @@ -160,7 +165,8 @@ public: /* Camera Effects */ - virtual RID camera_effects_create() = 0; + virtual RID camera_effects_allocate() = 0; + virtual void camera_effects_initialize(RID p_rid) = 0; virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; @@ -172,14 +178,17 @@ public: virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; virtual RID shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = false) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; /* Render Buffers */ virtual RID render_buffers_create() = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; + virtual void gi_set_use_half_resolution(bool p_enable) = 0; + virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index d3979521b1..e8155e4025 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -39,9 +39,11 @@ /* CAMERA API */ -RID RendererSceneCull::camera_create() { - Camera *camera = memnew(Camera); - return camera_owner.make_rid(camera); +RID RendererSceneCull::camera_allocate() { + return camera_owner.allocate_rid(); +} +void RendererSceneCull::camera_initialize(RID p_rid) { + camera_owner.initialize_rid(p_rid, memnew(Camera)); } void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { @@ -290,11 +292,12 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { } } -RID RendererSceneCull::scenario_create() { +RID RendererSceneCull::scenario_allocate() { + return scenario_owner.allocate_rid(); +} +void RendererSceneCull::scenario_initialize(RID p_rid) { Scenario *scenario = memnew(Scenario); - ERR_FAIL_COND_V(!scenario, RID()); - RID scenario_rid = scenario_owner.make_rid(scenario); - scenario->self = scenario_rid; + scenario->self = p_rid; scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create(); scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest @@ -307,7 +310,7 @@ RID RendererSceneCull::scenario_create() { scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool); scenario->instance_data.set_page_pool(&instance_data_page_pool); - return scenario_rid; + scenario_owner.initialize_rid(p_rid, scenario); } void RendererSceneCull::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) { @@ -367,14 +370,14 @@ void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_upda _instance_update_list.add(&p_instance->update_item); } -RID RendererSceneCull::instance_create() { +RID RendererSceneCull::instance_allocate() { + return instance_owner.allocate_rid(); +} +void RendererSceneCull::instance_initialize(RID p_rid) { Instance *instance = memnew(Instance); - ERR_FAIL_COND_V(!instance, RID()); + instance->self = p_rid; - RID instance_rid = instance_owner.make_rid(instance); - instance->self = instance_rid; - - return instance_rid; + instance_owner.initialize_rid(p_rid, instance); } void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) { @@ -436,7 +439,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { case RS::INSTANCE_LIGHT: { InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); - if (scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { + if (scenario && instance->visible && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { scenario->dynamic_lights.erase(light->instance); } @@ -783,6 +786,17 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) { _unpair_instance(instance); } + if (instance->base_type == RS::INSTANCE_LIGHT) { + InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); + if (instance->scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { + if (p_visible) { + instance->scenario->dynamic_lights.push_back(light->instance); + } else { + instance->scenario->dynamic_lights.erase(light->instance); + } + } + } + if (instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data); RSG::storage->particles_collision_instance_set_active(collision->instance, p_visible); @@ -1150,13 +1164,13 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { RS::LightBakeMode bake_mode = RSG::storage->light_get_bake_mode(p_instance->base); if (RSG::storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) { - if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { + if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { p_instance->scenario->dynamic_lights.erase(light->instance); } light->bake_mode = bake_mode; - if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { + if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) { p_instance->scenario->dynamic_lights.push_back(light->instance); } } @@ -1242,7 +1256,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); } - if (p_instance->scenario == nullptr || !p_instance->visible || Math::is_zero_approx(p_instance->transform.basis.determinant())) { + // note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes. + if (p_instance->scenario == nullptr || !p_instance->visible || p_instance->transform.basis.determinant() == 0) { p_instance->prev_transformed_aabb = p_instance->transformed_aabb; return; } @@ -1894,6 +1909,9 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base); if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) { + if (max_shadows_used + 2 > MAX_UPDATE_SHADOWS) { + return true; + } for (int i = 0; i < 2; i++) { //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); @@ -1910,7 +1928,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius)); planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0)); - geometry_instances_to_shadow_render.clear(); instance_shadow_cull_result.clear(); Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size()); @@ -1931,6 +1948,8 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); + RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; + for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { @@ -1945,16 +1964,21 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } } - geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); + shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); } RSG::storage->update_mesh_instances(); scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); - scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render); + shadow_data.light = light->instance; + shadow_data.pass = i; } } else { //shadow cube + if (max_shadows_used + 6 > MAX_UPDATE_SHADOWS) { + return true; + } + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); CameraMatrix cm; cm.set_perspective(90, 1, 0.01, radius); @@ -1984,7 +2008,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Vector<Plane> planes = cm.get_projection_planes(xform); - geometry_instances_to_shadow_render.clear(); instance_shadow_cull_result.clear(); Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size()); @@ -2003,7 +2026,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex); - Plane near_plane(xform.origin, -xform.basis.get_axis(2)); + RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { Instance *instance = instance_shadow_cull_result[j]; @@ -2018,22 +2041,28 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } } - geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); + shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); } RSG::storage->update_mesh_instances(); scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0); - scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render); + + shadow_data.light = light->instance; + shadow_data.pass = i; } //restore the regular DP matrix - scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); + //scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); } } break; case RS::LIGHT_SPOT: { RENDER_TIMESTAMP("Culling Spot Light"); + if (max_shadows_used + 1 > MAX_UPDATE_SHADOWS) { + return true; + } + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); @@ -2042,7 +2071,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Vector<Plane> planes = cm.get_projection_planes(light_transform); - geometry_instances_to_shadow_render.clear(); instance_shadow_cull_result.clear(); Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size()); @@ -2061,7 +2089,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex); - Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2)); + RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { Instance *instance = instance_shadow_cull_result[j]; @@ -2076,13 +2104,14 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons RSG::storage->mesh_instance_check_for_update(instance->mesh_instance); } } - geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); + shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); } RSG::storage->update_mesh_instances(); scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0); - scene_render->render_shadow(light->instance, p_shadow_atlas, 0, geometry_instances_to_shadow_render); + shadow_data.light = light->instance; + shadow_data.pass = 0; } break; } @@ -2135,14 +2164,13 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ RID environment = _render_get_environment(p_camera, p_scenario); - _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), p_screen_lod_threshold); - _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); + _render_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); #endif } void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) { // render for AR/VR interface - +#if 0 Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); @@ -2222,6 +2250,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_ // And render our scene... _render_scene(p_render_buffers, cam_transform, camera_matrix, false, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); +#endif }; void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data) { @@ -2440,7 +2469,7 @@ void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullRes } } -void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows) { +void RendererSceneCull::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) { // Note, in stereo rendering: // - p_cam_transform will be a transform in the middle of our two eyes // - p_cam_projection is a wider frustrum that encompasses both eyes @@ -2454,6 +2483,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca scene_render->set_scene_pass(render_pass); if (p_render_buffers.is_valid()) { + //no rendering code here, this is only to set up what needs to be done, request regions, etc. scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not) } @@ -2584,62 +2614,28 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca //render shadows - for (uint32_t i = 0; i < cull.shadow_count; i++) { - for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) { - const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j]; - // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size())); - scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale); - scene_render->render_shadow(cull.shadows[i].light_instance, p_shadow_atlas, j, frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j], near_plane, p_cam_projection.get_lod_multiplier(), p_screen_lod_threshold); - } - } + max_shadows_used = 0; - //render SDFGI + if (p_using_shadows) { //setup shadow maps - { - if (cull.sdfgi.region_count > 0) { - //update regions - for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { - scene_render->render_sdfgi(p_render_buffers, i, frustum_cull_result.sdfgi_region_geometry_instances[i]); - } - //check if static lights were culled - bool static_lights_culled = false; - for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) { - if (frustum_cull_result.sdfgi_cascade_lights[i].size()) { - static_lights_culled = true; - break; - } - } + // Directional Shadows - if (static_lights_culled) { - scene_render->render_sdfgi_static_lights(p_render_buffers, cull.sdfgi.cascade_light_count, cull.sdfgi.cascade_light_index, frustum_cull_result.sdfgi_cascade_lights); + for (uint32_t i = 0; i < cull.shadow_count; i++) { + for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) { + const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j]; + // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size())); + scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale); + if (max_shadows_used == MAX_UPDATE_SHADOWS) { + continue; + } + render_shadow_data[max_shadows_used].light = cull.shadows[i].light_instance; + render_shadow_data[max_shadows_used].pass = j; + render_shadow_data[max_shadows_used].instances.merge_unordered(frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j]); + max_shadows_used++; } } - if (p_render_buffers.is_valid()) { - scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_lights, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size()); - } - } - - //light_samplers_culled=0; - - /* - print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0)); - print_line("OTO: "+itos(p_scenario->octree.get_octant_count())); - print_line("OTE: "+itos(p_scenario->octree.get_elem_count())); - print_line("OTP: "+itos(p_scenario->octree.get_pair_count())); - */ - - /* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */ - //removed, will replace with culling - - /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */ - - /* STEP 5 - PROCESS POSITIONAL LIGHTS */ - - if (p_using_shadows) { //setup shadow maps - - //SortArray<Instance*,_InstanceLightsort> sorter; - //sorter.sort(light_cull_result,light_cull_count); + // Positional Shadowss for (uint32_t i = 0; i < (uint32_t)frustum_cull_result.lights.size(); i++) { Instance *ins = frustum_cull_result.lights[i]; @@ -2726,19 +2722,78 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca bool redraw = scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version); - if (redraw) { + if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) { //must redraw! RENDER_TIMESTAMP(">Rendering Light " + itos(i)); light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario, p_screen_lod_threshold); RENDER_TIMESTAMP("<Rendering Light " + itos(i)); + } else { + light->shadow_dirty = redraw; + } + } + } + + //render SDFGI + + { + sdfgi_update_data.update_static = false; + + if (cull.sdfgi.region_count > 0) { + //update regions + for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { + render_sdfgi_data[i].instances.merge_unordered(frustum_cull_result.sdfgi_region_geometry_instances[i]); + render_sdfgi_data[i].region = i; + } + //check if static lights were culled + bool static_lights_culled = false; + for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) { + if (frustum_cull_result.sdfgi_cascade_lights[i].size()) { + static_lights_culled = true; + break; + } + } + + if (static_lights_culled) { + sdfgi_update_data.static_cascade_count = cull.sdfgi.cascade_light_count; + sdfgi_update_data.static_cascade_indices = cull.sdfgi.cascade_light_index; + sdfgi_update_data.static_positional_lights = frustum_cull_result.sdfgi_cascade_lights; + sdfgi_update_data.update_static = true; } } + + if (p_render_buffers.is_valid()) { + sdfgi_update_data.directional_lights = &directional_lights; + sdfgi_update_data.positional_light_instances = scenario->dynamic_lights.ptr(); + sdfgi_update_data.positional_light_count = scenario->dynamic_lights.size(); + } } //append the directional lights to the lights culled for (int i = 0; i < directional_lights.size(); i++) { frustum_cull_result.light_instances.push_back(directional_lights[i]); } + + RID camera_effects; + if (p_force_camera_effects.is_valid()) { + camera_effects = p_force_camera_effects; + } else { + camera_effects = scenario->camera_effects; + } + /* PROCESS GEOMETRY AND DRAW SCENE */ + + RENDER_TIMESTAMP("Render Scene "); + scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data); + + for (uint32_t i = 0; i < max_shadows_used; i++) { + render_shadow_data[i].instances.clear(); + } + max_shadows_used = 0; + + for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { + render_sdfgi_data[i].instances.clear(); + } + + // virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; } RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { @@ -2762,21 +2817,6 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { return RID(); } -void RendererSceneCull::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) { - Scenario *scenario = scenario_owner.getornull(p_scenario); - - RID camera_effects; - if (p_force_camera_effects.is_valid()) { - camera_effects = p_force_camera_effects; - } else { - camera_effects = scenario->camera_effects; - } - /* PROCESS GEOMETRY AND DRAW SCENE */ - - RENDER_TIMESTAMP("Render Scene "); - scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold); -} - void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { #ifndef _3D_DISABLED @@ -2789,7 +2829,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, environment = scenario->fallback_environment; } RENDER_TIMESTAMP("Render Empty Scene "); - scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0); + scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif } @@ -2852,8 +2892,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int } RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); - _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, lod_threshold, use_shadows); - _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold); + _render_scene(xform, cm, false, false, RID(), RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold, use_shadows); } else { //do roughness postprocess step until it believes it's done @@ -3481,7 +3520,12 @@ RendererSceneCull::RendererSceneCull() { instance_cull_result.set_page_pool(&instance_cull_page_pool); instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool); - geometry_instances_to_shadow_render.set_page_pool(&geometry_instance_cull_page_pool); + for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) { + render_shadow_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool); + } + for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + render_sdfgi_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool); + } frustum_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); frustum_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); @@ -3489,8 +3533,8 @@ RendererSceneCull::RendererSceneCull() { frustum_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); } - indexer_update_iterations = GLOBAL_GET("rendering/spatial_indexer/update_iterations_per_frame"); - thread_cull_threshold = GLOBAL_GET("rendering/spatial_indexer/threaded_cull_minimum_instances"); + indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame"); + thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances"); thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU } @@ -3498,7 +3542,12 @@ RendererSceneCull::~RendererSceneCull() { instance_cull_result.reset(); instance_shadow_cull_result.reset(); - geometry_instances_to_shadow_render.reset(); + for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) { + render_shadow_data[i].instances.reset(); + } + for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + render_sdfgi_data[i].instances.reset(); + } frustum_cull_result.reset(); for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 796fb14743..32f4334288 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -54,7 +54,8 @@ public: enum { SDFGI_MAX_CASCADES = 8, SDFGI_MAX_REGIONS_PER_CASCADE = 3, - MAX_INSTANCE_PAIRS = 32 + MAX_INSTANCE_PAIRS = 32, + MAX_UPDATE_SHADOWS = 512 }; uint64_t render_pass; @@ -93,9 +94,11 @@ public: } }; - mutable RID_PtrOwner<Camera> camera_owner; + mutable RID_PtrOwner<Camera, true> camera_owner; + + virtual RID camera_allocate(); + virtual void camera_initialize(RID p_rid); - virtual RID camera_create(); virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far); virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far); @@ -295,14 +298,15 @@ public: int indexer_update_iterations = 0; - mutable RID_PtrOwner<Scenario> scenario_owner; + mutable RID_PtrOwner<Scenario, true> scenario_owner; static void _instance_pair(Instance *p_A, Instance *p_B); static void _instance_unpair(Instance *p_A, Instance *p_B); void _instance_update_mesh_instance(Instance *p_instance); - virtual RID scenario_create(); + virtual RID scenario_allocate(); + virtual void scenario_initialize(RID p_rid); virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode); virtual void scenario_set_environment(RID p_scenario, RID p_environment); @@ -696,7 +700,6 @@ public: PagedArray<Instance *> instance_cull_result; PagedArray<Instance *> instance_shadow_cull_result; - PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances_to_shadow_render; struct FrustumCullResult { PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances; @@ -795,6 +798,7 @@ public: lightmaps.set_page_pool(p_rid_pool); reflections.set_page_pool(p_rid_pool); decals.set_page_pool(p_rid_pool); + gi_probes.set_page_pool(p_rid_pool); mesh_instances.set_page_pool(p_rid_pool); for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { @@ -815,13 +819,20 @@ public: FrustumCullResult frustum_cull_result; LocalVector<FrustumCullResult> frustum_cull_result_threads; + RendererSceneRender::RenderShadowData render_shadow_data[MAX_UPDATE_SHADOWS]; + uint32_t max_shadows_used = 0; + + RendererSceneRender::RenderSDFGIData render_sdfgi_data[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; + RendererSceneRender::RenderSDFGIUpdateData sdfgi_update_data; + uint32_t thread_cull_threshold = 200; - RID_PtrOwner<Instance> instance_owner; + RID_PtrOwner<Instance, true> instance_owner; uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered - virtual RID instance_create(); + virtual RID instance_allocate(); + virtual void instance_initialize(RID p_rid); virtual void instance_set_base(RID p_instance, RID p_base); virtual void instance_set_scenario(RID p_instance, RID p_scenario); @@ -923,8 +934,7 @@ public: void _frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to); bool _render_reflection_probe_step(Instance *p_instance, int p_step); - void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows = true); - void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold); + void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true); void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas); void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas); @@ -946,18 +956,21 @@ public: #define PASSBASE scene_render - PASS1(directional_shadow_atlas_set_size, int) + PASS2(directional_shadow_atlas_set_size, int, bool) PASS1(gi_probe_set_quality, RS::GIProbeQuality) /* SKY API */ - PASS0R(RID, sky_create) + PASS0R(RID, sky_allocate) + PASS1(sky_initialize, RID) + PASS2(sky_set_radiance_size, RID, int) PASS2(sky_set_mode, RID, RS::SkyMode) PASS2(sky_set_material, RID, RID) PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) - PASS0R(RID, environment_create) + PASS0R(RID, environment_allocate) + PASS1(environment_initialize, RID) PASS1RC(bool, is_environment, RID) @@ -985,16 +998,15 @@ public: PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - PASS9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter) + PASS10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) PASS2(environment_set_volumetric_fog_volume_size, int, int) PASS1(environment_set_volumetric_fog_filter_active, bool) - PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) - PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) + PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float) PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount) PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge) + PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight) PASS1RC(RS::EnvironmentBG, environment_get_background, RID) PASS1RC(int, environment_get_canvas_max_layer, RID) @@ -1007,7 +1019,8 @@ public: /* CAMERA EFFECTS */ - PASS0R(RID, camera_effects_create) + PASS0R(RID, camera_effects_allocate) + PASS1(camera_effects_initialize, RID) PASS2(camera_effects_set_dof_blur_quality, RS::DOFBlurQuality, bool) PASS1(camera_effects_set_dof_blur_bokeh_shape, RS::DOFBokehShape) @@ -1024,10 +1037,11 @@ public: PASS0R(RID, render_buffers_create) PASS7(render_buffers_configure, RID, RID, int, int, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool) + PASS1(gi_set_use_half_resolution, bool) /* Shadow Atlas */ PASS0R(RID, shadow_atlas_create) - PASS2(shadow_atlas_set_size, RID, int) + PASS3(shadow_atlas_set_size, RID, int, bool) PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int) PASS1(set_debug_draw_mode, RS::ViewportDebugDraw) diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 85353c400d..1dea3580b6 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -71,13 +71,12 @@ public: /* SHADOW ATLAS API */ - virtual RID - shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; + virtual RID shadow_atlas_create() = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0; - virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; virtual int get_directional_light_shadow_size(RID p_light_intance) = 0; virtual void set_directional_shadow_count(int p_count) = 0; @@ -87,11 +86,12 @@ public: virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0; virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0; virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0; - virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0; /* SKY API */ - virtual RID sky_create() = 0; + virtual RID sky_allocate() = 0; + virtual void sky_initialize(RID p_rid) = 0; + virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; @@ -99,7 +99,8 @@ public: /* ENVIRONMENT API */ - virtual RID environment_create() = 0; + virtual RID environment_allocate() = 0; + virtual void environment_initialize(RID p_rid) = 0; virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; virtual void environment_set_sky(RID p_env, RID p_sky) = 0; @@ -118,12 +119,9 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; - + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; @@ -132,10 +130,11 @@ public: virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; + virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0; virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; @@ -149,7 +148,8 @@ public: virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; virtual int environment_get_canvas_max_layer(RID p_env) const = 0; - virtual RID camera_effects_create() = 0; + virtual RID camera_effects_allocate() = 0; + virtual void camera_effects_initialize(RID p_rid) = 0; virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; @@ -194,12 +194,31 @@ public: virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0; + struct RenderShadowData { + RID light; + int pass = 0; + PagedArray<GeometryInstance *> instances; + }; + + struct RenderSDFGIData { + int region = 0; + PagedArray<GeometryInstance *> instances; + }; + + struct RenderSDFGIUpdateData { + bool update_static = false; + uint32_t static_cascade_count; + uint32_t *static_cascade_indices; + PagedArray<RID> *static_positional_lights; + + const Vector<RID> *directional_lights; + const RID *positional_light_instances; + uint32_t positional_light_count; + }; + + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) = 0; - virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0; virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) = 0; - virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0; virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; virtual void set_scene_pass(uint64_t p_pass) = 0; @@ -208,6 +227,7 @@ public: virtual RID render_buffers_create() = 0; virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; + virtual void gi_set_use_half_resolution(bool p_enable) = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; virtual bool screen_space_roughness_limiter_is_active() const = 0; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 64c23c7803..69ad2cc191 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -98,6 +98,7 @@ public: while (to_clean_up.size()) { to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second); + dependencies.erase(to_clean_up.front()->get().first); to_clean_up.pop_front(); } } @@ -118,12 +119,15 @@ public: Set<Dependency *> dependencies; }; + virtual bool can_create_resources_async() const = 0; /* TEXTURE API */ - virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; - virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent + virtual RID texture_allocate() = 0; + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) = 0; + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; + virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; + virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; @@ -131,9 +135,9 @@ public: virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; //these two APIs can be used together or in combination with the others. - virtual RID texture_2d_placeholder_create() = 0; - virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_placeholder_create() = 0; + virtual void texture_2d_placeholder_initialize(RID p_texture) = 0; + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) = 0; + virtual void texture_3d_placeholder_initialize(RID p_texture) = 0; virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; @@ -160,7 +164,9 @@ public: /* CANVAS TEXTURE API */ - virtual RID canvas_texture_create() = 0; + virtual RID canvas_texture_allocate() = 0; + virtual void canvas_texture_initialize(RID p_rid) = 0; + virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0; virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0; @@ -169,7 +175,8 @@ public: /* SHADER API */ - virtual RID shader_create() = 0; + virtual RID shader_allocate() = 0; + virtual void shader_initialize(RID p_rid) = 0; virtual void shader_set_code(RID p_shader, const String &p_code) = 0; virtual String shader_get_code(RID p_shader) const = 0; @@ -183,7 +190,8 @@ public: /* COMMON MATERIAL API */ - virtual RID material_create() = 0; + virtual RID material_allocate() = 0; + virtual void material_initialize(RID p_rid) = 0; virtual void material_set_render_priority(RID p_material, int priority) = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; @@ -208,7 +216,8 @@ public: /* MESH API */ - virtual RID mesh_create() = 0; + virtual RID mesh_allocate() = 0; + virtual void mesh_initialize(RID p_rid) = 0; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) = 0; @@ -234,6 +243,8 @@ public: virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) = 0; + virtual void mesh_clear(RID p_mesh) = 0; virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) = 0; @@ -248,9 +259,10 @@ public: /* MULTIMESH API */ - virtual RID multimesh_create() = 0; + virtual RID multimesh_allocate() = 0; + virtual void multimesh_initialize(RID p_rid) = 0; - virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; + virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; @@ -277,7 +289,9 @@ public: /* IMMEDIATE API */ - virtual RID immediate_create() = 0; + virtual RID immediate_allocate() = 0; + virtual void immediate_initialize(RID p_rid) = 0; + virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0; virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0; virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0; @@ -293,8 +307,10 @@ public: /* SKELETON API */ - virtual RID skeleton_create() = 0; - virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; + virtual RID skeleton_allocate() = 0; + virtual void skeleton_initialize(RID p_rid) = 0; + + virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; @@ -304,11 +320,14 @@ public: /* Light API */ - virtual RID light_create(RS::LightType p_type) = 0; + virtual RID directional_light_allocate() = 0; + virtual void directional_light_initialize(RID p_rid) = 0; + + virtual RID omni_light_allocate() = 0; + virtual void omni_light_initialize(RID p_rid) = 0; - RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); } - RID omni_light_create() { return light_create(RS::LIGHT_OMNI); } - RID spot_light_create() { return light_create(RS::LIGHT_SPOT); } + virtual RID spot_light_allocate() = 0; + virtual void spot_light_initialize(RID p_rid) = 0; virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; @@ -346,7 +365,8 @@ public: /* PROBE API */ - virtual RID reflection_probe_create() = 0; + virtual RID reflection_probe_allocate() = 0; + virtual void reflection_probe_initialize(RID p_rid) = 0; virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0; virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0; @@ -377,7 +397,9 @@ public: /* DECAL API */ - virtual RID decal_create() = 0; + virtual RID decal_allocate() = 0; + virtual void decal_initialize(RID p_rid) = 0; + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0; virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0; virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0; @@ -392,9 +414,10 @@ public: /* GI PROBE API */ - virtual RID gi_probe_create() = 0; + virtual RID gi_probe_allocate() = 0; + virtual void gi_probe_initialize(RID p_rid) = 0; - virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; @@ -437,9 +460,10 @@ public: virtual uint32_t gi_probe_get_version(RID p_probe) = 0; - /* LIGHTMAP CAPTURE */ + /* LIGHTMAP */ - virtual RID lightmap_create() = 0; + virtual RID lightmap_allocate() = 0; + virtual void lightmap_initialize(RID p_rid) = 0; virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; @@ -457,7 +481,8 @@ public: /* PARTICLES */ - virtual RID particles_create() = 0; + virtual RID particles_allocate() = 0; + virtual void particles_initialize(RID p_rid) = 0; virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; virtual bool particles_get_emitting(RID p_particles) = 0; @@ -504,7 +529,9 @@ public: /* PARTICLES COLLISION */ - virtual RID particles_collision_create() = 0; + virtual RID particles_collision_allocate() = 0; + virtual void particles_collision_initialize(RID p_rid) = 0; + virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0; virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0; virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 9956e4050b..a5d5033c18 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -457,7 +457,7 @@ void RendererViewport::draw_viewports() { } if (Engine::get_singleton()->is_editor_hint()) { - set_default_clear_color(GLOBAL_GET("rendering/environment/default_clear_color")); + set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color")); } //sort viewports @@ -608,19 +608,20 @@ void RendererViewport::draw_viewports() { } } -RID RendererViewport::viewport_create() { - Viewport *viewport = memnew(Viewport); - - RID rid = viewport_owner.make_rid(viewport); +RID RendererViewport::viewport_allocate() { + return viewport_owner.allocate_rid(); +} - viewport->self = rid; +void RendererViewport::viewport_initialize(RID p_rid) { + Viewport *viewport = memnew(Viewport); + viewport->self = p_rid; viewport->hide_scenario = false; viewport->hide_canvas = false; viewport->render_target = RSG::storage->render_target_create(); viewport->shadow_atlas = RSG::scene->shadow_atlas_create(); viewport->viewport_render_direct_to_screen = false; - return rid; + viewport_owner.initialize_rid(p_rid, viewport); } void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { @@ -831,13 +832,14 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas viewport->canvas_map[p_canvas].sublayer = p_sublayer; } -void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) { +void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->shadow_atlas_size = p_size; + viewport->shadow_atlas_16_bits = p_16_bits; - RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size); + RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits); } void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { @@ -1018,5 +1020,10 @@ void RendererViewport::set_default_clear_color(const Color &p_color) { RSG::storage->set_default_clear_color(p_color); } +//workaround for setting this on thread +void RendererViewport::call_set_use_vsync(bool p_enable) { + DisplayServer::get_singleton()->_set_use_vsync(p_enable); +} + RendererViewport::RendererViewport() { } diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index c3ff52a836..f5ed543e8d 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -81,6 +81,7 @@ public: RID shadow_atlas; int shadow_atlas_size; + bool shadow_atlas_16_bits = false; bool sdf_active; @@ -164,7 +165,7 @@ public: uint64_t draw_viewports_pass = 0; - mutable RID_PtrOwner<Viewport> viewport_owner; + mutable RID_PtrOwner<Viewport, true> viewport_owner; struct ViewportSort { _FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const { @@ -185,7 +186,8 @@ private: void _draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye = XRInterface::EYE_MONO); public: - RID viewport_create(); + RID viewport_allocate(); + void viewport_initialize(RID p_rid); void viewport_set_use_xr(RID p_viewport, bool p_use_xr); @@ -217,7 +219,7 @@ public: void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform); void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer); - void viewport_set_shadow_atlas_size(RID p_viewport, int p_size); + void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false); void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv); void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa); @@ -248,6 +250,9 @@ public: bool free(RID p_rid); + //workaround for setting this on thread + void call_set_use_vsync(bool p_enable); + RendererViewport(); virtual ~RendererViewport() {} }; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 73c86a0a1d..27a9353e4e 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -174,8 +174,8 @@ RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, return uniform_set_create(uniforms, p_shader, p_shader_set); } -Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { - return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw); +Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) { + return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier); } RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) { @@ -240,16 +240,12 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); } -void RenderingDevice::compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads, uint32_t p_x_local_group, uint32_t p_y_local_group, uint32_t p_z_local_group) { - compute_list_dispatch(p_list, (p_x_threads - 1) / p_x_local_group + 1, (p_y_threads - 1) / p_y_local_group + 1, (p_z_threads - 1) / p_z_local_group + 1); -} - void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D)); - ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL)); ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data); ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage); @@ -257,15 +253,15 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared); ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid); - ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::texture_copy, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL)); ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create); - ClassDB::bind_method(D_METHOD("framebuffer_format_create_empty", "size"), &RenderingDevice::framebuffer_format_create_empty); + ClassDB::bind_method(D_METHOD("framebuffer_format_create_empty", "samples"), &RenderingDevice::framebuffer_format_create_empty, DEFVAL(TEXTURE_SAMPLES_1)); ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples); ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID)); - ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(INVALID_FORMAT_ID)); + ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "samples", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(TEXTURE_SAMPLES_1), DEFVAL(INVALID_FORMAT_ID)); ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format); ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); @@ -273,7 +269,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); - ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); @@ -287,7 +283,8 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid); - ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL)); ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0)); @@ -316,19 +313,19 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i())); ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor); - ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end); + ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL)); - ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin); + ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant); ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch); ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier); - ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end); + ClassDB::bind_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::compute_list_end, DEFVAL(BARRIER_MASK_ALL)); ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free); - ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp); + ClassDB::bind_method(D_METHOD("capture_timestamp", "name"), &RenderingDevice::capture_timestamp); ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count); ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame); ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time); @@ -340,8 +337,27 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit); ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync); + ClassDB::bind_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::barrier, DEFVAL(BARRIER_MASK_ALL), DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("full_barrier"), &RenderingDevice::full_barrier); + ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device); + ClassDB::bind_method(D_METHOD("set_resource_name", "id", "name"), &RenderingDevice::set_resource_name); + + ClassDB::bind_method(D_METHOD("draw_command_begin_label", "name", "color"), &RenderingDevice::draw_command_begin_label); + ClassDB::bind_method(D_METHOD("draw_command_insert_label", "name", "color"), &RenderingDevice::draw_command_insert_label); + ClassDB::bind_method(D_METHOD("draw_command_end_label"), &RenderingDevice::draw_command_end_label); + + ClassDB::bind_method(D_METHOD("get_device_vendor_name"), &RenderingDevice::get_device_vendor_name); + ClassDB::bind_method(D_METHOD("get_device_name"), &RenderingDevice::get_device_name); + ClassDB::bind_method(D_METHOD("get_device_pipeline_cache_uuid"), &RenderingDevice::get_device_pipeline_cache_uuid); + + BIND_CONSTANT(BARRIER_MASK_RASTER); + BIND_CONSTANT(BARRIER_MASK_COMPUTE); + BIND_CONSTANT(BARRIER_MASK_TRANSFER); + BIND_CONSTANT(BARRIER_MASK_ALL); + BIND_CONSTANT(BARRIER_MASK_NO_BARRIER); + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8); BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16); BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16); @@ -744,6 +760,8 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION_CONTINUE); //continue rendering and clear the framebuffer (supply params) BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 787805ea6a..9fbf58d131 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -336,6 +336,18 @@ public: }; /*****************/ + /**** BARRIER ****/ + /*****************/ + + enum BarrierMask { + BARRIER_MASK_RASTER = 1, + BARRIER_MASK_COMPUTE = 2, + BARRIER_MASK_TRANSFER = 4, + BARRIER_MASK_NO_BARRIER = 8, + BARRIER_MASK_ALL = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER + }; + + /*****************/ /**** TEXTURE ****/ /*****************/ @@ -438,16 +450,16 @@ public: virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0; - virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the beginning of the frame, unless sync with draw is used, which is used to mix updates with draw calls + virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0; virtual bool texture_is_shared(RID p_texture) = 0; virtual bool texture_is_valid(RID p_texture) = 0; - virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false) = 0; - virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false) = 0; - virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false) = 0; + virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; /*********************/ /**** FRAMEBUFFER ****/ @@ -468,11 +480,11 @@ public: // This ID is warranted to be unique for the same formats, does not need to be freed virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format) = 0; - virtual FramebufferFormatID framebuffer_format_create_empty(const Size2i &p_size) = 0; + virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1) = 0; virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) = 0; virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0; - virtual RID framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check = INVALID_ID) = 0; + virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID) = 0; virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer) = 0; @@ -649,7 +661,8 @@ public: virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0; virtual bool uniform_set_is_valid(RID p_uniform_set) = 0; - virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the beginning of the frame, unless sync with draw is used, which is used to mix updates with draw calls + virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving /*************************/ @@ -930,7 +943,9 @@ public: /********************/ enum InitialAction { - INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params) + INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params) + INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params) + INITIAL_ACTION_CLEAR_REGION_CONTINUE, //countinue rendering and clear the framebuffer in the specified region (supply params) INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared) INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously) @@ -962,7 +977,7 @@ public: virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect) = 0; virtual void draw_list_disable_scissor(DrawListID p_list) = 0; - virtual void draw_list_end() = 0; + virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; /***********************/ /**** COMPUTE LISTS ****/ @@ -970,17 +985,18 @@ public: typedef int64_t ComputeListID; - virtual ComputeListID compute_list_begin() = 0; + virtual ComputeListID compute_list_begin(bool p_allow_draw_overlap = false) = 0; virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0; virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0; virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; - virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads, uint32_t p_x_local_group, uint32_t p_y_local_group, uint32_t p_z_local_group); + virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads) = 0; virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; - virtual void compute_list_end() = 0; + virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual void barrier(uint32_t p_from = BARRIER_MASK_ALL, uint32_t p_to = BARRIER_MASK_ALL) = 0; virtual void full_barrier() = 0; /***************/ @@ -993,7 +1009,7 @@ public: /**** Timing ****/ /****************/ - virtual void capture_timestamp(const String &p_name, bool p_sync_to_draw) = 0; + virtual void capture_timestamp(const String &p_name) = 0; virtual uint32_t get_captured_timestamps_count() const = 0; virtual uint64_t get_captured_timestamps_frame() const = 0; virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0; @@ -1058,6 +1074,16 @@ public: virtual RenderingDevice *create_local_device() = 0; + virtual void set_resource_name(RID p_id, const String p_name) = 0; + + virtual void draw_command_begin_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)) = 0; + virtual void draw_command_insert_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)) = 0; + virtual void draw_command_end_label() = 0; + + virtual String get_device_vendor_name() const = 0; + virtual String get_device_name() const = 0; + virtual String get_device_pipeline_cache_uuid() const = 0; + static RenderingDevice *get_singleton(); RenderingDevice(); @@ -1077,7 +1103,7 @@ protected: RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); - Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false); + Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0); diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 8c6e97a0af..61d1efaf22 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -64,7 +64,7 @@ void RenderingServerDefault::_draw_margins() { /* FREE */ -void RenderingServerDefault::free(RID p_rid) { +void RenderingServerDefault::_free(RID p_rid) { if (RSG::storage->free(p_rid)) { return; } @@ -91,7 +91,7 @@ void RenderingServerDefault::request_frame_drawn_callback(Object *p_where, const frame_drawn_callbacks.push_back(fdc); } -void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) { +void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { //needs to be done before changes is reset to 0, to not force the editor to redraw RS::get_singleton()->emit_signal("frame_pre_draw"); @@ -162,24 +162,66 @@ void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) { } frame_profile_frame = RSG::storage->get_captured_timestamps_frame(); + + if (print_gpu_profile) { + if (print_frame_profile_ticks_from == 0) { + print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec(); + } + float total_time = 0.0; + + for (int i = 0; i < frame_profile.size() - 1; i++) { + String name = frame_profile[i].name; + if (name[0] == '<' || name[0] == '>') { + continue; + } + + float time = frame_profile[i + 1].gpu_msec - frame_profile[i].gpu_msec; + + if (name[0] != '<' && name[0] != '>') { + if (print_gpu_profile_task_time.has(name)) { + print_gpu_profile_task_time[name] += time; + } else { + print_gpu_profile_task_time[name] = time; + } + } + } + + if (frame_profile.size()) { + total_time = frame_profile[frame_profile.size() - 1].gpu_msec; + } + + uint64_t ticks_elapsed = OS::get_singleton()->get_ticks_usec() - print_frame_profile_ticks_from; + print_frame_profile_frame_count++; + if (ticks_elapsed > 1000000) { + print_line("GPU PROFILE (total " + rtos(total_time) + "ms): "); + + float print_threshold = 0.01; + for (OrderedHashMap<String, float>::Element E = print_gpu_profile_task_time.front(); E; E = E.next()) { + float time = E.value() / float(print_frame_profile_frame_count); + if (time > print_threshold) { + print_line("\t-" + E.key() + ": " + rtos(time) + "ms"); + } + } + print_gpu_profile_task_time.clear(); + print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec(); + print_frame_profile_frame_count = 0; + } + } } float RenderingServerDefault::get_frame_setup_time_cpu() const { return frame_setup_time; } -void RenderingServerDefault::sync() { -} - bool RenderingServerDefault::has_changed() const { return changes > 0; } -void RenderingServerDefault::init() { +void RenderingServerDefault::_init() { RSG::rasterizer->initialize(); } -void RenderingServerDefault::finish() { +void RenderingServerDefault::_finish() { if (test_cube.is_valid()) { free(test_cube); } @@ -187,6 +229,32 @@ void RenderingServerDefault::finish() { RSG::rasterizer->finalize(); } +void RenderingServerDefault::init() { + if (create_thread) { + print_verbose("RenderingServerWrapMT: Creating render thread"); + DisplayServer::get_singleton()->release_rendering_thread(); + if (create_thread) { + thread.start(_thread_callback, this); + print_verbose("RenderingServerWrapMT: Starting render thread"); + } + while (!draw_thread_up.is_set()) { + OS::get_singleton()->delay_usec(1000); + } + print_verbose("RenderingServerWrapMT: Finished render thread"); + } else { + _init(); + } +} + +void RenderingServerDefault::finish() { + if (create_thread) { + command_queue.push(this, &RenderingServerDefault::_thread_exit); + thread.wait_to_finish(); + } else { + _finish(); + } +} + /* STATUS INFORMATION */ int RenderingServerDefault::get_render_info(RenderInfo p_info) { @@ -232,6 +300,11 @@ void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_posit RSG::scene->sdfgi_set_debug_probe_select(p_position, p_dir); } +void RenderingServerDefault::set_print_gpu_profile(bool p_enable) { + RSG::storage->capturing_timestamps = p_enable; + print_gpu_profile = p_enable; +} + RID RenderingServerDefault::get_test_cube() { if (!test_cube.is_valid()) { test_cube = _make_test_cube(); @@ -247,10 +320,6 @@ void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) { RSG::storage->set_debug_generate_wireframes(p_generate); } -void RenderingServerDefault::call_set_use_vsync(bool p_enable) { - DisplayServer::get_singleton()->_set_use_vsync(p_enable); -} - bool RenderingServerDefault::is_low_end() const { // FIXME: Commented out when rebasing vulkan branch on master, // causes a crash, it seems rasterizer is not initialized yet the @@ -259,7 +328,74 @@ bool RenderingServerDefault::is_low_end() const { return false; } -RenderingServerDefault::RenderingServerDefault() { +void RenderingServerDefault::_thread_exit() { + exit.set(); +} + +void RenderingServerDefault::_thread_draw(bool p_swap_buffers, double frame_step) { + if (!draw_pending.decrement()) { + _draw(p_swap_buffers, frame_step); + } +} + +void RenderingServerDefault::_thread_flush() { + draw_pending.decrement(); +} + +void RenderingServerDefault::_thread_callback(void *_instance) { + RenderingServerDefault *vsmt = reinterpret_cast<RenderingServerDefault *>(_instance); + + vsmt->_thread_loop(); +} + +void RenderingServerDefault::_thread_loop() { + server_thread = Thread::get_caller_id(); + + DisplayServer::get_singleton()->make_rendering_thread(); + + _init(); + + draw_thread_up.set(); + while (!exit.is_set()) { + // flush commands one by one, until exit is requested + command_queue.wait_and_flush_one(); + } + + command_queue.flush_all(); // flush all + + _finish(); +} + +/* EVENT QUEUING */ + +void RenderingServerDefault::sync() { + if (create_thread) { + draw_pending.increment(); + command_queue.push_and_sync(this, &RenderingServerDefault::_thread_flush); + } else { + command_queue.flush_all(); //flush all pending from other threads + } +} + +void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) { + if (create_thread) { + draw_pending.increment(); + command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step); + } else { + _draw(p_swap_buffers, frame_step); + } +} + +RenderingServerDefault::RenderingServerDefault(bool p_create_thread) : + command_queue(p_create_thread) { + create_thread = p_create_thread; + + if (!p_create_thread) { + server_thread = Thread::get_caller_id(); + } else { + server_thread = 0; + } + RSG::canvas = memnew(RendererCanvasCull); RSG::viewport = memnew(RendererViewport); RendererSceneCull *sr = memnew(RendererSceneCull); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 71f459f34a..73b463f6e7 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -32,12 +32,15 @@ #define RENDERING_SERVER_DEFAULT_H #include "core/math/octree.h" +#include "core/templates/command_queue_mt.h" +#include "core/templates/ordered_hash_map.h" #include "renderer_canvas_cull.h" #include "renderer_scene_cull.h" #include "renderer_viewport.h" #include "rendering_server_globals.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" +#include "servers/server_wrap_mt_common.h" class RenderingServerDefault : public RenderingServer { enum { @@ -74,6 +77,37 @@ class RenderingServerDefault : public RenderingServer { float frame_setup_time = 0; + //for printing + bool print_gpu_profile = false; + OrderedHashMap<String, float> print_gpu_profile_task_time; + uint64_t print_frame_profile_ticks_from = 0; + uint32_t print_frame_profile_frame_count = 0; + + mutable CommandQueueMT command_queue; + + static void _thread_callback(void *_instance); + void _thread_loop(); + + Thread::ID server_thread; + SafeFlag exit; + Thread thread; + SafeFlag draw_thread_up; + bool create_thread; + + SafeNumeric<uint64_t> draw_pending; + void _thread_draw(bool p_swap_buffers, double frame_step); + void _thread_flush(); + + void _thread_exit(); + + Mutex alloc_mutex; + + void _draw(bool p_swap_buffers, double frame_step); + void _init(); + void _finish(); + + void _free(RID p_rid); + public: //if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() //#define DEBUG_CHANGES @@ -90,802 +124,813 @@ public: #else _FORCE_INLINE_ static void redraw_request() { changes++; } +#endif -#define DISPLAY_CHANGED \ - changes++; +#define WRITE_ACTION redraw_request(); + +#ifdef DEBUG_SYNC +#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); +#else +#define SYNC_DEBUG #endif -#define BIND0R(m_r, m_name) \ - m_r m_name() { return BINDBASE->m_name(); } -#define BIND0RC(m_r, m_name) \ - m_r m_name() const { return BINDBASE->m_name(); } -#define BIND1R(m_r, m_name, m_type1) \ - m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); } -#define BIND1RC(m_r, m_name, m_type1) \ - m_r m_name(m_type1 arg1) const { return BINDBASE->m_name(arg1); } -#define BIND2R(m_r, m_name, m_type1, m_type2) \ - m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); } -#define BIND2RC(m_r, m_name, m_type1, m_type2) \ - m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); } -#define BIND3R(m_r, m_name, m_type1, m_type2, m_type3) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return BINDBASE->m_name(arg1, arg2, arg3); } -#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return BINDBASE->m_name(arg1, arg2, arg3); } -#define BIND4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } -#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } -#define BIND5R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } -#define BIND5RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } -#define BIND6R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } -#define BIND6RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } - -#define BIND0(m_name) \ - void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); } -#define BIND1(m_name, m_type1) \ - void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); } -#define BIND1C(m_name, m_type1) \ - void m_name(m_type1 arg1) const { DISPLAY_CHANGED BINDBASE->m_name(arg1); } -#define BIND2(m_name, m_type1, m_type2) \ - void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); } -#define BIND2C(m_name, m_type1, m_type2) \ - void m_name(m_type1 arg1, m_type2 arg2) const { BINDBASE->m_name(arg1, arg2); } -#define BIND3(m_name, m_type1, m_type2, m_type3) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3); } -#define BIND4(m_name, m_type1, m_type2, m_type3, m_type4) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4); } -#define BIND5(m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } -#define BIND6(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } -#define BIND7(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -#define BIND8(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } -#define BIND9(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } -#define BIND10(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } -#define BIND11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); } -#define BIND12(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); } -#define BIND13(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); } -#define BIND14(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); } -#define BIND15(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14, m_type15) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14, m_type15 arg15) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); } +#include "servers/server_wrap_mt_common.h" //from now on, calls forwarded to this singleton -#define BINDBASE RSG::storage +#define ServerName RendererStorage +#define server_name RSG::storage /* TEXTURE API */ +#define FUNCRIDTEX0(m_type) \ + virtual RID m_type##_create() override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret); \ + } \ + return ret; \ + } + +#define FUNCRIDTEX1(m_type, m_type1) \ + virtual RID m_type##_create(m_type1 p1) override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret, p1); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1); \ + } \ + return ret; \ + } + +#define FUNCRIDTEX2(m_type, m_type1, m_type2) \ + virtual RID m_type##_create(m_type1 p1, m_type2 p2) override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret, p1, p2); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2); \ + } \ + return ret; \ + } + +#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6); \ + } \ + return ret; \ + } + //these go pass-through, as they can be called from any thread - BIND1R(RID, texture_2d_create, const Ref<Image> &) - BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image>> &, TextureLayeredType) - BIND6R(RID, texture_3d_create, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &) - BIND1R(RID, texture_proxy_create, RID) + FUNCRIDTEX1(texture_2d, const Ref<Image> &) + FUNCRIDTEX2(texture_2d_layered, const Vector<Ref<Image>> &, TextureLayeredType) + FUNCRIDTEX6(texture_3d, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &) + FUNCRIDTEX1(texture_proxy, RID) //goes pass-through - BIND3(texture_2d_update_immediate, RID, const Ref<Image> &, int) + FUNC3(texture_2d_update_immediate, RID, const Ref<Image> &, int) //these go through command queue if they are in another thread - BIND3(texture_2d_update, RID, const Ref<Image> &, int) - BIND2(texture_3d_update, RID, const Vector<Ref<Image>> &) - BIND2(texture_proxy_update, RID, RID) + FUNC3(texture_2d_update, RID, const Ref<Image> &, int) + FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &) + FUNC2(texture_proxy_update, RID, RID) //these also go pass-through - BIND0R(RID, texture_2d_placeholder_create) - BIND1R(RID, texture_2d_layered_placeholder_create, TextureLayeredType) - BIND0R(RID, texture_3d_placeholder_create) + FUNCRIDTEX0(texture_2d_placeholder) + FUNCRIDTEX1(texture_2d_layered_placeholder, TextureLayeredType) + FUNCRIDTEX0(texture_3d_placeholder) - BIND1RC(Ref<Image>, texture_2d_get, RID) - BIND2RC(Ref<Image>, texture_2d_layer_get, RID, int) - BIND1RC(Vector<Ref<Image>>, texture_3d_get, RID) + FUNC1RC(Ref<Image>, texture_2d_get, RID) + FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int) + FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID) - BIND2(texture_replace, RID, RID) + FUNC2(texture_replace, RID, RID) - BIND3(texture_set_size_override, RID, int, int) + FUNC3(texture_set_size_override, RID, int, int) // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 - BIND2(texture_bind, RID, uint32_t) + FUNC2(texture_bind, RID, uint32_t) #endif - BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) - BIND3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) - BIND3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *) + FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) + FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) + FUNC3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *) - BIND2(texture_set_path, RID, const String &) - BIND1RC(String, texture_get_path, RID) - BIND1(texture_debug_usage, List<TextureInfo> *) + FUNC2(texture_set_path, RID, const String &) + FUNC1RC(String, texture_get_path, RID) + FUNC1(texture_debug_usage, List<TextureInfo> *) - BIND2(texture_set_force_redraw_if_visible, RID, bool) + FUNC2(texture_set_force_redraw_if_visible, RID, bool) /* SHADER API */ - BIND0R(RID, shader_create) + FUNCRIDSPLIT(shader) - BIND2(shader_set_code, RID, const String &) - BIND1RC(String, shader_get_code, RID) + FUNC2(shader_set_code, RID, const String &) + FUNC1RC(String, shader_get_code, RID) - BIND2C(shader_get_param_list, RID, List<PropertyInfo> *) + FUNC2C(shader_get_param_list, RID, List<PropertyInfo> *) - BIND3(shader_set_default_texture_param, RID, const StringName &, RID) - BIND2RC(RID, shader_get_default_texture_param, RID, const StringName &) - BIND2RC(Variant, shader_get_param_default, RID, const StringName &) + FUNC3(shader_set_default_texture_param, RID, const StringName &, RID) + FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &) + FUNC2RC(Variant, shader_get_param_default, RID, const StringName &) - BIND1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) + FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) /* COMMON MATERIAL API */ - BIND0R(RID, material_create) + FUNCRIDSPLIT(material) - BIND2(material_set_shader, RID, RID) + FUNC2(material_set_shader, RID, RID) - BIND3(material_set_param, RID, const StringName &, const Variant &) - BIND2RC(Variant, material_get_param, RID, const StringName &) + FUNC3(material_set_param, RID, const StringName &, const Variant &) + FUNC2RC(Variant, material_get_param, RID, const StringName &) - BIND2(material_set_render_priority, RID, int) - BIND2(material_set_next_pass, RID, RID) + FUNC2(material_set_render_priority, RID, int) + FUNC2(material_set_next_pass, RID, RID) /* MESH API */ - virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) { - RID mesh = mesh_create(); - mesh_set_blend_shape_count(mesh, p_blend_shape_count); - for (int i = 0; i < p_surfaces.size(); i++) { - mesh_add_surface(mesh, p_surfaces[i]); + virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) override { + RID mesh = RSG::storage->mesh_allocate(); + + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { + if (Thread::get_caller_id() == server_thread) { + command_queue.flush_if_pending(); + } + RSG::storage->mesh_initialize(mesh); + RSG::storage->mesh_set_blend_shape_count(mesh, p_blend_shape_count); + for (int i = 0; i < p_surfaces.size(); i++) { + RSG::storage->mesh_add_surface(mesh, p_surfaces[i]); + } + } else { + command_queue.push(RSG::storage, &RendererStorage::mesh_initialize, mesh); + command_queue.push(RSG::storage, &RendererStorage::mesh_set_blend_shape_count, mesh, p_blend_shape_count); + for (int i = 0; i < p_surfaces.size(); i++) { + RSG::storage->mesh_add_surface(mesh, p_surfaces[i]); + command_queue.push(RSG::storage, &RendererStorage::mesh_add_surface, mesh, p_surfaces[i]); + } } + return mesh; } - BIND2(mesh_set_blend_shape_count, RID, int) + FUNC2(mesh_set_blend_shape_count, RID, int) - BIND0R(RID, mesh_create) + FUNCRIDSPLIT(mesh) - BIND2(mesh_add_surface, RID, const SurfaceData &) + FUNC2(mesh_add_surface, RID, const SurfaceData &) - BIND1RC(int, mesh_get_blend_shape_count, RID) + FUNC1RC(int, mesh_get_blend_shape_count, RID) - BIND2(mesh_set_blend_shape_mode, RID, BlendShapeMode) - BIND1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) + FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) + FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) - BIND4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) + FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) - BIND3(mesh_surface_set_material, RID, int, RID) - BIND2RC(RID, mesh_surface_get_material, RID, int) + FUNC3(mesh_surface_set_material, RID, int, RID) + FUNC2RC(RID, mesh_surface_get_material, RID, int) - BIND2RC(SurfaceData, mesh_get_surface, RID, int) + FUNC2RC(SurfaceData, mesh_get_surface, RID, int) - BIND1RC(int, mesh_get_surface_count, RID) + FUNC1RC(int, mesh_get_surface_count, RID) - BIND2(mesh_set_custom_aabb, RID, const AABB &) - BIND1RC(AABB, mesh_get_custom_aabb, RID) + FUNC2(mesh_set_custom_aabb, RID, const AABB &) + FUNC1RC(AABB, mesh_get_custom_aabb, RID) - BIND1(mesh_clear, RID) + FUNC2(mesh_set_shadow_mesh, RID, RID) + + FUNC1(mesh_clear, RID) /* MULTIMESH API */ - BIND0R(RID, multimesh_create) + FUNCRIDSPLIT(multimesh) - BIND5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool) - BIND1RC(int, multimesh_get_instance_count, RID) + FUNC5(multimesh_allocate_data, RID, int, MultimeshTransformFormat, bool, bool) + FUNC1RC(int, multimesh_get_instance_count, RID) - BIND2(multimesh_set_mesh, RID, RID) - BIND3(multimesh_instance_set_transform, RID, int, const Transform &) - BIND3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) - BIND3(multimesh_instance_set_color, RID, int, const Color &) - BIND3(multimesh_instance_set_custom_data, RID, int, const Color &) + FUNC2(multimesh_set_mesh, RID, RID) + FUNC3(multimesh_instance_set_transform, RID, int, const Transform &) + FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) + FUNC3(multimesh_instance_set_color, RID, int, const Color &) + FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &) - BIND1RC(RID, multimesh_get_mesh, RID) - BIND1RC(AABB, multimesh_get_aabb, RID) + FUNC1RC(RID, multimesh_get_mesh, RID) + FUNC1RC(AABB, multimesh_get_aabb, RID) - BIND2RC(Transform, multimesh_instance_get_transform, RID, int) - BIND2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) - BIND2RC(Color, multimesh_instance_get_color, RID, int) - BIND2RC(Color, multimesh_instance_get_custom_data, RID, int) + FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) + FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) + FUNC2RC(Color, multimesh_instance_get_color, RID, int) + FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int) - BIND2(multimesh_set_buffer, RID, const Vector<float> &) - BIND1RC(Vector<float>, multimesh_get_buffer, RID) + FUNC2(multimesh_set_buffer, RID, const Vector<float> &) + FUNC1RC(Vector<float>, multimesh_get_buffer, RID) - BIND2(multimesh_set_visible_instances, RID, int) - BIND1RC(int, multimesh_get_visible_instances, RID) + FUNC2(multimesh_set_visible_instances, RID, int) + FUNC1RC(int, multimesh_get_visible_instances, RID) /* IMMEDIATE API */ - BIND0R(RID, immediate_create) - BIND3(immediate_begin, RID, PrimitiveType, RID) - BIND2(immediate_vertex, RID, const Vector3 &) - BIND2(immediate_normal, RID, const Vector3 &) - BIND2(immediate_tangent, RID, const Plane &) - BIND2(immediate_color, RID, const Color &) - BIND2(immediate_uv, RID, const Vector2 &) - BIND2(immediate_uv2, RID, const Vector2 &) - BIND1(immediate_end, RID) - BIND1(immediate_clear, RID) - BIND2(immediate_set_material, RID, RID) - BIND1RC(RID, immediate_get_material, RID) + FUNCRIDSPLIT(immediate) + FUNC3(immediate_begin, RID, PrimitiveType, RID) + FUNC2(immediate_vertex, RID, const Vector3 &) + FUNC2(immediate_normal, RID, const Vector3 &) + FUNC2(immediate_tangent, RID, const Plane &) + FUNC2(immediate_color, RID, const Color &) + FUNC2(immediate_uv, RID, const Vector2 &) + FUNC2(immediate_uv2, RID, const Vector2 &) + FUNC1(immediate_end, RID) + FUNC1(immediate_clear, RID) + FUNC2(immediate_set_material, RID, RID) + FUNC1RC(RID, immediate_get_material, RID) /* SKELETON API */ - BIND0R(RID, skeleton_create) - BIND3(skeleton_allocate, RID, int, bool) - BIND1RC(int, skeleton_get_bone_count, RID) - BIND3(skeleton_bone_set_transform, RID, int, const Transform &) - BIND2RC(Transform, skeleton_bone_get_transform, RID, int) - BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) - BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) - BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &) + FUNCRIDSPLIT(skeleton) + FUNC3(skeleton_allocate_data, RID, int, bool) + FUNC1RC(int, skeleton_get_bone_count, RID) + FUNC3(skeleton_bone_set_transform, RID, int, const Transform &) + FUNC2RC(Transform, skeleton_bone_get_transform, RID, int) + FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) + FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) + FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &) /* Light API */ - BIND0R(RID, directional_light_create) - BIND0R(RID, omni_light_create) - BIND0R(RID, spot_light_create) + FUNCRIDSPLIT(directional_light) + FUNCRIDSPLIT(omni_light) + FUNCRIDSPLIT(spot_light) - BIND2(light_set_color, RID, const Color &) - BIND3(light_set_param, RID, LightParam, float) - BIND2(light_set_shadow, RID, bool) - BIND2(light_set_shadow_color, RID, const Color &) - BIND2(light_set_projector, RID, RID) - BIND2(light_set_negative, RID, bool) - BIND2(light_set_cull_mask, RID, uint32_t) - BIND2(light_set_reverse_cull_face_mode, RID, bool) - BIND2(light_set_bake_mode, RID, LightBakeMode) - BIND2(light_set_max_sdfgi_cascade, RID, uint32_t) + FUNC2(light_set_color, RID, const Color &) + FUNC3(light_set_param, RID, LightParam, float) + FUNC2(light_set_shadow, RID, bool) + FUNC2(light_set_shadow_color, RID, const Color &) + FUNC2(light_set_projector, RID, RID) + FUNC2(light_set_negative, RID, bool) + FUNC2(light_set_cull_mask, RID, uint32_t) + FUNC2(light_set_reverse_cull_face_mode, RID, bool) + FUNC2(light_set_bake_mode, RID, LightBakeMode) + FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t) - BIND2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) + FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) - BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) - BIND2(light_directional_set_blend_splits, RID, bool) - BIND2(light_directional_set_sky_only, RID, bool) - BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) + FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) + FUNC2(light_directional_set_blend_splits, RID, bool) + FUNC2(light_directional_set_sky_only, RID, bool) + FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) /* PROBE API */ - BIND0R(RID, reflection_probe_create) - - BIND2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) - BIND2(reflection_probe_set_intensity, RID, float) - BIND2(reflection_probe_set_ambient_color, RID, const Color &) - BIND2(reflection_probe_set_ambient_energy, RID, float) - BIND2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode) - BIND2(reflection_probe_set_max_distance, RID, float) - BIND2(reflection_probe_set_extents, RID, const Vector3 &) - BIND2(reflection_probe_set_origin_offset, RID, const Vector3 &) - BIND2(reflection_probe_set_as_interior, RID, bool) - BIND2(reflection_probe_set_enable_box_projection, RID, bool) - BIND2(reflection_probe_set_enable_shadows, RID, bool) - BIND2(reflection_probe_set_cull_mask, RID, uint32_t) - BIND2(reflection_probe_set_resolution, RID, int) - BIND2(reflection_probe_set_lod_threshold, RID, float) + FUNCRIDSPLIT(reflection_probe) + + FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) + FUNC2(reflection_probe_set_intensity, RID, float) + FUNC2(reflection_probe_set_ambient_color, RID, const Color &) + FUNC2(reflection_probe_set_ambient_energy, RID, float) + FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode) + FUNC2(reflection_probe_set_max_distance, RID, float) + FUNC2(reflection_probe_set_extents, RID, const Vector3 &) + FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &) + FUNC2(reflection_probe_set_as_interior, RID, bool) + FUNC2(reflection_probe_set_enable_box_projection, RID, bool) + FUNC2(reflection_probe_set_enable_shadows, RID, bool) + FUNC2(reflection_probe_set_cull_mask, RID, uint32_t) + FUNC2(reflection_probe_set_resolution, RID, int) + FUNC2(reflection_probe_set_lod_threshold, RID, float) /* DECAL API */ - BIND0R(RID, decal_create) + FUNCRIDSPLIT(decal) - BIND2(decal_set_extents, RID, const Vector3 &) - BIND3(decal_set_texture, RID, DecalTexture, RID) - BIND2(decal_set_emission_energy, RID, float) - BIND2(decal_set_albedo_mix, RID, float) - BIND2(decal_set_modulate, RID, const Color &) - BIND2(decal_set_cull_mask, RID, uint32_t) - BIND4(decal_set_distance_fade, RID, bool, float, float) - BIND3(decal_set_fade, RID, float, float) - BIND2(decal_set_normal_fade, RID, float) + FUNC2(decal_set_extents, RID, const Vector3 &) + FUNC3(decal_set_texture, RID, DecalTexture, RID) + FUNC2(decal_set_emission_energy, RID, float) + FUNC2(decal_set_albedo_mix, RID, float) + FUNC2(decal_set_modulate, RID, const Color &) + FUNC2(decal_set_cull_mask, RID, uint32_t) + FUNC4(decal_set_distance_fade, RID, bool, float, float) + FUNC3(decal_set_fade, RID, float, float) + FUNC2(decal_set_normal_fade, RID, float) /* BAKED LIGHT API */ - BIND0R(RID, gi_probe_create) + FUNCRIDSPLIT(gi_probe) - BIND8(gi_probe_allocate, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) + FUNC8(gi_probe_allocate_data, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) - BIND1RC(AABB, gi_probe_get_bounds, RID) - BIND1RC(Vector3i, gi_probe_get_octree_size, RID) - BIND1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) - BIND1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) - BIND1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) - BIND1RC(Vector<int>, gi_probe_get_level_counts, RID) - BIND1RC(Transform, gi_probe_get_to_cell_xform, RID) + FUNC1RC(AABB, gi_probe_get_bounds, RID) + FUNC1RC(Vector3i, gi_probe_get_octree_size, RID) + FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) + FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) + FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) + FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID) + FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID) - BIND2(gi_probe_set_dynamic_range, RID, float) - BIND1RC(float, gi_probe_get_dynamic_range, RID) + FUNC2(gi_probe_set_dynamic_range, RID, float) + FUNC1RC(float, gi_probe_get_dynamic_range, RID) - BIND2(gi_probe_set_propagation, RID, float) - BIND1RC(float, gi_probe_get_propagation, RID) + FUNC2(gi_probe_set_propagation, RID, float) + FUNC1RC(float, gi_probe_get_propagation, RID) - BIND2(gi_probe_set_energy, RID, float) - BIND1RC(float, gi_probe_get_energy, RID) + FUNC2(gi_probe_set_energy, RID, float) + FUNC1RC(float, gi_probe_get_energy, RID) - BIND2(gi_probe_set_ao, RID, float) - BIND1RC(float, gi_probe_get_ao, RID) + FUNC2(gi_probe_set_ao, RID, float) + FUNC1RC(float, gi_probe_get_ao, RID) - BIND2(gi_probe_set_ao_size, RID, float) - BIND1RC(float, gi_probe_get_ao_size, RID) + FUNC2(gi_probe_set_ao_size, RID, float) + FUNC1RC(float, gi_probe_get_ao_size, RID) - BIND2(gi_probe_set_bias, RID, float) - BIND1RC(float, gi_probe_get_bias, RID) + FUNC2(gi_probe_set_bias, RID, float) + FUNC1RC(float, gi_probe_get_bias, RID) - BIND2(gi_probe_set_normal_bias, RID, float) - BIND1RC(float, gi_probe_get_normal_bias, RID) + FUNC2(gi_probe_set_normal_bias, RID, float) + FUNC1RC(float, gi_probe_get_normal_bias, RID) - BIND2(gi_probe_set_interior, RID, bool) - BIND1RC(bool, gi_probe_is_interior, RID) + FUNC2(gi_probe_set_interior, RID, bool) + FUNC1RC(bool, gi_probe_is_interior, RID) - BIND2(gi_probe_set_use_two_bounces, RID, bool) - BIND1RC(bool, gi_probe_is_using_two_bounces, RID) + FUNC2(gi_probe_set_use_two_bounces, RID, bool) + FUNC1RC(bool, gi_probe_is_using_two_bounces, RID) - BIND2(gi_probe_set_anisotropy_strength, RID, float) - BIND1RC(float, gi_probe_get_anisotropy_strength, RID) + FUNC2(gi_probe_set_anisotropy_strength, RID, float) + FUNC1RC(float, gi_probe_get_anisotropy_strength, RID) /* LIGHTMAP */ - BIND0R(RID, lightmap_create) + FUNCRIDSPLIT(lightmap) - BIND3(lightmap_set_textures, RID, RID, bool) - BIND2(lightmap_set_probe_bounds, RID, const AABB &) - BIND2(lightmap_set_probe_interior, RID, bool) - BIND5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) - BIND1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) - BIND1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) - BIND1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) - BIND1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) - BIND1(lightmap_set_probe_capture_update_speed, float) + FUNC3(lightmap_set_textures, RID, RID, bool) + FUNC2(lightmap_set_probe_bounds, RID, const AABB &) + FUNC2(lightmap_set_probe_interior, RID, bool) + FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) + FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) + FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) + FUNC1(lightmap_set_probe_capture_update_speed, float) /* PARTICLES */ - BIND0R(RID, particles_create) - - BIND2(particles_set_emitting, RID, bool) - BIND1R(bool, particles_get_emitting, RID) - BIND2(particles_set_amount, RID, int) - BIND2(particles_set_lifetime, RID, float) - BIND2(particles_set_one_shot, RID, bool) - BIND2(particles_set_pre_process_time, RID, float) - BIND2(particles_set_explosiveness_ratio, RID, float) - BIND2(particles_set_randomness_ratio, RID, float) - BIND2(particles_set_custom_aabb, RID, const AABB &) - BIND2(particles_set_speed_scale, RID, float) - BIND2(particles_set_use_local_coordinates, RID, bool) - BIND2(particles_set_process_material, RID, RID) - BIND2(particles_set_fixed_fps, RID, int) - BIND2(particles_set_fractional_delta, RID, bool) - BIND1R(bool, particles_is_inactive, RID) - BIND1(particles_request_process, RID) - BIND1(particles_restart, RID) - BIND6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) - BIND2(particles_set_subemitter, RID, RID) - BIND2(particles_set_collision_base_size, RID, float) - - BIND2(particles_set_draw_order, RID, RS::ParticlesDrawOrder) - - BIND2(particles_set_draw_passes, RID, int) - BIND3(particles_set_draw_pass_mesh, RID, int, RID) - - BIND1R(AABB, particles_get_current_aabb, RID) - BIND2(particles_set_emission_transform, RID, const Transform &) + FUNCRIDSPLIT(particles) + + FUNC2(particles_set_emitting, RID, bool) + FUNC1R(bool, particles_get_emitting, RID) + FUNC2(particles_set_amount, RID, int) + FUNC2(particles_set_lifetime, RID, float) + FUNC2(particles_set_one_shot, RID, bool) + FUNC2(particles_set_pre_process_time, RID, float) + FUNC2(particles_set_explosiveness_ratio, RID, float) + FUNC2(particles_set_randomness_ratio, RID, float) + FUNC2(particles_set_custom_aabb, RID, const AABB &) + FUNC2(particles_set_speed_scale, RID, float) + FUNC2(particles_set_use_local_coordinates, RID, bool) + FUNC2(particles_set_process_material, RID, RID) + FUNC2(particles_set_fixed_fps, RID, int) + FUNC2(particles_set_fractional_delta, RID, bool) + FUNC1R(bool, particles_is_inactive, RID) + FUNC1(particles_request_process, RID) + FUNC1(particles_restart, RID) + FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) + FUNC2(particles_set_subemitter, RID, RID) + FUNC2(particles_set_collision_base_size, RID, float) + + FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder) + + FUNC2(particles_set_draw_passes, RID, int) + FUNC3(particles_set_draw_pass_mesh, RID, int, RID) + + FUNC1R(AABB, particles_get_current_aabb, RID) + FUNC2(particles_set_emission_transform, RID, const Transform &) /* PARTICLES COLLISION */ - BIND0R(RID, particles_collision_create) - - BIND2(particles_collision_set_collision_type, RID, ParticlesCollisionType) - BIND2(particles_collision_set_cull_mask, RID, uint32_t) - BIND2(particles_collision_set_sphere_radius, RID, float) - BIND2(particles_collision_set_box_extents, RID, const Vector3 &) - BIND2(particles_collision_set_attractor_strength, RID, float) - BIND2(particles_collision_set_attractor_directionality, RID, float) - BIND2(particles_collision_set_attractor_attenuation, RID, float) - BIND2(particles_collision_set_field_texture, RID, RID) - BIND1(particles_collision_height_field_update, RID) - BIND2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution) - -#undef BINDBASE + FUNCRIDSPLIT(particles_collision) + + FUNC2(particles_collision_set_collision_type, RID, ParticlesCollisionType) + FUNC2(particles_collision_set_cull_mask, RID, uint32_t) + FUNC2(particles_collision_set_sphere_radius, RID, float) + FUNC2(particles_collision_set_box_extents, RID, const Vector3 &) + FUNC2(particles_collision_set_attractor_strength, RID, float) + FUNC2(particles_collision_set_attractor_directionality, RID, float) + FUNC2(particles_collision_set_attractor_attenuation, RID, float) + FUNC2(particles_collision_set_field_texture, RID, RID) + FUNC1(particles_collision_height_field_update, RID) + FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution) + +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::scene +#define ServerName RendererScene +#define server_name RSG::scene /* CAMERA API */ - BIND0R(RID, camera_create) - BIND4(camera_set_perspective, RID, float, float, float) - BIND4(camera_set_orthogonal, RID, float, float, float) - BIND5(camera_set_frustum, RID, float, Vector2, float, float) - BIND2(camera_set_transform, RID, const Transform &) - BIND2(camera_set_cull_mask, RID, uint32_t) - BIND2(camera_set_environment, RID, RID) - BIND2(camera_set_camera_effects, RID, RID) - BIND2(camera_set_use_vertical_aspect, RID, bool) - -#undef BINDBASE + FUNCRIDSPLIT(camera) + FUNC4(camera_set_perspective, RID, float, float, float) + FUNC4(camera_set_orthogonal, RID, float, float, float) + FUNC5(camera_set_frustum, RID, float, Vector2, float, float) + FUNC2(camera_set_transform, RID, const Transform &) + FUNC2(camera_set_cull_mask, RID, uint32_t) + FUNC2(camera_set_environment, RID, RID) + FUNC2(camera_set_camera_effects, RID, RID) + FUNC2(camera_set_use_vertical_aspect, RID, bool) + +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::viewport +#define ServerName RendererViewport +#define server_name RSG::viewport /* VIEWPORT TARGET API */ - BIND0R(RID, viewport_create) + FUNCRIDSPLIT(viewport) + + FUNC2(viewport_set_use_xr, RID, bool) + FUNC3(viewport_set_size, RID, int, int) - BIND2(viewport_set_use_xr, RID, bool) - BIND3(viewport_set_size, RID, int, int) + FUNC2(viewport_set_active, RID, bool) + FUNC2(viewport_set_parent_viewport, RID, RID) - BIND2(viewport_set_active, RID, bool) - BIND2(viewport_set_parent_viewport, RID, RID) + FUNC2(viewport_set_clear_mode, RID, ViewportClearMode) - BIND2(viewport_set_clear_mode, RID, ViewportClearMode) + FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int) + FUNC2(viewport_set_render_direct_to_screen, RID, bool) - BIND3(viewport_attach_to_screen, RID, const Rect2 &, int) - BIND2(viewport_set_render_direct_to_screen, RID, bool) + FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) - BIND2(viewport_set_update_mode, RID, ViewportUpdateMode) - BIND2(viewport_set_vflip, RID, bool) + FUNC1RC(RID, viewport_get_texture, RID) - BIND1RC(RID, viewport_get_texture, RID) + FUNC2(viewport_set_hide_scenario, RID, bool) + FUNC2(viewport_set_hide_canvas, RID, bool) + FUNC2(viewport_set_disable_environment, RID, bool) - BIND2(viewport_set_hide_scenario, RID, bool) - BIND2(viewport_set_hide_canvas, RID, bool) - BIND2(viewport_set_disable_environment, RID, bool) + FUNC2(viewport_attach_camera, RID, RID) + FUNC2(viewport_set_scenario, RID, RID) + FUNC2(viewport_attach_canvas, RID, RID) - BIND2(viewport_attach_camera, RID, RID) - BIND2(viewport_set_scenario, RID, RID) - BIND2(viewport_attach_canvas, RID, RID) + FUNC2(viewport_remove_canvas, RID, RID) + FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &) + FUNC2(viewport_set_transparent_background, RID, bool) + FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) + FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) - BIND2(viewport_remove_canvas, RID, RID) - BIND3(viewport_set_canvas_transform, RID, RID, const Transform2D &) - BIND2(viewport_set_transparent_background, RID, bool) - BIND2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) - BIND2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) + FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) + FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat) - BIND2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) - BIND2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat) + FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &) + FUNC4(viewport_set_canvas_stacking, RID, RID, int, int) + FUNC3(viewport_set_shadow_atlas_size, RID, int, bool) + FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) + FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) + FUNC2(viewport_set_msaa, RID, ViewportMSAA) + FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) + FUNC2(viewport_set_use_debanding, RID, bool) + FUNC2(viewport_set_lod_threshold, RID, float) - BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &) - BIND4(viewport_set_canvas_stacking, RID, RID, int, int) - BIND2(viewport_set_shadow_atlas_size, RID, int) - BIND3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) - BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) - BIND2(viewport_set_msaa, RID, ViewportMSAA) - BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) - BIND2(viewport_set_use_debanding, RID, bool) - BIND2(viewport_set_lod_threshold, RID, float) + FUNC2R(int, viewport_get_render_info, RID, ViewportRenderInfo) + FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw) - BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo) - BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw) + FUNC2(viewport_set_measure_render_time, RID, bool) + FUNC1RC(float, viewport_get_measured_render_time_cpu, RID) + FUNC1RC(float, viewport_get_measured_render_time_gpu, RID) - BIND2(viewport_set_measure_render_time, RID, bool) - BIND1RC(float, viewport_get_measured_render_time_cpu, RID) - BIND1RC(float, viewport_get_measured_render_time_gpu, RID) + FUNC1(call_set_use_vsync, bool) /* ENVIRONMENT API */ -#undef BINDBASE +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::scene +#define ServerName RendererScene +#define server_name RSG::scene - BIND1(directional_shadow_atlas_set_size, int) - BIND1(gi_probe_set_quality, GIProbeQuality) + FUNC2(directional_shadow_atlas_set_size, int, bool) + FUNC1(gi_probe_set_quality, GIProbeQuality) /* SKY API */ - BIND0R(RID, sky_create) - BIND2(sky_set_radiance_size, RID, int) - BIND2(sky_set_mode, RID, SkyMode) - BIND2(sky_set_material, RID, RID) - BIND4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) + FUNCRIDSPLIT(sky) + FUNC2(sky_set_radiance_size, RID, int) + FUNC2(sky_set_mode, RID, SkyMode) + FUNC2(sky_set_material, RID, RID) + FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) - BIND0R(RID, environment_create) + FUNCRIDSPLIT(environment) - BIND2(environment_set_background, RID, EnvironmentBG) - BIND2(environment_set_sky, RID, RID) - BIND2(environment_set_sky_custom_fov, RID, float) - BIND2(environment_set_sky_orientation, RID, const Basis &) - BIND2(environment_set_bg_color, RID, const Color &) - BIND2(environment_set_bg_energy, RID, float) - BIND2(environment_set_canvas_max_layer, RID, int) - BIND7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &) + FUNC2(environment_set_background, RID, EnvironmentBG) + FUNC2(environment_set_sky, RID, RID) + FUNC2(environment_set_sky_custom_fov, RID, float) + FUNC2(environment_set_sky_orientation, RID, const Basis &) + FUNC2(environment_set_bg_color, RID, const Color &) + FUNC2(environment_set_bg_energy, RID, float) + FUNC2(environment_set_canvas_max_layer, RID, int) + FUNC7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &) // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 - BIND2(environment_set_camera_feed_id, RID, int) + FUNC2(environment_set_camera_feed_id, RID, int) #endif - BIND6(environment_set_ssr, RID, bool, int, float, float, float) - BIND1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) + FUNC6(environment_set_ssr, RID, bool, int, float, float, float) + FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) - BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) - BIND6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float) + FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) + FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float) - BIND11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) - BIND1(environment_glow_set_use_bicubic_upscale, bool) - BIND1(environment_glow_set_use_high_quality, bool) + FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) + FUNC1(environment_glow_set_use_bicubic_upscale, bool) + FUNC1(environment_glow_set_use_high_quality, bool) - BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) + FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) - BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) - BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - BIND9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter) + FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) + FUNC10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) - BIND2(environment_set_volumetric_fog_volume_size, int, int) - BIND1(environment_set_volumetric_fog_filter_active, bool) - BIND1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - BIND1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) + FUNC2(environment_set_volumetric_fog_volume_size, int, int) + FUNC1(environment_set_volumetric_fog_filter_active, bool) - BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) - BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) - BIND1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) + FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, float, bool, float, float, float) + FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) + FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) + FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight) - BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) - BIND3(screen_space_roughness_limiter_set_active, bool, float, float) - BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) - BIND2(sub_surface_scattering_set_scale, float, float) + FUNC3(screen_space_roughness_limiter_set_active, bool, float, float) + FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) + FUNC2(sub_surface_scattering_set_scale, float, float) /* CAMERA EFFECTS */ - BIND0R(RID, camera_effects_create) + FUNCRIDSPLIT(camera_effects) - BIND2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) - BIND1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) + FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) + FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) - BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) - BIND3(camera_effects_set_custom_exposure, RID, bool, float) + FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) + FUNC3(camera_effects_set_custom_exposure, RID, bool, float) - BIND1(shadows_quality_set, ShadowQuality); - BIND1(directional_shadow_quality_set, ShadowQuality); + FUNC1(shadows_quality_set, ShadowQuality); + FUNC1(directional_shadow_quality_set, ShadowQuality); /* SCENARIO API */ -#undef BINDBASE -#define BINDBASE RSG::scene +#undef server_name +#undef ServerName - BIND0R(RID, scenario_create) +#define ServerName RendererScene +#define server_name RSG::scene - BIND2(scenario_set_debug, RID, ScenarioDebugMode) - BIND2(scenario_set_environment, RID, RID) - BIND2(scenario_set_camera_effects, RID, RID) - BIND2(scenario_set_fallback_environment, RID, RID) + FUNCRIDSPLIT(scenario) + + FUNC2(scenario_set_debug, RID, ScenarioDebugMode) + FUNC2(scenario_set_environment, RID, RID) + FUNC2(scenario_set_camera_effects, RID, RID) + FUNC2(scenario_set_fallback_environment, RID, RID) /* INSTANCING API */ - BIND0R(RID, instance_create) + FUNCRIDSPLIT(instance) - BIND2(instance_set_base, RID, RID) - BIND2(instance_set_scenario, RID, RID) - BIND2(instance_set_layer_mask, RID, uint32_t) - BIND2(instance_set_transform, RID, const Transform &) - BIND2(instance_attach_object_instance_id, RID, ObjectID) - BIND3(instance_set_blend_shape_weight, RID, int, float) - BIND3(instance_set_surface_material, RID, int, RID) - BIND2(instance_set_visible, RID, bool) + FUNC2(instance_set_base, RID, RID) + FUNC2(instance_set_scenario, RID, RID) + FUNC2(instance_set_layer_mask, RID, uint32_t) + FUNC2(instance_set_transform, RID, const Transform &) + FUNC2(instance_attach_object_instance_id, RID, ObjectID) + FUNC3(instance_set_blend_shape_weight, RID, int, float) + FUNC3(instance_set_surface_material, RID, int, RID) + FUNC2(instance_set_visible, RID, bool) - BIND2(instance_set_custom_aabb, RID, AABB) + FUNC2(instance_set_custom_aabb, RID, AABB) - BIND2(instance_attach_skeleton, RID, RID) - BIND2(instance_set_exterior, RID, bool) + FUNC2(instance_attach_skeleton, RID, RID) + FUNC2(instance_set_exterior, RID, bool) - BIND2(instance_set_extra_visibility_margin, RID, real_t) + FUNC2(instance_set_extra_visibility_margin, RID, real_t) // don't use these in a game! - BIND2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) - BIND3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) - BIND2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) + FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) + FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) + FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) + + FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool) + FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting) + FUNC2(instance_geometry_set_material_override, RID, RID) - BIND3(instance_geometry_set_flag, RID, InstanceFlags, bool) - BIND2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting) - BIND2(instance_geometry_set_material_override, RID, RID) + FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) + FUNC2(instance_geometry_set_as_instance_lod, RID, RID) + FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) + FUNC2(instance_geometry_set_lod_bias, RID, float) - BIND5(instance_geometry_set_draw_range, RID, float, float, float, float) - BIND2(instance_geometry_set_as_instance_lod, RID, RID) - BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) - BIND2(instance_geometry_set_lod_bias, RID, float) + FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) + FUNC2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) - BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) - BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) - BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) - BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) - BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + FUNC1(gi_set_use_half_resolution, bool) -#undef BINDBASE +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::canvas +#define ServerName RendererCanvasCull +#define server_name RSG::canvas /* CANVAS (2D) */ - BIND0R(RID, canvas_create) - BIND3(canvas_set_item_mirroring, RID, RID, const Point2 &) - BIND2(canvas_set_modulate, RID, const Color &) - BIND3(canvas_set_parent, RID, RID, float) - BIND1(canvas_set_disable_scale, bool) - - BIND0R(RID, canvas_texture_create) - BIND3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID) - BIND3(canvas_texture_set_shading_parameters, RID, const Color &, float) - - BIND2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter) - BIND2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat) - - BIND0R(RID, canvas_item_create) - BIND2(canvas_item_set_parent, RID, RID) - - BIND2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter) - BIND2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat) - - BIND2(canvas_item_set_visible, RID, bool) - BIND2(canvas_item_set_light_mask, RID, int) - - BIND2(canvas_item_set_update_when_visible, RID, bool) - - BIND2(canvas_item_set_transform, RID, const Transform2D &) - BIND2(canvas_item_set_clip, RID, bool) - BIND2(canvas_item_set_distance_field_mode, RID, bool) - BIND3(canvas_item_set_custom_rect, RID, bool, const Rect2 &) - BIND2(canvas_item_set_modulate, RID, const Color &) - BIND2(canvas_item_set_self_modulate, RID, const Color &) - - BIND2(canvas_item_set_draw_behind_parent, RID, bool) - - BIND5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float) - BIND5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) - BIND4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) - BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &) - BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) - BIND6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) - BIND7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) - BIND10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &) - BIND6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float) - BIND5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID) - BIND9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int) - BIND5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID) - BIND3(canvas_item_add_multimesh, RID, RID, RID) - BIND3(canvas_item_add_particles, RID, RID, RID) - BIND2(canvas_item_add_set_transform, RID, const Transform2D &) - BIND2(canvas_item_add_clip_ignore, RID, bool) - BIND2(canvas_item_set_sort_children_by_y, RID, bool) - BIND2(canvas_item_set_z_index, RID, int) - BIND2(canvas_item_set_z_as_relative_to_parent, RID, bool) - BIND3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) - BIND2(canvas_item_attach_skeleton, RID, RID) - - BIND1(canvas_item_clear, RID) - BIND2(canvas_item_set_draw_index, RID, int) - - BIND2(canvas_item_set_material, RID, RID) - - BIND2(canvas_item_set_use_parent_material, RID, bool) - - BIND6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) - - BIND0R(RID, canvas_light_create) - - BIND2(canvas_light_set_mode, RID, CanvasLightMode) - - BIND2(canvas_light_attach_to_canvas, RID, RID) - BIND2(canvas_light_set_enabled, RID, bool) - BIND2(canvas_light_set_texture_scale, RID, float) - BIND2(canvas_light_set_transform, RID, const Transform2D &) - BIND2(canvas_light_set_texture, RID, RID) - BIND2(canvas_light_set_texture_offset, RID, const Vector2 &) - BIND2(canvas_light_set_color, RID, const Color &) - BIND2(canvas_light_set_height, RID, float) - BIND2(canvas_light_set_energy, RID, float) - BIND3(canvas_light_set_z_range, RID, int, int) - BIND3(canvas_light_set_layer_range, RID, int, int) - BIND2(canvas_light_set_item_cull_mask, RID, int) - BIND2(canvas_light_set_item_shadow_cull_mask, RID, int) - BIND2(canvas_light_set_directional_distance, RID, float) - - BIND2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) - - BIND2(canvas_light_set_shadow_enabled, RID, bool) - BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) - BIND2(canvas_light_set_shadow_color, RID, const Color &) - BIND2(canvas_light_set_shadow_smooth, RID, float) - - BIND0R(RID, canvas_light_occluder_create) - BIND2(canvas_light_occluder_attach_to_canvas, RID, RID) - BIND2(canvas_light_occluder_set_enabled, RID, bool) - BIND2(canvas_light_occluder_set_polygon, RID, RID) - BIND2(canvas_light_occluder_set_as_sdf_collision, RID, bool) - BIND2(canvas_light_occluder_set_transform, RID, const Transform2D &) - BIND2(canvas_light_occluder_set_light_mask, RID, int) - - BIND0R(RID, canvas_occluder_polygon_create) - BIND3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool) - - BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) - - BIND1(canvas_set_shadow_texture_size, int) + FUNCRIDSPLIT(canvas) + FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) + FUNC2(canvas_set_modulate, RID, const Color &) + FUNC3(canvas_set_parent, RID, RID, float) + FUNC1(canvas_set_disable_scale, bool) + + FUNCRIDSPLIT(canvas_texture) + FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID) + FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float) + + FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter) + FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat) + + FUNCRIDSPLIT(canvas_item) + FUNC2(canvas_item_set_parent, RID, RID) + + FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter) + FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat) + + FUNC2(canvas_item_set_visible, RID, bool) + FUNC2(canvas_item_set_light_mask, RID, int) + + FUNC2(canvas_item_set_update_when_visible, RID, bool) + + FUNC2(canvas_item_set_transform, RID, const Transform2D &) + FUNC2(canvas_item_set_clip, RID, bool) + FUNC2(canvas_item_set_distance_field_mode, RID, bool) + FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &) + FUNC2(canvas_item_set_modulate, RID, const Color &) + FUNC2(canvas_item_set_self_modulate, RID, const Color &) + + FUNC2(canvas_item_set_draw_behind_parent, RID, bool) + + FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float) + FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) + FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) + FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) + FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) + FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) + FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) + FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &) + FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float) + FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID) + FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int) + FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID) + FUNC3(canvas_item_add_multimesh, RID, RID, RID) + FUNC3(canvas_item_add_particles, RID, RID, RID) + FUNC2(canvas_item_add_set_transform, RID, const Transform2D &) + FUNC2(canvas_item_add_clip_ignore, RID, bool) + FUNC2(canvas_item_set_sort_children_by_y, RID, bool) + FUNC2(canvas_item_set_z_index, RID, int) + FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool) + FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) + FUNC2(canvas_item_attach_skeleton, RID, RID) + + FUNC1(canvas_item_clear, RID) + FUNC2(canvas_item_set_draw_index, RID, int) + + FUNC2(canvas_item_set_material, RID, RID) + + FUNC2(canvas_item_set_use_parent_material, RID, bool) + + FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) + + FUNCRIDSPLIT(canvas_light) + + FUNC2(canvas_light_set_mode, RID, CanvasLightMode) + + FUNC2(canvas_light_attach_to_canvas, RID, RID) + FUNC2(canvas_light_set_enabled, RID, bool) + FUNC2(canvas_light_set_texture_scale, RID, float) + FUNC2(canvas_light_set_transform, RID, const Transform2D &) + FUNC2(canvas_light_set_texture, RID, RID) + FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &) + FUNC2(canvas_light_set_color, RID, const Color &) + FUNC2(canvas_light_set_height, RID, float) + FUNC2(canvas_light_set_energy, RID, float) + FUNC3(canvas_light_set_z_range, RID, int, int) + FUNC3(canvas_light_set_layer_range, RID, int, int) + FUNC2(canvas_light_set_item_cull_mask, RID, int) + FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int) + FUNC2(canvas_light_set_directional_distance, RID, float) + + FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) + + FUNC2(canvas_light_set_shadow_enabled, RID, bool) + FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) + FUNC2(canvas_light_set_shadow_color, RID, const Color &) + FUNC2(canvas_light_set_shadow_smooth, RID, float) + + FUNCRIDSPLIT(canvas_light_occluder) + FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID) + FUNC2(canvas_light_occluder_set_enabled, RID, bool) + FUNC2(canvas_light_occluder_set_polygon, RID, RID) + FUNC2(canvas_light_occluder_set_as_sdf_collision, RID, bool) + FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &) + FUNC2(canvas_light_occluder_set_light_mask, RID, int) + + FUNCRIDSPLIT(canvas_occluder_polygon) + FUNC3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool) + + FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) + + FUNC1(canvas_set_shadow_texture_size, int) /* GLOBAL VARIABLES */ -#undef BINDBASE +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::storage +#define ServerName RendererStorage +#define server_name RSG::storage - BIND3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) - BIND1(global_variable_remove, const StringName &) - BIND0RC(Vector<StringName>, global_variable_get_list) - BIND2(global_variable_set, const StringName &, const Variant &) - BIND2(global_variable_set_override, const StringName &, const Variant &) - BIND1RC(GlobalVariableType, global_variable_get_type, const StringName &) - BIND1RC(Variant, global_variable_get, const StringName &) + FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) + FUNC1(global_variable_remove, const StringName &) + FUNC0RC(Vector<StringName>, global_variable_get_list) + FUNC2(global_variable_set, const StringName &, const Variant &) + FUNC2(global_variable_set_override, const StringName &, const Variant &) + FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &) + FUNC1RC(Variant, global_variable_get, const StringName &) - BIND1(global_variables_load_settings, bool) - BIND0(global_variables_clear) + FUNC1(global_variables_load_settings, bool) + FUNC0(global_variables_clear) + +#undef server_name +#undef ServerName +#undef WRITE_ACTION +#undef SYNC_DEBUG /* BLACK BARS */ - virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom); - virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom); + virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) override; + virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) override; /* FREE */ - virtual void free(RID p_rid); ///< free RIDs associated with the visual server + virtual void free(RID p_rid) override { + if (Thread::get_caller_id() == server_thread) { + command_queue.flush_if_pending(); + _free(p_rid); + } else { + command_queue.push(this, &RenderingServerDefault::_free, p_rid); + } + } /* EVENT QUEUING */ - virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata); + virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) override; - virtual void draw(bool p_swap_buffers, double frame_step); - virtual void sync(); - virtual bool has_changed() const; - virtual void init(); - virtual void finish(); + virtual void draw(bool p_swap_buffers, double frame_step) override; + virtual void sync() override; + virtual bool has_changed() const override; + virtual void init() override; + virtual void finish() override; /* STATUS INFORMATION */ - virtual int get_render_info(RenderInfo p_info); - virtual String get_video_adapter_name() const; - virtual String get_video_adapter_vendor() const; + virtual int get_render_info(RenderInfo p_info) override; + virtual String get_video_adapter_name() const override; + virtual String get_video_adapter_vendor() const override; - virtual void set_frame_profiling_enabled(bool p_enable); - virtual Vector<FrameProfileArea> get_frame_profile(); - virtual uint64_t get_frame_profile_frame(); + virtual void set_frame_profiling_enabled(bool p_enable) override; + virtual Vector<FrameProfileArea> get_frame_profile() override; + virtual uint64_t get_frame_profile_frame() override; - virtual RID get_test_cube(); + virtual RID get_test_cube() override; /* TESTING */ - virtual float get_frame_setup_time_cpu() const; + virtual float get_frame_setup_time_cpu() const override; - virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true); - virtual void set_default_clear_color(const Color &p_color); + virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override; + virtual void set_default_clear_color(const Color &p_color) override; - virtual bool has_feature(Features p_feature) const; + virtual bool has_feature(Features p_feature) const override; - virtual bool has_os_feature(const String &p_feature) const; - virtual void set_debug_generate_wireframes(bool p_generate); + virtual bool has_os_feature(const String &p_feature) const override; + virtual void set_debug_generate_wireframes(bool p_generate) override; - virtual void call_set_use_vsync(bool p_enable); + virtual bool is_low_end() const override; - virtual bool is_low_end() const; + virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override; - virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir); + virtual void set_print_gpu_profile(bool p_enable) override; - RenderingServerDefault(); + RenderingServerDefault(bool p_create_thread = false); ~RenderingServerDefault(); - -#undef DISPLAY_CHANGED - -#undef BIND0R -#undef BIND1RC -#undef BIND2RC -#undef BIND3RC -#undef BIND4RC - -#undef BIND1 -#undef BIND2 -#undef BIND3 -#undef BIND4 -#undef BIND5 -#undef BIND6 -#undef BIND7 -#undef BIND8 -#undef BIND9 -#undef BIND10 }; #endif diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp deleted file mode 100644 index 3572c4dc78..0000000000 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/*************************************************************************/ -/* rendering_server_wrap_mt.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "rendering_server_wrap_mt.h" -#include "core/config/project_settings.h" -#include "core/os/os.h" -#include "servers/display_server.h" - -void RenderingServerWrapMT::thread_exit() { - exit = true; -} - -void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) { - if (!atomic_decrement(&draw_pending)) { - rendering_server->draw(p_swap_buffers, frame_step); - } -} - -void RenderingServerWrapMT::thread_flush() { - atomic_decrement(&draw_pending); -} - -void RenderingServerWrapMT::_thread_callback(void *_instance) { - RenderingServerWrapMT *vsmt = reinterpret_cast<RenderingServerWrapMT *>(_instance); - - vsmt->thread_loop(); -} - -void RenderingServerWrapMT::thread_loop() { - server_thread = Thread::get_caller_id(); - - DisplayServer::get_singleton()->make_rendering_thread(); - - rendering_server->init(); - - exit = false; - draw_thread_up = true; - while (!exit) { - // flush commands one by one, until exit is requested - command_queue.wait_and_flush_one(); - } - - command_queue.flush_all(); // flush all - - rendering_server->finish(); -} - -/* EVENT QUEUING */ - -void RenderingServerWrapMT::sync() { - if (create_thread) { - atomic_increment(&draw_pending); - command_queue.push_and_sync(this, &RenderingServerWrapMT::thread_flush); - } else { - command_queue.flush_all(); //flush all pending from other threads - } -} - -void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) { - if (create_thread) { - atomic_increment(&draw_pending); - command_queue.push(this, &RenderingServerWrapMT::thread_draw, p_swap_buffers, frame_step); - } else { - rendering_server->draw(p_swap_buffers, frame_step); - } -} - -void RenderingServerWrapMT::init() { - if (create_thread) { - print_verbose("RenderingServerWrapMT: Creating render thread"); - DisplayServer::get_singleton()->release_rendering_thread(); - if (create_thread) { - thread = Thread::create(_thread_callback, this); - print_verbose("RenderingServerWrapMT: Starting render thread"); - } - while (!draw_thread_up) { - OS::get_singleton()->delay_usec(1000); - } - print_verbose("RenderingServerWrapMT: Finished render thread"); - } else { - rendering_server->init(); - } -} - -void RenderingServerWrapMT::finish() { - sky_free_cached_ids(); - shader_free_cached_ids(); - material_free_cached_ids(); - mesh_free_cached_ids(); - multimesh_free_cached_ids(); - immediate_free_cached_ids(); - skeleton_free_cached_ids(); - directional_light_free_cached_ids(); - omni_light_free_cached_ids(); - spot_light_free_cached_ids(); - reflection_probe_free_cached_ids(); - gi_probe_free_cached_ids(); - lightmap_free_cached_ids(); - particles_free_cached_ids(); - particles_collision_free_cached_ids(); - camera_free_cached_ids(); - viewport_free_cached_ids(); - environment_free_cached_ids(); - camera_effects_free_cached_ids(); - scenario_free_cached_ids(); - instance_free_cached_ids(); - canvas_free_cached_ids(); - canvas_item_free_cached_ids(); - canvas_light_occluder_free_cached_ids(); - canvas_occluder_polygon_free_cached_ids(); - - if (thread) { - command_queue.push(this, &RenderingServerWrapMT::thread_exit); - Thread::wait_to_finish(thread); - memdelete(thread); - - thread = nullptr; - } else { - rendering_server->finish(); - } -} - -void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { - singleton_mt->call_set_use_vsync(p_enable); -} - -RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr; - -RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) : - command_queue(p_create_thread) { - singleton_mt = this; - DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly - - rendering_server = p_contained; - create_thread = p_create_thread; - thread = nullptr; - draw_pending = 0; - draw_thread_up = false; - pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - - if (!p_create_thread) { - server_thread = Thread::get_caller_id(); - } else { - server_thread = 0; - } -} - -RenderingServerWrapMT::~RenderingServerWrapMT() { - memdelete(rendering_server); - //finish(); -} diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h deleted file mode 100644 index 3db90c32df..0000000000 --- a/servers/rendering/rendering_server_wrap_mt.h +++ /dev/null @@ -1,802 +0,0 @@ -/*************************************************************************/ -/* rendering_server_wrap_mt.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RENDERING_SERVER_WRAP_MT_H -#define RENDERING_SERVER_WRAP_MT_H - -#include "core/os/thread.h" -#include "core/templates/command_queue_mt.h" -#include "servers/rendering_server.h" - -class RenderingServerWrapMT : public RenderingServer { - // the real visual server - mutable RenderingServer *rendering_server; - - mutable CommandQueueMT command_queue; - - static void _thread_callback(void *_instance); - void thread_loop(); - - Thread::ID server_thread; - volatile bool exit; - Thread *thread; - volatile bool draw_thread_up; - bool create_thread; - - uint64_t draw_pending; - void thread_draw(bool p_swap_buffers, double frame_step); - void thread_flush(); - - void thread_exit(); - - Mutex alloc_mutex; - - int pool_max_size; - - //#define DEBUG_SYNC - - static RenderingServerWrapMT *singleton_mt; - -#ifdef DEBUG_SYNC -#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); -#else -#define SYNC_DEBUG -#endif - -public: -#define ServerName RenderingServer -#define ServerNameWrapMT RenderingServerWrapMT -#define server_name rendering_server -#include "servers/server_wrap_mt_common.h" - - //these go pass-through, as they can be called from any thread - virtual RID texture_2d_create(const Ref<Image> &p_image) { return rendering_server->texture_2d_create(p_image); } - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) { return rendering_server->texture_2d_layered_create(p_layers, p_layered_type); } - virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { return rendering_server->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); } - virtual RID texture_proxy_create(RID p_base) { return rendering_server->texture_proxy_create(p_base); } - - //goes pass-through - virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) { rendering_server->texture_2d_update_immediate(p_texture, p_image, p_layer); } - //these go through command queue if they are in another thread - FUNC3(texture_2d_update, RID, const Ref<Image> &, int) - FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &) - FUNC2(texture_proxy_update, RID, RID) - - //these also go pass-through - virtual RID texture_2d_placeholder_create() { return rendering_server->texture_2d_placeholder_create(); } - virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_type) { return rendering_server->texture_2d_layered_placeholder_create(p_type); } - virtual RID texture_3d_placeholder_create() { return rendering_server->texture_3d_placeholder_create(); } - - FUNC1RC(Ref<Image>, texture_2d_get, RID) - FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int) - FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID) - - FUNC2(texture_replace, RID, RID) - - FUNC3(texture_set_size_override, RID, int, int) -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - FUNC2(texture_bind, RID, uint32_t) -#endif - - FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) - FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) - FUNC3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *) - - FUNC2(texture_set_path, RID, const String &) - FUNC1RC(String, texture_get_path, RID) - FUNC1S(texture_debug_usage, List<TextureInfo> *) - - FUNC2(texture_set_force_redraw_if_visible, RID, bool) - - /* SHADER API */ - - FUNCRID(shader) - - FUNC2(shader_set_code, RID, const String &) - FUNC1RC(String, shader_get_code, RID) - - FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *) - - FUNC3(shader_set_default_texture_param, RID, const StringName &, RID) - FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &) - FUNC2RC(Variant, shader_get_param_default, RID, const StringName &) - - FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) - - /* COMMON MATERIAL API */ - - FUNCRID(material) - - FUNC2(material_set_shader, RID, RID) - - FUNC3(material_set_param, RID, const StringName &, const Variant &) - FUNC2RC(Variant, material_get_param, RID, const StringName &) - - FUNC2(material_set_render_priority, RID, int) - FUNC2(material_set_next_pass, RID, RID) - - /* MESH API */ - - virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) { - return rendering_server->mesh_create_from_surfaces(p_surfaces, p_blend_shape_count); - } - - FUNC2(mesh_set_blend_shape_count, RID, int) - - FUNCRID(mesh) - - FUNC2(mesh_add_surface, RID, const SurfaceData &) - - FUNC1RC(int, mesh_get_blend_shape_count, RID) - - FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) - FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) - - FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) - - FUNC3(mesh_surface_set_material, RID, int, RID) - FUNC2RC(RID, mesh_surface_get_material, RID, int) - - FUNC2RC(SurfaceData, mesh_get_surface, RID, int) - - FUNC1RC(int, mesh_get_surface_count, RID) - - FUNC2(mesh_set_custom_aabb, RID, const AABB &) - FUNC1RC(AABB, mesh_get_custom_aabb, RID) - - FUNC1(mesh_clear, RID) - - /* MULTIMESH API */ - - FUNCRID(multimesh) - - FUNC5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool) - FUNC1RC(int, multimesh_get_instance_count, RID) - - FUNC2(multimesh_set_mesh, RID, RID) - FUNC3(multimesh_instance_set_transform, RID, int, const Transform &) - FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) - FUNC3(multimesh_instance_set_color, RID, int, const Color &) - FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &) - - FUNC1RC(RID, multimesh_get_mesh, RID) - FUNC1RC(AABB, multimesh_get_aabb, RID) - - FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) - FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) - FUNC2RC(Color, multimesh_instance_get_color, RID, int) - FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int) - - FUNC2(multimesh_set_buffer, RID, const Vector<float> &) - FUNC1RC(Vector<float>, multimesh_get_buffer, RID) - - FUNC2(multimesh_set_visible_instances, RID, int) - FUNC1RC(int, multimesh_get_visible_instances, RID) - - /* IMMEDIATE API */ - - FUNCRID(immediate) - FUNC3(immediate_begin, RID, PrimitiveType, RID) - FUNC2(immediate_vertex, RID, const Vector3 &) - FUNC2(immediate_normal, RID, const Vector3 &) - FUNC2(immediate_tangent, RID, const Plane &) - FUNC2(immediate_color, RID, const Color &) - FUNC2(immediate_uv, RID, const Vector2 &) - FUNC2(immediate_uv2, RID, const Vector2 &) - FUNC1(immediate_end, RID) - FUNC1(immediate_clear, RID) - FUNC2(immediate_set_material, RID, RID) - FUNC1RC(RID, immediate_get_material, RID) - - /* SKELETON API */ - - FUNCRID(skeleton) - FUNC3(skeleton_allocate, RID, int, bool) - FUNC1RC(int, skeleton_get_bone_count, RID) - FUNC3(skeleton_bone_set_transform, RID, int, const Transform &) - FUNC2RC(Transform, skeleton_bone_get_transform, RID, int) - FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) - FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) - FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &) - - /* Light API */ - - FUNCRID(directional_light) - FUNCRID(omni_light) - FUNCRID(spot_light) - - FUNC2(light_set_color, RID, const Color &) - FUNC3(light_set_param, RID, LightParam, float) - FUNC2(light_set_shadow, RID, bool) - FUNC2(light_set_shadow_color, RID, const Color &) - FUNC2(light_set_projector, RID, RID) - FUNC2(light_set_negative, RID, bool) - FUNC2(light_set_cull_mask, RID, uint32_t) - FUNC2(light_set_reverse_cull_face_mode, RID, bool) - FUNC2(light_set_bake_mode, RID, LightBakeMode) - FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t) - - FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) - - FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) - FUNC2(light_directional_set_blend_splits, RID, bool) - FUNC2(light_directional_set_sky_only, RID, bool) - FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) - - /* PROBE API */ - - FUNCRID(reflection_probe) - - FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) - FUNC2(reflection_probe_set_intensity, RID, float) - FUNC2(reflection_probe_set_ambient_color, RID, const Color &) - FUNC2(reflection_probe_set_ambient_energy, RID, float) - FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode) - FUNC2(reflection_probe_set_max_distance, RID, float) - FUNC2(reflection_probe_set_extents, RID, const Vector3 &) - FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &) - FUNC2(reflection_probe_set_as_interior, RID, bool) - FUNC2(reflection_probe_set_enable_box_projection, RID, bool) - FUNC2(reflection_probe_set_enable_shadows, RID, bool) - FUNC2(reflection_probe_set_cull_mask, RID, uint32_t) - FUNC2(reflection_probe_set_resolution, RID, int) - FUNC2(reflection_probe_set_lod_threshold, RID, float) - - /* DECAL API */ - - FUNCRID(decal) - - FUNC2(decal_set_extents, RID, const Vector3 &) - FUNC3(decal_set_texture, RID, DecalTexture, RID) - FUNC2(decal_set_emission_energy, RID, float) - FUNC2(decal_set_albedo_mix, RID, float) - FUNC2(decal_set_modulate, RID, const Color &) - FUNC2(decal_set_cull_mask, RID, uint32_t) - FUNC4(decal_set_distance_fade, RID, bool, float, float) - FUNC3(decal_set_fade, RID, float, float) - FUNC2(decal_set_normal_fade, RID, float) - - /* BAKED LIGHT API */ - - FUNCRID(gi_probe) - - FUNC8(gi_probe_allocate, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) - - FUNC1RC(AABB, gi_probe_get_bounds, RID) - FUNC1RC(Vector3i, gi_probe_get_octree_size, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) - FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID) - FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID) - - FUNC2(gi_probe_set_dynamic_range, RID, float) - FUNC1RC(float, gi_probe_get_dynamic_range, RID) - - FUNC2(gi_probe_set_propagation, RID, float) - FUNC1RC(float, gi_probe_get_propagation, RID) - - FUNC2(gi_probe_set_energy, RID, float) - FUNC1RC(float, gi_probe_get_energy, RID) - - FUNC2(gi_probe_set_ao, RID, float) - FUNC1RC(float, gi_probe_get_ao, RID) - - FUNC2(gi_probe_set_ao_size, RID, float) - FUNC1RC(float, gi_probe_get_ao_size, RID) - - FUNC2(gi_probe_set_bias, RID, float) - FUNC1RC(float, gi_probe_get_bias, RID) - - FUNC2(gi_probe_set_normal_bias, RID, float) - FUNC1RC(float, gi_probe_get_normal_bias, RID) - - FUNC2(gi_probe_set_interior, RID, bool) - FUNC1RC(bool, gi_probe_is_interior, RID) - - FUNC2(gi_probe_set_use_two_bounces, RID, bool) - FUNC1RC(bool, gi_probe_is_using_two_bounces, RID) - - FUNC2(gi_probe_set_anisotropy_strength, RID, float) - FUNC1RC(float, gi_probe_get_anisotropy_strength, RID) - - FUNC1(gi_probe_set_quality, GIProbeQuality) - - /* LIGHTMAP CAPTURE */ - - FUNCRID(lightmap) - FUNC3(lightmap_set_textures, RID, RID, bool) - FUNC2(lightmap_set_probe_bounds, RID, const AABB &) - FUNC2(lightmap_set_probe_interior, RID, bool) - FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) - FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) - FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) - FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) - FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) - - FUNC1(lightmap_set_probe_capture_update_speed, float) - - /* PARTICLES */ - - FUNCRID(particles) - - FUNC2(particles_set_emitting, RID, bool) - FUNC1R(bool, particles_get_emitting, RID) - FUNC2(particles_set_amount, RID, int) - FUNC2(particles_set_lifetime, RID, float) - FUNC2(particles_set_one_shot, RID, bool) - FUNC2(particles_set_pre_process_time, RID, float) - FUNC2(particles_set_explosiveness_ratio, RID, float) - FUNC2(particles_set_randomness_ratio, RID, float) - FUNC2(particles_set_custom_aabb, RID, const AABB &) - FUNC2(particles_set_speed_scale, RID, float) - FUNC2(particles_set_use_local_coordinates, RID, bool) - FUNC2(particles_set_process_material, RID, RID) - FUNC2(particles_set_fixed_fps, RID, int) - FUNC2(particles_set_fractional_delta, RID, bool) - FUNC2(particles_set_collision_base_size, RID, float) - - FUNC1R(bool, particles_is_inactive, RID) - FUNC1(particles_request_process, RID) - FUNC1(particles_restart, RID) - - FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) - - FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder) - - FUNC2(particles_set_draw_passes, RID, int) - FUNC3(particles_set_draw_pass_mesh, RID, int, RID) - FUNC2(particles_set_emission_transform, RID, const Transform &) - FUNC2(particles_set_subemitter, RID, RID) - - FUNC1R(AABB, particles_get_current_aabb, RID) - - /* PARTICLES COLLISION */ - - FUNCRID(particles_collision) - - FUNC2(particles_collision_set_collision_type, RID, ParticlesCollisionType) - FUNC2(particles_collision_set_cull_mask, RID, uint32_t) - FUNC2(particles_collision_set_sphere_radius, RID, float) - FUNC2(particles_collision_set_box_extents, RID, const Vector3 &) - FUNC2(particles_collision_set_attractor_strength, RID, float) - FUNC2(particles_collision_set_attractor_directionality, RID, float) - FUNC2(particles_collision_set_attractor_attenuation, RID, float) - FUNC2(particles_collision_set_field_texture, RID, RID) - FUNC1(particles_collision_height_field_update, RID) - FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution) - - /* CAMERA API */ - - FUNCRID(camera) - FUNC4(camera_set_perspective, RID, float, float, float) - FUNC4(camera_set_orthogonal, RID, float, float, float) - FUNC5(camera_set_frustum, RID, float, Vector2, float, float) - FUNC2(camera_set_transform, RID, const Transform &) - FUNC2(camera_set_cull_mask, RID, uint32_t) - FUNC2(camera_set_environment, RID, RID) - FUNC2(camera_set_camera_effects, RID, RID) - FUNC2(camera_set_use_vertical_aspect, RID, bool) - - /* VIEWPORT TARGET API */ - - FUNCRID(viewport) - - FUNC2(viewport_set_use_xr, RID, bool) - - FUNC3(viewport_set_size, RID, int, int) - - FUNC2(viewport_set_active, RID, bool) - FUNC2(viewport_set_parent_viewport, RID, RID) - - FUNC2(viewport_set_clear_mode, RID, ViewportClearMode) - - FUNC3(viewport_attach_to_screen, RID, const Rect2 &, DisplayServer::WindowID) - FUNC2(viewport_set_render_direct_to_screen, RID, bool) - - FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) - - FUNC1RC(RID, viewport_get_texture, RID) - - FUNC2(viewport_set_hide_scenario, RID, bool) - FUNC2(viewport_set_hide_canvas, RID, bool) - FUNC2(viewport_set_disable_environment, RID, bool) - - FUNC2(viewport_attach_camera, RID, RID) - FUNC2(viewport_set_scenario, RID, RID) - FUNC2(viewport_attach_canvas, RID, RID) - - FUNC2(viewport_remove_canvas, RID, RID) - FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &) - FUNC2(viewport_set_transparent_background, RID, bool) - FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) - FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) - - FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) - FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat) - - FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &) - FUNC4(viewport_set_canvas_stacking, RID, RID, int, int) - FUNC2(viewport_set_shadow_atlas_size, RID, int) - FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) - - FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) - FUNC2(viewport_set_msaa, RID, ViewportMSAA) - FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) - FUNC2(viewport_set_use_debanding, RID, bool) - - FUNC2(viewport_set_lod_threshold, RID, float) - - //this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport - virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) { - return rendering_server->viewport_get_render_info(p_viewport, p_info); - } - - FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw) - - FUNC2(viewport_set_measure_render_time, RID, bool) - virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const { - return rendering_server->viewport_get_measured_render_time_cpu(p_viewport); - } - virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const { - return rendering_server->viewport_get_measured_render_time_gpu(p_viewport); - } - - FUNC1(directional_shadow_atlas_set_size, int) - - /* SKY API */ - - FUNCRID(sky) - FUNC2(sky_set_radiance_size, RID, int) - FUNC2(sky_set_mode, RID, SkyMode) - FUNC2(sky_set_material, RID, RID) - FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) - - /* ENVIRONMENT API */ - - FUNCRID(environment) - - FUNC2(environment_set_background, RID, EnvironmentBG) - FUNC2(environment_set_sky, RID, RID) - FUNC2(environment_set_sky_custom_fov, RID, float) - FUNC2(environment_set_sky_orientation, RID, const Basis &) - FUNC2(environment_set_bg_color, RID, const Color &) - FUNC2(environment_set_bg_energy, RID, float) - FUNC2(environment_set_canvas_max_layer, RID, int) - FUNC7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &) - -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - FUNC2(environment_set_camera_feed_id, RID, int) -#endif - FUNC6(environment_set_ssr, RID, bool, int, float, float, float) - FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) - - FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) - - FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float) - - FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) - FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) - FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) - - FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) - FUNC1(environment_glow_set_use_bicubic_upscale, bool) - FUNC1(environment_glow_set_use_high_quality, bool) - - FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) - - FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) - - FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - - FUNC9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter) - - FUNC2(environment_set_volumetric_fog_volume_size, int, int) - FUNC1(environment_set_volumetric_fog_filter_active, bool) - FUNC1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - FUNC1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) - - FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) - - FUNC3(screen_space_roughness_limiter_set_active, bool, float, float) - FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) - FUNC2(sub_surface_scattering_set_scale, float, float) - - FUNCRID(camera_effects) - - FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) - FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) - - FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) - FUNC3(camera_effects_set_custom_exposure, RID, bool, float) - - FUNC1(shadows_quality_set, ShadowQuality); - FUNC1(directional_shadow_quality_set, ShadowQuality); - - FUNCRID(scenario) - - FUNC2(scenario_set_debug, RID, ScenarioDebugMode) - FUNC2(scenario_set_environment, RID, RID) - FUNC2(scenario_set_camera_effects, RID, RID) - FUNC2(scenario_set_fallback_environment, RID, RID) - - /* INSTANCING API */ - FUNCRID(instance) - - FUNC2(instance_set_base, RID, RID) - FUNC2(instance_set_scenario, RID, RID) - FUNC2(instance_set_layer_mask, RID, uint32_t) - FUNC2(instance_set_transform, RID, const Transform &) - FUNC2(instance_attach_object_instance_id, RID, ObjectID) - FUNC3(instance_set_blend_shape_weight, RID, int, float) - FUNC3(instance_set_surface_material, RID, int, RID) - FUNC2(instance_set_visible, RID, bool) - - FUNC2(instance_set_custom_aabb, RID, AABB) - - FUNC2(instance_attach_skeleton, RID, RID) - FUNC2(instance_set_exterior, RID, bool) - - FUNC2(instance_set_extra_visibility_margin, RID, real_t) - - // don't use these in a game! - FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) - FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) - FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) - - FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool) - FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting) - FUNC2(instance_geometry_set_material_override, RID, RID) - - FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) - FUNC2(instance_geometry_set_as_instance_lod, RID, RID) - FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) - FUNC2(instance_geometry_set_lod_bias, RID, float) - - FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) - FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) - FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) - FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) - - /* BAKE */ - - FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) - - /* CANVAS (2D) */ - - FUNCRID(canvas) - FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) - FUNC2(canvas_set_modulate, RID, const Color &) - FUNC3(canvas_set_parent, RID, RID, float) - FUNC1(canvas_set_disable_scale, bool) - - FUNCRID(canvas_texture) - FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID) - FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float) - - FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter) - FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat) - - FUNCRID(canvas_item) - FUNC2(canvas_item_set_parent, RID, RID) - - FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter) - FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat) - - FUNC2(canvas_item_set_visible, RID, bool) - FUNC2(canvas_item_set_light_mask, RID, int) - - FUNC2(canvas_item_set_update_when_visible, RID, bool) - - FUNC2(canvas_item_set_transform, RID, const Transform2D &) - FUNC2(canvas_item_set_clip, RID, bool) - FUNC2(canvas_item_set_distance_field_mode, RID, bool) - FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &) - FUNC2(canvas_item_set_modulate, RID, const Color &) - FUNC2(canvas_item_set_self_modulate, RID, const Color &) - - FUNC2(canvas_item_set_draw_behind_parent, RID, bool) - - FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float) - FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) - FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) - FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) - FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) - FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) - FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) - FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &) - FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float) - FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID) - FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int) - FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID) - FUNC3(canvas_item_add_multimesh, RID, RID, RID) - FUNC3(canvas_item_add_particles, RID, RID, RID) - FUNC2(canvas_item_add_set_transform, RID, const Transform2D &) - FUNC2(canvas_item_add_clip_ignore, RID, bool) - FUNC2(canvas_item_set_sort_children_by_y, RID, bool) - FUNC2(canvas_item_set_z_index, RID, int) - FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool) - FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) - FUNC2(canvas_item_attach_skeleton, RID, RID) - - FUNC1(canvas_item_clear, RID) - FUNC2(canvas_item_set_draw_index, RID, int) - - FUNC2(canvas_item_set_material, RID, RID) - - FUNC2(canvas_item_set_use_parent_material, RID, bool) - - FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) - - FUNC0R(RID, canvas_light_create) - - FUNC2(canvas_light_set_mode, RID, CanvasLightMode) - - FUNC2(canvas_light_attach_to_canvas, RID, RID) - FUNC2(canvas_light_set_enabled, RID, bool) - FUNC2(canvas_light_set_texture_scale, RID, float) - FUNC2(canvas_light_set_transform, RID, const Transform2D &) - FUNC2(canvas_light_set_texture, RID, RID) - FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &) - FUNC2(canvas_light_set_color, RID, const Color &) - FUNC2(canvas_light_set_height, RID, float) - FUNC2(canvas_light_set_energy, RID, float) - FUNC3(canvas_light_set_z_range, RID, int, int) - FUNC3(canvas_light_set_layer_range, RID, int, int) - FUNC2(canvas_light_set_item_cull_mask, RID, int) - FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int) - FUNC2(canvas_light_set_directional_distance, RID, float) - - FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) - - FUNC2(canvas_light_set_shadow_enabled, RID, bool) - FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) - FUNC2(canvas_light_set_shadow_color, RID, const Color &) - FUNC2(canvas_light_set_shadow_smooth, RID, float) - - FUNCRID(canvas_light_occluder) - FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID) - FUNC2(canvas_light_occluder_set_enabled, RID, bool) - FUNC2(canvas_light_occluder_set_polygon, RID, RID) - FUNC2(canvas_light_occluder_set_as_sdf_collision, RID, bool) - FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &) - FUNC2(canvas_light_occluder_set_light_mask, RID, int) - - FUNCRID(canvas_occluder_polygon) - FUNC3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool) - - FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) - - FUNC1(canvas_set_shadow_texture_size, int) - - /* GLOBAL VARIABLES */ - - FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) - FUNC1(global_variable_remove, const StringName &) - FUNC0RC(Vector<StringName>, global_variable_get_list) - FUNC2(global_variable_set, const StringName &, const Variant &) - FUNC2(global_variable_set_override, const StringName &, const Variant &) - FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &) - FUNC1RC(Variant, global_variable_get, const StringName &) - FUNC1(global_variables_load_settings, bool) - FUNC0(global_variables_clear) - - /* BLACK BARS */ - - FUNC4(black_bars_set_margins, int, int, int, int) - FUNC4(black_bars_set_images, RID, RID, RID, RID) - - /* FREE */ - - FUNC1(free, RID) - - /* EVENT QUEUING */ - - FUNC3(request_frame_drawn_callback, Object *, const StringName &, const Variant &) - - virtual void init(); - virtual void finish(); - virtual void draw(bool p_swap_buffers, double frame_step); - virtual void sync(); - FUNC0RC(bool, has_changed) - - /* RENDER INFO */ - - //this passes directly to avoid stalling - virtual int get_render_info(RenderInfo p_info) { - return rendering_server->get_render_info(p_info); - } - - virtual String get_video_adapter_name() const { - return rendering_server->get_video_adapter_name(); - } - - virtual String get_video_adapter_vendor() const { - return rendering_server->get_video_adapter_vendor(); - } - - FUNC4(set_boot_image, const Ref<Image> &, const Color &, bool, bool) - FUNC1(set_default_clear_color, const Color &) - - FUNC0R(RID, get_test_cube) - - FUNC1(set_debug_generate_wireframes, bool) - - virtual bool has_feature(Features p_feature) const { - return rendering_server->has_feature(p_feature); - } - virtual bool has_os_feature(const String &p_feature) const { - return rendering_server->has_os_feature(p_feature); - } - - FUNC1(call_set_use_vsync, bool) - - static void set_use_vsync_callback(bool p_enable); - - virtual bool is_low_end() const { - return rendering_server->is_low_end(); - } - - virtual uint64_t get_frame_profile_frame() { - return rendering_server->get_frame_profile_frame(); - } - - virtual void set_frame_profiling_enabled(bool p_enabled) { - rendering_server->set_frame_profiling_enabled(p_enabled); - } - - virtual Vector<FrameProfileArea> get_frame_profile() { - return rendering_server->get_frame_profile(); - } - - virtual float get_frame_setup_time_cpu() const { - return rendering_server->get_frame_setup_time_cpu(); - } - - virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { - rendering_server->sdfgi_set_debug_probe_select(p_position, p_dir); - } - - RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread); - ~RenderingServerWrapMT(); - -#undef ServerName -#undef ServerNameWrapMT -#undef server_name -}; - -#ifdef DEBUG_SYNC -#undef DEBUG_SYNC -#endif -#undef SYNC_DEBUG - -#endif diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 0cb9220bb3..df1a7d58d0 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -558,13 +558,13 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_ERROR, "Invalid numeric constant"); } hexa_found = true; - } else if (GETCHAR(i) == 'e') { - if (hexa_found || exponent_found || float_suffix_found) { + } else if (GETCHAR(i) == 'e' && !hexa_found) { + if (exponent_found || float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); } exponent_found = true; - } else if (GETCHAR(i) == 'f') { - if (hexa_found || exponent_found) { + } else if (GETCHAR(i) == 'f' && !hexa_found) { + if (exponent_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); } float_suffix_found = true; @@ -643,7 +643,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { } if (hexa_found) { - tk.constant = (double)str.hex_to_int(true); + tk.constant = (double)str.hex_to_int(); } else { tk.constant = str.to_float(); } @@ -3102,6 +3102,72 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const { return false; } +bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) { + if (current_function == String("light")) { + *r_message = RTR("Varying may not be assigned in the 'light' function."); + return false; + } + switch (p_varying.stage) { + case ShaderNode::Varying::STAGE_UNKNOWN: // first assign + if (current_function == String("vertex")) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX; + } else if (current_function == String("fragment")) { + p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT; + } + break; + case ShaderNode::Varying::STAGE_VERTEX: + if (current_function == String("fragment")) { + *r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'."); + return false; + } + break; + case ShaderNode::Varying::STAGE_FRAGMENT: + if (current_function == String("vertex")) { + *r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'."); + return false; + } + break; + default: + break; + } + return true; +} + +bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, String *r_message) { + switch (p_varying.stage) { + case ShaderNode::Varying::STAGE_UNKNOWN: + *r_message = RTR("Varying must be assigned before using!"); + return false; + case ShaderNode::Varying::STAGE_VERTEX: + if (current_function == String("fragment")) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT; + } else if (current_function == String("light")) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT; + } + break; + case ShaderNode::Varying::STAGE_FRAGMENT: + if (current_function == String("light")) { + p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT; + } + break; + case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT: + if (current_function == String("light")) { + *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); + return false; + } + break; + case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT: + if (current_function == String("fragment")) { + *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); + return false; + } + break; + default: + break; + } + return true; +} + bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) { if (p_node->type == Node::TYPE_OPERATOR) { OperatorNode *op = static_cast<OperatorNode *>(p_node); @@ -3142,13 +3208,6 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi return false; } - if (shader->varyings.has(var->name) && current_function != String("vertex")) { - if (r_message) { - *r_message = RTR("Varyings can only be assigned in vertex function."); - } - return false; - } - if (shader->constants.has(var->name) || var->is_const) { if (r_message) { *r_message = RTR("Constants cannot be modified."); @@ -3169,13 +3228,6 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi return false; } - if (shader->varyings.has(arr->name) && current_function != String("vertex")) { - if (r_message) { - *r_message = RTR("Varyings can only be assigned in vertex function."); - } - return false; - } - return true; } @@ -3761,6 +3813,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Unknown identifier in expression: " + String(identifier)); return nullptr; } + if (ident_type == IDENTIFIER_VARYING) { + TkPos prev_pos = _get_tkpos(); + Token next_token = _get_token(); + _set_tkpos(prev_pos); + String error; + if (next_token.type == TK_OP_ASSIGN) { + if (!_validate_varying_assign(shader->varyings[identifier], &error)) { + _set_error(error); + return nullptr; + } + } else { + if (!_validate_varying_using(shader->varyings[identifier], &error)) { + _set_error(error); + return nullptr; + } + } + } last_const = is_const; if (ident_type == IDENTIFIER_FUNCTION) { @@ -3786,10 +3855,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Constants cannot be modified."); return nullptr; } - if (shader->varyings.has(identifier) && current_function != String("vertex")) { - _set_error("Varyings can only be assigned in vertex function."); - return nullptr; - } assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); if (!assign_expression) { return nullptr; @@ -5796,6 +5861,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_BUG; } + String return_struct_name = String(b->parent_function->return_struct_name); + ControlFlowNode *flow = alloc_node<ControlFlowNode>(); flow->flow_op = FLOW_OP_RETURN; @@ -5804,7 +5871,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (tk.type == TK_SEMICOLON) { //all is good if (b->parent_function->return_type != TYPE_VOID) { - _set_error("Expected return with expression of type '" + get_datatype_name(b->parent_function->return_type) + "'"); + _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'"); return ERR_PARSE_ERROR; } } else { @@ -5814,8 +5881,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } - if (b->parent_function->return_type != expr->get_datatype()) { - _set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'"); + if (b->parent_function->return_type != expr->get_datatype() || return_struct_name != expr->get_datatype_name()) { + _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'"); return ERR_PARSE_ERROR; } @@ -5859,15 +5926,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun pos = _get_tkpos(); tk = _get_token(); if (tk.type != TK_SEMICOLON) { - //all is good _set_error("Expected ';' after discard"); + return ERR_PARSE_ERROR; } p_block->statements.push_back(flow); } else if (tk.type == TK_CF_BREAK) { if (!p_can_break) { - //all is good - _set_error("Breaking is not allowed here"); + _set_error("'break' is not allowed outside of a loop or 'switch' statement"); + return ERR_PARSE_ERROR; } ControlFlowNode *flow = alloc_node<ControlFlowNode>(); @@ -5876,8 +5943,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun pos = _get_tkpos(); tk = _get_token(); if (tk.type != TK_SEMICOLON) { - //all is good _set_error("Expected ';' after break"); + return ERR_PARSE_ERROR; } p_block->statements.push_back(flow); @@ -5892,8 +5959,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } else if (tk.type == TK_CF_CONTINUE) { if (!p_can_continue) { - //all is good - _set_error("Continuing is not allowed here"); + _set_error("'continue' is not allowed outside of a loop"); + return ERR_PARSE_ERROR; } ControlFlowNode *flow = alloc_node<ControlFlowNode>(); @@ -5904,6 +5971,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (tk.type != TK_SEMICOLON) { //all is good _set_error("Expected ';' after continue"); + return ERR_PARSE_ERROR; } p_block->statements.push_back(flow); @@ -6068,6 +6136,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_IDENTIFIER) { st.name = tk.text; + if (shader->structs.has(st.name)) { + _set_error("Redefinition of '" + String(st.name) + "'"); + return ERR_PARSE_ERROR; + } tk = _get_token(); if (tk.type != TK_CURLY_BRACKET_OPEN) { _set_error("Expected '{'"); @@ -6260,6 +6332,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } + TkPos name_pos = _get_tkpos(); name = tk.text; if (_find_identifier(nullptr, false, FunctionInfo(), name)) { @@ -6305,7 +6378,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } uniform2.texture_order = -1; - uniform2.order = uniforms++; + if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) { + uniform2.order = uniforms++; + } } uniform2.type = type; uniform2.scope = uniform_scope; @@ -6539,11 +6614,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct _set_error("Expected ';'"); return ERR_PARSE_ERROR; } - } else { + } else { // varying ShaderNode::Varying varying; varying.type = type; varying.precision = precision; varying.interpolation = interpolation; + varying.tkpos = name_pos; tk = _get_token(); if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) { @@ -7156,6 +7232,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); } + for (Map<StringName, ShaderNode::Varying>::Element *E = shader->varyings.front(); E; E = E->next()) { + if (E->get().stage == ShaderNode::Varying::STAGE_VERTEX || E->get().stage == ShaderNode::Varying::STAGE_FRAGMENT) { + _set_tkpos(E->get().tkpos); + _set_error(RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'")); + return ERR_PARSE_ERROR; + } + } + return OK; } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 27767378f9..14594b039c 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -41,6 +41,11 @@ class ShaderLanguage { public: + struct TkPos { + int char_idx; + int tk_line; + }; + enum TokenType { TK_EMPTY, TK_IDENTIFIER, @@ -598,10 +603,21 @@ public: }; struct Varying { + enum Stage { + STAGE_UNKNOWN, + STAGE_VERTEX, // transition stage to STAGE_VERTEX_TO_FRAGMENT or STAGE_VERTEX_TO_LIGHT, emits error if they are not used + STAGE_FRAGMENT, // transition stage to STAGE_FRAGMENT_TO_LIGHT, emits error if it's not used + STAGE_VERTEX_TO_FRAGMENT, + STAGE_VERTEX_TO_LIGHT, + STAGE_FRAGMENT_TO_LIGHT, + }; + + Stage stage = STAGE_UNKNOWN; DataType type = TYPE_VOID; DataInterpolation interpolation = INTERPOLATION_FLAT; DataPrecision precision = PRECISION_DEFAULT; int array_size = 0; + TkPos tkpos; Varying() {} }; @@ -780,11 +796,6 @@ private: StringName current_function; bool last_const = false; - struct TkPos { - int char_idx; - int tk_line; - }; - TkPos _get_tkpos() { TkPos tkp; tkp.char_idx = char_idx; @@ -864,6 +875,8 @@ private: bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr); bool _propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat); bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin); + bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message); + bool _validate_varying_using(ShaderNode::Varying &p_varying, String *r_message); Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index c1fa4a8ca7..e99b8504bb 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -347,7 +347,7 @@ ShaderTypes::ShaderTypes() { emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("custom", ShaderLanguage::TYPE_VEC4)); emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("flags", ShaderLanguage::TYPE_UINT)); emit_vertex_func.return_type = ShaderLanguage::TYPE_BOOL; //whether it could emit - shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_particle"] = emit_vertex_func; + shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_subparticle"] = emit_vertex_func; } shader_modes[RS::SHADER_PARTICLES].modes.push_back("collision_use_scale"); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index b87171dc5e..809343114c 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -242,22 +242,24 @@ RID RenderingServer::_make_test_cube() { RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) { Vector<Vector3> vertices; Vector<Vector3> normals; + const double lat_step = Math_TAU / p_lats; + const double lon_step = Math_TAU / p_lons; for (int i = 1; i <= p_lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / p_lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = p_lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / p_lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); @@ -1487,7 +1489,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &RenderingServer::mesh_clear); ClassDB::bind_method(D_METHOD("multimesh_create"), &RenderingServer::multimesh_create); - ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("multimesh_allocate_data", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate_data, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &RenderingServer::multimesh_get_instance_count); ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &RenderingServer::multimesh_set_mesh); ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform", "multimesh", "index", "transform"), &RenderingServer::multimesh_instance_set_transform); @@ -1521,7 +1523,7 @@ void RenderingServer::_bind_methods() { #endif ClassDB::bind_method(D_METHOD("skeleton_create"), &RenderingServer::skeleton_create); - ClassDB::bind_method(D_METHOD("skeleton_allocate", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("skeleton_allocate_data", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate_data, DEFVAL(false)); ClassDB::bind_method(D_METHOD("skeleton_get_bone_count", "skeleton"), &RenderingServer::skeleton_get_bone_count); ClassDB::bind_method(D_METHOD("skeleton_bone_set_transform", "skeleton", "bone", "transform"), &RenderingServer::skeleton_bone_set_transform); ClassDB::bind_method(D_METHOD("skeleton_bone_get_transform", "skeleton", "bone"), &RenderingServer::skeleton_bone_get_transform); @@ -1661,7 +1663,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &RenderingServer::viewport_set_transparent_background); ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &RenderingServer::viewport_set_global_canvas_transform); ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &RenderingServer::viewport_set_canvas_stacking); - ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size); + ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_shadow_atlas_size, DEFVAL(false)); ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision); ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa); ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "enable"), &RenderingServer::viewport_set_use_debanding); @@ -2257,138 +2259,130 @@ RenderingServer::RenderingServer() { thread_pool = memnew(RendererThreadPool); singleton = this; - GLOBAL_DEF_RST("rendering/vram_compression/import_bptc", false); - GLOBAL_DEF_RST("rendering/vram_compression/import_s3tc", true); - GLOBAL_DEF_RST("rendering/vram_compression/import_etc", false); - GLOBAL_DEF_RST("rendering/vram_compression/import_etc2", true); - GLOBAL_DEF_RST("rendering/vram_compression/import_pvrtc", false); + GLOBAL_DEF_RST("rendering/textures/vram_compression/import_bptc", false); + GLOBAL_DEF_RST("rendering/textures/vram_compression/import_s3tc", true); + GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc", false); + GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc2", true); + GLOBAL_DEF_RST("rendering/textures/vram_compression/import_pvrtc", false); GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600); ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); - GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096); - GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384")); - GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2); - GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); - - GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2); - GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); - - GLOBAL_DEF("rendering/quality/2d_shadow_atlas/size", 2048); - - GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer", false); - GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer.mobile", true); - - GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096); - GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384")); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - - GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8); - GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true); - GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false); - GLOBAL_DEF("rendering/quality/reflections/ggx_samples", 1024); - GLOBAL_DEF("rendering/quality/reflections/ggx_samples.mobile", 128); - GLOBAL_DEF("rendering/quality/reflections/fast_filter_high_quality", false); - GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size", 256); - GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size.mobile", 128); - GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64); - - GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false); - GLOBAL_DEF("rendering/quality/gi_probes/quality", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)")); - - GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false); - GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true); - GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley", false); - GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley.mobile", true); - GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false); - GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true); - - GLOBAL_DEF("rendering/quality/depth_prepass/enable", true); - GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); - - GLOBAL_DEF("rendering/quality/texture_filters/use_nearest_mipmap_filter", false); - GLOBAL_DEF("rendering/quality/texture_filters/anisotropic_filtering_level", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/texture_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/quality/texture_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)")); - - GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)")); - GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)")); - GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_use_jitter", false); - - GLOBAL_DEF("rendering/quality/ssao/quality", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low (Fast),Medium (Average),High (Slow),Ultra (Custom)")); - GLOBAL_DEF("rendering/quality/ssao/half_size", false); - GLOBAL_DEF("rendering/quality/ssao/half_size.mobile", true); - GLOBAL_DEF("rendering/quality/ssao/adaptive_target", 0.5); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/adaptive_target", PropertyInfo(Variant::FLOAT, "rendering/quality/ssao/adaptive_target", PROPERTY_HINT_RANGE, "0.0,1.0,0.01")); - GLOBAL_DEF("rendering/quality/ssao/blur_passes", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/blur_passes", PropertyInfo(Variant::INT, "rendering/quality/ssao/blur_passes", PROPERTY_HINT_RANGE, "0,6")); - GLOBAL_DEF("rendering/quality/ssao/fadeout_from", 50.0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/fadeout_from", PropertyInfo(Variant::FLOAT, "rendering/quality/ssao/fadeout_from", PROPERTY_HINT_RANGE, "0.0,512,0.1,or_greater")); - GLOBAL_DEF("rendering/quality/ssao/fadeout_to", 300.0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/fadeout_to", PropertyInfo(Variant::FLOAT, "rendering/quality/ssao/fadeout_to", PROPERTY_HINT_RANGE, "64,65536,0.1,or_greater")); - - GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled", true); - GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_amount", 0.25); - GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_limit", 0.18); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_amount", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_amount", PROPERTY_HINT_RANGE, "0.01,4.0,0.01")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_limit", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_limit", PROPERTY_HINT_RANGE, "0.01,1.0,0.01")); - - GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)")); - GLOBAL_DEF("rendering/quality/glow/upscale_mode.mobile", 0); - GLOBAL_DEF("rendering/quality/glow/use_high_quality", false); - - GLOBAL_DEF("rendering/quality/screen_space_reflection/roughness_quality", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/quality/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); - - GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_quality", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/subsurface_scattering_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); - GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_scale", 0.05); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); - GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", 0.01); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); - - GLOBAL_DEF("rendering/high_end/global_shader_variables_buffer_size", 65536); - - GLOBAL_DEF("rendering/lightmapper/probe_capture_update_speed", 15); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapper/probe_capture_update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapper/probe_capture_update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001")); - - GLOBAL_DEF("rendering/sdfgi/probe_ray_count", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/probe_ray_count", PropertyInfo(Variant::INT, "rendering/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)")); - GLOBAL_DEF("rendering/sdfgi/frames_to_converge", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/frames_to_converge", PropertyInfo(Variant::INT, "rendering/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)")); - - GLOBAL_DEF("rendering/volumetric_fog/volume_size", 64); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1")); - GLOBAL_DEF("rendering/volumetric_fog/volume_depth", 128); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1")); - GLOBAL_DEF("rendering/volumetric_fog/use_filter", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)")); - GLOBAL_DEF("rendering/volumetric_fog/directional_shadow_shrink", 512); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/directional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/directional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1")); - GLOBAL_DEF("rendering/volumetric_fog/positional_shadow_shrink", 512); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/positional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/positional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1")); - - GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1")); - GLOBAL_DEF("rendering/spatial_indexer/threaded_cull_minimum_instances", 1000); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/threaded_cull_minimum_instances", PropertyInfo(Variant::INT, "rendering/spatial_indexer/threaded_cull_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1")); - GLOBAL_DEF("rendering/forward_renderer/threaded_render_minimum_instances", 500); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/forward_renderer/threaded_render_minimum_instances", PropertyInfo(Variant::INT, "rendering/forward_renderer/threaded_render_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1")); + GLOBAL_DEF("rendering/shadows/directional_shadow/size", 4096); + GLOBAL_DEF("rendering/shadows/directional_shadow/size.mobile", 2048); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384")); + GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 2); + GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality.mobile", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); + GLOBAL_DEF("rendering/shadows/directional_shadow/16_bits", true); + + GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 2); + GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality.mobile", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); + + GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048); + + GLOBAL_DEF("rendering/driver/rd_renderer/use_low_end_renderer", false); + GLOBAL_DEF("rendering/driver/rd_renderer/use_low_end_renderer.mobile", true); + + GLOBAL_DEF("rendering/reflections/sky_reflections/roughness_layers", 8); + GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections", true); + GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections.mobile", false); + GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples", 1024); + GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples.mobile", 128); + GLOBAL_DEF("rendering/reflections/sky_reflections/fast_filter_high_quality", false); + GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size", 256); + GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size.mobile", 128); + GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_count", 64); + + GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); + + GLOBAL_DEF("rendering/global_illumination/gi_probes/anisotropic", false); + GLOBAL_DEF("rendering/global_illumination/gi_probes/quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/global_illumination/gi_probes/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)")); + + GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading", false); + GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true); + GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley", false); + GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true); + GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx", false); + GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx.mobile", true); + + GLOBAL_DEF("rendering/driver/depth_prepass/enable", true); + GLOBAL_DEF("rendering/driver/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); + + GLOBAL_DEF("rendering/textures/default_filters/use_nearest_mipmap_filter", false); + GLOBAL_DEF("rendering/textures/default_filters/anisotropic_filtering_level", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/default_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/textures/default_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)")); + + GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_bokeh_shape", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/camera/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/camera/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)")); + GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_bokeh_quality", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/camera/depth_of_field/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/camera/depth_of_field/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)")); + GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_use_jitter", false); + + GLOBAL_DEF("rendering/environment/ssao/quality", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/quality", PropertyInfo(Variant::INT, "rendering/environment/ssao/quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low (Fast),Medium (Average),High (Slow),Ultra (Custom)")); + GLOBAL_DEF("rendering/environment/ssao/half_size", false); + GLOBAL_DEF("rendering/environment/ssao/half_size.mobile", true); + GLOBAL_DEF("rendering/environment/ssao/adaptive_target", 0.5); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/adaptive_target", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/adaptive_target", PROPERTY_HINT_RANGE, "0.0,1.0,0.01")); + GLOBAL_DEF("rendering/environment/ssao/blur_passes", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/blur_passes", PropertyInfo(Variant::INT, "rendering/environment/ssao/blur_passes", PROPERTY_HINT_RANGE, "0,6")); + GLOBAL_DEF("rendering/environment/ssao/fadeout_from", 50.0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/fadeout_from", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/fadeout_from", PROPERTY_HINT_RANGE, "0.0,512,0.1,or_greater")); + GLOBAL_DEF("rendering/environment/ssao/fadeout_to", 300.0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/fadeout_to", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/fadeout_to", PROPERTY_HINT_RANGE, "64,65536,0.1,or_greater")); + + GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/enabled", true); + GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/amount", 0.25); + GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/limit", 0.18); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/screen_space_roughness_limiter/amount", PropertyInfo(Variant::FLOAT, "rendering/anti_aliasing/screen_space_roughness_limiter/amount", PROPERTY_HINT_RANGE, "0.01,4.0,0.01")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/screen_space_roughness_limiter/limit", PropertyInfo(Variant::FLOAT, "rendering/anti_aliasing/screen_space_roughness_limiter/limit", PROPERTY_HINT_RANGE, "0.01,1.0,0.01")); + + GLOBAL_DEF("rendering/environment/glow/upscale_mode", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/environment/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)")); + GLOBAL_DEF("rendering/environment/glow/upscale_mode.mobile", 0); + GLOBAL_DEF("rendering/environment/glow/use_high_quality", false); + + GLOBAL_DEF("rendering/environment/screen_space_reflection/roughness_quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/environment/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); + + GLOBAL_DEF("rendering/environment/subsurface_scattering/subsurface_scattering_quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/subsurface_scattering/subsurface_scattering_quality", PropertyInfo(Variant::INT, "rendering/environment/subsurface_scattering/subsurface_scattering_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); + GLOBAL_DEF("rendering/environment/subsurface_scattering/subsurface_scattering_scale", 0.05); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/environment/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); + GLOBAL_DEF("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale", 0.01); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); + + GLOBAL_DEF("rendering/limits/global_shader_variables/buffer_size", 65536); + + GLOBAL_DEF("rendering/lightmapping/probe_capture/update_speed", 15); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapping/probe_capture/update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapping/probe_capture/update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001")); + + GLOBAL_DEF("rendering/global_illumination/sdfgi/probe_ray_count", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/probe_ray_count", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)")); + GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_converge", 4); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/frames_to_converge", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)")); + GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_update_lights", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/frames_to_update_lights", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_update_lights", PROPERTY_HINT_ENUM, "1 (Slower),2,4,8,16 (Faster)")); + + GLOBAL_DEF("rendering/environment/volumetric_fog/volume_size", 64); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/environment/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1")); + GLOBAL_DEF("rendering/environment/volumetric_fog/volume_depth", 128); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/environment/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1")); + GLOBAL_DEF("rendering/environment/volumetric_fog/use_filter", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/environment/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)")); + + GLOBAL_DEF("rendering/limits/spatial_indexer/update_iterations_per_frame", 10); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/limits/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1")); + GLOBAL_DEF("rendering/limits/spatial_indexer/threaded_cull_minimum_instances", 1000); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/spatial_indexer/threaded_cull_minimum_instances", PropertyInfo(Variant::INT, "rendering/limits/spatial_indexer/threaded_cull_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1")); + GLOBAL_DEF("rendering/limits/forward_renderer/threaded_render_minimum_instances", 500); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/forward_renderer/threaded_render_minimum_instances", PropertyInfo(Variant::INT, "rendering/limits/forward_renderer/threaded_render_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1")); + + GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1")); } RenderingServer::~RenderingServer() { diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 74bdb344bd..65065841a6 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -354,6 +354,8 @@ public: virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) = 0; + virtual void mesh_clear(RID p_mesh) = 0; /* MULTIMESH API */ @@ -365,7 +367,7 @@ public: MULTIMESH_TRANSFORM_3D, }; - virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; + virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; @@ -407,7 +409,7 @@ public: /* SKELETON API */ virtual RID skeleton_create() = 0; - virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; + virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; @@ -550,7 +552,7 @@ public: virtual RID gi_probe_create() = 0; - virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; @@ -798,7 +800,7 @@ public: virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0; - virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0; + virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false) = 0; virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0; enum ViewportMSAA { @@ -856,7 +858,10 @@ public: VIEWPORT_DEBUG_DRAW_SDFGI_PROBES, VIEWPORT_DEBUG_DRAW_GI_BUFFER, VIEWPORT_DEBUG_DRAW_DISABLE_LOD, - + VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS, + VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS, + VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS, + VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES, }; virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0; @@ -865,7 +870,7 @@ public: virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0; virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0; - virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; /* SKY API */ @@ -980,9 +985,10 @@ public: ENV_SDFGI_Y_SCALE_50_PERCENT }; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; enum EnvironmentSDFGIRayCount { + ENV_SDFGI_RAY_COUNT_4, ENV_SDFGI_RAY_COUNT_8, ENV_SDFGI_RAY_COUNT_16, ENV_SDFGI_RAY_COUNT_32, @@ -1006,20 +1012,22 @@ public: virtual void environment_set_sdfgi_frames_to_converge(EnvironmentSDFGIFramesToConverge p_frames) = 0; - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; - - enum EnvVolumetricFogShadowFilter { - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED, - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW, - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM, - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH, + enum EnvironmentSDFGIFramesToUpdateLight { + ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME, + ENV_SDFGI_UPDATE_LIGHT_IN_2_FRAMES, + ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES, + ENV_SDFGI_UPDATE_LIGHT_IN_8_FRAMES, + ENV_SDFGI_UPDATE_LIGHT_IN_16_FRAMES, + ENV_SDFGI_UPDATE_LIGHT_MAX, }; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + virtual void environment_set_sdfgi_frames_to_update_light(EnvironmentSDFGIFramesToUpdateLight p_update) = 0; + + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; + + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; @@ -1427,6 +1435,8 @@ public: virtual float get_frame_setup_time_cpu() const = 0; + virtual void gi_set_use_half_resolution(bool p_enable) = 0; + /* TESTING */ virtual RID get_test_cube() = 0; @@ -1459,6 +1469,8 @@ public: virtual bool is_low_end() const = 0; + virtual void set_print_gpu_profile(bool p_enable) = 0; + RenderingDevice *create_local_rendering_device() const; bool is_render_loop_enabled() const; diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index 5e18dc1e6d..95d2e2254e 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -29,245 +29,89 @@ /*************************************************************************/ #define FUNC0R(m_r, m_type) \ - virtual m_r m_type() { \ + virtual m_r m_type() override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(); \ } \ } -#define FUNCRID(m_type) \ - List<RID> m_type##_id_pool; \ - int m_type##allocn() { \ - for (int i = 0; i < pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - server_name->free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create() { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(); \ - } \ - } - -#define FUNC1RID(m_type, m_arg1) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1); \ - } \ - } - -#define FUNC2RID(m_type, m_arg1, m_arg2) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2); \ - } \ - } - -#define FUNC3RID(m_type, m_arg1, m_arg2, m_arg3) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2, p3); \ - } \ - } - -#define FUNC4RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2, p3, p4); \ - } \ +#define FUNCRIDSPLIT(m_type) \ + virtual RID m_type##_create() override { \ + RID ret = server_name->m_type##_allocate(); \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type##_initialize, ret); \ + } else { \ + server_name->m_type##_initialize(ret); \ + } \ + return ret; \ } -#define FUNC5RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - List<RID> m_type##_id_pool; \ - int m_type##allocn(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - for (int i = 0; i < pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create(p1, p2, p3, p4, p5)); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2, p3, p4, p5); \ - } \ +//RID now returns directly, ensure thread safety yourself +#define FUNCRID(m_type) \ + virtual RID m_type##_create() override { \ + return server_name->m_type##_create(); \ } #define FUNC0RC(m_r, m_type) \ - virtual m_r m_type() const { \ + virtual m_r m_type() const override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(); \ } \ } #define FUNC0(m_type) \ - virtual void m_type() { \ + virtual void m_type() override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } #define FUNC0C(m_type) \ - virtual void m_type() const { \ + virtual void m_type() const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } #define FUNC0S(m_type) \ - virtual void m_type() { \ + virtual void m_type() override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } #define FUNC0SC(m_type) \ - virtual void m_type() const { \ + virtual void m_type() const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } @@ -275,560 +119,646 @@ /////////////////////////////////////////////// #define FUNC1R(m_r, m_type, m_arg1) \ - virtual m_r m_type(m_arg1 p1) { \ + virtual m_r m_type(m_arg1 p1) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1); \ } \ } #define FUNC1RC(m_r, m_type, m_arg1) \ - virtual m_r m_type(m_arg1 p1) const { \ + virtual m_r m_type(m_arg1 p1) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1); \ } \ } #define FUNC1S(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) { \ + virtual void m_type(m_arg1 p1) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC1SC(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) const { \ + virtual void m_type(m_arg1 p1) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC1(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) { \ + virtual void m_type(m_arg1 p1) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC1C(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) const { \ + virtual void m_type(m_arg1 p1) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC2R(m_r, m_type, m_arg1, m_arg2) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2) { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2); \ } \ } #define FUNC2RC(m_r, m_type, m_arg1, m_arg2) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2); \ } \ } #define FUNC2S(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC2SC(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC2(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC2C(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC3R(m_r, m_type, m_arg1, m_arg2, m_arg3) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3RC(m_r, m_type, m_arg1, m_arg2, m_arg3) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3S(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3SC(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3C(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC4R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4S(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4); \ } \ } -#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \ - } else { \ - server_name->m_type(p1, p2, p3, p4); \ - } \ +#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4); \ + } \ } #define FUNC5R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4, p5); \ } \ } #define FUNC5RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4, p5); \ } \ } #define FUNC5S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4, p5); \ } \ } -#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } -#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } -#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } #define FUNC6R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4, p5, p6); \ } \ } -#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ + } + +#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ + } + +#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ } -#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ } -#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ } -#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ } -#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ - } - -#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ - } \ - } - -#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ - } \ - } - -#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ - } \ - } - -#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ - } \ - } - -#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ - } \ - } - -#define FUNC14(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ - } \ - } - -#define FUNC15(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14, m_arg15) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14, m_arg15 p15) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ - } \ +#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } \ + } + +#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } \ + } + +#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } \ + } + +#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } \ + } + +#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ + } \ + } + +#define FUNC14(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ + } \ + } + +#define FUNC15(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14, m_arg15) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14, m_arg15 p15) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ + } \ } diff --git a/servers/text_server.cpp b/servers/text_server.cpp index da68ceb128..d6d3c11cfb 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -219,6 +219,11 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("create_font_system", "name", "base_size"), &TextServer::create_font_system, DEFVAL(16)); ClassDB::bind_method(D_METHOD("create_font_resource", "filename", "base_size"), &TextServer::create_font_resource, DEFVAL(16)); ClassDB::bind_method(D_METHOD("create_font_memory", "data", "type", "base_size"), &TextServer::_create_font_memory, DEFVAL(16)); + ClassDB::bind_method(D_METHOD("create_font_bitmap", "height", "ascent", "base_size"), &TextServer::create_font_bitmap); + + ClassDB::bind_method(D_METHOD("font_bitmap_add_texture", "font", "texture"), &TextServer::font_bitmap_add_texture); + ClassDB::bind_method(D_METHOD("font_bitmap_add_char", "font", "char", "texture_idx", "rect", "align", "advance"), &TextServer::font_bitmap_add_char); + ClassDB::bind_method(D_METHOD("font_bitmap_add_kerning_pair", "font", "A", "B", "kerning"), &TextServer::font_bitmap_add_kerning_pair); ClassDB::bind_method(D_METHOD("font_get_height", "font", "size"), &TextServer::font_get_height); ClassDB::bind_method(D_METHOD("font_get_ascent", "font", "size"), &TextServer::font_get_ascent); @@ -227,6 +232,12 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_get_underline_position", "font", "size"), &TextServer::font_get_underline_position); ClassDB::bind_method(D_METHOD("font_get_underline_thickness", "font", "size"), &TextServer::font_get_underline_thickness); + ClassDB::bind_method(D_METHOD("font_get_spacing_space", "font"), &TextServer::font_get_spacing_space); + ClassDB::bind_method(D_METHOD("font_set_spacing_space", "font", "value"), &TextServer::font_set_spacing_space); + + ClassDB::bind_method(D_METHOD("font_get_spacing_glyph", "font"), &TextServer::font_get_spacing_glyph); + ClassDB::bind_method(D_METHOD("font_set_spacing_glyph", "font", "value"), &TextServer::font_set_spacing_glyph); + ClassDB::bind_method(D_METHOD("font_set_antialiased", "font", "antialiased"), &TextServer::font_set_antialiased); ClassDB::bind_method(D_METHOD("font_get_antialiased", "font"), &TextServer::font_get_antialiased); @@ -284,7 +295,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("create_shaped_text", "direction", "orientation"), &TextServer::create_shaped_text, DEFVAL(DIRECTION_AUTO), DEFVAL(ORIENTATION_HORIZONTAL)); - ClassDB::bind_method(D_METHOD("shaped_text_clear"), &TextServer::shaped_text_clear); + ClassDB::bind_method(D_METHOD("shaped_text_clear", "rid"), &TextServer::shaped_text_clear); ClassDB::bind_method(D_METHOD("shaped_text_set_direction", "shaped", "direction"), &TextServer::shaped_text_set_direction, DEFVAL(DIRECTION_AUTO)); ClassDB::bind_method(D_METHOD("shaped_text_get_direction", "shaped"), &TextServer::shaped_text_get_direction); diff --git a/servers/text_server.h b/servers/text_server.h index 23367de4c8..e1429da1d1 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -192,18 +192,6 @@ public: Vector<TextServer::Glyph> glyphs_logical; }; - struct BitmapFontData { - int height = 0; - int ascent = 0; - int charcount = 0; - const int *char_rects = nullptr; - int kerning_count = 0; - const int *kernings = nullptr; - int w = 0; - int h = 0; - const unsigned char *img = nullptr; - }; - protected: static void _bind_methods(); @@ -236,11 +224,22 @@ public: virtual RID create_font_system(const String &p_name, int p_base_size = 16) = 0; virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) = 0; virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) = 0; + virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) = 0; + + virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) = 0; + virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) = 0; + virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) = 0; virtual float font_get_height(RID p_font, int p_size) const = 0; virtual float font_get_ascent(RID p_font, int p_size) const = 0; virtual float font_get_descent(RID p_font, int p_size) const = 0; + virtual int font_get_spacing_space(RID p_font) const = 0; + virtual void font_set_spacing_space(RID p_font, int p_value) = 0; + + virtual int font_get_spacing_glyph(RID p_font) const = 0; + virtual void font_set_spacing_glyph(RID p_font, int p_value) = 0; + virtual float font_get_underline_position(RID p_font, int p_size) const = 0; virtual float font_get_underline_thickness(RID p_font, int p_size) const = 0; diff --git a/tests/data/images/icon.bmp b/tests/data/images/icon.bmp Binary files differnew file mode 100644 index 0000000000..e006f7ebdd --- /dev/null +++ b/tests/data/images/icon.bmp diff --git a/tests/data/images/icon.jpg b/tests/data/images/icon.jpg Binary files differnew file mode 100644 index 0000000000..b45bfa8d9b --- /dev/null +++ b/tests/data/images/icon.jpg diff --git a/tests/data/images/icon.png b/tests/data/images/icon.png Binary files differnew file mode 100644 index 0000000000..45aaaf584f --- /dev/null +++ b/tests/data/images/icon.png diff --git a/tests/data/images/icon.tga b/tests/data/images/icon.tga Binary files differnew file mode 100644 index 0000000000..dcacdc5c67 --- /dev/null +++ b/tests/data/images/icon.tga diff --git a/tests/data/images/icon.webp b/tests/data/images/icon.webp Binary files differnew file mode 100644 index 0000000000..6c4707e858 --- /dev/null +++ b/tests/data/images/icon.webp diff --git a/tests/test_array.h b/tests/test_array.h new file mode 100644 index 0000000000..52da256860 --- /dev/null +++ b/tests/test_array.h @@ -0,0 +1,186 @@ +/*************************************************************************/ +/* test_array.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_ARRAY_H +#define TEST_ARRAY_H + +#include "core/object/class_db.h" +#include "core/object/script_language.h" +#include "core/templates/hashfuncs.h" +#include "core/templates/vector.h" +#include "core/variant/array.h" +#include "core/variant/container_type_validate.h" +#include "core/variant/variant.h" +#include "tests/test_macros.h" + +namespace TestArray { + +TEST_CASE("[Array] size(), clear(), and is_empty()") { + Array arr; + CHECK(arr.size() == 0); + CHECK(arr.is_empty()); + arr.push_back(1); + CHECK(arr.size() == 1); + arr.clear(); + CHECK(arr.is_empty()); + CHECK(arr.size() == 0); +} + +TEST_CASE("[Array] Assignment and comparison operators") { + Array arr1; + Array arr2; + arr1.push_back(1); + CHECK(arr1 != arr2); + CHECK(arr1 > arr2); + CHECK(arr1 >= arr2); + arr2.push_back(2); + CHECK(arr1 != arr2); + CHECK(arr1 < arr2); + CHECK(arr1 <= arr2); + CHECK(arr2 > arr1); + CHECK(arr2 >= arr1); + Array arr3 = arr2; + CHECK(arr3 == arr2); +} + +TEST_CASE("[Array] append_array()") { + Array arr1; + Array arr2; + arr1.push_back(1); + arr1.append_array(arr2); + CHECK(arr1.size() == 1); + arr2.push_back(2); + arr1.append_array(arr2); + CHECK(arr1.size() == 2); + CHECK(int(arr1[0]) == 1); + CHECK(int(arr1[1]) == 2); +} + +TEST_CASE("[Array] resize(), insert(), and erase()") { + Array arr; + arr.resize(2); + CHECK(arr.size() == 2); + arr.insert(0, 1); + CHECK(int(arr[0]) == 1); + arr.insert(0, 2); + CHECK(int(arr[0]) == 2); + arr.erase(2); + CHECK(int(arr[0]) == 1); +} + +TEST_CASE("[Array] front() and back()") { + Array arr; + arr.push_back(1); + CHECK(int(arr.front()) == 1); + CHECK(int(arr.back()) == 1); + arr.push_back(3); + CHECK(int(arr.front()) == 1); + CHECK(int(arr.back()) == 3); +} + +TEST_CASE("[Array] has() and count()") { + Array arr; + arr.push_back(1); + arr.push_back(1); + CHECK(arr.has(1)); + CHECK(!arr.has(2)); + CHECK(arr.count(1) == 2); + CHECK(arr.count(2) == 0); +} + +TEST_CASE("[Array] remove()") { + Array arr; + arr.push_back(1); + arr.push_back(2); + arr.remove(0); + CHECK(arr.size() == 1); + CHECK(int(arr[0]) == 2); + arr.remove(0); + CHECK(arr.size() == 0); + + // The array is now empty; try to use `remove()` again. + // Normally, this prints an error message so we silence it. + ERR_PRINT_OFF; + arr.remove(0); + ERR_PRINT_ON; + + CHECK(arr.size() == 0); +} + +TEST_CASE("[Array] get()") { + Array arr; + arr.push_back(1); + CHECK(int(arr.get(0)) == 1); +} + +TEST_CASE("[Array] sort()") { + Array arr; + + arr.push_back(3); + arr.push_back(4); + arr.push_back(2); + arr.push_back(1); + arr.sort(); + int val = 1; + for (int i = 0; i < arr.size(); i++) { + CHECK(int(arr[i]) == val); + val++; + } +} + +TEST_CASE("[Array] push_front(), pop_front(), pop_back()") { + Array arr; + arr.push_front(1); + arr.push_front(2); + CHECK(int(arr[0]) == 2); + arr.pop_front(); + CHECK(int(arr[0]) == 1); + CHECK(arr.size() == 1); + arr.push_front(2); + arr.push_front(3); + arr.pop_back(); + CHECK(int(arr[1]) == 2); + CHECK(arr.size() == 2); +} + +TEST_CASE("[Array] max() and min()") { + Array arr; + arr.push_back(3); + arr.push_front(4); + arr.push_back(5); + arr.push_back(2); + int max = int(arr.max()); + int min = int(arr.min()); + CHECK(max == 5); + CHECK(min == 2); +} +} // namespace TestArray + +#endif // TEST_ARRAY_H diff --git a/tests/test_class_db.h b/tests/test_class_db.h index 11bf95ae28..9ef4569c14 100644 --- a/tests/test_class_db.h +++ b/tests/test_class_db.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_TEST_CLASS_DB_H -#define GODOT_TEST_CLASS_DB_H +#ifndef TEST_CLASS_DB_H +#define TEST_CLASS_DB_H #include "core/register_core_types.h" @@ -42,11 +42,6 @@ #include "tests/test_macros.h" -#define TEST_COND DOCTEST_CHECK_FALSE_MESSAGE -#define TEST_FAIL DOCTEST_FAIL -#define TEST_FAIL_COND DOCTEST_REQUIRE_FALSE_MESSAGE -#define TEST_FAIL_COND_WARN DOCTEST_WARN_FALSE_MESSAGE - namespace TestClassDB { struct TypeReference { @@ -298,7 +293,7 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co const ExposedClass *top = &p_class; while (!setter && top->base != StringName()) { top = p_context.find_exposed_class(top->base); - TEST_FAIL_COND(!top, "Class not found '" + top->base + "'. Inherited by '" + top->name + "'."); + TEST_FAIL_COND(!top, "Class not found '", top->base, "'. Inherited by '", top->name, "'."); setter = top->find_method_by_name(p_prop.setter); } @@ -308,23 +303,23 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co top = &p_class; while (!getter && top->base != StringName()) { top = p_context.find_exposed_class(top->base); - TEST_FAIL_COND(!top, "Class not found '" + top->base + "'. Inherited by '" + top->name + "'."); + TEST_FAIL_COND(!top, "Class not found '", top->base, "'. Inherited by '", top->name, "'."); getter = top->find_method_by_name(p_prop.getter); } TEST_FAIL_COND((!setter && !getter), - "Couldn't find neither the setter nor the getter for property: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Couldn't find neither the setter nor the getter for property: '", p_class.name, ".", String(p_prop.name), "'."); if (setter) { int setter_argc = p_prop.index != -1 ? 2 : 1; TEST_FAIL_COND(setter->arguments.size() != setter_argc, - "Invalid property setter argument count: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Invalid property setter argument count: '", p_class.name, ".", String(p_prop.name), "'."); } if (getter) { int getter_argc = p_prop.index != -1 ? 1 : 0; TEST_FAIL_COND(getter->arguments.size() != getter_argc, - "Invalid property setter argument count: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Invalid property setter argument count: '", p_class.name, ".", String(p_prop.name), "'."); } if (getter && setter) { @@ -335,7 +330,7 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co setter_first_arg.type.name == p_context.names_cache.string_type; TEST_FAIL_COND(!whitelisted, - "Return type from getter doesn't match first argument of setter, for property: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Return type from getter doesn't match first argument of setter, for property: '", p_class.name, ".", String(p_prop.name), "'."); } } @@ -344,10 +339,17 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co const ExposedClass *prop_class = p_context.find_exposed_class(prop_type_ref); if (prop_class) { TEST_COND(prop_class->is_singleton, - "Property type is a singleton: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Property type is a singleton: '", p_class.name, ".", String(p_prop.name), "'."); + + if (p_class.api_type == ClassDB::API_CORE) { + TEST_COND(prop_class->api_type == ClassDB::API_EDITOR, + "Property '", p_class.name, ".", p_prop.name, "' has type '", prop_class->name, + "' from the editor API. Core API cannot have dependencies on the editor API."); + } } else { + // Look for types that don't inherit Object TEST_FAIL_COND(!p_context.has_type(prop_type_ref), - "Property type '" + prop_type_ref.name + "' not found: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Property type '", prop_type_ref.name, "' not found: '", p_class.name, ".", String(p_prop.name), "'."); } if (getter) { @@ -356,7 +358,7 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co if (idx_arg.type.name != p_context.names_cache.int_type) { // If not an int, it can be an enum TEST_COND(p_context.enum_types.find(idx_arg.type.name) < 0, - "Invalid type '" + idx_arg.type.name + "' for index argument of property getter: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Invalid type '", idx_arg.type.name, "' for index argument of property getter: '", p_class.name, ".", String(p_prop.name), "'."); } } } @@ -368,17 +370,29 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co // Assume the index parameter is an enum // If not an int, it can be an enum TEST_COND(p_context.enum_types.find(idx_arg.type.name) < 0, - "Invalid type '" + idx_arg.type.name + "' for index argument of property setter: '" + p_class.name + "." + String(p_prop.name) + "'."); + "Invalid type '", idx_arg.type.name, "' for index argument of property setter: '", p_class.name, ".", String(p_prop.name), "'."); } } } } void validate_method(const Context &p_context, const ExposedClass &p_class, const MethodData &p_method) { - const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type); - if (return_class) { - TEST_COND(return_class->is_singleton, - "Method return type is a singleton: '" + p_class.name + "." + p_method.name + "'."); + if (p_method.return_type.name != StringName()) { + const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type); + if (return_class) { + TEST_COND(return_class->is_singleton, + "Method return type is a singleton: '", p_class.name, ".", p_method.name, "'."); + + if (p_class.api_type == ClassDB::API_CORE) { + TEST_COND(return_class->api_type == ClassDB::API_EDITOR, + "Method '", p_class.name, ".", p_method.name, "' has return type '", return_class->name, + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + } else { + // Look for types that don't inherit Object + TEST_FAIL_COND(!p_context.has_type(p_method.return_type), + "Method return type '", p_method.return_type.name, "' not found: '", p_class.name, ".", p_method.name, "'."); + } } for (const List<ArgumentData>::Element *F = p_method.arguments.front(); F; F = F->next()) { @@ -387,10 +401,17 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons const ExposedClass *arg_class = p_context.find_exposed_class(arg.type); if (arg_class) { TEST_COND(arg_class->is_singleton, - "Argument type is a singleton: '" + arg.name + "' of method '" + p_class.name + "." + p_method.name + "'."); + "Argument type is a singleton: '", arg.name, "' of method '", p_class.name, ".", p_method.name, "'."); + + if (p_class.api_type == ClassDB::API_CORE) { + TEST_COND(arg_class->api_type == ClassDB::API_EDITOR, + "Argument '", arg.name, "' of method '", p_class.name, ".", p_method.name, "' has type '", + arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API."); + } } else { + // Look for types that don't inherit Object TEST_FAIL_COND(!p_context.has_type(arg.type), - "Argument type '" + arg.type.name + "' not found: '" + arg.name + "' of method" + p_class.name + "." + p_method.name + "'."); + "Argument type '", arg.type.name, "' not found: '", arg.name, "' of method", p_class.name, ".", p_method.name, "'."); } if (arg.has_defval) { @@ -412,10 +433,17 @@ void validate_signal(const Context &p_context, const ExposedClass &p_class, cons const ExposedClass *arg_class = p_context.find_exposed_class(arg.type); if (arg_class) { TEST_COND(arg_class->is_singleton, - "Argument class is a singleton: '" + arg.name + "' of signal" + p_class.name + "." + p_signal.name + "'."); + "Argument class is a singleton: '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "'."); + + if (p_class.api_type == ClassDB::API_CORE) { + TEST_COND(arg_class->api_type == ClassDB::API_EDITOR, + "Argument '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "' has type '", + arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API."); + } } else { + // Look for types that don't inherit Object TEST_FAIL_COND(!p_context.has_type(arg.type), - "Argument type '" + arg.type.name + "' not found: '" + arg.name + "' of signal" + p_class.name + "." + p_signal.name + "'."); + "Argument type '", arg.type.name, "' not found: '", arg.name, "' of signal", p_class.name, ".", p_signal.name, "'."); } } } @@ -426,7 +454,7 @@ void validate_class(const Context &p_context, const ExposedClass &p_exposed_clas if (!is_derived_type) { // Asserts about the base Object class TEST_FAIL_COND(p_exposed_class.name != p_context.names_cache.object_class, - "Class '" + p_exposed_class.name + "' has no base class."); + "Class '", p_exposed_class.name, "' has no base class."); TEST_FAIL_COND(!p_exposed_class.is_instantiable, "Object class is not instantiable."); TEST_FAIL_COND(p_exposed_class.api_type != ClassDB::API_CORE, @@ -436,10 +464,10 @@ void validate_class(const Context &p_context, const ExposedClass &p_exposed_clas } TEST_FAIL_COND((p_exposed_class.is_singleton && p_exposed_class.base != p_context.names_cache.object_class), - "Singleton base class '" + String(p_exposed_class.base) + "' is not Object, for class '" + p_exposed_class.name + "'."); + "Singleton base class '", String(p_exposed_class.base), "' is not Object, for class '", p_exposed_class.name, "'."); TEST_FAIL_COND((is_derived_type && !p_context.exposed_classes.has(p_exposed_class.base)), - "Base type '" + p_exposed_class.base.operator String() + "' does not exist, for class '" + p_exposed_class.name + "'."); + "Base type '", p_exposed_class.base.operator String(), "' does not exist, for class '", p_exposed_class.name, "'."); for (const List<PropertyData>::Element *F = p_exposed_class.properties.front(); F; F = F->next()) { validate_property(p_context, p_exposed_class, F->get()); @@ -519,7 +547,7 @@ void add_exposed_classes(Context &r_context) { bool valid = false; prop.index = ClassDB::get_property_index(class_name, prop.name, &valid); - TEST_FAIL_COND(!valid, "Invalid property: '" + exposed_class.name + "." + String(prop.name) + "'."); + TEST_FAIL_COND(!valid, "Invalid property: '", exposed_class.name, ".", String(prop.name), "'."); exposed_class.properties.push_back(prop); } @@ -557,7 +585,7 @@ void add_exposed_classes(Context &r_context) { if (!m && !method.is_virtual) { TEST_FAIL_COND(!virtual_method_list.find(method_info), - "Missing MethodBind for non-virtual method: '" + exposed_class.name + "." + method.name + "'."); + "Missing MethodBind for non-virtual method: '", exposed_class.name, ".", method.name, "'."); // A virtual method without the virtual flag. This is a special case. @@ -584,9 +612,8 @@ void add_exposed_classes(Context &r_context) { bool bad_reference_hint = !method.is_virtual && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE && ClassDB::is_parent_class(return_info.class_name, r_context.names_cache.reference_class); - TEST_COND(bad_reference_hint, String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." + - " Are you returning a reference type by pointer? Method: '" + - exposed_class.name + "." + method.name + "'."); + TEST_COND(bad_reference_hint, "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'.", " Are you returning a reference type by pointer? Method: '", + exposed_class.name, ".", method.name, "'."); } else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { method.return_type.name = return_info.hint_string; } else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { @@ -636,7 +663,7 @@ void add_exposed_classes(Context &r_context) { } TEST_COND(exposed_class.find_property_by_name(method.name), - "Method name conflicts with property: '" + String(class_name) + "." + String(method.name) + "'."); + "Method name conflicts with property: '", String(class_name), ".", String(method.name), "'."); // Classes starting with an underscore are ignored unless they're used as a property setter or getter if (!method.is_virtual && String(method.name)[0] == '_') { @@ -724,8 +751,8 @@ void add_exposed_classes(Context &r_context) { for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { const StringName &constant_name = E->get(); int *value = class_info->constant_map.getptr(constant_name); - TEST_FAIL_COND(!value, "Missing enum constant value: '" + - String(class_name) + "." + String(enum_.name) + "." + String(constant_name) + "'."); + TEST_FAIL_COND(!value, "Missing enum constant value: '", + String(class_name), ".", String(enum_.name), ".", String(constant_name), "'."); constants.erase(constant_name); ConstantData constant; @@ -743,7 +770,7 @@ void add_exposed_classes(Context &r_context) { for (const List<String>::Element *E = constants.front(); E; E = E->next()) { const String &constant_name = E->get(); int *value = class_info->constant_map.getptr(StringName(E->get())); - TEST_FAIL_COND(!value, "Missing enum constant value: '" + String(class_name) + "." + String(constant_name) + "'."); + TEST_FAIL_COND(!value, "Missing enum constant value: '", String(class_name), ".", String(constant_name), "'."); ConstantData constant; constant.name = constant_name; @@ -822,7 +849,7 @@ TEST_SUITE("[ClassDB]") { const ExposedClass *object_class = context.find_exposed_class(context.names_cache.object_class); TEST_FAIL_COND(!object_class, "Object class not found."); TEST_FAIL_COND(object_class->base != StringName(), - "Object class derives from another class: '" + object_class->base + "'."); + "Object class derives from another class: '", object_class->base, "'."); for (ExposedClasses::Element E = context.exposed_classes.front(); E; E = E.next()) { validate_class(context, E.value()); @@ -832,4 +859,4 @@ TEST_SUITE("[ClassDB]") { } } // namespace TestClassDB -#endif //GODOT_TEST_CLASS_DB_H +#endif // TEST_CLASS_DB_H diff --git a/tests/test_command_queue.h b/tests/test_command_queue.h index 2f0b75760d..b4fa63ad2b 100644 --- a/tests/test_command_queue.h +++ b/tests/test_command_queue.h @@ -122,8 +122,8 @@ public: int message_count_to_read = 0; bool exit_threads = false; - Thread *reader_thread = nullptr; - Thread *writer_thread = nullptr; + Thread reader_thread; + Thread writer_thread; int func1_count = 0; @@ -221,20 +221,16 @@ public: } void init_threads() { - reader_thread = Thread::create(&SharedThreadState::static_reader_thread_loop, this); - writer_thread = Thread::create(&SharedThreadState::static_writer_thread_loop, this); + reader_thread.start(&SharedThreadState::static_reader_thread_loop, this); + writer_thread.start(&SharedThreadState::static_writer_thread_loop, this); } void destroy_threads() { exit_threads = true; reader_threadwork.main_start_work(); writer_threadwork.main_start_work(); - Thread::wait_to_finish(reader_thread); - memdelete(reader_thread); - reader_thread = nullptr; - Thread::wait_to_finish(writer_thread); - memdelete(writer_thread); - writer_thread = nullptr; + reader_thread.wait_to_finish(); + writer_thread.wait_to_finish(); } }; diff --git a/tests/test_geometry_3d.h b/tests/test_geometry_3d.h new file mode 100644 index 0000000000..2b2a424b2b --- /dev/null +++ b/tests/test_geometry_3d.h @@ -0,0 +1,417 @@ +/*************************************************************************/ +/* test_geometry_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_3D_GEOMETRY_H +#define TEST_3D_GEOMETRY_H + +#include "core/math/geometry_3d.h" +#include "core/math/plane.h" +#include "core/math/random_number_generator.h" +#include "core/math/vector3.h" +#include "tests/test_macros.h" +#include "vector" + +namespace Test3DGeometry { +TEST_CASE("[Geometry3D] Closest Points Between Segments") { + struct Case { + Vector3 p_1, p_2, p_3, p_4; + Vector3 got_1, got_2; + Vector3 want_1, want_2; + Case(){}; + Case(Vector3 p_p_1, Vector3 p_p_2, Vector3 p_p_3, Vector3 p_p_4, Vector3 p_want_1, Vector3 p_want_2) : + p_1(p_p_1), p_2(p_p_2), p_3(p_p_3), p_4(p_p_4), want_1(p_want_1), want_2(p_want_2){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(1, -1, 1), Vector3(1, 1, -1), Vector3(-1, -2, -1), Vector3(-1, 1, 1), Vector3(1, -0.2, 0.2), Vector3(-1, -0.2, 0.2))); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Geometry3D::get_closest_points_between_segments(current_case.p_1, current_case.p_2, current_case.p_3, current_case.p_4, current_case.got_1, current_case.got_2); + CHECK(current_case.got_1.is_equal_approx(current_case.want_1)); + CHECK(current_case.got_2.is_equal_approx(current_case.want_2)); + } +} +TEST_CASE("[Geometry3D] Closest Distance Between Segments") { + struct Case { + Vector3 p_1, p_2, p_3, p_4; + float want; + Case(){}; + Case(Vector3 p_p_1, Vector3 p_p_2, Vector3 p_p_3, Vector3 p_p_4, float p_want) : + p_1(p_p_1), p_2(p_p_2), p_3(p_p_3), p_4(p_p_4), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(1, -2, 0), Vector3(1, 2, 0), Vector3(-1, 2, 0), Vector3(-1, -2, 0), 0.0f)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + float out = Geometry3D::get_closest_distance_between_segments(current_case.p_1, current_case.p_2, current_case.p_3, current_case.p_4); + CHECK(out == current_case.want); + } +} +TEST_CASE("[Geometry3D] Build Box Planes") { + const Vector3 extents = Vector3(5, 5, 20); + Vector<Plane> box = Geometry3D::build_box_planes(extents); + CHECK(box.size() == 6); + CHECK(extents.x == box[0].d); + CHECK(box[0].normal == Vector3(1, 0, 0)); + CHECK(extents.x == box[1].d); + CHECK(box[1].normal == Vector3(-1, 0, 0)); + CHECK(extents.y == box[2].d); + CHECK(box[2].normal == Vector3(0, 1, 0)); + CHECK(extents.y == box[3].d); + CHECK(box[3].normal == Vector3(0, -1, 0)); + CHECK(extents.z == box[4].d); + CHECK(box[4].normal == Vector3(0, 0, 1)); + CHECK(extents.z == box[5].d); + CHECK(box[5].normal == Vector3(0, 0, -1)); +} +TEST_CASE("[Geometry3D] Build Capsule Planes") { + struct Case { + real_t radius, height; + int sides, lats; + Vector3::Axis axis; + int want_size; + Case(){}; + Case(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis, int p_want) : + radius(p_radius), height(p_height), sides(p_sides), lats(p_lats), axis(p_axis), want_size(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(10, 20, 6, 10, Vector3::Axis(), 126)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Vector<Plane> capsule = Geometry3D::build_capsule_planes(current_case.radius, current_case.height, current_case.sides, current_case.lats, current_case.axis); + // Should equal (p_sides * p_lats) * 2 + p_sides + CHECK(capsule.size() == current_case.want_size); + } +} +TEST_CASE("[Geometry3D] Build Cylinder Planes") { + struct Case { + real_t radius, height; + int sides; + Vector3::Axis axis; + int want_size; + Case(){}; + Case(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis, int p_want) : + radius(p_radius), height(p_height), sides(p_sides), axis(p_axis), want_size(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(3.0f, 10.0f, 10, Vector3::Axis(), 12)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Vector<Plane> planes = Geometry3D::build_cylinder_planes(current_case.radius, current_case.height, current_case.sides, current_case.axis); + CHECK(planes.size() == current_case.want_size); + } +} +TEST_CASE("[Geometry3D] Build Sphere Planes") { + struct Case { + real_t radius; + int lats, lons; + Vector3::Axis axis; + int want_size; + Case(){}; + Case(real_t p_radius, int p_lat, int p_lons, Vector3::Axis p_axis, int p_want) : + radius(p_radius), lats(p_lat), lons(p_lons), axis(p_axis), want_size(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(10.0f, 10, 3, Vector3::Axis(), 63)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Vector<Plane> planes = Geometry3D::build_sphere_planes(current_case.radius, current_case.lats, current_case.lons, current_case.axis); + CHECK(planes.size() == 63); + } +} +TEST_CASE("[Geometry3D] Build Convex Mesh") { + struct Case { + Vector<Plane> object; + int want_faces, want_edges, want_vertices; + Case(){}; + Case(Vector<Plane> p_object, int p_want_faces, int p_want_edges, int p_want_vertices) : + object(p_object), want_faces(p_want_faces), want_edges(p_want_edges), want_vertices(p_want_vertices){}; + }; + Vector<Case> tt; + tt.push_back(Case(Geometry3D::build_box_planes(Vector3(5, 10, 5)), 6, 12, 8)); + tt.push_back(Case(Geometry3D::build_capsule_planes(5, 5, 20, 20, Vector3::Axis()), 820, 7603, 6243)); + tt.push_back(Case(Geometry3D::build_cylinder_planes(5, 5, 20, Vector3::Axis()), 22, 100, 80)); + tt.push_back(Case(Geometry3D::build_sphere_planes(5, 5, 20), 220, 1011, 522)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Geometry3D::MeshData mesh = Geometry3D::build_convex_mesh(current_case.object); + CHECK(mesh.faces.size() == current_case.want_faces); + CHECK(mesh.edges.size() == current_case.want_edges); + CHECK(mesh.vertices.size() == current_case.want_vertices); + } +} +TEST_CASE("[Geometry3D] Clip Polygon") { + struct Case { + Plane clipping_plane; + Vector<Vector3> polygon; + bool want; + Case(){}; + Case(Plane p_clipping_plane, Vector<Vector3> p_polygon, bool p_want) : + clipping_plane(p_clipping_plane), polygon(p_polygon), want(p_want){}; + }; + Vector<Case> tt; + Vector<Plane> box_planes = Geometry3D::build_box_planes(Vector3(5, 10, 5)); + Vector<Vector3> box = Geometry3D::compute_convex_mesh_points(&box_planes[0], box_planes.size()); + tt.push_back(Case(Plane(), box, true)); + tt.push_back(Case(Plane(Vector3(0, 3, 0), Vector3(0, 1, 0)), box, false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Vector<Vector3> output = Geometry3D::clip_polygon(current_case.polygon, current_case.clipping_plane); + if (current_case.want) { + CHECK(output == current_case.polygon); + } else { + CHECK(output != current_case.polygon); + } + } +} +TEST_CASE("[Geometry3D] Compute Convex Mesh Points") { + struct Case { + Vector<Plane> mesh; + Vector<Vector3> want; + Case(){}; + Case(Vector<Plane> p_mesh, Vector<Vector3> p_want) : + mesh(p_mesh), want(p_want){}; + }; + Vector<Case> tt; + Vector<Vector3> cube; + cube.push_back(Vector3(-5, -5, -5)); + cube.push_back(Vector3(5, -5, -5)); + cube.push_back(Vector3(-5, 5, -5)); + cube.push_back(Vector3(5, 5, -5)); + cube.push_back(Vector3(-5, -5, 5)); + cube.push_back(Vector3(5, -5, 5)); + cube.push_back(Vector3(-5, 5, 5)); + cube.push_back(Vector3(5, 5, 5)); + tt.push_back(Case(Geometry3D::build_box_planes(Vector3(5, 5, 5)), cube)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Vector<Vector3> vectors = Geometry3D::compute_convex_mesh_points(¤t_case.mesh[0], current_case.mesh.size()); + CHECK(vectors == current_case.want); + } +} +TEST_CASE("[Geometry3D] Get Closest Point To Segment") { + struct Case { + Vector3 point; + Vector<Vector3> segment; + Vector3 want; + Case(){}; + Case(Vector3 p_point, Vector<Vector3> p_segment, Vector3 p_want) : + point(p_point), segment(p_segment), want(p_want){}; + }; + Vector<Case> tt; + Vector<Vector3> test_segment; + test_segment.push_back(Vector3(1, 1, 1)); + test_segment.push_back(Vector3(5, 5, 5)); + tt.push_back(Case(Vector3(2, 1, 4), test_segment, Vector3(2.33333, 2.33333, 2.33333))); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + Vector3 output = Geometry3D::get_closest_point_to_segment(current_case.point, ¤t_case.segment[0]); + CHECK(output.is_equal_approx(current_case.want)); + } +} +TEST_CASE("[Geometry3D] Plane and Box Overlap") { + struct Case { + Vector3 normal, max_box; + float d; + bool want; + Case(){}; + Case(Vector3 p_normal, float p_d, Vector3 p_max_box, bool p_want) : + normal(p_normal), max_box(p_max_box), d(p_d), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(3, 4, 2), 5, Vector3(5, 5, 5), true)); + tt.push_back(Case(Vector3(0, 1, 0), -10, Vector3(5, 5, 5), false)); + tt.push_back(Case(Vector3(1, 0, 0), -6, Vector3(5, 5, 5), false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool overlap = Geometry3D::planeBoxOverlap(current_case.normal, current_case.d, current_case.max_box); + CHECK(overlap == current_case.want); + } +} +TEST_CASE("[Geometry3D] Is Point in Projected Triangle") { + struct Case { + Vector3 point, v_1, v_2, v_3; + bool want; + Case(){}; + Case(Vector3 p_point, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) : + point(p_point), v_1(p_v_1), v_2(p_v_2), v_3(p_v_3), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(1, 1, 0), Vector3(3, 0, 0), Vector3(0, 3, 0), Vector3(-3, 0, 0), true)); + tt.push_back(Case(Vector3(5, 1, 0), Vector3(3, 0, 0), Vector3(0, 3, 0), Vector3(-3, 0, 0), false)); + tt.push_back(Case(Vector3(3, 0, 0), Vector3(3, 0, 0), Vector3(0, 3, 0), Vector3(-3, 0, 0), true)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::point_in_projected_triangle(current_case.point, current_case.v_1, current_case.v_2, current_case.v_3); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Does Ray Intersect Triangle") { + struct Case { + Vector3 from, direction, v_1, v_2, v_3; + Vector3 *result; + bool want; + Case(){}; + Case(Vector3 p_from, Vector3 p_direction, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) : + from(p_from), direction(p_direction), v_1(p_v_1), v_2(p_v_2), v_3(p_v_3), result(nullptr), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(0, 1, 1), Vector3(0, 0, -10), Vector3(0, 3, 0), Vector3(-3, 0, 0), Vector3(3, 0, 0), true)); + tt.push_back(Case(Vector3(5, 10, 1), Vector3(0, 0, -10), Vector3(0, 3, 0), Vector3(-3, 0, 0), Vector3(3, 0, 0), false)); + tt.push_back(Case(Vector3(0, 1, 1), Vector3(0, 0, 10), Vector3(0, 3, 0), Vector3(-3, 0, 0), Vector3(3, 0, 0), false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::ray_intersects_triangle(current_case.from, current_case.direction, current_case.v_1, current_case.v_2, current_case.v_3, current_case.result); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Does Segment Intersect Convex") { + struct Case { + Vector3 from, to; + Vector<Plane> planes; + Vector3 *result, *normal; + bool want; + Case(){}; + Case(Vector3 p_from, Vector3 p_to, Vector<Plane> p_planes, bool p_want) : + from(p_from), to(p_to), planes(p_planes), result(nullptr), normal(nullptr), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 0), Geometry3D::build_box_planes(Vector3(5, 5, 5)), true)); + tt.push_back(Case(Vector3(10, 10, 10), Vector3(5, 5, 5), Geometry3D::build_box_planes(Vector3(5, 5, 5)), true)); + tt.push_back(Case(Vector3(10, 10, 10), Vector3(6, 5, 5), Geometry3D::build_box_planes(Vector3(5, 5, 5)), false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::segment_intersects_convex(current_case.from, current_case.to, ¤t_case.planes[0], current_case.planes.size(), current_case.result, current_case.normal); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Segment Intersects Cylinder") { + struct Case { + Vector3 from, to; + real_t height, radius; + Vector3 *result, *normal; + bool want; + Case(){}; + Case(Vector3 p_from, Vector3 p_to, real_t p_height, real_t p_radius, bool p_want) : + from(p_from), to(p_to), height(p_height), radius(p_radius), result(nullptr), normal(nullptr), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 0), 5, 5, true)); + tt.push_back(Case(Vector3(10, 10, 10), Vector3(6, 6, 6), 5, 5, false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::segment_intersects_cylinder(current_case.from, current_case.to, current_case.height, current_case.radius, current_case.result, current_case.normal); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Segment Intersects Cylinder") { + struct Case { + Vector3 from, to, sphere_pos; + real_t radius; + Vector3 *result, *normal; + bool want; + Case(){}; + Case(Vector3 p_from, Vector3 p_to, Vector3 p_sphere_pos, real_t p_radius, bool p_want) : + from(p_from), to(p_to), sphere_pos(p_sphere_pos), radius(p_radius), result(nullptr), normal(nullptr), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 0), Vector3(0, 0, 0), 5, true)); + tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 2.5), Vector3(0, 0, 0), 5, true)); + tt.push_back(Case(Vector3(10, 10, 10), Vector3(5, 5, 5), Vector3(0, 0, 0), 5, false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::segment_intersects_sphere(current_case.from, current_case.to, current_case.sphere_pos, current_case.radius, current_case.result, current_case.normal); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Segment Intersects Triangle") { + struct Case { + Vector3 from, to, v_1, v_2, v_3, *result; + bool want; + Case(){}; + Case(Vector3 p_from, Vector3 p_to, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) : + from(p_from), to(p_to), v_1(p_v_1), v_2(p_v_2), v_3(p_v_3), result(nullptr), want(p_want){}; + }; + Vector<Case> tt; + tt.push_back(Case(Vector3(1, 1, 1), Vector3(-1, -1, -1), Vector3(-3, 0, 0), Vector3(0, 3, 0), Vector3(3, 0, 0), true)); + tt.push_back(Case(Vector3(1, 1, 1), Vector3(3, 0, 0), Vector3(-3, 0, 0), Vector3(0, 3, 0), Vector3(3, 0, 0), true)); + tt.push_back(Case(Vector3(1, 1, 1), Vector3(10, -1, -1), Vector3(-3, 0, 0), Vector3(0, 3, 0), Vector3(3, 0, 0), false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::segment_intersects_triangle(current_case.from, current_case.to, current_case.v_1, current_case.v_2, current_case.v_3, current_case.result); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Triangle and Box Overlap") { + struct Case { + Vector3 box_centre; + Vector3 box_half_size; + Vector3 *tri_verts; + bool want; + Case(){}; + Case(Vector3 p_centre, Vector3 p_half_size, Vector3 *p_verts, bool p_want) : + box_centre(p_centre), box_half_size(p_half_size), tri_verts(p_verts), want(p_want){}; + }; + Vector<Case> tt; + Vector3 GoodTriangle[3] = { Vector3(3, 2, 3), Vector3(2, 2, 1), Vector3(2, 1, 1) }; + tt.push_back(Case(Vector3(0, 0, 0), Vector3(5, 5, 5), GoodTriangle, true)); + Vector3 BadTriangle[3] = { Vector3(100, 100, 100), Vector3(-100, -100, -100), Vector3(10, 10, 10) }; + tt.push_back(Case(Vector3(1000, 1000, 1000), Vector3(1, 1, 1), BadTriangle, false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::triangle_box_overlap(current_case.box_centre, current_case.box_half_size, current_case.tri_verts); + CHECK(output == current_case.want); + } +} +TEST_CASE("[Geometry3D] Triangle and Sphere Intersect") { + struct Case { + Vector<Vector3> triangle; + Vector3 normal, sphere_pos, triangle_contact, sphere_contact; + real_t sphere_radius; + bool want; + Case(){}; + Case(Vector<Vector3> p_triangle, Vector3 p_normal, Vector3 p_sphere_pos, real_t p_sphere_radius, bool p_want) : + triangle(p_triangle), normal(p_normal), sphere_pos(p_sphere_pos), triangle_contact(Vector3()), sphere_contact(Vector3()), sphere_radius(p_sphere_radius), want(p_want){}; + }; + Vector<Case> tt; + Vector<Vector3> triangle; + triangle.push_back(Vector3(3, 0, 0)); + triangle.push_back(Vector3(-3, 0, 0)); + triangle.push_back(Vector3(0, 3, 0)); + tt.push_back(Case(triangle, Vector3(0, -1, 0), Vector3(0, 0, 0), 5, true)); + tt.push_back(Case(triangle, Vector3(0, 1, 0), Vector3(0, 0, 0), 5, true)); + tt.push_back(Case(triangle, Vector3(0, 1, 0), Vector3(20, 0, 0), 5, false)); + for (int i = 0; i < tt.size(); ++i) { + Case current_case = tt[i]; + bool output = Geometry3D::triangle_sphere_intersection_test(¤t_case.triangle[0], current_case.normal, current_case.sphere_pos, current_case.sphere_radius, current_case.triangle_contact, current_case.sphere_contact); + CHECK(output == current_case.want); + } +} +} // namespace Test3DGeometry +#endif diff --git a/tests/test_image.h b/tests/test_image.h new file mode 100644 index 0000000000..d73717f5b7 --- /dev/null +++ b/tests/test_image.h @@ -0,0 +1,259 @@ +/*************************************************************************/ +/* test_image.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_IMAGE_H +#define TEST_IMAGE_H + +#include "core/io/file_access_pack.h" +#include "core/io/image.h" +#include "test_utils.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestImage { + +TEST_CASE("[Image] Instantiation") { + Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_RGBA8)); + CHECK_MESSAGE( + !image->is_empty(), + "An image created with specified size and format should not be empty at first."); + CHECK_MESSAGE( + image->is_invisible(), + "A newly created image should be invisible."); + CHECK_MESSAGE( + !image->is_compressed(), + "A newly created image should not be compressed."); + CHECK(!image->has_mipmaps()); + + Ref<Image> image_copy = memnew(Image()); + CHECK_MESSAGE( + image_copy->is_empty(), + "An image created without any specified size and format be empty at first."); + image_copy->copy_internals_from(image); + + CHECK_MESSAGE( + image->get_data() == image_copy->get_data(), + "Duplicated images should have the same data."); + + PackedByteArray image_data = image->get_data(); + Ref<Image> image_from_data = memnew(Image(8, 4, false, Image::FORMAT_RGBA8, image_data)); + CHECK_MESSAGE( + image->get_data() == image_from_data->get_data(), + "An image created from data of another image should have the same data of the original image."); +} + +TEST_CASE("[Image] Saving and loading") { + Ref<Image> image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8)); + const String save_path_png = OS::get_singleton()->get_cache_path().plus_file("image.png"); + const String save_path_exr = OS::get_singleton()->get_cache_path().plus_file("image.exr"); + + // Save PNG + Error err; + err = image->save_png(save_path_png); + CHECK_MESSAGE( + err == OK, + "The image should be saved successfully as a .png file."); + + // Save EXR + err = image->save_exr(save_path_exr, false); + CHECK_MESSAGE( + err == OK, + "The image should be saved successfully as an .exr file."); + + // Load using load() + Ref<Image> image_load = memnew(Image()); + err = image_load->load(save_path_png); + CHECK_MESSAGE( + err == OK, + "The image should load successfully using load()."); + CHECK_MESSAGE( + image->get_data() == image_load->get_data(), + "The loaded image should have the same data as the one that got saved."); + + // Load BMP + Ref<Image> image_bmp = memnew(Image()); + FileAccessRef f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err); + PackedByteArray data_bmp; + data_bmp.resize(f_bmp->get_len() + 1); + f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_len()); + CHECK_MESSAGE( + image_bmp->load_bmp_from_buffer(data_bmp) == OK, + "The BMP image should load successfully."); + + // Load JPG + Ref<Image> image_jpg = memnew(Image()); + FileAccessRef f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err); + PackedByteArray data_jpg; + data_jpg.resize(f_jpg->get_len() + 1); + f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_len()); + CHECK_MESSAGE( + image_jpg->load_jpg_from_buffer(data_jpg) == OK, + "The JPG image should load successfully."); + + // Load WEBP + Ref<Image> image_webp = memnew(Image()); + FileAccessRef f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err); + PackedByteArray data_webp; + data_webp.resize(f_webp->get_len() + 1); + f_webp->get_buffer(data_webp.ptrw(), f_webp->get_len()); + CHECK_MESSAGE( + image_webp->load_webp_from_buffer(data_webp) == OK, + "The WEBP image should load successfully."); + + // Load PNG + Ref<Image> image_png = memnew(Image()); + FileAccessRef f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err); + PackedByteArray data_png; + data_png.resize(f_png->get_len() + 1); + f_png->get_buffer(data_png.ptrw(), f_png->get_len()); + CHECK_MESSAGE( + image_png->load_png_from_buffer(data_png) == OK, + "The PNG image should load successfully."); + + // Load TGA + Ref<Image> image_tga = memnew(Image()); + FileAccessRef f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err); + PackedByteArray data_tga; + data_tga.resize(f_tga->get_len() + 1); + f_tga->get_buffer(data_tga.ptrw(), f_tga->get_len()); + CHECK_MESSAGE( + image_tga->load_tga_from_buffer(data_tga) == OK, + "The TGA image should load successfully."); +} + +TEST_CASE("[Image] Basic getters") { + Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_LA8)); + CHECK(image->get_width() == 8); + CHECK(image->get_height() == 4); + CHECK(image->get_size() == Vector2(8, 4)); + CHECK(image->get_format() == Image::FORMAT_LA8); + CHECK(image->get_used_rect() == Rect2(0, 0, 0, 0)); + Ref<Image> image_get_rect = image->get_rect(Rect2(0, 0, 2, 1)); + CHECK(image_get_rect->get_size() == Vector2(2, 1)); +} + +TEST_CASE("[Image] Resizing") { + Ref<Image> image = memnew(Image(8, 8, false, Image::FORMAT_RGBA8)); + // Crop + image->crop(4, 4); + CHECK_MESSAGE( + image->get_size() == Vector2(4, 4), + "get_size() should return the correct size after cropping."); + image->set_pixel(0, 0, Color(1, 1, 1, 1)); + + // Resize + for (int i = 0; i < 5; i++) { + Ref<Image> image_resized = memnew(Image()); + image_resized->copy_internals_from(image); + Image::Interpolation interpolation = static_cast<Image::Interpolation>(i); + image_resized->resize(8, 8, interpolation); + CHECK_MESSAGE( + image_resized->get_size() == Vector2(8, 8), + "get_size() should return the correct size after resizing."); + CHECK_MESSAGE( + image_resized->get_pixel(1, 1).a > 0, + "Resizing an image should also affect its content."); + } + + // shrink_x2() + image->shrink_x2(); + CHECK_MESSAGE( + image->get_size() == Vector2(2, 2), + "get_size() should return the correct size after shrink_x2()."); + + // resize_to_po2() + Ref<Image> image_po_2 = memnew(Image(14, 28, false, Image::FORMAT_RGBA8)); + image_po_2->resize_to_po2(); + CHECK_MESSAGE( + image_po_2->get_size() == Vector2(16, 32), + "get_size() should return the correct size after resize_to_po2()."); +} + +TEST_CASE("[Image] Modifying pixels of an image") { + Ref<Image> image = memnew(Image(3, 3, false, Image::FORMAT_RGBA8)); + image->set_pixel(0, 0, Color(1, 1, 1, 1)); + CHECK_MESSAGE( + !image->is_invisible(), + "Image should not be invisible after drawing on it."); + CHECK_MESSAGE( + image->get_pixelv(Vector2(0, 0)).is_equal_approx(Color(1, 1, 1, 1)), + "Image's get_pixel() should return the same color value as the one being set with set_pixel() in the same position."); + CHECK_MESSAGE( + image->get_used_rect() == Rect2(0, 0, 1, 1), + "Image's get_used_rect should return the expected value, larger than Rect2(0, 0, 0, 0) if it's visible."); + + image->set_pixelv(Vector2(0, 0), Color(0.5, 0.5, 0.5, 0.5)); + Ref<Image> image2 = memnew(Image(3, 3, false, Image::FORMAT_RGBA8)); + + // Fill image with color + image2->fill(Color(0.5, 0.5, 0.5, 0.5)); + for (int x = 0; x < image2->get_width(); x++) { + for (int y = 0; y < image2->get_height(); y++) { + CHECK_MESSAGE( + image2->get_pixel(x, y).r > 0.49, + "fill() should colorize all pixels of the image."); + } + } + + // Blend two images together + image->blend_rect(image2, Rect2(Vector2(0, 0), image2->get_size()), Vector2(0, 0)); + CHECK_MESSAGE( + image->get_pixel(0, 0).a > 0.7, + "blend_rect() should blend the alpha values of the two images."); + CHECK_MESSAGE( + image->get_used_rect().size == image->get_size(), + "get_used_rect() should return the expected value, its Rect size should be the same as get_size() if there are no transparent pixels."); + + Ref<Image> image3 = memnew(Image(2, 2, false, Image::FORMAT_RGBA8)); + image3->set_pixel(0, 0, Color(0, 1, 0, 1)); + + //blit_rect() two images together + image->blit_rect(image3, Rect2(Vector2(0, 0), image3->get_size()), Vector2(0, 0)); + CHECK_MESSAGE( + image->get_pixel(0, 0).is_equal_approx(Color(0, 1, 0, 1)), + "blit_rect() should replace old colors and not blend them."); + CHECK_MESSAGE( + !image->get_pixel(2, 2).is_equal_approx(Color(0, 1, 0, 1)), + "blit_rect() should not affect the area of the image that is outside src_rect."); + + // Flip image + image3->flip_x(); + CHECK(image3->get_pixel(1, 0).is_equal_approx(Color(0, 1, 0, 1))); + CHECK_MESSAGE( + image3->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0, 0)), + "flip_x() should not leave old pixels behind."); + image3->flip_y(); + CHECK(image3->get_pixel(1, 1).is_equal_approx(Color(0, 1, 0, 1))); + CHECK_MESSAGE( + image3->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 0)), + "flip_y() should not leave old pixels behind."); +} +} // namespace TestImage +#endif // TEST_IMAGE_H diff --git a/tests/test_local_vector.h b/tests/test_local_vector.h new file mode 100644 index 0000000000..eff2a16abc --- /dev/null +++ b/tests/test_local_vector.h @@ -0,0 +1,229 @@ +/*************************************************************************/ +/* test_local_vector.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_LOCAL_VECTOR_H +#define TEST_LOCAL_VECTOR_H + +#include "core/templates/local_vector.h" + +#include "tests/test_macros.h" + +namespace TestLocalVector { + +TEST_CASE("[LocalVector] Push Back.") { + LocalVector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + CHECK(vector[0] == 0); + CHECK(vector[1] == 1); + CHECK(vector[2] == 2); + CHECK(vector[3] == 3); + CHECK(vector[4] == 4); +} + +TEST_CASE("[LocalVector] Find.") { + LocalVector<int> vector; + vector.push_back(3); + vector.push_back(1); + vector.push_back(4); + vector.push_back(0); + vector.push_back(2); + + CHECK(vector[0] == 3); + CHECK(vector[1] == 1); + CHECK(vector[2] == 4); + CHECK(vector[3] == 0); + CHECK(vector[4] == 2); + + CHECK(vector.find(0) == 3); + CHECK(vector.find(1) == 1); + CHECK(vector.find(2) == 4); + CHECK(vector.find(3) == 0); + CHECK(vector.find(4) == 2); + + CHECK(vector.find(-1) == -1); + CHECK(vector.find(5) == -1); +} + +TEST_CASE("[LocalVector] Remove.") { + LocalVector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + vector.remove(0); + + CHECK(vector[0] == 1); + CHECK(vector[1] == 2); + CHECK(vector[2] == 3); + CHECK(vector[3] == 4); + + vector.remove(2); + + CHECK(vector[0] == 1); + CHECK(vector[1] == 2); + CHECK(vector[2] == 4); + + vector.remove(1); + + CHECK(vector[0] == 1); + CHECK(vector[1] == 4); + + vector.remove(0); + + CHECK(vector[0] == 4); +} + +TEST_CASE("[LocalVector] Remove Unordered.") { + LocalVector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + CHECK(vector.size() == 5); + + vector.remove_unordered(0); + + CHECK(vector.size() == 4); + + CHECK(vector.find(0) == -1); + CHECK(vector.find(1) != -1); + CHECK(vector.find(2) != -1); + CHECK(vector.find(3) != -1); + CHECK(vector.find(4) != -1); + + // Now the vector is no more ordered. + vector.remove_unordered(vector.find(3)); + + CHECK(vector.size() == 3); + + CHECK(vector.find(3) == -1); + CHECK(vector.find(1) != -1); + CHECK(vector.find(2) != -1); + CHECK(vector.find(4) != -1); + + vector.remove_unordered(vector.find(2)); + + CHECK(vector.size() == 2); + + CHECK(vector.find(2) == -1); + CHECK(vector.find(1) != -1); + CHECK(vector.find(4) != -1); + + vector.remove_unordered(vector.find(4)); + + CHECK(vector.size() == 1); + + CHECK(vector.find(4) == -1); + CHECK(vector.find(1) != -1); + + // Remove the last one. + vector.remove_unordered(0); + + CHECK(vector.is_empty()); + CHECK(vector.size() == 0); +} + +TEST_CASE("[LocalVector] Erase.") { + LocalVector<int> vector; + vector.push_back(1); + vector.push_back(3); + vector.push_back(0); + vector.push_back(2); + vector.push_back(4); + + CHECK(vector.find(2) == 3); + + vector.erase(2); + + CHECK(vector.find(2) == -1); + CHECK(vector.size() == 4); +} + +TEST_CASE("[LocalVector] Size / Resize / Reserve.") { + LocalVector<int> vector; + + CHECK(vector.is_empty()); + CHECK(vector.size() == 0); + CHECK(vector.get_capacity() == 0); + + vector.resize(10); + + CHECK(vector.size() == 10); + CHECK(vector.get_capacity() >= 10); + + vector.resize(5); + + CHECK(vector.size() == 5); + // Capacity is supposed to change only when the size increase. + CHECK(vector.get_capacity() >= 10); + + vector.remove(0); + vector.remove(0); + vector.remove(0); + + CHECK(vector.size() == 2); + // Capacity is supposed to change only when the size increase. + CHECK(vector.get_capacity() >= 10); + + vector.reset(); + + CHECK(vector.size() == 0); + CHECK(vector.get_capacity() == 0); + + vector.reserve(3); + + CHECK(vector.is_empty()); + CHECK(vector.size() == 0); + CHECK(vector.get_capacity() >= 3); + + vector.push_back(0); + vector.push_back(0); + vector.push_back(0); + + CHECK(vector.size() == 3); + CHECK(vector.get_capacity() >= 3); + + vector.push_back(0); + + CHECK(vector.size() == 4); + CHECK(vector.get_capacity() >= 4); +} +} // namespace TestLocalVector + +#endif // TEST_LOCAL_VECTOR_H diff --git a/tests/test_macros.h b/tests/test_macros.h index d284407667..a13f3abbe7 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -44,6 +44,12 @@ // The test case is marked as failed, but does not fail the entire test run. #define TEST_CASE_MAY_FAIL(name) TEST_CASE(name *doctest::may_fail()) +// Provide aliases to conform with Godot naming conventions (see error macros). +#define TEST_COND(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__) +#define TEST_FAIL(cond, ...) DOCTEST_FAIL(cond, __VA_ARGS__) +#define TEST_FAIL_COND(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__) +#define TEST_FAIL_COND_WARN(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__) + // Temporarily disable error prints to test failure paths. // This allows to avoid polluting the test summary with error messages. // The `_print_error_enabled` boolean is defined in `core/print_string.cpp` and diff --git a/tests/test_main.cpp b/tests/test_main.cpp index ca1fe234c0..7e9f8319a0 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -33,6 +33,7 @@ #include "core/templates/list.h" #include "test_aabb.h" +#include "test_array.h" #include "test_astar.h" #include "test_basis.h" #include "test_class_db.h" @@ -44,11 +45,15 @@ #include "test_expression.h" #include "test_file_access.h" #include "test_geometry_2d.h" +#include "test_geometry_3d.h" #include "test_gradient.h" #include "test_gui.h" +#include "test_image.h" #include "test_json.h" #include "test_list.h" +#include "test_local_vector.h" #include "test_lru.h" +#include "test_marshalls.h" #include "test_math.h" #include "test_method_bind.h" #include "test_node_path.h" @@ -62,11 +67,13 @@ #include "test_random_number_generator.h" #include "test_rect2.h" #include "test_render.h" +#include "test_resource.h" #include "test_shader_lang.h" #include "test_string.h" #include "test_text_server.h" #include "test_validate_testing.h" #include "test_variant.h" +#include "test_xml_parser.h" #include "modules/modules_tests.gen.h" diff --git a/tests/test_marshalls.h b/tests/test_marshalls.h new file mode 100644 index 0000000000..6bd916164e --- /dev/null +++ b/tests/test_marshalls.h @@ -0,0 +1,329 @@ +/*************************************************************************/ +/* test_marshalls.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_MARSHALLS_H +#define TEST_MARSHALLS_H + +#include "core/io/marshalls.h" + +#include "tests/test_macros.h" + +namespace TestMarshalls { + +TEST_CASE("[Marshalls] Unsigned 16 bit integer encoding") { + uint8_t arr[2]; + + unsigned int actual_size = encode_uint16(0x1234, arr); + CHECK(actual_size == sizeof(uint16_t)); + CHECK_MESSAGE(arr[0] == 0x34, "First encoded byte value should be equal to low order byte value."); + CHECK_MESSAGE(arr[1] == 0x12, "Last encoded byte value should be equal to high order byte value."); +} + +TEST_CASE("[Marshalls] Unsigned 32 bit integer encoding") { + uint8_t arr[4]; + + unsigned int actual_size = encode_uint32(0x12345678, arr); + CHECK(actual_size == sizeof(uint32_t)); + CHECK_MESSAGE(arr[0] == 0x78, "First encoded byte value should be equal to low order byte value."); + CHECK(arr[1] == 0x56); + CHECK(arr[2] == 0x34); + CHECK_MESSAGE(arr[3] == 0x12, "Last encoded byte value should be equal to high order byte value."); +} + +TEST_CASE("[Marshalls] Unsigned 64 bit integer encoding") { + uint8_t arr[8]; + + unsigned int actual_size = encode_uint64(0x0f123456789abcdef, arr); + CHECK(actual_size == sizeof(uint64_t)); + CHECK_MESSAGE(arr[0] == 0xef, "First encoded byte value should be equal to low order byte value."); + CHECK(arr[1] == 0xcd); + CHECK(arr[2] == 0xab); + CHECK(arr[3] == 0x89); + CHECK(arr[4] == 0x67); + CHECK(arr[5] == 0x45); + CHECK(arr[6] == 0x23); + CHECK_MESSAGE(arr[7] == 0xf1, "Last encoded byte value should be equal to high order byte value."); +} + +TEST_CASE("[Marshalls] Unsigned 16 bit integer decoding") { + uint8_t arr[] = { 0x34, 0x12 }; + + CHECK(decode_uint16(arr) == 0x1234); +} + +TEST_CASE("[Marshalls] Unsigned 32 bit integer decoding") { + uint8_t arr[] = { 0x78, 0x56, 0x34, 0x12 }; + + CHECK(decode_uint32(arr) == 0x12345678); +} + +TEST_CASE("[Marshalls] Unsigned 64 bit integer decoding") { + uint8_t arr[] = { 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0xf1 }; + + CHECK(decode_uint64(arr) == 0x0f123456789abcdef); +} + +TEST_CASE("[Marshalls] Floating point single precision encoding") { + uint8_t arr[4]; + + // Decimal: 0.15625 + // IEEE 754 single-precision binary floating-point format: + // sign exponent (8 bits) fraction (23 bits) + // 0 01111100 01000000000000000000000 + // Hexadecimal: 0x3E200000 + unsigned int actual_size = encode_float(0.15625f, arr); + CHECK(actual_size == sizeof(uint32_t)); + CHECK(arr[0] == 0x00); + CHECK(arr[1] == 0x00); + CHECK(arr[2] == 0x20); + CHECK(arr[3] == 0x3e); +} + +TEST_CASE("[Marshalls] Floating point double precision encoding") { + uint8_t arr[8]; + + // Decimal: 0.333333333333333314829616256247390992939472198486328125 + // IEEE 754 double-precision binary floating-point format: + // sign exponent (11 bits) fraction (52 bits) + // 0 01111111101 0101010101010101010101010101010101010101010101010101 + // Hexadecimal: 0x3FD5555555555555 + unsigned int actual_size = encode_double(0.33333333333333333, arr); + CHECK(actual_size == sizeof(uint64_t)); + CHECK(arr[0] == 0x55); + CHECK(arr[1] == 0x55); + CHECK(arr[2] == 0x55); + CHECK(arr[3] == 0x55); + CHECK(arr[4] == 0x55); + CHECK(arr[5] == 0x55); + CHECK(arr[6] == 0xd5); + CHECK(arr[7] == 0x3f); +} + +TEST_CASE("[Marshalls] Floating point single precision decoding") { + uint8_t arr[] = { 0x00, 0x00, 0x20, 0x3e }; + + // See floating point encoding test case for details behind expected values + CHECK(decode_float(arr) == 0.15625f); +} + +TEST_CASE("[Marshalls] Floating point double precision decoding") { + uint8_t arr[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x3f }; + + // See floating point encoding test case for details behind expected values + CHECK(decode_double(arr) == 0.33333333333333333); +} + +TEST_CASE("[Marshalls] C string encoding") { + char cstring[] = "Godot"; // 5 characters + uint8_t data[6]; + + int actual_size = encode_cstring(cstring, data); + CHECK(actual_size == 6); + CHECK(data[0] == 'G'); + CHECK(data[1] == 'o'); + CHECK(data[2] == 'd'); + CHECK(data[3] == 'o'); + CHECK(data[4] == 't'); + CHECK(data[5] == '\0'); +} + +TEST_CASE("[Marshalls] NIL Variant encoding") { + int r_len; + Variant variant; + uint8_t buffer[4]; + + CHECK(encode_variant(variant, buffer, r_len) == OK); + CHECK_MESSAGE(r_len == 4, "Length == 4 bytes for Variant::Type"); + CHECK_MESSAGE(buffer[0] == 0x00, "Variant::NIL"); + CHECK(buffer[1] == 0x00); + CHECK(buffer[2] == 0x00); + CHECK(buffer[3] == 0x00); + // No value +} + +TEST_CASE("[Marshalls] INT 32 bit Variant encoding") { + int r_len; + Variant variant(0x12345678); + uint8_t buffer[8]; + + CHECK(encode_variant(variant, buffer, r_len) == OK); + CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for Variant::Type + 4 bytes for int32_t"); + CHECK_MESSAGE(buffer[0] == 0x02, "Variant::INT"); + CHECK(buffer[1] == 0x00); + CHECK(buffer[2] == 0x00); + CHECK(buffer[3] == 0x00); + // Check value + CHECK(buffer[4] == 0x78); + CHECK(buffer[5] == 0x56); + CHECK(buffer[6] == 0x34); + CHECK(buffer[7] == 0x12); +} + +TEST_CASE("[Marshalls] INT 64 bit Variant encoding") { + int r_len; + Variant variant(uint64_t(0x0f123456789abcdef)); + uint8_t buffer[12]; + + CHECK(encode_variant(variant, buffer, r_len) == OK); + CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for Variant::Type + 8 bytes for int64_t"); + CHECK_MESSAGE(buffer[0] == 0x02, "Variant::INT"); + CHECK(buffer[1] == 0x00); + CHECK_MESSAGE(buffer[2] == 0x01, "ENCODE_FLAG_64"); + CHECK(buffer[3] == 0x00); + // Check value + CHECK(buffer[4] == 0xef); + CHECK(buffer[5] == 0xcd); + CHECK(buffer[6] == 0xab); + CHECK(buffer[7] == 0x89); + CHECK(buffer[8] == 0x67); + CHECK(buffer[9] == 0x45); + CHECK(buffer[10] == 0x23); + CHECK(buffer[11] == 0xf1); +} + +TEST_CASE("[Marshalls] FLOAT single precision Variant encoding") { + int r_len; + Variant variant(0.15625f); + uint8_t buffer[8]; + + CHECK(encode_variant(variant, buffer, r_len) == OK); + CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for Variant::Type + 4 bytes for float"); + CHECK_MESSAGE(buffer[0] == 0x03, "Variant::FLOAT"); + CHECK(buffer[1] == 0x00); + CHECK(buffer[2] == 0x00); + CHECK(buffer[3] == 0x00); + // Check value + CHECK(buffer[4] == 0x00); + CHECK(buffer[5] == 0x00); + CHECK(buffer[6] == 0x20); + CHECK(buffer[7] == 0x3e); +} + +TEST_CASE("[Marshalls] FLOAT double precision Variant encoding") { + int r_len; + Variant variant(0.33333333333333333); + uint8_t buffer[12]; + + CHECK(encode_variant(variant, buffer, r_len) == OK); + CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for Variant::Type + 8 bytes for double"); + CHECK_MESSAGE(buffer[0] == 0x03, "Variant::FLOAT"); + CHECK(buffer[1] == 0x00); + CHECK_MESSAGE(buffer[2] == 0x01, "ENCODE_FLAG_64"); + CHECK(buffer[3] == 0x00); + // Check value + CHECK(buffer[4] == 0x55); + CHECK(buffer[5] == 0x55); + CHECK(buffer[6] == 0x55); + CHECK(buffer[7] == 0x55); + CHECK(buffer[8] == 0x55); + CHECK(buffer[9] == 0x55); + CHECK(buffer[10] == 0xd5); + CHECK(buffer[11] == 0x3f); +} + +TEST_CASE("[Marshalls] Invalid data Variant decoding") { + Variant variant; + int r_len = 0; + uint8_t some_buffer[1] = { 0x00 }; + uint8_t out_of_range_type_buffer[4] = { 0xff }; // Greater than Variant::VARIANT_MAX + + CHECK(decode_variant(variant, some_buffer, /* less than 4 */ 1, &r_len) == ERR_INVALID_DATA); + CHECK(r_len == 0); + + CHECK(decode_variant(variant, out_of_range_type_buffer, 4, &r_len) == ERR_INVALID_DATA); + CHECK(r_len == 0); +} + +TEST_CASE("[Marshalls] NIL Variant decoding") { + Variant variant; + int r_len; + uint8_t buffer[] = { + 0x00, 0x00, 0x00, 0x00 // Variant::NIL + }; + + CHECK(decode_variant(variant, buffer, 4, &r_len) == OK); + CHECK(r_len == 4); + CHECK(variant == Variant()); +} + +TEST_CASE("[Marshalls] INT 32 bit Variant decoding") { + Variant variant; + int r_len; + uint8_t buffer[] = { + 0x02, 0x00, 0x00, 0x00, // Variant::INT + 0x78, 0x56, 0x34, 0x12 // value + }; + + CHECK(decode_variant(variant, buffer, 8, &r_len) == OK); + CHECK(r_len == 8); + CHECK(variant == Variant(0x12345678)); +} + +TEST_CASE("[Marshalls] INT 64 bit Variant decoding") { + Variant variant; + int r_len; + uint8_t buffer[] = { + 0x02, 0x00, 0x01, 0x00, // Variant::INT & ENCODE_FLAG_64 + 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0xf1 // value + }; + + CHECK(decode_variant(variant, buffer, 12, &r_len) == OK); + CHECK(r_len == 12); + CHECK(variant == Variant(uint64_t(0x0f123456789abcdef))); +} + +TEST_CASE("[Marshalls] FLOAT single precision Variant decoding") { + Variant variant; + int r_len; + uint8_t buffer[] = { + 0x03, 0x00, 0x00, 0x00, // Variant::FLOAT + 0x00, 0x00, 0x20, 0x3e // value + }; + + CHECK(decode_variant(variant, buffer, 8, &r_len) == OK); + CHECK(r_len == 8); + CHECK(variant == Variant(0.15625f)); +} + +TEST_CASE("[Marshalls] FLOAT double precision Variant decoding") { + Variant variant; + int r_len; + uint8_t buffer[] = { + 0x03, 0x00, 0x01, 0x00, // Variant::FLOAT & ENCODE_FLAG_64 + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x3f // value + }; + + CHECK(decode_variant(variant, buffer, 12, &r_len) == OK); + CHECK(r_len == 12); + CHECK(variant == Variant(0.33333333333333333)); +} +} // namespace TestMarshalls + +#endif // TEST_MARSHALLS_H diff --git a/tests/test_math.cpp b/tests/test_math.cpp index cda0cffda3..26c2aa2088 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -617,7 +617,7 @@ MainLoop *test() { List<String> args; args.push_back("-l"); - Error err = OS::get_singleton()->execute("/bin/ls", args, true, nullptr, &ret); + Error err = OS::get_singleton()->execute("/bin/ls", args, &ret); print_line("error: " + itos(err)); print_line(ret); diff --git a/tests/test_object.h b/tests/test_object.h index 7f310fc096..142d76553d 100644 --- a/tests/test_object.h +++ b/tests/test_object.h @@ -31,12 +31,103 @@ #ifndef TEST_OBJECT_H #define TEST_OBJECT_H +#include "core/core_string_names.h" #include "core/object/object.h" #include "thirdparty/doctest/doctest.h" +// Declared in global namespace because of GDCLASS macro warning (Windows): +// "Unqualified friend declaration referring to type outside of the nearest enclosing namespace +// is a Microsoft extension; add a nested name specifier". +class _TestDerivedObject : public Object { + GDCLASS(_TestDerivedObject, Object); + + int property_value; + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_property", "property"), &_TestDerivedObject::set_property); + ClassDB::bind_method(D_METHOD("get_property"), &_TestDerivedObject::get_property); + ADD_PROPERTY(PropertyInfo(Variant::INT, "property"), "set_property", "get_property"); + } + +public: + void set_property(int value) { property_value = value; } + int get_property() const { return property_value; } +}; + namespace TestObject { +class _MockScriptInstance : public ScriptInstance { + StringName property_name = "NO_NAME"; + Variant property_value; + +public: + bool set(const StringName &p_name, const Variant &p_value) override { + property_name = p_name; + property_value = p_value; + return true; + } + bool get(const StringName &p_name, Variant &r_ret) const override { + if (property_name == p_name) { + r_ret = property_value; + return true; + } + return false; + } + void get_property_list(List<PropertyInfo> *p_properties) const override { + } + Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override { + return Variant::PACKED_FLOAT32_ARRAY; + } + void get_method_list(List<MethodInfo> *p_list) const override { + } + bool has_method(const StringName &p_method) const override { + return false; + } + Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override { + return Variant(); + } + void notification(int p_notification) override { + } + Ref<Script> get_script() const override { + return Ref<Script>(); + } + Vector<ScriptNetData> get_rpc_methods() const override { + return Vector<ScriptNetData>(); + } + uint16_t get_rpc_method_id(const StringName &p_method) const override { + return 0; + } + StringName get_rpc_method(uint16_t p_id) const override { + return StringName(); + } + MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const override { + return MultiplayerAPI::RPC_MODE_PUPPET; + } + MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override { + return MultiplayerAPI::RPC_MODE_PUPPET; + } + Vector<ScriptNetData> get_rset_properties() const override { + return Vector<ScriptNetData>(); + } + uint16_t get_rset_property_id(const StringName &p_variable) const override { + return 0; + } + StringName get_rset_property(uint16_t p_id) const override { + return StringName(); + } + MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const override { + return MultiplayerAPI::RPC_MODE_PUPPET; + } + MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override { + return MultiplayerAPI::RPC_MODE_PUPPET; + } + ScriptLanguage *get_language() override { + return nullptr; + } +}; + TEST_CASE("[Object] Core getters") { Object object; @@ -55,6 +146,15 @@ TEST_CASE("[Object] Core getters") { CHECK_MESSAGE( object.get_save_class() == "Object", "The returned save class should match the expected value."); + + List<String> inheritance_list; + object.get_inheritance_list_static(&inheritance_list); + CHECK_MESSAGE( + inheritance_list.size() == 1, + "The inheritance list should consist of Object only"); + CHECK_MESSAGE( + inheritance_list[0] == "Object", + "The inheritance list should consist of Object only"); } TEST_CASE("[Object] Metadata") { @@ -87,6 +187,119 @@ TEST_CASE("[Object] Metadata") { meta_list2.size() == 0, "The metadata list should contain 0 items after removing all metadata items."); } + +TEST_CASE("[Object] Construction") { + Object object; + + CHECK_MESSAGE( + !object.is_reference(), + "Object is not a Reference."); + + Object *p_db = ObjectDB::get_instance(object.get_instance_id()); + CHECK_MESSAGE( + p_db == &object, + "The database pointer returned by the object id should reference same object."); +} + +TEST_CASE("[Object] Script instance property setter") { + Object object; + _MockScriptInstance *script_instance = memnew(_MockScriptInstance); + object.set_script_instance(script_instance); + + bool valid = false; + object.set("some_name", 100, &valid); + CHECK(valid); + Variant actual_value; + CHECK_MESSAGE( + script_instance->get("some_name", actual_value), + "The assigned script instance should successfully retrieve value by name."); + CHECK_MESSAGE( + actual_value == Variant(100), + "The returned value should equal the one which was set by the object."); +} + +TEST_CASE("[Object] Script instance property getter") { + Object object; + _MockScriptInstance *script_instance = memnew(_MockScriptInstance); + script_instance->set("some_name", 100); // Make sure script instance has the property + object.set_script_instance(script_instance); + + bool valid = false; + const Variant &actual_value = object.get("some_name", &valid); + CHECK(valid); + CHECK_MESSAGE( + actual_value == Variant(100), + "The returned value should equal the one which was set by the script instance."); +} + +TEST_CASE("[Object] Built-in property setter") { + ClassDB::register_class<_TestDerivedObject>(); + _TestDerivedObject derived_object; + + bool valid = false; + derived_object.set("property", 100, &valid); + CHECK(valid); + CHECK_MESSAGE( + derived_object.get_property() == 100, + "The property value should equal the one which was set with built-in setter."); +} + +TEST_CASE("[Object] Built-in property getter") { + ClassDB::register_class<_TestDerivedObject>(); + _TestDerivedObject derived_object; + derived_object.set_property(100); + + bool valid = false; + const Variant &actual_value = derived_object.get("property", &valid); + CHECK(valid); + CHECK_MESSAGE( + actual_value == Variant(100), + "The returned value should equal the one which was set with built-in setter."); +} + +TEST_CASE("[Object] Script property setter") { + Object object; + Variant script; + + bool valid = false; + object.set(CoreStringNames::get_singleton()->_script, script, &valid); + CHECK(valid); + CHECK_MESSAGE( + object.get_script() == script, + "The object script should be equal to the assigned one."); +} + +TEST_CASE("[Object] Script property getter") { + Object object; + Variant script; + object.set_script(script); + + bool valid = false; + const Variant &actual_value = object.get(CoreStringNames::get_singleton()->_script, &valid); + CHECK(valid); + CHECK_MESSAGE( + actual_value == script, + "The returned value should be equal to the assigned script."); +} + +TEST_CASE("[Object] Absent name setter") { + Object object; + + bool valid = true; + object.set("absent_name", 100, &valid); + CHECK(!valid); +} + +TEST_CASE("[Object] Absent name getter") { + Object object; + + bool valid = true; + const Variant &actual_value = object.get("absent_name", &valid); + CHECK(!valid); + CHECK_MESSAGE( + actual_value == Variant(), + "The returned value should equal nil variant."); +} } // namespace TestObject #endif // TEST_OBJECT_H diff --git a/tests/test_path_follow_2d.h b/tests/test_path_follow_2d.h new file mode 100644 index 0000000000..388b690060 --- /dev/null +++ b/tests/test_path_follow_2d.h @@ -0,0 +1,241 @@ +/*************************************************************************/ +/* test_path_follow_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_PATH_FOLLOW_2D_H +#define TEST_PATH_FOLLOW_2D_H + +#include "scene/2d/path_2d.h" +#include "scene/resources/curve.h" + +#include "tests/test_macros.h" + +namespace TestPathFollow2D { + +TEST_CASE("[PathFollow2D] Sampling with unit offset") { + const Ref<Curve2D> &curve = memnew(Curve2D()); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(100, 0)); + curve->add_point(Vector2(100, 100)); + curve->add_point(Vector2(0, 100)); + curve->add_point(Vector2(0, 0)); + const Path2D *path = memnew(Path2D); + path->set_curve(curve); + const PathFollow2D *path_follow_2d = memnew(PathFollow2D); + path->add_child(path_follow_2d); + + path_follow_2d->set_unit_offset(0); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0))); + + path_follow_2d->set_unit_offset(0.125); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 0))); + + path_follow_2d->set_unit_offset(0.25); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 0))); + + path_follow_2d->set_unit_offset(0.375); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 50))); + + path_follow_2d->set_unit_offset(0.5); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 100))); + + path_follow_2d->set_unit_offset(0.625); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 100))); + + path_follow_2d->set_unit_offset(0.75); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 100))); + + path_follow_2d->set_unit_offset(0.875); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 50))); + + path_follow_2d->set_unit_offset(1); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0))); + + memdelete(path); +} + +TEST_CASE("[PathFollow2D] Sampling with offset") { + const Ref<Curve2D> &curve = memnew(Curve2D()); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(100, 0)); + curve->add_point(Vector2(100, 100)); + curve->add_point(Vector2(0, 100)); + curve->add_point(Vector2(0, 0)); + const Path2D *path = memnew(Path2D); + path->set_curve(curve); + const PathFollow2D *path_follow_2d = memnew(PathFollow2D); + path->add_child(path_follow_2d); + + path_follow_2d->set_offset(0); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0))); + + path_follow_2d->set_offset(50); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 0))); + + path_follow_2d->set_offset(100); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 0))); + + path_follow_2d->set_offset(150); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 50))); + + path_follow_2d->set_offset(200); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 100))); + + path_follow_2d->set_offset(250); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 100))); + + path_follow_2d->set_offset(300); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 100))); + + path_follow_2d->set_offset(350); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 50))); + + path_follow_2d->set_offset(400); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0))); + + memdelete(path); +} + +TEST_CASE("[PathFollow2D] Removal of a point in curve") { + const Ref<Curve2D> &curve = memnew(Curve2D()); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(100, 0)); + curve->add_point(Vector2(100, 100)); + const Path2D *path = memnew(Path2D); + path->set_curve(curve); + const PathFollow2D *path_follow_2d = memnew(PathFollow2D); + path->add_child(path_follow_2d); + + path_follow_2d->set_unit_offset(0.5); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 0))); + + curve->remove_point(1); + + CHECK_MESSAGE( + path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 50)), + "Path follow's position should be updated after removing a point from the curve"); + + memdelete(path); +} + +TEST_CASE("[PathFollow2D] Setting h_offset and v_offset") { + const Ref<Curve2D> &curve = memnew(Curve2D()); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(100, 0)); + const Path2D *path = memnew(Path2D); + path->set_curve(curve); + const PathFollow2D *path_follow_2d = memnew(PathFollow2D); + path->add_child(path_follow_2d); + + path_follow_2d->set_unit_offset(0.5); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 0))); + + path_follow_2d->set_h_offset(25); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(75, 0))); + + path_follow_2d->set_v_offset(25); + CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(75, 25))); + + memdelete(path); +} + +TEST_CASE("[PathFollow2D] Unit offset out of range") { + const Ref<Curve2D> &curve = memnew(Curve2D()); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(100, 0)); + const Path2D *path = memnew(Path2D); + path->set_curve(curve); + const PathFollow2D *path_follow_2d = memnew(PathFollow2D); + path->add_child(path_follow_2d); + + path_follow_2d->set_loop(true); + + path_follow_2d->set_unit_offset(-0.3); + CHECK_MESSAGE( + path_follow_2d->get_unit_offset() == 0.7, + "Unit Offset should loop back from the end in the opposite direction"); + + path_follow_2d->set_unit_offset(1.3); + CHECK_MESSAGE( + path_follow_2d->get_unit_offset() == 0.3, + "Unit Offset should loop back from the end in the opposite direction"); + + path_follow_2d->set_loop(false); + + path_follow_2d->set_unit_offset(-0.3); + CHECK_MESSAGE( + path_follow_2d->get_unit_offset() == 0, + "Unit Offset should be clamped at 0"); + + path_follow_2d->set_unit_offset(1.3); + CHECK_MESSAGE( + path_follow_2d->get_unit_offset() == 1, + "Unit Offset should be clamped at 1"); + + memdelete(path); +} + +TEST_CASE("[PathFollow2D] Offset out of range") { + const Ref<Curve2D> &curve = memnew(Curve2D()); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(100, 0)); + const Path2D *path = memnew(Path2D); + path->set_curve(curve); + const PathFollow2D *path_follow_2d = memnew(PathFollow2D); + path->add_child(path_follow_2d); + + path_follow_2d->set_loop(true); + + path_follow_2d->set_offset(-50); + CHECK_MESSAGE( + path_follow_2d->get_offset() == 50, + "Offset should loop back from the end in the opposite direction"); + + path_follow_2d->set_offset(150); + CHECK_MESSAGE( + path_follow_2d->get_offset() == 50, + "Offset should loop back from the end in the opposite direction"); + + path_follow_2d->set_loop(false); + + path_follow_2d->set_offset(-50); + CHECK_MESSAGE( + path_follow_2d->get_offset() == 0, + "Offset should be clamped at 0"); + + path_follow_2d->set_offset(150); + CHECK_MESSAGE( + path_follow_2d->get_offset() == 100, + "Offset should be clamped at 1"); + + memdelete(path); +} +} // namespace TestPathFollow2D + +#endif // TEST_PATH_FOLLOW_2D_H diff --git a/tests/test_path_follow_3d.h b/tests/test_path_follow_3d.h new file mode 100644 index 0000000000..b6b4c88222 --- /dev/null +++ b/tests/test_path_follow_3d.h @@ -0,0 +1,220 @@ +/*************************************************************************/ +/* test_path_follow_3d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_PATH_FOLLOW_3D_H +#define TEST_PATH_FOLLOW_3D_H + +#include "scene/3d/path_3d.h" +#include "scene/resources/curve.h" + +#include "tests/test_macros.h" + +namespace TestPathFollow3D { + +TEST_CASE("[PathFollow3D] Sampling with unit offset") { + const Ref<Curve3D> &curve = memnew(Curve3D()); + curve->add_point(Vector3(0, 0, 0)); + curve->add_point(Vector3(100, 0, 0)); + curve->add_point(Vector3(100, 100, 0)); + curve->add_point(Vector3(100, 100, 100)); + curve->add_point(Vector3(100, 0, 100)); + const Path3D *path = memnew(Path3D); + path->set_curve(curve); + const PathFollow3D *path_follow_3d = memnew(PathFollow3D); + path->add_child(path_follow_3d); + + path_follow_3d->set_unit_offset(0); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0)); + + path_follow_3d->set_unit_offset(0.125); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0)); + + path_follow_3d->set_unit_offset(0.25); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0); + + path_follow_3d->set_unit_offset(0.375); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0))); + + path_follow_3d->set_unit_offset(0.5); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0))); + + path_follow_3d->set_unit_offset(0.625); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50))); + + path_follow_3d->set_unit_offset(0.75); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100))); + + path_follow_3d->set_unit_offset(0.875); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100))); + + path_follow_3d->set_unit_offset(1); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100))); + + memdelete(path); +} + +TEST_CASE("[PathFollow3D] Sampling with offset") { + const Ref<Curve3D> &curve = memnew(Curve3D()); + curve->add_point(Vector3(0, 0, 0)); + curve->add_point(Vector3(100, 0, 0)); + curve->add_point(Vector3(100, 100, 0)); + curve->add_point(Vector3(100, 100, 100)); + curve->add_point(Vector3(100, 0, 100)); + const Path3D *path = memnew(Path3D); + path->set_curve(curve); + const PathFollow3D *path_follow_3d = memnew(PathFollow3D); + path->add_child(path_follow_3d); + + path_follow_3d->set_offset(0); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0)); + + path_follow_3d->set_offset(50); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0)); + + path_follow_3d->set_offset(100); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0); + + path_follow_3d->set_offset(150); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0))); + + path_follow_3d->set_offset(200); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0))); + + path_follow_3d->set_offset(250); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50))); + + path_follow_3d->set_offset(300); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100))); + + path_follow_3d->set_offset(350); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100))); + + path_follow_3d->set_offset(400); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100))); + + memdelete(path); +} + +TEST_CASE("[PathFollow3D] Removal of a point in curve") { + const Ref<Curve3D> &curve = memnew(Curve3D()); + curve->add_point(Vector3(0, 0, 0)); + curve->add_point(Vector3(100, 0, 0)); + curve->add_point(Vector3(100, 100, 0)); + const Path3D *path = memnew(Path3D); + path->set_curve(curve); + const PathFollow3D *path_follow_3d = memnew(PathFollow3D); + path->add_child(path_follow_3d); + + path_follow_3d->set_unit_offset(0.5); + CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(100, 0, 0))); + + curve->remove_point(1); + + CHECK_MESSAGE( + path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(50, 50, 0)), + "Path follow's position should be updated after removing a point from the curve"); + + memdelete(path); +} + +TEST_CASE("[PathFollow3D] Unit offset out of range") { + const Ref<Curve3D> &curve = memnew(Curve3D()); + curve->add_point(Vector3(0, 0, 0)); + curve->add_point(Vector3(100, 0, 0)); + const Path3D *path = memnew(Path3D); + path->set_curve(curve); + const PathFollow3D *path_follow_3d = memnew(PathFollow3D); + path->add_child(path_follow_3d); + + path_follow_3d->set_loop(true); + + path_follow_3d->set_unit_offset(-0.3); + CHECK_MESSAGE( + path_follow_3d->get_unit_offset() == 0.7, + "Unit Offset should loop back from the end in the opposite direction"); + + path_follow_3d->set_unit_offset(1.3); + CHECK_MESSAGE( + path_follow_3d->get_unit_offset() == 0.3, + "Unit Offset should loop back from the end in the opposite direction"); + + path_follow_3d->set_loop(false); + + path_follow_3d->set_unit_offset(-0.3); + CHECK_MESSAGE( + path_follow_3d->get_unit_offset() == 0, + "Unit Offset should be clamped at 0"); + + path_follow_3d->set_unit_offset(1.3); + CHECK_MESSAGE( + path_follow_3d->get_unit_offset() == 1, + "Unit Offset should be clamped at 1"); + + memdelete(path); +} + +TEST_CASE("[PathFollow3D] Offset out of range") { + const Ref<Curve3D> &curve = memnew(Curve3D()); + curve->add_point(Vector3(0, 0, 0)); + curve->add_point(Vector3(100, 0, 0)); + const Path3D *path = memnew(Path3D); + path->set_curve(curve); + const PathFollow3D *path_follow_3d = memnew(PathFollow3D); + path->add_child(path_follow_3d); + + path_follow_3d->set_loop(true); + + path_follow_3d->set_offset(-50); + CHECK_MESSAGE( + path_follow_3d->get_offset() == 50, + "Offset should loop back from the end in the opposite direction"); + + path_follow_3d->set_offset(150); + CHECK_MESSAGE( + path_follow_3d->get_offset() == 50, + "Offset should loop back from the end in the opposite direction"); + + path_follow_3d->set_loop(false); + + path_follow_3d->set_offset(-50); + CHECK_MESSAGE( + path_follow_3d->get_offset() == 0, + "Offset should be clamped at 0"); + + path_follow_3d->set_offset(150); + CHECK_MESSAGE( + path_follow_3d->get_offset() == 100, + "Offset should be clamped at max value of curve"); + + memdelete(path); +} +} // namespace TestPathFollow3D + +#endif // TEST_PATH_FOLLOW_3D_H diff --git a/tests/test_physics_3d.cpp b/tests/test_physics_3d.cpp index a11140cfc3..74afbad9d1 100644 --- a/tests/test_physics_3d.cpp +++ b/tests/test_physics_3d.cpp @@ -59,7 +59,7 @@ class TestPhysics3DMainLoop : public MainLoop { RID character; - float ofs_x, ofs_y; + real_t ofs_x, ofs_y; Point2 joy_direction; @@ -86,7 +86,9 @@ protected: PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape], scenario); - RID body = ps->body_create(p_body, !p_active_default); + RID body = ps->body_create(); + ps->body_set_mode(body, p_body); + ps->body_set_state(body, PhysicsServer3D::BODY_STATE_SLEEPING, !p_active_default); ps->body_set_space(body, space); ps->body_set_param(body, PhysicsServer3D::BODY_PARAM_BOUNCE, 0.0); //todo set space @@ -108,14 +110,16 @@ protected: RID world_margin_shape = ps->shape_create(PhysicsServer3D::SHAPE_PLANE); ps->shape_set_data(world_margin_shape, p_plane); - RID b = ps->body_create(PhysicsServer3D::BODY_MODE_STATIC); + RID b = ps->body_create(); + ps->body_set_mode(b, PhysicsServer3D::BODY_MODE_STATIC); + ps->body_set_space(b, space); //todo set space ps->body_add_shape(b, world_margin_shape); return b; } - void configure_body(RID p_body, float p_mass, float p_friction, float p_bounce) { + void configure_body(RID p_body, real_t p_mass, real_t p_friction, real_t p_bounce) { PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_MASS, p_mass); ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_FRICTION, p_friction); @@ -202,7 +206,8 @@ protected: RID triins = vs->instance_create2(trimesh_mesh, scenario); - RID tribody = ps->body_create(PhysicsServer3D::BODY_MODE_STATIC); + RID tribody = ps->body_create(); + ps->body_set_mode(tribody, PhysicsServer3D::BODY_MODE_STATIC); ps->body_set_space(tribody, space); //todo set space ps->body_add_shape(tribody, trimesh_shape); @@ -211,8 +216,8 @@ protected: vs->instance_set_transform(triins, tritrans); } - void make_grid(int p_width, int p_height, float p_cellsize, float p_cellheight, const Transform &p_xform = Transform()) { - Vector<Vector<float>> grid; + void make_grid(int p_width, int p_height, real_t p_cellsize, real_t p_cellheight, const Transform &p_xform = Transform()) { + Vector<Vector<real_t>> grid; grid.resize(p_width); @@ -253,8 +258,8 @@ public: } if (mm.is_valid() && mm->get_button_mask() & 1) { - float y = -mm->get_relative().y / 20.0; - float x = mm->get_relative().x / 20.0; + real_t y = -mm->get_relative().y / 20.0; + real_t x = mm->get_relative().x / 20.0; if (mover.is_valid()) { PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); @@ -312,7 +317,7 @@ public: } virtual bool physics_process(float p_time) override { if (mover.is_valid()) { - static float joy_speed = 10; + static real_t joy_speed = 10; PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); Transform t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM); t.origin += Vector3(joy_speed * joy_direction.x * p_time, -joy_speed * joy_direction.y * p_time, 0); @@ -358,7 +363,8 @@ public: ps->shape_set_data(capsule_shape, capsule_params); RID mesh_instance = vs->instance_create2(capsule_mesh, scenario); - character = ps->body_create(PhysicsServer3D::BODY_MODE_CHARACTER); + character = ps->body_create(); + ps->body_set_mode(character, PhysicsServer3D::BODY_MODE_CHARACTER); ps->body_set_space(character, space); //todo add space ps->body_add_shape(character, capsule_shape); diff --git a/tests/test_random_number_generator.h b/tests/test_random_number_generator.h index db830d32e0..39c4771c19 100644 --- a/tests/test_random_number_generator.h +++ b/tests/test_random_number_generator.h @@ -73,8 +73,8 @@ TEST_CASE_MAY_FAIL("[RandomNumberGenerator] Integer 32 bit") { break; } } - INFO("Current seed: " << rng->get_seed()); - INFO("Current iteration: " << i); + INFO("Current seed: ", rng->get_seed()); + INFO("Current iteration: ", i); CHECK_MESSAGE(higher, "Given current seed, this should give an integer higher than 0x0fff'ffff at least once."); } @@ -185,13 +185,13 @@ TEST_CASE("[RandomNumberGenerator] Zero for first number immediately after seedi rng->set_seed(0); uint32_t n1 = rng->randi(); uint32_t n2 = rng->randi(); - INFO("Initial random values: " << n1 << " " << n2); + INFO("Initial random values: ", n1, " ", n2); CHECK(n1 != 0); rng->set_seed(1); uint32_t n3 = rng->randi(); uint32_t n4 = rng->randi(); - INFO("Values after changing the seed: " << n3 << " " << n4); + INFO("Values after changing the seed: ", n3, " ", n4); CHECK(n3 != 0); } @@ -199,7 +199,7 @@ TEST_CASE("[RandomNumberGenerator] Restore state") { Ref<RandomNumberGenerator> rng = memnew(RandomNumberGenerator); rng->randomize(); uint64_t last_seed = rng->get_seed(); - INFO("Current seed: " << last_seed); + INFO("Current seed: ", last_seed); rng->randi(); rng->randi(); @@ -208,18 +208,18 @@ TEST_CASE("[RandomNumberGenerator] Restore state") { "The seed should remain the same after generating some numbers"); uint64_t saved_state = rng->get_state(); - INFO("Current state: " << saved_state); + INFO("Current state: ", saved_state); real_t f1_before = rng->randf(); real_t f2_before = rng->randf(); - INFO("This seed produces: " << f1_before << " " << f2_before); + INFO("This seed produces: ", f1_before, " ", f2_before); // Restore now. rng->set_state(saved_state); real_t f1_after = rng->randf(); real_t f2_after = rng->randf(); - INFO("Resetting the state produces: " << f1_after << " " << f2_after); + INFO("Resetting the state produces: ", f1_after, " ", f2_after); String msg = "Should restore the sequence of numbers after resetting the state"; CHECK_MESSAGE(f1_before == f1_after, msg); @@ -229,22 +229,22 @@ TEST_CASE("[RandomNumberGenerator] Restore state") { TEST_CASE("[RandomNumberGenerator] Restore from seed") { Ref<RandomNumberGenerator> rng = memnew(RandomNumberGenerator); rng->set_seed(0); - INFO("Current seed: " << rng->get_seed()); + INFO("Current seed: ", rng->get_seed()); uint32_t s0_1_before = rng->randi(); uint32_t s0_2_before = rng->randi(); - INFO("This seed produces: " << s0_1_before << " " << s0_2_before); + INFO("This seed produces: ", s0_1_before, " ", s0_2_before); rng->set_seed(9000); - INFO("Current seed: " << rng->get_seed()); + INFO("Current seed: ", rng->get_seed()); uint32_t s9000_1 = rng->randi(); uint32_t s9000_2 = rng->randi(); - INFO("This seed produces: " << s9000_1 << " " << s9000_2); + INFO("This seed produces: ", s9000_1, " ", s9000_2); rng->set_seed(0); - INFO("Current seed: " << rng->get_seed()); + INFO("Current seed: ", rng->get_seed()); uint32_t s0_1_after = rng->randi(); uint32_t s0_2_after = rng->randi(); - INFO("This seed produces: " << s0_1_after << " " << s0_2_after); + INFO("This seed produces: ", s0_1_after, " ", s0_2_after); String msg = "Should restore the sequence of numbers after resetting the seed"; CHECK_MESSAGE(s0_1_before == s0_1_after, msg); diff --git a/tests/test_render.cpp b/tests/test_render.cpp index 2a4ae8bd73..72b2840098 100644 --- a/tests/test_render.cpp +++ b/tests/test_render.cpp @@ -183,8 +183,8 @@ public: //vs->light_set_shadow( lightaux, true ); light = vs->instance_create2(lightaux, scenario); Transform lla; - //lla.set_look_at(Vector3(),Vector3(1,-1,1),Vector3(0,1,0)); - lla.set_look_at(Vector3(), Vector3(-0.000000, -0.836026, -0.548690), Vector3(0, 1, 0)); + //lla.set_look_at(Vector3(),Vector3(1, -1, 1)); + lla.set_look_at(Vector3(), Vector3(0.0, -0.836026, -0.548690)); vs->instance_set_transform(light, lla); diff --git a/tests/test_resource.h b/tests/test_resource.h new file mode 100644 index 0000000000..cee3281995 --- /dev/null +++ b/tests/test_resource.h @@ -0,0 +1,114 @@ +/*************************************************************************/ +/* test_resource.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_RESOURCE +#define TEST_RESOURCE + +#include "core/io/resource.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/os.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestResource { + +TEST_CASE("[Resource] Duplication") { + Ref<Resource> resource = memnew(Resource); + resource->set_name("Hello world"); + Ref<Resource> child_resource = memnew(Resource); + child_resource->set_name("I'm a child resource"); + resource->set_meta("other_resource", child_resource); + + Ref<Resource> resource_dupe = resource->duplicate(); + const Ref<Resource> &resource_dupe_reference = resource_dupe; + resource_dupe->set_name("Changed name"); + child_resource->set_name("My name was changed too"); + + CHECK_MESSAGE( + resource_dupe->get_name() == "Changed name", + "Duplicated resource should have the new name."); + CHECK_MESSAGE( + resource_dupe_reference->get_name() == "Changed name", + "Reference to the duplicated resource should have the new name."); + CHECK_MESSAGE( + resource->get_name() == "Hello world", + "Original resource name should not be affected after editing the duplicate's name."); + CHECK_MESSAGE( + Ref<Resource>(resource_dupe->get_meta("other_resource"))->get_name() == "My name was changed too", + "Duplicated resource should share its child resource with the original."); +} + +TEST_CASE("[Resource] Saving and loading") { + Ref<Resource> resource = memnew(Resource); + resource->set_name("Hello world"); + resource->set_meta(" ExampleMetadata ", Vector2i(40, 80)); + resource->set_meta("string", "The\nstring\nwith\nunnecessary\nline\n\t\\\nbreaks"); + Ref<Resource> child_resource = memnew(Resource); + child_resource->set_name("I'm a child resource"); + resource->set_meta("other_resource", child_resource); + const String save_path_binary = OS::get_singleton()->get_cache_path().plus_file("resource.res"); + const String save_path_text = OS::get_singleton()->get_cache_path().plus_file("resource.tres"); + ResourceSaver::save(save_path_binary, resource); + ResourceSaver::save(save_path_text, resource); + + const Ref<Resource> &loaded_resource_binary = ResourceLoader::load(save_path_binary); + CHECK_MESSAGE( + loaded_resource_binary->get_name() == "Hello world", + "The loaded resource name should be equal to the expected value."); + CHECK_MESSAGE( + loaded_resource_binary->get_meta(" ExampleMetadata ") == Vector2i(40, 80), + "The loaded resource metadata should be equal to the expected value."); + CHECK_MESSAGE( + loaded_resource_binary->get_meta("string") == "The\nstring\nwith\nunnecessary\nline\n\t\\\nbreaks", + "The loaded resource metadata should be equal to the expected value."); + const Ref<Resource> &loaded_child_resource_binary = loaded_resource_binary->get_meta("other_resource"); + CHECK_MESSAGE( + loaded_child_resource_binary->get_name() == "I'm a child resource", + "The loaded child resource name should be equal to the expected value."); + + const Ref<Resource> &loaded_resource_text = ResourceLoader::load(save_path_text); + CHECK_MESSAGE( + loaded_resource_text->get_name() == "Hello world", + "The loaded resource name should be equal to the expected value."); + CHECK_MESSAGE( + loaded_resource_text->get_meta(" ExampleMetadata ") == Vector2i(40, 80), + "The loaded resource metadata should be equal to the expected value."); + CHECK_MESSAGE( + loaded_resource_text->get_meta("string") == "The\nstring\nwith\nunnecessary\nline\n\t\\\nbreaks", + "The loaded resource metadata should be equal to the expected value."); + const Ref<Resource> &loaded_child_resource_text = loaded_resource_text->get_meta("other_resource"); + CHECK_MESSAGE( + loaded_child_resource_text->get_name() == "I'm a child resource", + "The loaded child resource name should be equal to the expected value."); +} +} // namespace TestResource + +#endif // TEST_RESOURCE diff --git a/tests/test_string.h b/tests/test_string.h index 17a2df190d..17f24fb0d8 100644 --- a/tests/test_string.h +++ b/tests/test_string.h @@ -266,7 +266,7 @@ TEST_CASE("[String] Operator []") { a[6] = 'C'; CHECK(a == "Sugar Cane"); CHECK(a[1] == 'u'); - CHECK(a.ord_at(1) == 'u'); + CHECK(a.unicode_at(1) == 'u'); } TEST_CASE("[String] Case function test") { @@ -370,12 +370,9 @@ TEST_CASE("[String] String to integer") { TEST_CASE("[String] Hex to integer") { static const char *nums[4] = { "0xFFAE", "22", "0", "AADDAD" }; static const int64_t num[4] = { 0xFFAE, 0x22, 0, 0xAADDAD }; - static const bool wo_prefix[4] = { false, true, true, true }; - static const bool w_prefix[4] = { true, false, true, false }; for (int i = 0; i < 4; i++) { - CHECK((String(nums[i]).hex_to_int(true) == num[i]) == w_prefix[i]); - CHECK((String(nums[i]).hex_to_int(false) == num[i]) == wo_prefix[i]); + CHECK(String(nums[i]).hex_to_int() == num[i]); } } @@ -1155,20 +1152,12 @@ TEST_CASE("[String] hash") { CHECK(a.hash64() != c.hash64()); } -TEST_CASE("[String] http_escape/unescape") { +TEST_CASE("[String] uri_encode/unescape") { String s = "Godot Engine:'docs'"; String t = "Godot%20Engine%3A%27docs%27"; - CHECK(s.http_escape() == t); - CHECK(t.http_unescape() == s); -} - -TEST_CASE("[String] percent_encode/decode") { // Note: is it redundant? Seems to be same as http_escape/unescape but in lower case. - String s = "Godot Engine:'docs'"; - String t = "Godot%20Engine%3a%27docs%27"; - - CHECK(s.percent_encode() == t); - CHECK(t.percent_decode() == s); + CHECK(s.uri_encode() == t); + CHECK(t.uri_decode() == s); } TEST_CASE("[String] xml_escape/unescape") { @@ -1177,6 +1166,52 @@ TEST_CASE("[String] xml_escape/unescape") { CHECK(s.xml_escape(false).xml_unescape() == s); } +TEST_CASE("[String] xml_unescape") { + // Named entities + String input = ""&'<>"; + CHECK(input.xml_unescape() == "\"&\'<>"); + + // Numeric entities + input = "AB"; + CHECK(input.xml_unescape() == "AB"); + + input = "�&x#0;More text"; + String result = input.xml_unescape(); + // Didn't put in a leading NUL and terminate the string + CHECK(input.length() > 0); + CHECK(input[0] != '\0'); + // Entity should be left as-is if invalid + CHECK(input.xml_unescape() == input); + + // Check near char32_t range + input = "�"; + result = input.xml_unescape(); + CHECK(result.length() == 1); + CHECK(result[0] == 0xFFFFFFFF); + input = "�"; + result = input.xml_unescape(); + CHECK(result.length() == 1); + CHECK(result[0] == 0xFFFFFFFF); + + // Check out of range of char32_t + input = "�"; + CHECK(input.xml_unescape() == input); + input = "�"; + CHECK(input.xml_unescape() == input); + + // Shouldn't consume without ending in a ';' + input = "B"; + CHECK(input.xml_unescape() == input); + input = "A"; + CHECK(input.xml_unescape() == input); + + // Invalid characters should make the entity ignored + input = "ASomeIrrelevantText;"; + CHECK(input.xml_unescape() == input); + input = "BSomeIrrelevantText;"; + CHECK(input.xml_unescape() == input); +} + TEST_CASE("[String] Strip escapes") { String s = "\t\tTest Test\r\n Test"; CHECK(s.strip_escapes() == "Test Test Test"); diff --git a/tests/test_text_server.h b/tests/test_text_server.h index d981ebd5fd..b0b40447fe 100644 --- a/tests/test_text_server.h +++ b/tests/test_text_server.h @@ -45,7 +45,7 @@ TEST_SUITE("[[TextServer]") { SUBCASE("[TextServer] Init") { for (int i = 0; i < TextServerManager::get_interface_count(); i++) { TextServer *ts = TextServerManager::initialize(i, err); - TEST_FAIL_COND((err != OK || ts == nullptr), "Text server " + TextServerManager::get_interface_name(i) + " init failed."); + TEST_FAIL_COND((err != OK || ts == nullptr), "Text server ", TextServerManager::get_interface_name(i), " init failed."); } } diff --git a/tests/test_validate_testing.h b/tests/test_validate_testing.h index cb6c037795..6d3eea724c 100644 --- a/tests/test_validate_testing.h +++ b/tests/test_validate_testing.h @@ -179,10 +179,8 @@ TEST_SUITE("Validate tests") { color_arr.push_back(Color(2, 2, 2)); INFO(color_arr); - INFO("doctest insertion operator << " - << var << " " << vec2 << " " << rect2 << " " << color); - - CHECK(true); // So all above prints. + // doctest string concatenation. + CHECK_MESSAGE(true, var, " ", vec2, " ", rect2, " ", color); } } diff --git a/tests/test_variant.h b/tests/test_variant.h index f8fa852bf4..dfc72b512c 100644 --- a/tests/test_variant.h +++ b/tests/test_variant.h @@ -105,6 +105,600 @@ TEST_CASE("[Variant] Writer and parser float") { CHECK_MESSAGE(b64_float_parsed == 340282001837565597733306976381245063168.0, "Should not overflow."); } + +TEST_CASE("[Variant] Assignment To Bool from Int,Float,String,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant int_v = 0; + Variant bool_v = true; + int_v = bool_v; // int_v is now a bool + CHECK(int_v == Variant(true)); + bool_v = false; + int_v = bool_v; + CHECK(int_v.get_type() == Variant::BOOL); + + Variant float_v = 0.0f; + bool_v = true; + float_v = bool_v; + CHECK(float_v == Variant(true)); + bool_v = false; + float_v = bool_v; + CHECK(float_v.get_type() == Variant::BOOL); + + Variant string_v = ""; + bool_v = true; + string_v = bool_v; + CHECK(string_v == Variant(true)); + bool_v = false; + string_v = bool_v; + CHECK(string_v.get_type() == Variant::BOOL); + + Variant vec2_v = Vector2(0, 0); + bool_v = true; + vec2_v = bool_v; + CHECK(vec2_v == Variant(true)); + bool_v = false; + vec2_v = bool_v; + CHECK(vec2_v.get_type() == Variant::BOOL); + + Variant vec2i_v = Vector2i(0, 0); + bool_v = true; + vec2i_v = bool_v; + CHECK(vec2i_v == Variant(true)); + bool_v = false; + vec2i_v = bool_v; + CHECK(vec2i_v.get_type() == Variant::BOOL); + + Variant vec3_v = Vector3(0, 0, 0); + bool_v = true; + vec3_v = bool_v; + CHECK(vec3_v == Variant(true)); + bool_v = false; + vec3_v = bool_v; + CHECK(vec3_v.get_type() == Variant::BOOL); + + Variant vec3i_v = Vector3i(0, 0, 0); + bool_v = true; + vec3i_v = bool_v; + CHECK(vec3i_v == Variant(true)); + bool_v = false; + vec3i_v = bool_v; + CHECK(vec3i_v.get_type() == Variant::BOOL); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + bool_v = true; + col_v = bool_v; + CHECK(col_v == Variant(true)); + bool_v = false; + col_v = bool_v; + CHECK(col_v.get_type() == Variant::BOOL); +} + +TEST_CASE("[Variant] Assignment To Int from Bool,Float,String,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant int_v = 2; + bool_v = int_v; // Now bool_v is int + CHECK(bool_v == Variant(2)); + int_v = -3; + bool_v = int_v; + CHECK(bool_v.get_type() == Variant::INT); + + Variant float_v = 0.0f; + int_v = 2; + float_v = int_v; + CHECK(float_v == Variant(2)); + int_v = -3; + float_v = int_v; + CHECK(float_v.get_type() == Variant::INT); + + Variant string_v = ""; + int_v = 2; + string_v = int_v; + CHECK(string_v == Variant(2)); + int_v = -3; + string_v = int_v; + CHECK(string_v.get_type() == Variant::INT); + + Variant vec2_v = Vector2(0, 0); + int_v = 2; + vec2_v = int_v; + CHECK(vec2_v == Variant(2)); + int_v = -3; + vec2_v = int_v; + CHECK(vec2_v.get_type() == Variant::INT); + + Variant vec2i_v = Vector2i(0, 0); + int_v = 2; + vec2i_v = int_v; + CHECK(vec2i_v == Variant(2)); + int_v = -3; + vec2i_v = int_v; + CHECK(vec2i_v.get_type() == Variant::INT); + + Variant vec3_v = Vector3(0, 0, 0); + int_v = 2; + vec3_v = int_v; + CHECK(vec3_v == Variant(2)); + int_v = -3; + vec3_v = int_v; + CHECK(vec3_v.get_type() == Variant::INT); + + Variant vec3i_v = Vector3i(0, 0, 0); + int_v = 2; + vec3i_v = int_v; + CHECK(vec3i_v == Variant(2)); + int_v = -3; + vec3i_v = int_v; + CHECK(vec3i_v.get_type() == Variant::INT); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + int_v = 2; + col_v = int_v; + CHECK(col_v == Variant(2)); + int_v = -3; + col_v = int_v; + CHECK(col_v.get_type() == Variant::INT); +} + +TEST_CASE("[Variant] Assignment To Float from Bool,Int,String,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant float_v = 1.5f; + bool_v = float_v; // Now bool_v is float + CHECK(bool_v == Variant(1.5f)); + float_v = -4.6f; + bool_v = float_v; + CHECK(bool_v.get_type() == Variant::FLOAT); + + Variant int_v = 1; + float_v = 1.5f; + int_v = float_v; + CHECK(int_v == Variant(1.5f)); + float_v = -4.6f; + int_v = float_v; + CHECK(int_v.get_type() == Variant::FLOAT); + + Variant string_v = ""; + float_v = 1.5f; + string_v = float_v; + CHECK(string_v == Variant(1.5f)); + float_v = -4.6f; + string_v = float_v; + CHECK(string_v.get_type() == Variant::FLOAT); + + Variant vec2_v = Vector2(0, 0); + float_v = 1.5f; + vec2_v = float_v; + CHECK(vec2_v == Variant(1.5f)); + float_v = -4.6f; + vec2_v = float_v; + CHECK(vec2_v.get_type() == Variant::FLOAT); + + Variant vec2i_v = Vector2i(0, 0); + float_v = 1.5f; + vec2i_v = float_v; + CHECK(vec2i_v == Variant(1.5f)); + float_v = -4.6f; + vec2i_v = float_v; + CHECK(vec2i_v.get_type() == Variant::FLOAT); + + Variant vec3_v = Vector3(0, 0, 0); + float_v = 1.5f; + vec3_v = float_v; + CHECK(vec3_v == Variant(1.5f)); + float_v = -4.6f; + vec3_v = float_v; + CHECK(vec3_v.get_type() == Variant::FLOAT); + + Variant vec3i_v = Vector3i(0, 0, 0); + float_v = 1.5f; + vec3i_v = float_v; + CHECK(vec3i_v == Variant(1.5f)); + float_v = -4.6f; + vec3i_v = float_v; + CHECK(vec3i_v.get_type() == Variant::FLOAT); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + float_v = 1.5f; + col_v = float_v; + CHECK(col_v == Variant(1.5f)); + float_v = -4.6f; + col_v = float_v; + CHECK(col_v.get_type() == Variant::FLOAT); +} + +TEST_CASE("[Variant] Assignment To String from Bool,Int,Float,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant string_v = "Hello"; + bool_v = string_v; // Now bool_v is string + CHECK(bool_v == Variant("Hello")); + string_v = "Hello there"; + bool_v = string_v; + CHECK(bool_v.get_type() == Variant::STRING); + + Variant int_v = 0; + string_v = "Hello"; + int_v = string_v; + CHECK(int_v == Variant("Hello")); + string_v = "Hello there"; + int_v = string_v; + CHECK(int_v.get_type() == Variant::STRING); + + Variant float_v = 0.0f; + string_v = "Hello"; + float_v = string_v; + CHECK(float_v == Variant("Hello")); + string_v = "Hello there"; + float_v = string_v; + CHECK(float_v.get_type() == Variant::STRING); + + Variant vec2_v = Vector2(0, 0); + string_v = "Hello"; + vec2_v = string_v; + CHECK(vec2_v == Variant("Hello")); + string_v = "Hello there"; + vec2_v = string_v; + CHECK(vec2_v.get_type() == Variant::STRING); + + Variant vec2i_v = Vector2i(0, 0); + string_v = "Hello"; + vec2i_v = string_v; + CHECK(vec2i_v == Variant("Hello")); + string_v = "Hello there"; + vec2i_v = string_v; + CHECK(vec2i_v.get_type() == Variant::STRING); + + Variant vec3_v = Vector3(0, 0, 0); + string_v = "Hello"; + vec3_v = string_v; + CHECK(vec3_v == Variant("Hello")); + string_v = "Hello there"; + vec3_v = string_v; + CHECK(vec3_v.get_type() == Variant::STRING); + + Variant vec3i_v = Vector3i(0, 0, 0); + string_v = "Hello"; + vec3i_v = string_v; + CHECK(vec3i_v == Variant("Hello")); + string_v = "Hello there"; + vec3i_v = string_v; + CHECK(vec3i_v.get_type() == Variant::STRING); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + string_v = "Hello"; + col_v = string_v; + CHECK(col_v == Variant("Hello")); + string_v = "Hello there"; + col_v = string_v; + CHECK(col_v.get_type() == Variant::STRING); +} + +TEST_CASE("[Variant] Assignment To Vec2 from Bool,Int,Float,String,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant vec2_v = Vector2(2.2f, 3.5f); + bool_v = vec2_v; // Now bool_v is Vector2 + CHECK(bool_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + bool_v = vec2_v; + CHECK(bool_v.get_type() == Variant::VECTOR2); + + Variant int_v = 0; + vec2_v = Vector2(2.2f, 3.5f); + int_v = vec2_v; + CHECK(int_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + int_v = vec2_v; + CHECK(int_v.get_type() == Variant::VECTOR2); + + Variant float_v = 0.0f; + vec2_v = Vector2(2.2f, 3.5f); + float_v = vec2_v; + CHECK(float_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + float_v = vec2_v; + CHECK(float_v.get_type() == Variant::VECTOR2); + + Variant string_v = ""; + vec2_v = Vector2(2.2f, 3.5f); + string_v = vec2_v; + CHECK(string_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + string_v = vec2_v; + CHECK(string_v.get_type() == Variant::VECTOR2); + + Variant vec2i_v = Vector2i(0, 0); + vec2_v = Vector2(2.2f, 3.5f); + vec2i_v = vec2_v; + CHECK(vec2i_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + vec2i_v = vec2_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR2); + + Variant vec3_v = Vector3(0, 0, 0); + vec2_v = Vector2(2.2f, 3.5f); + vec3_v = vec2_v; + CHECK(vec3_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + vec3_v = vec2_v; + CHECK(vec3_v.get_type() == Variant::VECTOR2); + + Variant vec3i_v = Vector3i(0, 0, 0); + vec2_v = Vector2(2.2f, 3.5f); + vec3i_v = vec2_v; + CHECK(vec3i_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + vec3i_v = vec2_v; + CHECK(vec3i_v.get_type() == Variant::VECTOR2); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec2_v = Vector2(2.2f, 3.5f); + col_v = vec2_v; + CHECK(col_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + col_v = vec2_v; + CHECK(col_v.get_type() == Variant::VECTOR2); +} + +TEST_CASE("[Variant] Assignment To Vec2i from Bool,Int,Float,String,Vec2,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant vec2i_v = Vector2i(2, 3); + bool_v = vec2i_v; // Now bool_v is Vector2i + CHECK(bool_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + bool_v = vec2i_v; + CHECK(bool_v.get_type() == Variant::VECTOR2I); + + Variant int_v = 0; + vec2i_v = Vector2i(2, 3); + int_v = vec2i_v; + CHECK(int_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + int_v = vec2i_v; + CHECK(int_v.get_type() == Variant::VECTOR2I); + + Variant float_v = 0.0f; + vec2i_v = Vector2i(2, 3); + float_v = vec2i_v; + CHECK(float_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + float_v = vec2i_v; + CHECK(float_v.get_type() == Variant::VECTOR2I); + + Variant string_v = ""; + vec2i_v = Vector2i(2, 3); + string_v = vec2i_v; + CHECK(string_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + string_v = vec2i_v; + CHECK(string_v.get_type() == Variant::VECTOR2I); + + Variant vec2_v = Vector2(0, 0); + vec2i_v = Vector2i(2, 3); + vec2_v = vec2i_v; + CHECK(vec2_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + vec2_v = vec2i_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR2I); + + Variant vec3_v = Vector3(0, 0, 0); + vec2i_v = Vector2i(2, 3); + vec3_v = vec2i_v; + CHECK(vec3_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + vec3_v = vec2i_v; + CHECK(vec3_v.get_type() == Variant::VECTOR2I); + + Variant vec3i_v = Vector3i(0, 0, 0); + vec2i_v = Vector2i(2, 3); + vec3i_v = vec2i_v; + CHECK(vec3i_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + vec3i_v = vec2i_v; + CHECK(vec3i_v.get_type() == Variant::VECTOR2I); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec2i_v = Vector2i(2, 3); + col_v = vec2i_v; + CHECK(col_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + col_v = vec2i_v; + CHECK(col_v.get_type() == Variant::VECTOR2I); +} + +TEST_CASE("[Variant] Assignment To Vec3 from Bool,Int,Float,String,Vec2,Vec2i,Vec3i and Color") { + Variant bool_v = false; + Variant vec3_v = Vector3(2.2f, 3.5f, 5.3f); + bool_v = vec3_v; // Now bool_v is Vector3 + CHECK(bool_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + bool_v = vec3_v; + CHECK(bool_v.get_type() == Variant::VECTOR3); + + Variant int_v = 0; + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + int_v = vec3_v; + CHECK(int_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + int_v = vec3_v; + CHECK(int_v.get_type() == Variant::VECTOR3); + + Variant float_v = 0.0f; + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + float_v = vec3_v; + CHECK(float_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + float_v = vec3_v; + CHECK(float_v.get_type() == Variant::VECTOR3); + + Variant string_v = ""; + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + string_v = vec3_v; + CHECK(string_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + string_v = vec3_v; + CHECK(string_v.get_type() == Variant::VECTOR3); + + Variant vec2_v = Vector2(0, 0); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + vec2_v = vec3_v; + CHECK(vec2_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + vec2_v = vec3_v; + CHECK(vec2_v.get_type() == Variant::VECTOR3); + + Variant vec2i_v = Vector2i(0, 0); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + vec2i_v = vec3_v; + CHECK(vec2i_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + vec2i_v = vec3_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR3); + + Variant vec3i_v = Vector3i(0, 0, 0); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + vec3i_v = vec3_v; + CHECK(vec3i_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + vec3i_v = vec3_v; + CHECK(vec3i_v.get_type() == Variant::VECTOR3); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + col_v = vec3_v; + CHECK(col_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + col_v = vec3_v; + CHECK(col_v.get_type() == Variant::VECTOR3); +} + +TEST_CASE("[Variant] Assignment To Vec3i from Bool,Int,Float,String,Vec2,Vec2i,Vec3 and Color") { + Variant bool_v = false; + Variant vec3i_v = Vector3i(2, 3, 5); + bool_v = vec3i_v; // Now bool_v is Vector3i + CHECK(bool_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + bool_v = vec3i_v; + CHECK(bool_v.get_type() == Variant::VECTOR3I); + + Variant int_v = 0; + vec3i_v = Vector3i(2, 3, 5); + int_v = vec3i_v; + CHECK(int_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + int_v = vec3i_v; + CHECK(int_v.get_type() == Variant::VECTOR3I); + + Variant float_v = 0.0f; + vec3i_v = Vector3i(2, 3, 5); + float_v = vec3i_v; + CHECK(float_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + float_v = vec3i_v; + CHECK(float_v.get_type() == Variant::VECTOR3I); + + Variant string_v = ""; + vec3i_v = Vector3i(2, 3, 5); + string_v = vec3i_v; + CHECK(string_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + string_v = vec3i_v; + CHECK(string_v.get_type() == Variant::VECTOR3I); + + Variant vec2_v = Vector2(0, 0); + vec3i_v = Vector3i(2, 3, 5); + vec2_v = vec3i_v; + CHECK(vec2_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + vec2_v = vec3i_v; + CHECK(vec2_v.get_type() == Variant::VECTOR3I); + + Variant vec2i_v = Vector2i(0, 0); + vec3i_v = Vector3i(2, 3, 5); + vec2i_v = vec3i_v; + CHECK(vec2i_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + vec2i_v = vec3i_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR3I); + + Variant vec3_v = Vector3(0, 0, 0); + vec3i_v = Vector3i(2, 3, 5); + vec3_v = vec3i_v; + CHECK(vec3_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + vec3_v = vec3i_v; + CHECK(vec3_v.get_type() == Variant::VECTOR3I); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec3i_v = Vector3i(2, 3, 5); + col_v = vec3i_v; + CHECK(col_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + col_v = vec3i_v; + CHECK(col_v.get_type() == Variant::VECTOR3I); +} + +TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,Vec3 and Vec3i") { + Variant bool_v = false; + Variant col_v = Color(0.25f, 0.4f, 0.78f); + bool_v = col_v; // Now bool_v is Color + CHECK(bool_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + bool_v = col_v; + CHECK(bool_v.get_type() == Variant::COLOR); + + Variant int_v = 0; + col_v = Color(0.25f, 0.4f, 0.78f); + int_v = col_v; + CHECK(int_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + int_v = col_v; + CHECK(int_v.get_type() == Variant::COLOR); + + Variant float_v = 0.0f; + col_v = Color(0.25f, 0.4f, 0.78f); + float_v = col_v; + CHECK(float_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + float_v = col_v; + CHECK(float_v.get_type() == Variant::COLOR); + + Variant string_v = ""; + col_v = Color(0.25f, 0.4f, 0.78f); + string_v = col_v; + CHECK(string_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + string_v = col_v; + CHECK(string_v.get_type() == Variant::COLOR); + + Variant vec2_v = Vector2(0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec2_v = col_v; + CHECK(vec2_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec2_v = col_v; + CHECK(vec2_v.get_type() == Variant::COLOR); + + Variant vec2i_v = Vector2i(0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec2i_v = col_v; + CHECK(vec2i_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec2i_v = col_v; + CHECK(vec2i_v.get_type() == Variant::COLOR); + + Variant vec3_v = Vector3(0, 0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec3_v = col_v; + CHECK(vec3_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec3_v = col_v; + CHECK(vec3_v.get_type() == Variant::COLOR); + + Variant vec3i_v = Vector3i(0, 0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec3i_v = col_v; + CHECK(vec3i_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec3i_v = col_v; + CHECK(vec3i_v.get_type() == Variant::COLOR); +} } // namespace TestVariant #endif // TEST_VARIANT_H diff --git a/drivers/windows/rw_lock_windows.cpp b/tests/test_xml_parser.h index 6f59e072bb..55de048d6a 100644 --- a/drivers/windows/rw_lock_windows.cpp +++ b/tests/test_xml_parser.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rw_lock_windows.cpp */ +/* test_xml_parser.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,60 +28,47 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if defined(WINDOWS_ENABLED) +#ifndef TEST_XML_PARSER_H +#define TEST_XML_PARSER_H -#include "rw_lock_windows.h" +#include <inttypes.h> -#include "core/error/error_macros.h" -#include "core/os/memory.h" +#include "core/io/xml_parser.h" +#include "core/string/ustring.h" -#include <stdio.h> +#include "tests/test_macros.h" -void RWLockWindows::read_lock() { - AcquireSRWLockShared(&lock); -} - -void RWLockWindows::read_unlock() { - ReleaseSRWLockShared(&lock); -} - -Error RWLockWindows::read_try_lock() { - if (TryAcquireSRWLockShared(&lock) == 0) { - return ERR_BUSY; - } else { - return OK; - } -} - -void RWLockWindows::write_lock() { - AcquireSRWLockExclusive(&lock); -} +namespace TestXMLParser { +TEST_CASE("[XMLParser] End-to-end") { + String source = "<?xml version = \"1.0\" encoding=\"UTF-8\" ?>\ +<top attr=\"attr value\">\ + Text<AB>\ +</top>"; + Vector<uint8_t> buff = source.to_utf8_buffer(); -void RWLockWindows::write_unlock() { - ReleaseSRWLockExclusive(&lock); -} + XMLParser parser; + parser.open_buffer(buff); -Error RWLockWindows::write_try_lock() { - if (TryAcquireSRWLockExclusive(&lock) == 0) { - return ERR_BUSY; - } else { - return OK; - } -} + // <?xml ...?> gets parsed as NODE_UNKNOWN + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_UNKNOWN); -RWLock *RWLockWindows::create_func_windows() { - return memnew(RWLockWindows); -} + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT); + CHECK(parser.get_node_name() == "top"); + CHECK(parser.has_attribute("attr")); + CHECK(parser.get_attribute_value("attr") == "attr value"); -void RWLockWindows::make_default() { - create_func = create_func_windows; -} + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_TEXT); + CHECK(parser.get_node_data().lstrip(" \t") == "Text<AB>"); -RWLockWindows::RWLockWindows() { - InitializeSRWLock(&lock); -} + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT_END); + CHECK(parser.get_node_name() == "top"); -RWLockWindows::~RWLockWindows() { + parser.close(); } +} // namespace TestXMLParser -#endif +#endif // TEST_XML_PARSER_H diff --git a/thirdparty/README.md b/thirdparty/README.md index dd937dcfec..3803e87fea 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -3,7 +3,6 @@ Please keep categories (`##` level) listed alphabetically and matching their respective folder names. Use two empty lines to separate categories for readability. -Subcategories (`###` level) where needed are separated by a single empty line. ## basis_universal @@ -46,7 +45,7 @@ as it's generated on the user's system.) ## cvtt - Upstream: https://github.com/elasota/cvtt -- Version: 1.0.0-beta4 (2018) +- Version: 1.0.0-beta4 (cc8472a04ba110fe999c686d07af40f7839051fd, 2018) - License: MIT Files extracted from upstream source: @@ -55,16 +54,18 @@ Files extracted from upstream source: ## doctest + - Upstream: https://github.com/onqtam/doctest -- Version: 8424be5 (2.4.1) +- Version: 2.4.4 (97d5a9447e66cd5e107b7a6c463be4a468a40496, 2020) - License: MIT Extracted from .zip provided. Extracted license and header only. + ## enet - Upstream: http://enet.bespin.org -- Version: 1.3.15 (224f31101fc60939c02f6bbe8e8fc810a7db306b, 2020) +- Version: 1.3.17 (e0e7045b7e056b454b5093cb34df49dc4cee0bee, 2020) - License: MIT Files extracted from upstream source: @@ -74,11 +75,11 @@ Files extracted from upstream source: - LICENSE file Important: enet.h, host.c, protocol.c have been slightly modified -to be usable by godot socket implementation and allow IPv6 and DTLS. +to be usable by Godot's socket implementation and allow IPv6 and DTLS. Apply the patches in the `patches/` folder when syncing on newer upstream commits. -Two files (godot.cpp and enet/godot.h) have been added to provide +Three files (godot.cpp, enet/godot.h, enet/godot_ext.h) have been added to provide enet socket implementation using Godot classes. It is still possible to build against a system wide ENet but doing so @@ -103,37 +104,31 @@ comments. ## fonts -### Noto Sans - -- Upstream: https://github.com/googlei18n/noto-fonts -- Version: 1.06 (2017) -- License: OFL-1.1 - -Use UI font variant if available, because it has tight vertical metrics and good for UI. - -### Hack Regular - -- Upstream: https://github.com/source-foundry/Hack -- Version: 3.003 (2018) -- License: MIT + Bitstream Vera License - -### DroidSans*.ttf - -- Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/ -- Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted) -- License: Apache 2.0 - -### Tamsyn -- Upstream: http://www.fial.com/~scott/tamsyn-font/ -- Version: 1.11 -- License: Tamsyn +- `NotoSans*.ttf`, `NotoNaskhArabicUI_Regular.ttf`: + * Upstream: https://github.com/googlei18n/noto-fonts + * Version: 1.06 (2017) + * License: OFL-1.1 + * Comment: Use UI font variant if available, because it has tight vertical metrics and + good for UI. +- `Hack_Regular.ttf`: + * Upstream: https://github.com/source-foundry/Hack + * Version: 3.003 (2018) + * License: MIT + Bitstream Vera License +- `DroidSans*.ttf`: + * Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/ + * Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted) + * License: Apache 2.0 +- `Tamsyn*.png`: + * Upstream: http://www.fial.com/~scott/tamsyn-font/ + * Version: 1.11 (2015) + * License: Tamsyn + * Comment: Extracted "0..9,A..F" characters for hex code printing. -Extracted "0..9,A..F" characters for hex code printing. ## freetype - Upstream: https://www.freetype.org -- Version: 2.10.4 (2020) +- Version: 2.10.4 (6a2b3e4007e794bfc6c91030d0ed987f925164a8, 2020) - License: FreeType License (BSD-like) Files extracted from upstream source: @@ -162,45 +157,55 @@ Files extracted from upstream source: - `LICENSE.txt` - Unnecessary files like `CMakeLists.txt` and `updateGrammar` removed. -## Graphite engine + +## graphite - Upstream: https://github.com/silnrsi/graphite -- Version: 1.3.14 +- Version: 1.3.14 (92f59dcc52f73ce747f1cdc831579ed2546884aa, 2020) - License: MPL-2.0 Files extracted from upstream source: + - the `include` folder - the `src` folder - `COPYING`, `ChangeLog` -## HarfBuzz + +## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 2.7.4 -- License: HarfBuzz +- Version: 2.7.4 (7236c7e29cef1c2d76c7a284c5081ff4d3aa1127, 2020) +- License: MIT Files extracted from upstream source: + - the `src` folder - `AUTHORS`, `COPYING`, `NEWS`, `THANKS` -## International Components for Unicode + +## icu4c - Upstream: https://github.com/unicode-org/icu -- Version: 68.2 +- Version: 68.2 (84e1f26ea77152936e70d53178a816dbfbf69989, 2020) - License: Unicode Files extracted from upstream source: + - the `common` folder - `APIChangeReport.md`, `LICENSE` Files generated from upstream source: -- the `icudt68l.dat` built with the provided `godot_data.json` config file (see https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md for instructions) + +- the `icudt68l.dat` built with the provided `godot_data.json` config file (see + https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md + for instructions) + ## jpeg-compressor - Upstream: https://github.com/richgel999/jpeg-compressor - Version: 2.00 (aeb7d3b463aa8228b87a28013c15ee50a7e6fcf3, 2020) -- License: Public domain +- License: Public domain or MIT Files extracted from upstream source: @@ -223,7 +228,7 @@ Files extracted from upstream source: ## libpng - Upstream: http://libpng.org/pub/png/libpng.html -- Version: 1.6.37 (2019) +- Version: 1.6.37 (a40189cf881e9f0db80511c382292a5604c3c3d1, 2019) - License: libpng/zlib Files extracted from upstream source: @@ -303,7 +308,7 @@ from the Android NDK r18. ## libwebp - Upstream: https://chromium.googlesource.com/webm/libwebp/ -- Version: 1.1.0 (2020) +- Version: 1.1.0 (d7844e9762b61c9638c263657bd49e1690184832, 2020) - License: BSD-3-Clause Files extracted from upstream source: @@ -319,7 +324,7 @@ changes are marked with `// -- GODOT --` comments. ## mbedtls - Upstream: https://tls.mbed.org/ -- Version: 2.16.9 (2020) +- Version: 2.16.9 (3fac0bae4a50113989b3d015cd2d948f51a6d9ac, 2020) - License: Apache 2.0 File extracted from upstream release tarball: @@ -339,11 +344,14 @@ File extracted from upstream release tarball: ## meshoptimizer - Upstream: https://github.com/zeux/meshoptimizer -- Version: git (e4e43fe36e7a8705e602e7ca2f9fb795ded1d0b9, 2020) +- Version: git (e3f53f66e7a35b9b8764bee478589d79e34fa698, 2021) - License: MIT -- File extracted from upstream tarball: +Files extracted from upstream repository: + - All files in `src/`. +- `LICENSE.md`. + ## miniupnpc @@ -380,8 +388,6 @@ comments and a patch is provided in the minizip/ folder. Collection of single-file libraries used in Godot components. -### core - - `clipper.{cpp,hpp}` * Upstream: https://sourceforge.net/projects/polyclipping * Version: 6.4.2 (2017) + Godot changes (added optional exceptions handling) @@ -390,6 +396,10 @@ Collection of single-file libraries used in Godot components. * Upstream: https://research.activision.com/publications/archives/fast-filtering-of-reflection-probes File coeffs_const_8.txt (retrieved April 2020) * License: MIT +- `easing_equations.cpp` + * Upstream: http://robertpenner.com/easing/ via https://github.com/jesusgollonet/ofpennereasing (modified to fit Godot types) + * Version: git (af72c147c3a74e7e872aa28c7e2abfcced04fdce, 2008) + Godot types and style changes + * License: BSD-3-Clause - `fastlz.{c,h}` * Upstream: https://github.com/ariya/FastLZ * Version: 0.5.0 (4f20f54d46f5a6dd4fae4def134933369b7602d2, 2020) @@ -398,61 +408,49 @@ Collection of single-file libraries used in Godot components. * Upstream: https://github.com/brunexgeek/hqx * Version: TBD, file structure differs * License: Apache 2.0 +- `ifaddrs-android.{cc,h}` + * Upstream: https://chromium.googlesource.com/external/webrtc/stable/talk/+/master/base/ifaddrs-android.h + * Version: git (5976650443d68ccfadf1dea24999ee459dd2819d, 2013) + * License: BSD-3-Clause +- `mikktspace.{c,h}` + * Upstream: https://archive.blender.org/wiki/index.php/Dev:Shading/Tangent_Space_Normal_Maps/ + * Version: 1.0 (2011) + * License: zlib - `open-simplex-noise.{c,h}` * Upstream: https://github.com/smcameron/open-simplex-noise-in-c * Version: git (826f1dd1724e6fb3ff45f58e48c0fbae864c3403, 2020) + custom changes - * License: Unlicense + * License: Public Domain or Unlicense - `pcg.{cpp,h}` * Upstream: http://www.pcg-random.org * Version: minimal C implementation, http://www.pcg-random.org/download.html * License: Apache 2.0 +- `polypartition.{cpp,h}` + * Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.{cpp,h}`) + * Version: git (7bdffb428b2b19ad1c43aa44c714dcc104177e84, 2021) + * Modifications: Change from STL to Godot types (see provided patch). + * License: MIT - `r128.h` * Upstream: https://github.com/fahickman/r128 - * Version: git (423f693617faafd01de21e92818add4208eb8bd1, 2020) - * License: Public Domain + * Version: 1.4.4 (cf2e88fc3e7d7dfe99189686f914874cd0bda15e, 2020) + * License: Public Domain or Unlicense - `smaz.{c,h}` * Upstream: https://github.com/antirez/smaz - * Version: git (150e125cbae2e8fd20dd332432776ce13395d4d4, 2009) + * Version: git (2f625846a775501fb69456567409a8b12f10ea25, 2012) * License: BSD-3-Clause * Modifications: use `const char*` instead of `char*` for input string - `stb_rect_pack.h` * Upstream: https://github.com/nothings/stb - * Version: 1.00 (2019) - * License: Public Domain (Unlicense) or MIT -- `triangulator.{cpp,h}` - * Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.cpp`) - * Version: TBD, class was renamed - * License: MIT - -### modules - + * Version: 1.00 (2bb4a0accd4003c1db4c24533981e01b1adfd656, 2019) + * License: Public Domain or Unlicense or MIT +- `stb_vorbis.c` + * Upstream: https://github.com/nothings/stb + * Version: 1.20 (314d0a6f9af5af27e585336eecea333e95c5a2d8, 2020) + * License: Public Domain or Unlicense or MIT - `yuv2rgb.h` * Upstream: http://wss.co.uk/pinknoise/yuv2rgb/ (to check) * Version: ? * License: BSD -### platform - -- `ifaddrs-android.{cc,h}` - * Upstream: https://chromium.googlesource.com/external/webrtc/stable/talk/+/master/base/ifaddrs-android.h - * Version: git (5976650443d68ccfadf1dea24999ee459dd2819d, 2013) - * License: BSD-3-Clause - -### scene - -- `easing_equations.cpp` - * Upstream: http://robertpenner.com/easing/ via https://github.com/jesusgollonet/ofpennereasing (modified to fit Godot types) - * Version: git (af72c147c3a74e7e872aa28c7e2abfcced04fdce, 2008) + Godot types and style changes - * License: BSD-3-Clause -- `mikktspace.{c,h}` - * Upstream: https://archive.blender.org/wiki/index.php/Dev:Shading/Tangent_Space_Normal_Maps/ - * Version: 1.0 (2011) - * License: zlib -- `stb_vorbis.c` - * Upstream: https://github.com/nothings/stb - * Version: 1.20 - * License: Public Domain (Unlicense) or MIT - ## nanosvg @@ -474,27 +472,27 @@ Files extracted from the upstream source: Files extracted from upstream source: -common/* (except tasking.* and CMakeLists.txt) -core/* -include/OpenImageDenoise/* (except version.h.in) -LICENSE.txt -mkl-dnn/include/* -mkl-dnn/src/* (except CMakeLists.txt) -weights/rtlightmap_hdr.tza -scripts/resource_to_cpp.py +- common/* (except tasking.* and CMakeLists.txt) +- core/* +- include/OpenImageDenoise/* (except version.h.in) +- LICENSE.txt +- mkl-dnn/include/* +- mkl-dnn/src/* (except CMakeLists.txt) +- weights/rtlightmap_hdr.tza +- scripts/resource_to_cpp.py Modified files: Modifications are marked with `// -- GODOT start --` and `// -- GODOT end --`. Patch files are provided in `oidn/patches/`. -core/autoencoder.cpp -core/autoencoder.h -core/common.h -core/device.cpp -core/device.h -core/transfer_function.cpp +- core/autoencoder.cpp +- core/autoencoder.h +- core/common.h +- core/device.cpp +- core/device.h +- core/transfer_function.cpp -scripts/resource_to_cpp.py (used in modules/denoise/resource_to_cpp.py) +- scripts/resource_to_cpp.py (used in modules/denoise/resource_to_cpp.py) ## opus @@ -517,7 +515,7 @@ Files extracted from upstream source: ## pcre2 - Upstream: http://www.pcre.org -- Version: 10.34 (2019) +- Version: 10.36 (r1288, 2020) - License: BSD-3-Clause Files extracted from upstream source: @@ -526,13 +524,14 @@ Files extracted from upstream source: - All .h files in src/ apart from pcre2posix.h - src/pcre2_jit_match.c - src/pcre2_jit_misc.c -- src/sljit/* +- src/sljit/ - AUTHORS and LICENCE ## pvrtccompressor -- Upstream: https://bitbucket.org/jthlim/pvrtccompressor +- Upstream: https://bitbucket.org/jthlim/pvrtccompressor (dead link) + Unofficial backup fork: https://github.com/LibreGamesArchive/PVRTCCompressor - Version: hg (cf7177748ee0dcdccfe89716dc11a47d2dc81af5, 2015) - License: BSD-3-Clause @@ -556,8 +555,8 @@ Files extracted from upstream source: ## rvo2 -- Upstream: http://gamma.cs.unc.edu/RVO2/ -- Version: 3D - 1.0.1 (2016) +- Upstream: https://github.com/snape/RVO2-3D +- Version: 1.0.1 (e3883f288a9e55ecfed3633a01af3e12778c6acf, 2016) - License: Apache 2.0 Files extracted from upstream source: @@ -570,10 +569,23 @@ originally proposed by this library and better integrate this library with Godot. Please check the file to know what's new. +## spirv-reflect + +- Upstream: https://github.com/KhronosGroup/SPIRV-Reflect +- Version: git (c0ce03a43ca77fedb5abfd1976ae2fd0eeb0e611, 2021) +- License: Apache 2.0 + +Files extracted from upstream source: + +- `spirv_reflect.{c,h}` +- `include` folder +- `LICENSE` + + ## squish - Upstream: https://sourceforge.net/projects/libsquish -- Version: 1.15 (2017) +- Version: 1.15 (r104, 2017) - License: MIT Files extracted from upstream source: @@ -616,7 +628,7 @@ folder. ## vulkan - Upstream: https://github.com/KhronosGroup/Vulkan-Loader -- Version: sdk-1.2.162.0 (2020) +- Version: sdk-1.2.162.0 (7a313093b5c4af964d50a5a64e73d7df6152ea3f, 2020) - License: Apache 2.0 Unless there is a specific reason to package a more recent version, please stick @@ -645,7 +657,7 @@ Patches in the `patches` directory should be re-applied after updates. ## wslay - Upstream: https://github.com/tatsuhiro-t/wslay -- Version: 1.1.1 (2020) +- Version: 1.1.1 (c9a84aa6df8512584c77c8cd15be9536b89c35aa, 2020) - License: MIT File extracted from upstream release tarball: @@ -681,7 +693,7 @@ Files extracted from upstream source: ## zstd - Upstream: https://github.com/facebook/zstd -- Version: 1.4.5 (2020) +- Version: 1.4.8 (97a3da1df009d4dc67251de0c4b1c9d7fe286fc1, 2020) - License: BSD-3-Clause Files extracted from upstream source: diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp index cac5302a73..cac5302a73 100755..100644 --- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp +++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h index 75ca34e978..75ca34e978 100755..100644 --- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h +++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h diff --git a/thirdparty/doctest/doctest.h b/thirdparty/doctest/doctest.h index acbe6cd321..7712dd6b63 100644 --- a/thirdparty/doctest/doctest.h +++ b/thirdparty/doctest/doctest.h @@ -48,8 +48,8 @@ #define DOCTEST_VERSION_MAJOR 2 #define DOCTEST_VERSION_MINOR 4 -#define DOCTEST_VERSION_PATCH 1 -#define DOCTEST_VERSION_STR "2.4.1" +#define DOCTEST_VERSION_PATCH 4 +#define DOCTEST_VERSION_STR "2.4.4" #define DOCTEST_VERSION \ (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) @@ -368,7 +368,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' #define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP) #endif #elif defined(DOCTEST_PLATFORM_MAC) -#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) +#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386) #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) #else #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); @@ -747,6 +747,7 @@ struct ContextOptions //!OCLINT too many fields bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x): bool no_path_in_filenames; // if the path to files should be removed from the output bool no_line_numbers; // if source code line numbers should be omitted from the output + bool no_debug_output; // no output in the debug console when a debugger is attached bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!! @@ -806,7 +807,7 @@ namespace detail { } // namespace has_insertion_operator_impl template<class T> - using has_insertion_operator = has_insertion_operator_impl::check<T>; + using has_insertion_operator = has_insertion_operator_impl::check<const T>; DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num); @@ -1035,6 +1036,7 @@ namespace detail { template <typename L, typename R> String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, const DOCTEST_REF_WRAP(R) rhs) { + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) return toString(lhs) + op + toString(rhs); } @@ -1122,6 +1124,7 @@ namespace detail { #define DOCTEST_COMPARISON_RETURN_TYPE bool #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING #define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } @@ -1541,12 +1544,24 @@ namespace detail { MessageBuilder() = delete; ~MessageBuilder(); + // the preferred way of chaining parameters for stringification template <typename T> - MessageBuilder& operator<<(const T& in) { + MessageBuilder& operator,(const T& in) { toStream(m_stream, in); return *this; } + // kept here just for backwards-compatibility - the comma operator should be preferred now + template <typename T> + MessageBuilder& operator<<(const T& in) { return this->operator,(in); } + + // the `,` operator has the lowest operator precedence - if `<<` is used by the user then + // the `,` operator will be called last which is not what we want and thus the `*` operator + // is used first (has higher operator precedence compared to `<<`) so that we guarantee that + // an operator of the MessageBuilder class is called first before the rest of the parameters + template <typename T> + MessageBuilder& operator*(const T& in) { return this->operator,(in); } + bool log(); void react(); }; @@ -1962,38 +1977,38 @@ int registerReporter(const char* name, int priority, bool isReporter) { DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) // for logging -#define DOCTEST_INFO(expression) \ +#define DOCTEST_INFO(...) \ DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \ - DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), expression) + DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), __VA_ARGS__) -#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, expression) \ +#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, ...) \ DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626) \ auto lambda_name = [&](std::ostream* s_name) { \ doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \ mb_name.m_stream = s_name; \ - mb_name << expression; \ + mb_name * __VA_ARGS__; \ }; \ DOCTEST_MSVC_SUPPRESS_WARNING_POP \ auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name) -#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x) +#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x) -#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \ +#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \ do { \ doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ - mb << x; \ + mb * __VA_ARGS__; \ DOCTEST_ASSERT_LOG_AND_REACT(mb); \ } while(false) // clang-format off -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) +#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) +#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) +#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) // clang-format on -#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x) +#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__) +#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__) +#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__) #define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility. @@ -2036,12 +2051,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) // clang-format off -#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false) -#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false) +#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false) +#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false) +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false) +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false) +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false) +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false) // clang-format on #define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \ @@ -2051,8 +2066,8 @@ int registerReporter(const char* name, int priority, bool isReporter) { __LINE__, #expr, #__VA_ARGS__, message); \ try { \ DOCTEST_CAST_TO_VOID(expr) \ - } catch(const doctest::detail::remove_const< \ - doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \ + } catch(const typename doctest::detail::remove_const< \ + typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \ _DOCTEST_RB.translateException(); \ _DOCTEST_RB.m_threw_as = true; \ } catch(...) { _DOCTEST_RB.translateException(); } \ @@ -2103,21 +2118,21 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__) #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__) -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while(false) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while(false) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while(false) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while(false) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while(false) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while(false) +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false) +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false) +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false) +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false) +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false) +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false) +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false) +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false) +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false) +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false) // clang-format on #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS @@ -2230,21 +2245,21 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0)) #define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0)) #else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS @@ -2335,14 +2350,14 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_REGISTER_REPORTER(name, priority, reporter) #define DOCTEST_REGISTER_LISTENER(name, priority, reporter) -#define DOCTEST_INFO(x) (static_cast<void>(0)) +#define DOCTEST_INFO(...) (static_cast<void>(0)) #define DOCTEST_CAPTURE(x) (static_cast<void>(0)) -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast<void>(0)) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast<void>(0)) -#define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast<void>(0)) -#define DOCTEST_MESSAGE(x) (static_cast<void>(0)) -#define DOCTEST_FAIL_CHECK(x) (static_cast<void>(0)) -#define DOCTEST_FAIL(x) (static_cast<void>(0)) +#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0)) +#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0)) +#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0)) +#define DOCTEST_MESSAGE(...) (static_cast<void>(0)) +#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0)) +#define DOCTEST_FAIL(...) (static_cast<void>(0)) #define DOCTEST_WARN(...) (static_cast<void>(0)) #define DOCTEST_CHECK(...) (static_cast<void>(0)) @@ -2351,12 +2366,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0)) #define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0)) -#define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast<void>(0)) +#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast<void>(0)) #define DOCTEST_WARN_THROWS(...) (static_cast<void>(0)) #define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0)) @@ -2374,21 +2389,21 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0)) #define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0)) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0)) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0)) +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0)) +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0)) #define DOCTEST_WARN_EQ(...) (static_cast<void>(0)) #define DOCTEST_CHECK_EQ(...) (static_cast<void>(0)) @@ -2754,9 +2769,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN #include <map> #include <exception> #include <stdexcept> -#ifdef DOCTEST_CONFIG_POSIX_SIGNALS #include <csignal> -#endif // DOCTEST_CONFIG_POSIX_SIGNALS #include <cfloat> #include <cctype> #include <cstdint> @@ -3071,6 +3084,7 @@ String::String() { String::~String() { if(!isOnStack()) delete[] data.ptr; + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } String::String(const char* in) @@ -3112,6 +3126,7 @@ String& String::operator+=(const String& other) { if(total_size < len) { // append to the current stack space memcpy(buf + my_old_size, other.c_str(), other_size + 1); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) setLast(last - total_size); } else { // alloc new chunk @@ -3153,6 +3168,7 @@ String& String::operator+=(const String& other) { return *this; } +// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) String String::operator+(const String& other) const { return String(*this) += other; } String::String(String&& other) { @@ -3307,6 +3323,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") // depending on the current options this will remove the path of filenames const char* skipPathFromFilename(const char* file) { +#ifndef DOCTEST_CONFIG_DISABLE if(getContextOptions()->no_path_in_filenames) { auto back = std::strrchr(file, '\\'); auto forward = std::strrchr(file, '/'); @@ -3316,6 +3333,7 @@ const char* skipPathFromFilename(const char* file) { return forward + 1; } } +#endif // DOCTEST_CONFIG_DISABLE return file; } DOCTEST_CLANG_SUPPRESS_WARNING_POP @@ -3334,6 +3352,7 @@ IContextScope::~IContextScope() = default; #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING String toString(char* in) { return toString(static_cast<const char*>(in)); } +// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING String toString(bool in) { return in ? "true" : "false"; } @@ -3406,6 +3425,7 @@ bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } String toString(const Approx& in) { + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) return String("Approx( ") + doctest::toString(in.m_value) + " )"; } const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); } @@ -3698,11 +3718,15 @@ namespace detail { } bool TestCase::operator<(const TestCase& other) const { + // this will be used only to differentiate between test cases - not relevant for sorting if(m_line != other.m_line) return m_line < other.m_line; const int file_cmp = m_file.compare(other.m_file); if(file_cmp != 0) return file_cmp < 0; + const int name_cmp = strcmp(m_name, other.m_name); + if(name_cmp != 0) + return name_cmp < 0; return m_template_id < other.m_template_id; } } // namespace detail @@ -4009,24 +4033,40 @@ namespace { // Windows can easily distinguish between SO and SigSegV, // but SigInt, SigTerm, etc are handled differently. SignalDefs signalDefs[] = { - {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"}, - {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"}, - {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"}, - {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"}, + {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), + "SIGILL - Illegal instruction signal"}, + {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"}, + {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), + "SIGSEGV - Segmentation violation signal"}, + {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"}, }; struct FatalConditionHandler { static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) { - for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { - reportFatal(signalDefs[i].name); - break; + // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the + // console just once no matter how many threads have crashed. + static std::mutex mutex; + static bool execute = true; + { + std::lock_guard<std::mutex> lock(mutex); + if(execute) { + bool reported = false; + for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { + if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { + reportFatal(signalDefs[i].name); + reported = true; + break; + } + } + if(reported == false) + reportFatal("Unhandled SEH exception caught"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); } + execute = false; } - // If its not an exception we care about, pass it along. - // This stops us from eating debugger breaks etc. - return EXCEPTION_CONTINUE_SEARCH; + std::exit(EXIT_FAILURE); } FatalConditionHandler() { @@ -4038,6 +4078,51 @@ namespace { previousTop = SetUnhandledExceptionFilter(handleException); // Pass in guarantee size to be filled SetThreadStackGuarantee(&guaranteeSize); + + // On Windows uncaught exceptions from another thread, exceptions from + // destructors, or calls to std::terminate are not a SEH exception + + // The terminal handler gets called when: + // - std::terminate is called FROM THE TEST RUNNER THREAD + // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD + original_terminate_handler = std::get_terminate(); + std::set_terminate([]() noexcept { + reportFatal("Terminate handler called"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well + }); + + // SIGABRT is raised when: + // - std::terminate is called FROM A DIFFERENT THREAD + // - an exception is thrown from a destructor FROM A DIFFERENT THREAD + // - an uncaught exception is thrown FROM A DIFFERENT THREAD + prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) noexcept { + if(signal == SIGABRT) { + reportFatal("SIGABRT - Abort (abnormal termination) signal"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + std::exit(EXIT_FAILURE); + } + }); + + // The following settings are taken from google test, and more + // specifically from UnitTest::Run() inside of gtest.cc + + // the user does not want to see pop-up dialogs about crashes + prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + // This forces the abort message to go to stderr in all circumstances. + prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR); + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program - we want to disable that. + prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + // In debug mode, the Windows CRT can crash with an assertion over invalid + // input (e.g. passing an invalid file descriptor). The default handling + // for these assertions is to pop up a dialog and wait for user input. + // Instead ask the CRT to dump such assertions to stderr non-interactively. + prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); } static void reset() { @@ -4045,7 +4130,13 @@ namespace { // Unregister handler and restore the old guarantee SetUnhandledExceptionFilter(previousTop); SetThreadStackGuarantee(&guaranteeSize); - previousTop = nullptr; + std::set_terminate(original_terminate_handler); + std::signal(SIGABRT, prev_sigabrt_handler); + SetErrorMode(prev_error_mode_1); + _set_error_mode(prev_error_mode_2); + _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + _CrtSetReportMode(_CRT_ASSERT, prev_report_mode); + _CrtSetReportFile(_CRT_ASSERT, prev_report_file); isSet = false; } } @@ -4053,11 +4144,25 @@ namespace { ~FatalConditionHandler() { reset(); } private: + static UINT prev_error_mode_1; + static int prev_error_mode_2; + static unsigned int prev_abort_behavior; + static int prev_report_mode; + static _HFILE prev_report_file; + static void (*prev_sigabrt_handler)(int); + static std::terminate_handler original_terminate_handler; static bool isSet; static ULONG guaranteeSize; static LPTOP_LEVEL_EXCEPTION_FILTER previousTop; }; + UINT FatalConditionHandler::prev_error_mode_1; + int FatalConditionHandler::prev_error_mode_2; + unsigned int FatalConditionHandler::prev_abort_behavior; + int FatalConditionHandler::prev_report_mode; + _HFILE FatalConditionHandler::prev_report_file; + void (*FatalConditionHandler::prev_sigabrt_handler)(int); + std::terminate_handler FatalConditionHandler::original_terminate_handler; bool FatalConditionHandler::isSet = false; ULONG FatalConditionHandler::guaranteeSize = 0; LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr; @@ -4257,6 +4362,7 @@ namespace detail { // ################################################################################### DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp); DOCTEST_ASSERT_IN_TESTS(result.m_decomp); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) { @@ -4979,7 +5085,6 @@ namespace { } // TODO: - // - log_contexts() // - log_message() // - respond to queries // - honor remaining options @@ -4993,7 +5098,6 @@ namespace { struct JUnitTestCaseData { -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime static std::string getCurrentTimestamp() { // Beware, this is not reentrant because of backward compatibility issues // Also, UTC only, again because of backward compatibility (%z is C++11) @@ -5001,16 +5105,19 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime std::time(&rawtime); auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); - std::tm* timeInfo; - timeInfo = std::gmtime(&rawtime); + std::tm timeInfo; +#ifdef DOCTEST_PLATFORM_WINDOWS + gmtime_s(&timeInfo, &rawtime); +#else // DOCTEST_PLATFORM_WINDOWS + gmtime_r(&rawtime, &timeInfo); +#endif // DOCTEST_PLATFORM_WINDOWS char timeStamp[timeStampSize]; const char* const fmt = "%Y-%m-%dT%H:%M:%SZ"; - std::strftime(timeStamp, timeStampSize, fmt, timeInfo); + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); return std::string(timeStamp); } -DOCTEST_CLANG_SUPPRESS_WARNING_POP struct JUnitTestMessage { @@ -5175,12 +5282,27 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl; fulltext_log_assert_to_stream(os, rb); + log_contexts(os); testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str()); } void log_message(const MessageData&) override {} void test_case_skipped(const TestCaseData&) override {} + + void log_contexts(std::ostringstream& s) { + int num_contexts = get_num_active_contexts(); + if(num_contexts) { + auto contexts = get_active_contexts(); + + s << " logged: "; + for(int i = 0; i < num_contexts; ++i) { + s << (i == 0 ? "" : " "); + contexts[i]->stringify(&s); + s << std::endl; + } + } + } }; DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter); @@ -5894,6 +6016,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC)); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false); // clang-format on @@ -5951,6 +6074,7 @@ void Context::clearFilters() { // allows the user to override procedurally the int/bool options from the command line void Context::setOption(const char* option, int value) { setOption(option, toString(value).c_str()); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } // allows the user to override procedurally the string options from the command line @@ -6026,7 +6150,7 @@ int Context::run() { p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs)); #ifdef DOCTEST_PLATFORM_WINDOWS - if(isDebuggerActive()) + if(isDebuggerActive() && p->no_debug_output == false) p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs)); #endif // DOCTEST_PLATFORM_WINDOWS diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h index 24d36647d9..77f8004b80 100644 --- a/thirdparty/enet/enet/enet.h +++ b/thirdparty/enet/enet/enet.h @@ -31,7 +31,7 @@ extern "C" #define ENET_VERSION_MAJOR 1 #define ENET_VERSION_MINOR 3 -#define ENET_VERSION_PATCH 15 +#define ENET_VERSION_PATCH 17 #define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) #define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF) #define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF) @@ -323,12 +323,10 @@ typedef struct _ENetPeer ENetList acknowledgements; ENetList sentReliableCommands; ENetList sentUnreliableCommands; - ENetList outgoingReliableCommands; - ENetList outgoingUnreliableCommands; + ENetList outgoingCommands; ENetList dispatchedCommands; enet_uint16 flags; - enet_uint8 roundTripTimeRemainder; - enet_uint8 roundTripTimeVarianceRemainder; + enet_uint16 reserved; enet_uint16 incomingUnsequencedGroup; enet_uint16 outgoingUnsequencedGroup; enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; @@ -604,8 +602,8 @@ extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetO extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32); extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16); -extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *); -extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *); +extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *); +extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *); extern void enet_peer_on_connect (ENetPeer *); extern void enet_peer_on_disconnect (ENetPeer *); diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c index fc4da4ca67..21ab27e247 100644 --- a/thirdparty/enet/host.c +++ b/thirdparty/enet/host.c @@ -124,8 +124,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL enet_list_clear (& currentPeer -> acknowledgements); enet_list_clear (& currentPeer -> sentReliableCommands); enet_list_clear (& currentPeer -> sentUnreliableCommands); - enet_list_clear (& currentPeer -> outgoingReliableCommands); - enet_list_clear (& currentPeer -> outgoingUnreliableCommands); + enet_list_clear (& currentPeer -> outgoingCommands); enet_list_clear (& currentPeer -> dispatchedCommands); enet_peer_reset (currentPeer); diff --git a/thirdparty/enet/patches/godot.patch b/thirdparty/enet/patches/godot_socket.patch index c8b4a5225d..364b3536be 100644 --- a/thirdparty/enet/patches/godot.patch +++ b/thirdparty/enet/patches/godot_socket.patch @@ -1,5 +1,5 @@ diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h -index 54d91b5603..24d36647d9 100644 +index fc45cbd0c9..77f8004b80 100644 --- a/thirdparty/enet/enet/enet.h +++ b/thirdparty/enet/enet/enet.h @@ -10,13 +10,19 @@ extern "C" @@ -38,7 +38,7 @@ index 54d91b5603..24d36647d9 100644 /** * Packet flag bit constants. -@@ -606,6 +616,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, +@@ -604,6 +614,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, extern size_t enet_protocol_command_size (enet_uint8); @@ -50,7 +50,7 @@ index 54d91b5603..24d36647d9 100644 } #endif diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c -index 3be6c0922c..fc4da4ca67 100644 +index 3b2180f7fd..21ab27e247 100644 --- a/thirdparty/enet/host.c +++ b/thirdparty/enet/host.c @@ -87,7 +87,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL @@ -63,10 +63,10 @@ index 3be6c0922c..fc4da4ca67 100644 host -> receivedData = NULL; host -> receivedDataLength = 0; diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c -index 0a60253173..fefc0e6f0a 100644 +index 9d654f1d96..d7fe80f117 100644 --- a/thirdparty/enet/protocol.c +++ b/thirdparty/enet/protocol.c -@@ -307,7 +307,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet +@@ -309,7 +309,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet } else if (currentPeer -> state != ENET_PEER_STATE_CONNECTING && @@ -75,7 +75,7 @@ index 0a60253173..fefc0e6f0a 100644 { if (currentPeer -> address.port == host -> receivedAddress.port && currentPeer -> connectID == command -> connect.connectID) -@@ -1027,9 +1027,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) +@@ -1031,9 +1031,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || @@ -87,7 +87,7 @@ index 0a60253173..fefc0e6f0a 100644 (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && sessionID != peer -> incomingSessionID)) return 0; -@@ -1071,7 +1070,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) +@@ -1075,7 +1074,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (peer != NULL) { diff --git a/thirdparty/enet/peer.c b/thirdparty/enet/peer.c index 1278b85a80..9370ef4be1 100644 --- a/thirdparty/enet/peer.c +++ b/thirdparty/enet/peer.c @@ -76,7 +76,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) return 1; } else - if (rtt >= peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance) + if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance) { if (peer -> packetThrottle > peer -> packetThrottleDeceleration) peer -> packetThrottle -= peer -> packetThrottleDeceleration; @@ -268,7 +268,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue) } static void -enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand) +enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand, ENetIncomingCommand * excludeCommand) { ENetListIterator currentCommand; @@ -278,6 +278,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm currentCommand = enet_list_next (currentCommand); + if (incomingCommand == excludeCommand) + continue; + enet_list_remove (& incomingCommand -> incomingCommandList); if (incomingCommand -> packet != NULL) @@ -298,7 +301,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm static void enet_peer_reset_incoming_commands (ENetList * queue) { - enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue)); + enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue), NULL); } void @@ -318,8 +321,7 @@ enet_peer_reset_queues (ENetPeer * peer) enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); - enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands); - enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands); + enet_peer_reset_outgoing_commands (& peer -> outgoingCommands); enet_peer_reset_incoming_commands (& peer -> dispatchedCommands); if (peer -> channels != NULL && peer -> channelCount > 0) @@ -419,8 +421,6 @@ enet_peer_reset (ENetPeer * peer) peer -> eventData = 0; peer -> totalWaitingData = 0; peer -> flags = 0; - peer -> roundTripTimeRemainder = 0; - peer -> roundTripTimeVarianceRemainder = 0; memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); @@ -573,8 +573,7 @@ void enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) { if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && - ! (enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && + ! (enet_list_empty (& peer -> outgoingCommands) && enet_list_empty (& peer -> sentReliableCommands))) { peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; @@ -676,10 +675,7 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin break; } - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) - enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); - else - enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); + enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand); } ENetOutgoingCommand * @@ -702,7 +698,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, } void -enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) +enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand) { ENetListIterator droppedCommand, startCommand, currentCommand; @@ -781,11 +777,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * droppedCommand = currentCommand; } - enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand); + enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand, queuedCommand); } void -enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel) +enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand) { ENetListIterator currentCommand; @@ -820,7 +816,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch } if (! enet_list_empty (& channel -> incomingUnreliableCommands)) - enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand); } ENetIncomingCommand * @@ -978,11 +974,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, { case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: - enet_peer_dispatch_incoming_reliable_commands (peer, channel); + enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand); break; default: - enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand); break; } diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c index fefc0e6f0a..d7fe80f117 100644 --- a/thirdparty/enet/protocol.c +++ b/thirdparty/enet/protocol.c @@ -188,8 +188,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) } while (! enet_list_empty (& peer -> sentUnreliableCommands)); if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && - enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> outgoingCommands) && enet_list_empty (& peer -> sentReliableCommands)) enet_peer_disconnect (peer, peer -> eventData); } @@ -215,12 +214,15 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) { - for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); - currentCommand != enet_list_end (& peer -> outgoingReliableCommands); + for (currentCommand = enet_list_begin (& peer -> outgoingCommands); + currentCommand != enet_list_end (& peer -> outgoingCommands); currentCommand = enet_list_next (currentCommand)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; + if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)) + continue; + if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE; if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && @@ -228,7 +230,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl break; } - if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands)) + if (currentCommand == enet_list_end (& peer -> outgoingCommands)) return ENET_PROTOCOL_COMMAND_NONE; wasSent = 0; @@ -623,7 +625,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet fragmentLength); if (startCommand -> fragmentsRemaining <= 0) - enet_peer_dispatch_incoming_reliable_commands (peer, channel); + enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL); } return 0; @@ -741,7 +743,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, fragmentLength); if (startCommand -> fragmentsRemaining <= 0) - enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL); } return 0; @@ -856,19 +858,22 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * if (peer -> lastReceiveTime > 0) { - enet_uint32 accumRoundTripTime = (peer -> roundTripTime << 8) + peer -> roundTripTimeRemainder; - enet_uint32 accumRoundTripTimeVariance = (peer -> roundTripTimeVariance << 8) + peer -> roundTripTimeVarianceRemainder; - enet_peer_throttle (peer, roundTripTime); - roundTripTime <<= 8; - accumRoundTripTimeVariance = (accumRoundTripTimeVariance * 3 + ENET_DIFFERENCE (roundTripTime, accumRoundTripTime)) / 4; - accumRoundTripTime = (accumRoundTripTime * 7 + roundTripTime) / 8; + peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; - peer -> roundTripTime = accumRoundTripTime >> 8; - peer -> roundTripTimeRemainder = accumRoundTripTime & 0xFF; - peer -> roundTripTimeVariance = accumRoundTripTimeVariance >> 8; - peer -> roundTripTimeVarianceRemainder = accumRoundTripTimeVariance & 0xFF; + if (roundTripTime >= peer -> roundTripTime) + { + enet_uint32 diff = roundTripTime - peer -> roundTripTime; + peer -> roundTripTimeVariance += diff / 4; + peer -> roundTripTime += diff / 8; + } + else + { + enet_uint32 diff = peer -> roundTripTime - roundTripTime; + peer -> roundTripTimeVariance += diff / 4; + peer -> roundTripTime -= diff / 8; + } } else { @@ -879,14 +884,14 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * if (peer -> roundTripTime < peer -> lowestRoundTripTime) peer -> lowestRoundTripTime = peer -> roundTripTime; - if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) + if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; if (peer -> packetThrottleEpoch == 0 || ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) { peer -> lastRoundTripTime = peer -> lowestRoundTripTime; - peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 2); + peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1); peer -> lowestRoundTripTime = peer -> roundTripTime; peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; peer -> packetThrottleEpoch = host -> serviceTime; @@ -916,8 +921,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * break; case ENET_PEER_STATE_DISCONNECT_LATER: - if (enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && + if (enet_list_empty (& peer -> outgoingCommands) && enet_list_empty (& peer -> sentReliableCommands)) enet_peer_disconnect (peer, peer -> eventData); break; @@ -1325,108 +1329,6 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) host -> bufferCount = buffer - host -> buffers; } -static void -enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) -{ - ENetProtocol * command = & host -> commands [host -> commandCount]; - ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; - ENetOutgoingCommand * outgoingCommand; - ENetListIterator currentCommand; - - currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); - - while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) - { - size_t commandSize; - - outgoingCommand = (ENetOutgoingCommand *) currentCommand; - commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; - - if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || - buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || - peer -> mtu - host -> packetSize < commandSize || - (outgoingCommand -> packet != NULL && - peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength)) - { - host -> continueSending = 1; - - break; - } - - currentCommand = enet_list_next (currentCommand); - - if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0) - { - peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; - peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; - - if (peer -> packetThrottleCounter > peer -> packetThrottle) - { - enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, - unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; - for (;;) - { - -- outgoingCommand -> packet -> referenceCount; - - if (outgoingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (outgoingCommand -> packet); - - enet_list_remove (& outgoingCommand -> outgoingCommandList); - enet_free (outgoingCommand); - - if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands)) - break; - - outgoingCommand = (ENetOutgoingCommand *) currentCommand; - if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || - outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) - break; - - currentCommand = enet_list_next (currentCommand); - } - - continue; - } - } - - buffer -> data = command; - buffer -> dataLength = commandSize; - - host -> packetSize += buffer -> dataLength; - - * command = outgoingCommand -> command; - - enet_list_remove (& outgoingCommand -> outgoingCommandList); - - if (outgoingCommand -> packet != NULL) - { - ++ buffer; - - buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; - buffer -> dataLength = outgoingCommand -> fragmentLength; - - host -> packetSize += buffer -> dataLength; - - enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); - } - else - enet_free (outgoingCommand); - - ++ command; - ++ buffer; - } - - host -> commandCount = command - host -> commands; - host -> bufferCount = buffer - host -> buffers; - - if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && - enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && - enet_list_empty (& peer -> sentReliableCommands) && - enet_list_empty (& peer -> sentUnreliableCommands)) - enet_peer_disconnect (peer, peer -> eventData); -} - static int enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) { @@ -1434,7 +1336,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even ENetListIterator currentCommand, insertPosition; currentCommand = enet_list_begin (& peer -> sentReliableCommands); - insertPosition = enet_list_begin (& peer -> outgoingReliableCommands); + insertPosition = enet_list_begin (& peer -> outgoingCommands); while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) { @@ -1481,7 +1383,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even } static int -enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer) { ENetProtocol * command = & host -> commands [host -> commandCount]; ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; @@ -1492,49 +1394,52 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) size_t commandSize; int windowExceeded = 0, windowWrap = 0, canPing = 1; - currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); + currentCommand = enet_list_begin (& peer -> outgoingCommands); - while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) + while (currentCommand != enet_list_end (& peer -> outgoingCommands)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; - channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; - reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (channel != NULL) + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { - if (! windowWrap && - outgoingCommand -> sendAttempts < 1 && - ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && - (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || - channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | - (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow))))) - windowWrap = 1; - if (windowWrap) + channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; + reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (channel != NULL) { - currentCommand = enet_list_next (currentCommand); + if (! windowWrap && + outgoingCommand -> sendAttempts < 1 && + ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && + (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || + channel -> usedReliableWindows & ((((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) << reliableWindow) | + (((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow))))) + windowWrap = 1; + if (windowWrap) + { + currentCommand = enet_list_next (currentCommand); - continue; + continue; + } } - } - if (outgoingCommand -> packet != NULL) - { - if (! windowExceeded) + if (outgoingCommand -> packet != NULL) { - enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; + if (! windowExceeded) + { + enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; - if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) - windowExceeded = 1; - } - if (windowExceeded) - { - currentCommand = enet_list_next (currentCommand); + if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) + windowExceeded = 1; + } + if (windowExceeded) + { + currentCommand = enet_list_next (currentCommand); - continue; + continue; + } } - } - canPing = 0; + canPing = 0; + } commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || @@ -1550,33 +1455,80 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) currentCommand = enet_list_next (currentCommand); - if (channel != NULL && outgoingCommand -> sendAttempts < 1) + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { - channel -> usedReliableWindows |= 1 << reliableWindow; - ++ channel -> reliableWindows [reliableWindow]; - } + if (channel != NULL && outgoingCommand -> sendAttempts < 1) + { + channel -> usedReliableWindows |= 1 << reliableWindow; + ++ channel -> reliableWindows [reliableWindow]; + } - ++ outgoingCommand -> sendAttempts; + ++ outgoingCommand -> sendAttempts; - if (outgoingCommand -> roundTripTimeout == 0) - { - outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; - outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; + if (outgoingCommand -> roundTripTimeout == 0) + { + outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; + outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; + } + + if (enet_list_empty (& peer -> sentReliableCommands)) + peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; + + enet_list_insert (enet_list_end (& peer -> sentReliableCommands), + enet_list_remove (& outgoingCommand -> outgoingCommandList)); + + outgoingCommand -> sentTime = host -> serviceTime; + + host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; + + peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; } + else + { + if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0) + { + peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; + peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; + + if (peer -> packetThrottleCounter > peer -> packetThrottle) + { + enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, + unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; + for (;;) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); - if (enet_list_empty (& peer -> sentReliableCommands)) - peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; + enet_list_remove (& outgoingCommand -> outgoingCommandList); + enet_free (outgoingCommand); - enet_list_insert (enet_list_end (& peer -> sentReliableCommands), - enet_list_remove (& outgoingCommand -> outgoingCommandList)); + if (currentCommand == enet_list_end (& peer -> outgoingCommands)) + break; - outgoingCommand -> sentTime = host -> serviceTime; + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || + outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) + break; + + currentCommand = enet_list_next (currentCommand); + } + + continue; + } + } + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); + } buffer -> data = command; buffer -> dataLength = commandSize; host -> packetSize += buffer -> dataLength; - host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; * command = outgoingCommand -> command; @@ -1588,9 +1540,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) buffer -> dataLength = outgoingCommand -> fragmentLength; host -> packetSize += outgoingCommand -> fragmentLength; - - peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; } + else + if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)) + enet_free (outgoingCommand); ++ peer -> packetsSent; @@ -1601,6 +1554,12 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) host -> commandCount = command - host -> commands; host -> bufferCount = buffer - host -> buffers; + if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && + enet_list_empty (& peer -> outgoingCommands) && + enet_list_empty (& peer -> sentReliableCommands) && + enet_list_empty (& peer -> sentUnreliableCommands)) + enet_peer_disconnect (peer, peer -> eventData); + return canPing; } @@ -1644,18 +1603,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch continue; } - if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) || - enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) && + if ((enet_list_empty (& currentPeer -> outgoingCommands) || + enet_protocol_check_outgoing_commands (host, currentPeer)) && enet_list_empty (& currentPeer -> sentReliableCommands) && ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) { enet_peer_ping (currentPeer); - enet_protocol_send_reliable_outgoing_commands (host, currentPeer); + enet_protocol_check_outgoing_commands (host, currentPeer); } - - if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands)) - enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); if (host -> commandCount == 0) continue; @@ -1669,7 +1625,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; #ifdef ENET_DEBUG - printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); + printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); #endif currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4; diff --git a/thirdparty/meshoptimizer/indexcodec.cpp b/thirdparty/meshoptimizer/indexcodec.cpp index 5c35eb43ae..e4495b8586 100644 --- a/thirdparty/meshoptimizer/indexcodec.cpp +++ b/thirdparty/meshoptimizer/indexcodec.cpp @@ -108,7 +108,7 @@ static unsigned int decodeVByte(const unsigned char*& data) for (int i = 0; i < 4; ++i) { unsigned char group = *data++; - result |= (group & 127) << shift; + result |= unsigned(group & 127) << shift; shift += 7; if (group < 128) diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h index 4071f0a371..1714000384 100644 --- a/thirdparty/meshoptimizer/meshoptimizer.h +++ b/thirdparty/meshoptimizer/meshoptimizer.h @@ -262,7 +262,7 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t ver * The resulting index buffer references vertices from the original vertex buffer. * If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended. * - * destination must contain enough space for the *source* index buffer (since optimization is iterative, this means index_count elements - *not* target_index_count!) + * destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)! * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation * result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification @@ -272,15 +272,17 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, co /** * Experimental: Mesh simplifier (sloppy) * Reduces the number of triangles in the mesh, sacrificing mesh apperance for simplification performance - * The algorithm doesn't preserve mesh topology but is always able to reach target triangle count. + * The algorithm doesn't preserve mesh topology but can stop short of the target goal based on target error. * Returns the number of indices after simplification, with destination containing new index data * The resulting index buffer references vertices from the original vertex buffer. * If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended. * - * destination must contain enough space for the target index buffer + * destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)! * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer + * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation + * result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification */ -MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count); +MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error); /** * Experimental: Point cloud simplifier @@ -289,7 +291,7 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati * The resulting index buffer references vertices from the original vertex buffer. * If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended. * - * destination must contain enough space for the target index buffer + * destination must contain enough space for the target index buffer (target_vertex_count elements) * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer */ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_vertex_count); @@ -533,7 +535,7 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const template <typename T> inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0); template <typename T> -inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count); +inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0); template <typename T> inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_count, size_t vertex_count, T restart_index); template <typename T> @@ -855,12 +857,12 @@ inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_co } template <typename T> -inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count) +inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error) { meshopt_IndexAdapter<T> in(0, indices, index_count); - meshopt_IndexAdapter<T> out(destination, 0, target_index_count); + meshopt_IndexAdapter<T> out(destination, 0, index_count); - return meshopt_simplifySloppy(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count); + return meshopt_simplifySloppy(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error); } template <typename T> diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp index 5205b01172..942db14461 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -1400,7 +1400,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, return result_count; } -size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count) +size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) { using namespace meshopt; @@ -1412,9 +1412,6 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind // we expect to get ~2 triangles/vertex in the output size_t target_cell_count = target_index_count / 6; - if (target_cell_count == 0) - return 0; - meshopt_Allocator allocator; Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count); @@ -1431,18 +1428,25 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind const int kInterpolationPasses = 5; // invariant: # of triangles in min_grid <= target_count - int min_grid = 0; + int min_grid = int(1.f / (target_error < 1e-3f ? 1e-3f : target_error)); int max_grid = 1025; size_t min_triangles = 0; size_t max_triangles = index_count / 3; + // when we're error-limited, we compute the triangle count for the min. size; this accelerates convergence and provides the correct answer when we can't use a larger grid + if (min_grid > 1) + { + computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid); + min_triangles = countTriangles(vertex_ids, indices, index_count); + } + // instead of starting in the middle, let's guess as to what the answer might be! triangle count usually grows as a square of grid size... int next_grid_size = int(sqrtf(float(target_cell_count)) + 0.5f); for (int pass = 0; pass < 10 + kInterpolationPasses; ++pass) { - assert(min_triangles < target_index_count / 3); - assert(max_grid - min_grid > 1); + if (min_triangles >= target_index_count / 3 || max_grid - min_grid <= 1) + break; // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; @@ -1471,16 +1475,18 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind max_triangles = triangles; } - if (triangles == target_index_count / 3 || max_grid - min_grid <= 1) - break; - // we start by using interpolation search - it usually converges faster // however, interpolation search has a worst case of O(N) so we switch to binary search after a few iterations which converges in O(logN) next_grid_size = (pass < kInterpolationPasses) ? int(tip + 0.5f) : (min_grid + max_grid) / 2; } if (min_triangles == 0) + { + if (out_result_error) + *out_result_error = 1.f; + return 0; + } // build vertex->cell association by mapping all vertices with the same quantized position to the same cell size_t table_size = hashBuckets2(vertex_count); @@ -1503,18 +1509,26 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_quadrics, vertex_positions, vertex_count); + // compute error + float result_error = 0.f; + + for (size_t i = 0; i < cell_count; ++i) + result_error = result_error < cell_errors[i] ? cell_errors[i] : result_error; + // collapse triangles! // note that we need to filter out triangles that we've already output because we very frequently generate redundant triangles between cells :( size_t tritable_size = hashBuckets2(min_triangles); unsigned int* tritable = allocator.allocate<unsigned int>(tritable_size); size_t write = filterTriangles(destination, tritable, tritable_size, indices, index_count, vertex_cells, cell_remap); - assert(write <= target_index_count); #if TRACE - printf("result: %d cells, %d triangles (%d unfiltered)\n", int(cell_count), int(write / 3), int(min_triangles)); + printf("result: %d cells, %d triangles (%d unfiltered), error %e\n", int(cell_count), int(write / 3), int(min_triangles), sqrtf(result_error)); #endif + if (out_result_error) + *out_result_error = sqrtf(result_error); + return write; } diff --git a/thirdparty/misc/patches/polypartition-godot-types.patch b/thirdparty/misc/patches/polypartition-godot-types.patch new file mode 100644 index 0000000000..59fdb2707c --- /dev/null +++ b/thirdparty/misc/patches/polypartition-godot-types.patch @@ -0,0 +1,819 @@ +diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp +index 3a8a6efa8319..4f1b6dcb21d8 100644 +--- a/thirdparty/misc/polypartition.cpp ++++ b/thirdparty/misc/polypartition.cpp +@@ -23,10 +23,7 @@ + + #include "polypartition.h" + +-#include <math.h> +-#include <string.h> + #include <algorithm> +-#include <vector> + + TPPLPoly::TPPLPoly() { + hole = false; +@@ -186,7 +183,7 @@ int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TP + // Removes holes from inpolys by merging them with non-holes. + int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + TPPLPolyList polys; +- TPPLPolyList::iterator holeiter, polyiter, iter, iter2; ++ TPPLPolyList::Element *holeiter, *polyiter, *iter, *iter2; + long i, i2, holepointindex, polypointindex; + TPPLPoint holepoint, polypoint, bestpolypoint; + TPPLPoint linep1, linep2; +@@ -198,15 +195,15 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + + // Check for the trivial case of no holes. + hasholes = false; +- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) { +- if (iter->IsHole()) { ++ for (iter = inpolys->front(); iter; iter = iter->next()) { ++ if (iter->get().IsHole()) { + hasholes = true; + break; + } + } + if (!hasholes) { +- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) { +- outpolys->push_back(*iter); ++ for (iter = inpolys->front(); iter; iter = iter->next()) { ++ outpolys->push_back(iter->get()); + } + return 1; + } +@@ -216,8 +213,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + while (1) { + // Find the hole point with the largest x. + hasholes = false; +- for (iter = polys.begin(); iter != polys.end(); iter++) { +- if (!iter->IsHole()) { ++ for (iter = polys.front(); iter; iter = iter->next()) { ++ if (!iter->get().IsHole()) { + continue; + } + +@@ -227,8 +224,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + holepointindex = 0; + } + +- for (i = 0; i < iter->GetNumPoints(); i++) { +- if (iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) { ++ for (i = 0; i < iter->get().GetNumPoints(); i++) { ++ if (iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) { + holeiter = iter; + holepointindex = i; + } +@@ -237,24 +234,24 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + if (!hasholes) { + break; + } +- holepoint = holeiter->GetPoint(holepointindex); ++ holepoint = holeiter->get().GetPoint(holepointindex); + + pointfound = false; +- for (iter = polys.begin(); iter != polys.end(); iter++) { +- if (iter->IsHole()) { ++ for (iter = polys.front(); iter; iter = iter->next()) { ++ if (iter->get().IsHole()) { + continue; + } +- for (i = 0; i < iter->GetNumPoints(); i++) { +- if (iter->GetPoint(i).x <= holepoint.x) { ++ for (i = 0; i < iter->get().GetNumPoints(); i++) { ++ if (iter->get().GetPoint(i).x <= holepoint.x) { + continue; + } +- if (!InCone(iter->GetPoint((i + iter->GetNumPoints() - 1) % (iter->GetNumPoints())), +- iter->GetPoint(i), +- iter->GetPoint((i + 1) % (iter->GetNumPoints())), ++ if (!InCone(iter->get().GetPoint((i + iter->get().GetNumPoints() - 1) % (iter->get().GetNumPoints())), ++ iter->get().GetPoint(i), ++ iter->get().GetPoint((i + 1) % (iter->get().GetNumPoints())), + holepoint)) { + continue; + } +- polypoint = iter->GetPoint(i); ++ polypoint = iter->get().GetPoint(i); + if (pointfound) { + v1 = Normalize(polypoint - holepoint); + v2 = Normalize(bestpolypoint - holepoint); +@@ -263,13 +260,13 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + } + } + pointvisible = true; +- for (iter2 = polys.begin(); iter2 != polys.end(); iter2++) { +- if (iter2->IsHole()) { ++ for (iter2 = polys.front(); iter2; iter2->next()) { ++ if (iter2->get().IsHole()) { + continue; + } +- for (i2 = 0; i2 < iter2->GetNumPoints(); i2++) { +- linep1 = iter2->GetPoint(i2); +- linep2 = iter2->GetPoint((i2 + 1) % (iter2->GetNumPoints())); ++ for (i2 = 0; i2 < iter2->get().GetNumPoints(); i2++) { ++ linep1 = iter2->get().GetPoint(i2); ++ linep2 = iter2->get().GetPoint((i2 + 1) % (iter2->get().GetNumPoints())); + if (Intersects(holepoint, polypoint, linep1, linep2)) { + pointvisible = false; + break; +@@ -292,18 +289,18 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + return 0; + } + +- newpoly.Init(holeiter->GetNumPoints() + polyiter->GetNumPoints() + 2); ++ newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2); + i2 = 0; + for (i = 0; i <= polypointindex; i++) { +- newpoly[i2] = polyiter->GetPoint(i); ++ newpoly[i2] = polyiter->get().GetPoint(i); + i2++; + } +- for (i = 0; i <= holeiter->GetNumPoints(); i++) { +- newpoly[i2] = holeiter->GetPoint((i + holepointindex) % holeiter->GetNumPoints()); ++ for (i = 0; i <= holeiter->get().GetNumPoints(); i++) { ++ newpoly[i2] = holeiter->get().GetPoint((i + holepointindex) % holeiter->get().GetNumPoints()); + i2++; + } +- for (i = polypointindex; i < polyiter->GetNumPoints(); i++) { +- newpoly[i2] = polyiter->GetPoint(i); ++ for (i = polypointindex; i < polyiter->get().GetNumPoints(); i++) { ++ newpoly[i2] = polyiter->get().GetPoint(i); + i2++; + } + +@@ -312,8 +309,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + polys.push_back(newpoly); + } + +- for (iter = polys.begin(); iter != polys.end(); iter++) { +- outpolys->push_back(*iter); ++ for (iter = polys.front(); iter; iter = iter->next()) { ++ outpolys->push_back(iter->get()); + } + + return 1; +@@ -524,13 +521,13 @@ int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) { + + int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) { + TPPLPolyList outpolys; +- TPPLPolyList::iterator iter; ++ TPPLPolyList::Element *iter; + + if (!RemoveHoles(inpolys, &outpolys)) { + return 0; + } +- for (iter = outpolys.begin(); iter != outpolys.end(); iter++) { +- if (!Triangulate_EC(&(*iter), triangles)) { ++ for (iter = outpolys.front(); iter; iter = iter->next()) { ++ if (!Triangulate_EC(&(iter->get()), triangles)) { + return 0; + } + } +@@ -543,7 +540,7 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) { + } + + TPPLPolyList triangles; +- TPPLPolyList::iterator iter1, iter2; ++ TPPLPolyList::Element *iter1, *iter2; + TPPLPoly *poly1 = NULL, *poly2 = NULL; + TPPLPoly newpoly; + TPPLPoint d1, d2, p1, p2, p3; +@@ -578,19 +575,19 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) { + return 0; + } + +- for (iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { +- poly1 = &(*iter1); ++ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) { ++ poly1 = &(iter1->get()); + for (i11 = 0; i11 < poly1->GetNumPoints(); i11++) { + d1 = poly1->GetPoint(i11); + i12 = (i11 + 1) % (poly1->GetNumPoints()); + d2 = poly1->GetPoint(i12); + + isdiagonal = false; +- for (iter2 = iter1; iter2 != triangles.end(); iter2++) { ++ for (iter2 = iter1; iter2; iter2 = iter2->next()) { + if (iter1 == iter2) { + continue; + } +- poly2 = &(*iter2); ++ poly2 = &(iter2->get()); + + for (i21 = 0; i21 < poly2->GetNumPoints(); i21++) { + if ((d2.x != poly2->GetPoint(i21).x) || (d2.y != poly2->GetPoint(i21).y)) { +@@ -660,16 +657,16 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) { + } + + triangles.erase(iter2); +- *iter1 = newpoly; +- poly1 = &(*iter1); ++ iter1->get() = newpoly; ++ poly1 = &(iter1->get()); + i11 = -1; + + continue; + } + } + +- for (iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { +- parts->push_back(*iter1); ++ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) { ++ parts->push_back(iter1->get()); + } + + return 1; +@@ -677,13 +674,13 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) { + + int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) { + TPPLPolyList outpolys; +- TPPLPolyList::iterator iter; ++ TPPLPolyList::Element *iter; + + if (!RemoveHoles(inpolys, &outpolys)) { + return 0; + } +- for (iter = outpolys.begin(); iter != outpolys.end(); iter++) { +- if (!ConvexPartition_HM(&(*iter), parts)) { ++ for (iter = outpolys.front(); iter; iter = iter->next()) { ++ if (!ConvexPartition_HM(&(iter->get()), parts)) { + return 0; + } + } +@@ -824,8 +821,8 @@ int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) { + newdiagonal.index1 = 0; + newdiagonal.index2 = n - 1; + diagonals.push_back(newdiagonal); +- while (!diagonals.empty()) { +- diagonal = *(diagonals.begin()); ++ while (!diagonals.is_empty()) { ++ diagonal = diagonals.front()->get(); + diagonals.pop_front(); + bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex; + if (bestvertex == -1) { +@@ -873,10 +870,10 @@ void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 + pairs->push_front(newdiagonal); + dpstates[a][b].weight = w; + } else { +- if ((!pairs->empty()) && (i <= pairs->begin()->index1)) { ++ if ((!pairs->is_empty()) && (i <= pairs->front()->get().index1)) { + return; + } +- while ((!pairs->empty()) && (pairs->begin()->index2 >= j)) { ++ while ((!pairs->is_empty()) && (pairs->front()->get().index2 >= j)) { + pairs->pop_front(); + } + pairs->push_front(newdiagonal); +@@ -885,7 +882,7 @@ void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 + + void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { + DiagonalList *pairs = NULL; +- DiagonalList::iterator iter, lastiter; ++ DiagonalList::Element *iter, *lastiter; + long top; + long w; + +@@ -902,23 +899,23 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS + } + if (j - i > 1) { + pairs = &(dpstates[i][j].pairs); +- iter = pairs->end(); +- lastiter = pairs->end(); +- while (iter != pairs->begin()) { ++ iter = pairs->back(); ++ lastiter = pairs->back(); ++ while (iter != pairs->front()) { + iter--; +- if (!IsReflex(vertices[iter->index2].p, vertices[j].p, vertices[k].p)) { ++ if (!IsReflex(vertices[iter->get().index2].p, vertices[j].p, vertices[k].p)) { + lastiter = iter; + } else { + break; + } + } +- if (lastiter == pairs->end()) { ++ if (lastiter == pairs->back()) { + w++; + } else { +- if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->index1].p)) { ++ if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->get().index1].p)) { + w++; + } else { +- top = lastiter->index1; ++ top = lastiter->get().index1; + } + } + } +@@ -927,7 +924,7 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS + + void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { + DiagonalList *pairs = NULL; +- DiagonalList::iterator iter, lastiter; ++ DiagonalList::Element *iter, *lastiter; + long top; + long w; + +@@ -946,21 +943,21 @@ void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPS + if (k - j > 1) { + pairs = &(dpstates[j][k].pairs); + +- iter = pairs->begin(); +- if ((!pairs->empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->index1].p))) { ++ iter = pairs->front(); ++ if ((!pairs->is_empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p))) { + lastiter = iter; +- while (iter != pairs->end()) { +- if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->index1].p)) { ++ while (iter) { ++ if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p)) { + lastiter = iter; +- iter++; ++ iter = iter->next(); + } else { + break; + } + } +- if (IsReflex(vertices[lastiter->index2].p, vertices[k].p, vertices[i].p)) { ++ if (IsReflex(vertices[lastiter->get().index2].p, vertices[k].p, vertices[i].p)) { + w++; + } else { +- top = lastiter->index2; ++ top = lastiter->get().index2; + } + } else { + w++; +@@ -981,11 +978,11 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + DiagonalList diagonals, diagonals2; + Diagonal diagonal, newdiagonal; + DiagonalList *pairs = NULL, *pairs2 = NULL; +- DiagonalList::iterator iter, iter2; ++ DiagonalList::Element *iter, *iter2; + int ret; + TPPLPoly newpoly; +- std::vector<long> indices; +- std::vector<long>::iterator iiter; ++ List<long> indices; ++ List<long>::Element *iiter; + bool ijreal, jkreal; + + n = poly->GetNumPoints(); +@@ -1110,35 +1107,35 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + newdiagonal.index1 = 0; + newdiagonal.index2 = n - 1; + diagonals.push_front(newdiagonal); +- while (!diagonals.empty()) { +- diagonal = *(diagonals.begin()); ++ while (!diagonals.is_empty()) { ++ diagonal = diagonals.front()->get(); + diagonals.pop_front(); + if ((diagonal.index2 - diagonal.index1) <= 1) { + continue; + } + pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); +- if (pairs->empty()) { ++ if (pairs->is_empty()) { + ret = 0; + break; + } + if (!vertices[diagonal.index1].isConvex) { +- iter = pairs->end(); ++ iter = pairs->back(); + iter--; +- j = iter->index2; ++ j = iter->get().index2; + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + diagonals.push_front(newdiagonal); + if ((j - diagonal.index1) > 1) { +- if (iter->index1 != iter->index2) { ++ if (iter->get().index1 != iter->get().index2) { + pairs2 = &(dpstates[diagonal.index1][j].pairs); + while (1) { +- if (pairs2->empty()) { ++ if (pairs2->is_empty()) { + ret = 0; + break; + } +- iter2 = pairs2->end(); ++ iter2 = pairs2->back(); + iter2--; +- if (iter->index1 != iter2->index1) { ++ if (iter->get().index1 != iter2->get().index1) { + pairs2->pop_back(); + } else { + break; +@@ -1153,21 +1150,21 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + diagonals.push_front(newdiagonal); + } + } else { +- iter = pairs->begin(); +- j = iter->index1; ++ iter = pairs->front(); ++ j = iter->get().index1; + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + diagonals.push_front(newdiagonal); + if ((diagonal.index2 - j) > 1) { +- if (iter->index1 != iter->index2) { ++ if (iter->get().index1 != iter->get().index2) { + pairs2 = &(dpstates[j][diagonal.index2].pairs); + while (1) { +- if (pairs2->empty()) { ++ if (pairs2->is_empty()) { + ret = 0; + break; + } +- iter2 = pairs2->begin(); +- if (iter->index2 != iter2->index2) { ++ iter2 = pairs2->front(); ++ if (iter->get().index2 != iter2->get().index2) { + pairs2->pop_front(); + } else { + break; +@@ -1197,8 +1194,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + newdiagonal.index1 = 0; + newdiagonal.index2 = n - 1; + diagonals.push_front(newdiagonal); +- while (!diagonals.empty()) { +- diagonal = *(diagonals.begin()); ++ while (!diagonals.is_empty()) { ++ diagonal = diagonals.front()->get(); + diagonals.pop_front(); + if ((diagonal.index2 - diagonal.index1) <= 1) { + continue; +@@ -1210,8 +1207,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + indices.push_back(diagonal.index2); + diagonals2.push_front(diagonal); + +- while (!diagonals2.empty()) { +- diagonal = *(diagonals2.begin()); ++ while (!diagonals2.is_empty()) { ++ diagonal = diagonals2.front()->get(); + diagonals2.pop_front(); + if ((diagonal.index2 - diagonal.index1) <= 1) { + continue; +@@ -1220,16 +1217,16 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + jkreal = true; + pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); + if (!vertices[diagonal.index1].isConvex) { +- iter = pairs->end(); ++ iter = pairs->back(); + iter--; +- j = iter->index2; +- if (iter->index1 != iter->index2) { ++ j = iter->get().index2; ++ if (iter->get().index1 != iter->get().index2) { + ijreal = false; + } + } else { +- iter = pairs->begin(); +- j = iter->index1; +- if (iter->index1 != iter->index2) { ++ iter = pairs->front(); ++ j = iter->get().index1; ++ if (iter->get().index1 != iter->get().index2) { + jkreal = false; + } + } +@@ -1253,11 +1250,12 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + indices.push_back(j); + } + +- std::sort(indices.begin(), indices.end()); ++ //std::sort(indices.begin(), indices.end()); ++ indices.sort(); + newpoly.Init((long)indices.size()); + k = 0; +- for (iiter = indices.begin(); iiter != indices.end(); iiter++) { +- newpoly[k] = vertices[*iiter].p; ++ for (iiter = indices.front(); iiter != indices.back(); iiter = iiter->next()) { ++ newpoly[k] = vertices[iiter->get()].p; + k++; + } + parts->push_back(newpoly); +@@ -1281,7 +1279,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + // "Computational Geometry: Algorithms and Applications" + // by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars. + int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys) { +- TPPLPolyList::iterator iter; ++ TPPLPolyList::Element *iter; + MonotoneVertex *vertices = NULL; + long i, numvertices, vindex, vindex2, newnumvertices, maxnumvertices; + long polystartindex, polyendindex; +@@ -1291,11 +1289,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + bool error = false; + + numvertices = 0; +- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) { +- if (!iter->Valid()) { +- return 0; +- } +- numvertices += iter->GetNumPoints(); ++ for (iter = inpolys->front(); iter; iter++) { ++ numvertices += iter->get().GetNumPoints(); + } + + maxnumvertices = numvertices * 3; +@@ -1303,8 +1298,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + newnumvertices = numvertices; + + polystartindex = 0; +- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) { +- poly = &(*iter); ++ for (iter = inpolys->front(); iter; iter++) { ++ poly = &(iter->get()); + polyendindex = polystartindex + poly->GetNumPoints() - 1; + for (i = 0; i < poly->GetNumPoints(); i++) { + vertices[i + polystartindex].p = poly->GetPoint(i); +@@ -1360,14 +1355,14 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + // Note that while set doesn't actually have to be implemented as + // a tree, complexity requirements for operations are the same as + // for the balanced binary search tree. +- std::set<ScanLineEdge> edgeTree; ++ Set<ScanLineEdge> edgeTree; + // Store iterators to the edge tree elements. + // This makes deleting existing edges much faster. +- std::set<ScanLineEdge>::iterator *edgeTreeIterators, edgeIter; +- edgeTreeIterators = new std::set<ScanLineEdge>::iterator[maxnumvertices]; +- std::pair<std::set<ScanLineEdge>::iterator, bool> edgeTreeRet; ++ Set<ScanLineEdge>::Element **edgeTreeIterators, *edgeIter; ++ edgeTreeIterators = new Set<ScanLineEdge>::Element *[maxnumvertices]; ++ //Pair<Set<ScanLineEdge>::iterator, bool> edgeTreeRet; + for (i = 0; i < numvertices; i++) { +- edgeTreeIterators[i] = edgeTree.end(); ++ edgeTreeIterators[i] = nullptr; + } + + // For each vertex. +@@ -1387,13 +1382,14 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + newedge.p1 = v->p; + newedge.p2 = vertices[v->next].p; + newedge.index = vindex; +- edgeTreeRet = edgeTree.insert(newedge); +- edgeTreeIterators[vindex] = edgeTreeRet.first; ++ //edgeTreeRet = edgeTree.insert(newedge); ++ //edgeTreeIterators[vindex] = edgeTreeRet.first; ++ edgeTreeIterators[vindex] = edgeTree.insert(newedge); + helpers[vindex] = vindex; + break; + + case TPPL_VERTEXTYPE_END: +- if (edgeTreeIterators[v->previous] == edgeTree.end()) { ++ if (edgeTreeIterators[v->previous] == edgeTree.back()) { + error = true; + break; + } +@@ -1412,29 +1408,30 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); +- if (edgeIter == edgeTree.begin()) { ++ if (edgeIter == edgeTree.front()) { + error = true; + break; + } + edgeIter--; + // Insert the diagonal connecting vi to helper(e_j) in D. +- AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->index], ++ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices - 2; + v2 = &(vertices[vindex2]); + // helper(e_j) in v_i. +- helpers[edgeIter->index] = vindex; ++ helpers[edgeIter->get().index] = vindex; + // Insert e_i in T and set helper(e_i) to v_i. + newedge.p1 = v2->p; + newedge.p2 = vertices[v2->next].p; + newedge.index = vindex2; +- edgeTreeRet = edgeTree.insert(newedge); +- edgeTreeIterators[vindex2] = edgeTreeRet.first; ++ //edgeTreeRet = edgeTree.insert(newedge); ++ //edgeTreeIterators[vindex2] = edgeTreeRet.first; ++ edgeTreeIterators[vindex2] = edgeTree.insert(newedge); + helpers[vindex2] = vindex2; + break; + + case TPPL_VERTEXTYPE_MERGE: +- if (edgeTreeIterators[v->previous] == edgeTree.end()) { ++ if (edgeTreeIterators[v->previous] == edgeTree.back()) { + error = true; + break; + } +@@ -1452,25 +1449,25 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); +- if (edgeIter == edgeTree.begin()) { ++ if (edgeIter == edgeTree.front()) { + error = true; + break; + } + edgeIter--; + // If helper(e_j) is a merge vertex. +- if (vertextypes[helpers[edgeIter->index]] == TPPL_VERTEXTYPE_MERGE) { ++ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting v_i to helper(e_j) in D. +- AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->index], ++ AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->get().index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + // helper(e_j) <- v_i +- helpers[edgeIter->index] = vindex2; ++ helpers[edgeIter->get().index] = vindex2; + break; + + case TPPL_VERTEXTYPE_REGULAR: + // If the interior of P lies to the right of v_i. + if (Below(v->p, vertices[v->previous].p)) { +- if (edgeTreeIterators[v->previous] == edgeTree.end()) { ++ if (edgeTreeIterators[v->previous] == edgeTree.back()) { + error = true; + break; + } +@@ -1488,27 +1485,28 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + newedge.p1 = v2->p; + newedge.p2 = vertices[v2->next].p; + newedge.index = vindex2; +- edgeTreeRet = edgeTree.insert(newedge); +- edgeTreeIterators[vindex2] = edgeTreeRet.first; ++ //edgeTreeRet = edgeTree.insert(newedge); ++ //edgeTreeIterators[vindex2] = edgeTreeRet.first; ++ edgeTreeIterators[vindex2] = edgeTree.insert(newedge); + helpers[vindex2] = vindex; + } else { + // Search in T to find the edge e_j directly left of v_i. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); +- if (edgeIter == edgeTree.begin()) { ++ if (edgeIter == edgeTree.front()) { + error = true; + break; + } +- edgeIter--; ++ edgeIter = edgeIter->prev(); + // If helper(e_j) is a merge vertex. +- if (vertextypes[helpers[edgeIter->index]] == TPPL_VERTEXTYPE_MERGE) { ++ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting v_i to helper(e_j) in D. +- AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->index], ++ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + // helper(e_j) <- v_i. +- helpers[edgeIter->index] = vindex; ++ helpers[edgeIter->get().index] = vindex; + } + break; + } +@@ -1569,8 +1567,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto + + // Adds a diagonal to the doubly-connected list of vertices. + void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, +- TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators, +- std::set<ScanLineEdge> *edgeTree, long *helpers) { ++ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators, ++ Set<ScanLineEdge> *edgeTree, long *helpers) { + long newindex1, newindex2; + + newindex1 = *numvertices; +@@ -1597,14 +1595,14 @@ void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, lon + vertextypes[newindex1] = vertextypes[index1]; + edgeTreeIterators[newindex1] = edgeTreeIterators[index1]; + helpers[newindex1] = helpers[index1]; +- if (edgeTreeIterators[newindex1] != edgeTree->end()) { +- edgeTreeIterators[newindex1]->index = newindex1; ++ if (edgeTreeIterators[newindex1] != edgeTree->back()) { ++ edgeTreeIterators[newindex1]->get().index = newindex1; + } + vertextypes[newindex2] = vertextypes[index2]; + edgeTreeIterators[newindex2] = edgeTreeIterators[index2]; + helpers[newindex2] = helpers[index2]; +- if (edgeTreeIterators[newindex2] != edgeTree->end()) { +- edgeTreeIterators[newindex2]->index = newindex2; ++ if (edgeTreeIterators[newindex2] != edgeTree->back()) { ++ edgeTreeIterators[newindex2]->get().index = newindex2; + } + } + +@@ -1830,13 +1828,13 @@ int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles + + int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) { + TPPLPolyList monotone; +- TPPLPolyList::iterator iter; ++ TPPLPolyList::Element *iter; + + if (!MonotonePartition(inpolys, &monotone)) { + return 0; + } +- for (iter = monotone.begin(); iter != monotone.end(); iter++) { +- if (!TriangulateMonotone(&(*iter), triangles)) { ++ for (iter = monotone.front(); iter; iter = iter->next()) { ++ if (!TriangulateMonotone(&(iter->get()), triangles)) { + return 0; + } + } +diff --git a/thirdparty/misc/polypartition.h b/thirdparty/misc/polypartition.h +index f163f5d2173f..b2d905a3ef76 100644 +--- a/thirdparty/misc/polypartition.h ++++ b/thirdparty/misc/polypartition.h +@@ -24,8 +24,9 @@ + #ifndef POLYPARTITION_H + #define POLYPARTITION_H + +-#include <list> +-#include <set> ++#include "core/math/vector2.h" ++#include "core/templates/list.h" ++#include "core/templates/set.h" + + typedef double tppl_float; + +@@ -44,49 +45,7 @@ enum TPPLVertexType { + }; + + // 2D point structure. +-struct TPPLPoint { +- tppl_float x; +- tppl_float y; +- // User-specified vertex identifier. Note that this isn't used internally +- // by the library, but will be faithfully copied around. +- int id; +- +- TPPLPoint operator+(const TPPLPoint &p) const { +- TPPLPoint r; +- r.x = x + p.x; +- r.y = y + p.y; +- return r; +- } +- +- TPPLPoint operator-(const TPPLPoint &p) const { +- TPPLPoint r; +- r.x = x - p.x; +- r.y = y - p.y; +- return r; +- } +- +- TPPLPoint operator*(const tppl_float f) const { +- TPPLPoint r; +- r.x = x * f; +- r.y = y * f; +- return r; +- } +- +- TPPLPoint operator/(const tppl_float f) const { +- TPPLPoint r; +- r.x = x / f; +- r.y = y / f; +- return r; +- } +- +- bool operator==(const TPPLPoint &p) const { +- return ((x == p.x) && (y == p.y)); +- } +- +- bool operator!=(const TPPLPoint &p) const { +- return !((x == p.x) && (y == p.y)); +- } +-}; ++typedef Vector2 TPPLPoint; + + // Polygon implemented as an array of points with a "hole" flag. + class TPPLPoly { +@@ -168,9 +127,9 @@ class TPPLPoly { + }; + + #ifdef TPPL_ALLOCATOR +-typedef std::list<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList; ++typedef List<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList; + #else +-typedef std::list<TPPLPoly> TPPLPolyList; ++typedef List<TPPLPoly> TPPLPolyList; + #endif + + class TPPLPartition { +@@ -209,9 +168,9 @@ public: + }; + + #ifdef TPPL_ALLOCATOR +- typedef std::list<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList; ++ typedef List<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList; + #else +- typedef std::list<Diagonal> DiagonalList; ++ typedef List<Diagonal> DiagonalList; + #endif + + // Dynamic programming state for minimum-weight triangulation. +@@ -265,8 +224,8 @@ public: + // Helper functions for MonotonePartition. + bool Below(TPPLPoint &p1, TPPLPoint &p2); + void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, +- TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators, +- std::set<ScanLineEdge> *edgeTree, long *helpers); ++ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators, ++ Set<ScanLineEdge> *edgeTree, long *helpers); + + // Triangulates a monotone polygon, used in Triangulate_MONO. + int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles); diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp new file mode 100644 index 0000000000..4f1b6dcb21 --- /dev/null +++ b/thirdparty/misc/polypartition.cpp @@ -0,0 +1,1849 @@ +/*************************************************************************/ +/* Copyright (c) 2011-2021 Ivan Fratric and contributors. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "polypartition.h" + +#include <algorithm> + +TPPLPoly::TPPLPoly() { + hole = false; + numpoints = 0; + points = NULL; +} + +TPPLPoly::~TPPLPoly() { + if (points) { + delete[] points; + } +} + +void TPPLPoly::Clear() { + if (points) { + delete[] points; + } + hole = false; + numpoints = 0; + points = NULL; +} + +void TPPLPoly::Init(long numpoints) { + Clear(); + this->numpoints = numpoints; + points = new TPPLPoint[numpoints]; +} + +void TPPLPoly::Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) { + Init(3); + points[0] = p1; + points[1] = p2; + points[2] = p3; +} + +TPPLPoly::TPPLPoly(const TPPLPoly &src) : + TPPLPoly() { + hole = src.hole; + numpoints = src.numpoints; + + if (numpoints > 0) { + points = new TPPLPoint[numpoints]; + memcpy(points, src.points, numpoints * sizeof(TPPLPoint)); + } +} + +TPPLPoly &TPPLPoly::operator=(const TPPLPoly &src) { + Clear(); + hole = src.hole; + numpoints = src.numpoints; + + if (numpoints > 0) { + points = new TPPLPoint[numpoints]; + memcpy(points, src.points, numpoints * sizeof(TPPLPoint)); + } + + return *this; +} + +TPPLOrientation TPPLPoly::GetOrientation() const { + long i1, i2; + tppl_float area = 0; + for (i1 = 0; i1 < numpoints; i1++) { + i2 = i1 + 1; + if (i2 == numpoints) { + i2 = 0; + } + area += points[i1].x * points[i2].y - points[i1].y * points[i2].x; + } + if (area > 0) { + return TPPL_ORIENTATION_CCW; + } + if (area < 0) { + return TPPL_ORIENTATION_CW; + } + return TPPL_ORIENTATION_NONE; +} + +void TPPLPoly::SetOrientation(TPPLOrientation orientation) { + TPPLOrientation polyorientation = GetOrientation(); + if (polyorientation != TPPL_ORIENTATION_NONE && polyorientation != orientation) { + Invert(); + } +} + +void TPPLPoly::Invert() { + std::reverse(points, points + numpoints); +} + +TPPLPartition::PartitionVertex::PartitionVertex() : + previous(NULL), next(NULL) { +} + +TPPLPoint TPPLPartition::Normalize(const TPPLPoint &p) { + TPPLPoint r; + tppl_float n = sqrt(p.x * p.x + p.y * p.y); + if (n != 0) { + r = p / n; + } else { + r.x = 0; + r.y = 0; + } + return r; +} + +tppl_float TPPLPartition::Distance(const TPPLPoint &p1, const TPPLPoint &p2) { + tppl_float dx, dy; + dx = p2.x - p1.x; + dy = p2.y - p1.y; + return (sqrt(dx * dx + dy * dy)); +} + +// Checks if two lines intersect. +int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22) { + if ((p11.x == p21.x) && (p11.y == p21.y)) { + return 0; + } + if ((p11.x == p22.x) && (p11.y == p22.y)) { + return 0; + } + if ((p12.x == p21.x) && (p12.y == p21.y)) { + return 0; + } + if ((p12.x == p22.x) && (p12.y == p22.y)) { + return 0; + } + + TPPLPoint v1ort, v2ort, v; + tppl_float dot11, dot12, dot21, dot22; + + v1ort.x = p12.y - p11.y; + v1ort.y = p11.x - p12.x; + + v2ort.x = p22.y - p21.y; + v2ort.y = p21.x - p22.x; + + v = p21 - p11; + dot21 = v.x * v1ort.x + v.y * v1ort.y; + v = p22 - p11; + dot22 = v.x * v1ort.x + v.y * v1ort.y; + + v = p11 - p21; + dot11 = v.x * v2ort.x + v.y * v2ort.y; + v = p12 - p21; + dot12 = v.x * v2ort.x + v.y * v2ort.y; + + if (dot11 * dot12 > 0) { + return 0; + } + if (dot21 * dot22 > 0) { + return 0; + } + + return 1; +} + +// Removes holes from inpolys by merging them with non-holes. +int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) { + TPPLPolyList polys; + TPPLPolyList::Element *holeiter, *polyiter, *iter, *iter2; + long i, i2, holepointindex, polypointindex; + TPPLPoint holepoint, polypoint, bestpolypoint; + TPPLPoint linep1, linep2; + TPPLPoint v1, v2; + TPPLPoly newpoly; + bool hasholes; + bool pointvisible; + bool pointfound; + + // Check for the trivial case of no holes. + hasholes = false; + for (iter = inpolys->front(); iter; iter = iter->next()) { + if (iter->get().IsHole()) { + hasholes = true; + break; + } + } + if (!hasholes) { + for (iter = inpolys->front(); iter; iter = iter->next()) { + outpolys->push_back(iter->get()); + } + return 1; + } + + polys = *inpolys; + + while (1) { + // Find the hole point with the largest x. + hasholes = false; + for (iter = polys.front(); iter; iter = iter->next()) { + if (!iter->get().IsHole()) { + continue; + } + + if (!hasholes) { + hasholes = true; + holeiter = iter; + holepointindex = 0; + } + + for (i = 0; i < iter->get().GetNumPoints(); i++) { + if (iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) { + holeiter = iter; + holepointindex = i; + } + } + } + if (!hasholes) { + break; + } + holepoint = holeiter->get().GetPoint(holepointindex); + + pointfound = false; + for (iter = polys.front(); iter; iter = iter->next()) { + if (iter->get().IsHole()) { + continue; + } + for (i = 0; i < iter->get().GetNumPoints(); i++) { + if (iter->get().GetPoint(i).x <= holepoint.x) { + continue; + } + if (!InCone(iter->get().GetPoint((i + iter->get().GetNumPoints() - 1) % (iter->get().GetNumPoints())), + iter->get().GetPoint(i), + iter->get().GetPoint((i + 1) % (iter->get().GetNumPoints())), + holepoint)) { + continue; + } + polypoint = iter->get().GetPoint(i); + if (pointfound) { + v1 = Normalize(polypoint - holepoint); + v2 = Normalize(bestpolypoint - holepoint); + if (v2.x > v1.x) { + continue; + } + } + pointvisible = true; + for (iter2 = polys.front(); iter2; iter2->next()) { + if (iter2->get().IsHole()) { + continue; + } + for (i2 = 0; i2 < iter2->get().GetNumPoints(); i2++) { + linep1 = iter2->get().GetPoint(i2); + linep2 = iter2->get().GetPoint((i2 + 1) % (iter2->get().GetNumPoints())); + if (Intersects(holepoint, polypoint, linep1, linep2)) { + pointvisible = false; + break; + } + } + if (!pointvisible) { + break; + } + } + if (pointvisible) { + pointfound = true; + bestpolypoint = polypoint; + polyiter = iter; + polypointindex = i; + } + } + } + + if (!pointfound) { + return 0; + } + + newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2); + i2 = 0; + for (i = 0; i <= polypointindex; i++) { + newpoly[i2] = polyiter->get().GetPoint(i); + i2++; + } + for (i = 0; i <= holeiter->get().GetNumPoints(); i++) { + newpoly[i2] = holeiter->get().GetPoint((i + holepointindex) % holeiter->get().GetNumPoints()); + i2++; + } + for (i = polypointindex; i < polyiter->get().GetNumPoints(); i++) { + newpoly[i2] = polyiter->get().GetPoint(i); + i2++; + } + + polys.erase(holeiter); + polys.erase(polyiter); + polys.push_back(newpoly); + } + + for (iter = polys.front(); iter; iter = iter->next()) { + outpolys->push_back(iter->get()); + } + + return 1; +} + +bool TPPLPartition::IsConvex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) { + tppl_float tmp; + tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y); + if (tmp > 0) { + return 1; + } else { + return 0; + } +} + +bool TPPLPartition::IsReflex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) { + tppl_float tmp; + tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y); + if (tmp < 0) { + return 1; + } else { + return 0; + } +} + +bool TPPLPartition::IsInside(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) { + if (IsConvex(p1, p, p2)) { + return false; + } + if (IsConvex(p2, p, p3)) { + return false; + } + if (IsConvex(p3, p, p1)) { + return false; + } + return true; +} + +bool TPPLPartition::InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) { + bool convex; + + convex = IsConvex(p1, p2, p3); + + if (convex) { + if (!IsConvex(p1, p2, p)) { + return false; + } + if (!IsConvex(p2, p3, p)) { + return false; + } + return true; + } else { + if (IsConvex(p1, p2, p)) { + return true; + } + if (IsConvex(p2, p3, p)) { + return true; + } + return false; + } +} + +bool TPPLPartition::InCone(PartitionVertex *v, TPPLPoint &p) { + TPPLPoint p1, p2, p3; + + p1 = v->previous->p; + p2 = v->p; + p3 = v->next->p; + + return InCone(p1, p2, p3, p); +} + +void TPPLPartition::UpdateVertexReflexity(PartitionVertex *v) { + PartitionVertex *v1 = NULL, *v3 = NULL; + v1 = v->previous; + v3 = v->next; + v->isConvex = !IsReflex(v1->p, v->p, v3->p); +} + +void TPPLPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) { + long i; + PartitionVertex *v1 = NULL, *v3 = NULL; + TPPLPoint vec1, vec3; + + v1 = v->previous; + v3 = v->next; + + v->isConvex = IsConvex(v1->p, v->p, v3->p); + + vec1 = Normalize(v1->p - v->p); + vec3 = Normalize(v3->p - v->p); + v->angle = vec1.x * vec3.x + vec1.y * vec3.y; + + if (v->isConvex) { + v->isEar = true; + for (i = 0; i < numvertices; i++) { + if ((vertices[i].p.x == v->p.x) && (vertices[i].p.y == v->p.y)) { + continue; + } + if ((vertices[i].p.x == v1->p.x) && (vertices[i].p.y == v1->p.y)) { + continue; + } + if ((vertices[i].p.x == v3->p.x) && (vertices[i].p.y == v3->p.y)) { + continue; + } + if (IsInside(v1->p, v->p, v3->p, vertices[i].p)) { + v->isEar = false; + break; + } + } + } else { + v->isEar = false; + } +} + +// Triangulation by ear removal. +int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) { + if (!poly->Valid()) { + return 0; + } + + long numvertices; + PartitionVertex *vertices = NULL; + PartitionVertex *ear = NULL; + TPPLPoly triangle; + long i, j; + bool earfound; + + if (poly->GetNumPoints() < 3) { + return 0; + } + if (poly->GetNumPoints() == 3) { + triangles->push_back(*poly); + return 1; + } + + numvertices = poly->GetNumPoints(); + + vertices = new PartitionVertex[numvertices]; + for (i = 0; i < numvertices; i++) { + vertices[i].isActive = true; + vertices[i].p = poly->GetPoint(i); + if (i == (numvertices - 1)) { + vertices[i].next = &(vertices[0]); + } else { + vertices[i].next = &(vertices[i + 1]); + } + if (i == 0) { + vertices[i].previous = &(vertices[numvertices - 1]); + } else { + vertices[i].previous = &(vertices[i - 1]); + } + } + for (i = 0; i < numvertices; i++) { + UpdateVertex(&vertices[i], vertices, numvertices); + } + + for (i = 0; i < numvertices - 3; i++) { + earfound = false; + // Find the most extruded ear. + for (j = 0; j < numvertices; j++) { + if (!vertices[j].isActive) { + continue; + } + if (!vertices[j].isEar) { + continue; + } + if (!earfound) { + earfound = true; + ear = &(vertices[j]); + } else { + if (vertices[j].angle > ear->angle) { + ear = &(vertices[j]); + } + } + } + if (!earfound) { + delete[] vertices; + return 0; + } + + triangle.Triangle(ear->previous->p, ear->p, ear->next->p); + triangles->push_back(triangle); + + ear->isActive = false; + ear->previous->next = ear->next; + ear->next->previous = ear->previous; + + if (i == numvertices - 4) { + break; + } + + UpdateVertex(ear->previous, vertices, numvertices); + UpdateVertex(ear->next, vertices, numvertices); + } + for (i = 0; i < numvertices; i++) { + if (vertices[i].isActive) { + triangle.Triangle(vertices[i].previous->p, vertices[i].p, vertices[i].next->p); + triangles->push_back(triangle); + break; + } + } + + delete[] vertices; + + return 1; +} + +int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) { + TPPLPolyList outpolys; + TPPLPolyList::Element *iter; + + if (!RemoveHoles(inpolys, &outpolys)) { + return 0; + } + for (iter = outpolys.front(); iter; iter = iter->next()) { + if (!Triangulate_EC(&(iter->get()), triangles)) { + return 0; + } + } + return 1; +} + +int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) { + if (!poly->Valid()) { + return 0; + } + + TPPLPolyList triangles; + TPPLPolyList::Element *iter1, *iter2; + TPPLPoly *poly1 = NULL, *poly2 = NULL; + TPPLPoly newpoly; + TPPLPoint d1, d2, p1, p2, p3; + long i11, i12, i21, i22, i13, i23, j, k; + bool isdiagonal; + long numreflex; + + // Check if the poly is already convex. + numreflex = 0; + for (i11 = 0; i11 < poly->GetNumPoints(); i11++) { + if (i11 == 0) { + i12 = poly->GetNumPoints() - 1; + } else { + i12 = i11 - 1; + } + if (i11 == (poly->GetNumPoints() - 1)) { + i13 = 0; + } else { + i13 = i11 + 1; + } + if (IsReflex(poly->GetPoint(i12), poly->GetPoint(i11), poly->GetPoint(i13))) { + numreflex = 1; + break; + } + } + if (numreflex == 0) { + parts->push_back(*poly); + return 1; + } + + if (!Triangulate_EC(poly, &triangles)) { + return 0; + } + + for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) { + poly1 = &(iter1->get()); + for (i11 = 0; i11 < poly1->GetNumPoints(); i11++) { + d1 = poly1->GetPoint(i11); + i12 = (i11 + 1) % (poly1->GetNumPoints()); + d2 = poly1->GetPoint(i12); + + isdiagonal = false; + for (iter2 = iter1; iter2; iter2 = iter2->next()) { + if (iter1 == iter2) { + continue; + } + poly2 = &(iter2->get()); + + for (i21 = 0; i21 < poly2->GetNumPoints(); i21++) { + if ((d2.x != poly2->GetPoint(i21).x) || (d2.y != poly2->GetPoint(i21).y)) { + continue; + } + i22 = (i21 + 1) % (poly2->GetNumPoints()); + if ((d1.x != poly2->GetPoint(i22).x) || (d1.y != poly2->GetPoint(i22).y)) { + continue; + } + isdiagonal = true; + break; + } + if (isdiagonal) { + break; + } + } + + if (!isdiagonal) { + continue; + } + + p2 = poly1->GetPoint(i11); + if (i11 == 0) { + i13 = poly1->GetNumPoints() - 1; + } else { + i13 = i11 - 1; + } + p1 = poly1->GetPoint(i13); + if (i22 == (poly2->GetNumPoints() - 1)) { + i23 = 0; + } else { + i23 = i22 + 1; + } + p3 = poly2->GetPoint(i23); + + if (!IsConvex(p1, p2, p3)) { + continue; + } + + p2 = poly1->GetPoint(i12); + if (i12 == (poly1->GetNumPoints() - 1)) { + i13 = 0; + } else { + i13 = i12 + 1; + } + p3 = poly1->GetPoint(i13); + if (i21 == 0) { + i23 = poly2->GetNumPoints() - 1; + } else { + i23 = i21 - 1; + } + p1 = poly2->GetPoint(i23); + + if (!IsConvex(p1, p2, p3)) { + continue; + } + + newpoly.Init(poly1->GetNumPoints() + poly2->GetNumPoints() - 2); + k = 0; + for (j = i12; j != i11; j = (j + 1) % (poly1->GetNumPoints())) { + newpoly[k] = poly1->GetPoint(j); + k++; + } + for (j = i22; j != i21; j = (j + 1) % (poly2->GetNumPoints())) { + newpoly[k] = poly2->GetPoint(j); + k++; + } + + triangles.erase(iter2); + iter1->get() = newpoly; + poly1 = &(iter1->get()); + i11 = -1; + + continue; + } + } + + for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) { + parts->push_back(iter1->get()); + } + + return 1; +} + +int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) { + TPPLPolyList outpolys; + TPPLPolyList::Element *iter; + + if (!RemoveHoles(inpolys, &outpolys)) { + return 0; + } + for (iter = outpolys.front(); iter; iter = iter->next()) { + if (!ConvexPartition_HM(&(iter->get()), parts)) { + return 0; + } + } + return 1; +} + +// Minimum-weight polygon triangulation by dynamic programming. +// Time complexity: O(n^3) +// Space complexity: O(n^2) +int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) { + if (!poly->Valid()) { + return 0; + } + + long i, j, k, gap, n; + DPState **dpstates = NULL; + TPPLPoint p1, p2, p3, p4; + long bestvertex; + tppl_float weight, minweight, d1, d2; + Diagonal diagonal, newdiagonal; + DiagonalList diagonals; + TPPLPoly triangle; + int ret = 1; + + n = poly->GetNumPoints(); + dpstates = new DPState *[n]; + for (i = 1; i < n; i++) { + dpstates[i] = new DPState[i]; + } + + // Initialize states and visibility. + for (i = 0; i < (n - 1); i++) { + p1 = poly->GetPoint(i); + for (j = i + 1; j < n; j++) { + dpstates[j][i].visible = true; + dpstates[j][i].weight = 0; + dpstates[j][i].bestvertex = -1; + if (j != (i + 1)) { + p2 = poly->GetPoint(j); + + // Visibility check. + if (i == 0) { + p3 = poly->GetPoint(n - 1); + } else { + p3 = poly->GetPoint(i - 1); + } + if (i == (n - 1)) { + p4 = poly->GetPoint(0); + } else { + p4 = poly->GetPoint(i + 1); + } + if (!InCone(p3, p1, p4, p2)) { + dpstates[j][i].visible = false; + continue; + } + + if (j == 0) { + p3 = poly->GetPoint(n - 1); + } else { + p3 = poly->GetPoint(j - 1); + } + if (j == (n - 1)) { + p4 = poly->GetPoint(0); + } else { + p4 = poly->GetPoint(j + 1); + } + if (!InCone(p3, p2, p4, p1)) { + dpstates[j][i].visible = false; + continue; + } + + for (k = 0; k < n; k++) { + p3 = poly->GetPoint(k); + if (k == (n - 1)) { + p4 = poly->GetPoint(0); + } else { + p4 = poly->GetPoint(k + 1); + } + if (Intersects(p1, p2, p3, p4)) { + dpstates[j][i].visible = false; + break; + } + } + } + } + } + dpstates[n - 1][0].visible = true; + dpstates[n - 1][0].weight = 0; + dpstates[n - 1][0].bestvertex = -1; + + for (gap = 2; gap < n; gap++) { + for (i = 0; i < (n - gap); i++) { + j = i + gap; + if (!dpstates[j][i].visible) { + continue; + } + bestvertex = -1; + for (k = (i + 1); k < j; k++) { + if (!dpstates[k][i].visible) { + continue; + } + if (!dpstates[j][k].visible) { + continue; + } + + if (k <= (i + 1)) { + d1 = 0; + } else { + d1 = Distance(poly->GetPoint(i), poly->GetPoint(k)); + } + if (j <= (k + 1)) { + d2 = 0; + } else { + d2 = Distance(poly->GetPoint(k), poly->GetPoint(j)); + } + + weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2; + + if ((bestvertex == -1) || (weight < minweight)) { + bestvertex = k; + minweight = weight; + } + } + if (bestvertex == -1) { + for (i = 1; i < n; i++) { + delete[] dpstates[i]; + } + delete[] dpstates; + + return 0; + } + + dpstates[j][i].bestvertex = bestvertex; + dpstates[j][i].weight = minweight; + } + } + + newdiagonal.index1 = 0; + newdiagonal.index2 = n - 1; + diagonals.push_back(newdiagonal); + while (!diagonals.is_empty()) { + diagonal = diagonals.front()->get(); + diagonals.pop_front(); + bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex; + if (bestvertex == -1) { + ret = 0; + break; + } + triangle.Triangle(poly->GetPoint(diagonal.index1), poly->GetPoint(bestvertex), poly->GetPoint(diagonal.index2)); + triangles->push_back(triangle); + if (bestvertex > (diagonal.index1 + 1)) { + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = bestvertex; + diagonals.push_back(newdiagonal); + } + if (diagonal.index2 > (bestvertex + 1)) { + newdiagonal.index1 = bestvertex; + newdiagonal.index2 = diagonal.index2; + diagonals.push_back(newdiagonal); + } + } + + for (i = 1; i < n; i++) { + delete[] dpstates[i]; + } + delete[] dpstates; + + return ret; +} + +void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates) { + Diagonal newdiagonal; + DiagonalList *pairs = NULL; + long w2; + + w2 = dpstates[a][b].weight; + if (w > w2) { + return; + } + + pairs = &(dpstates[a][b].pairs); + newdiagonal.index1 = i; + newdiagonal.index2 = j; + + if (w < w2) { + pairs->clear(); + pairs->push_front(newdiagonal); + dpstates[a][b].weight = w; + } else { + if ((!pairs->is_empty()) && (i <= pairs->front()->get().index1)) { + return; + } + while ((!pairs->is_empty()) && (pairs->front()->get().index2 >= j)) { + pairs->pop_front(); + } + pairs->push_front(newdiagonal); + } +} + +void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { + DiagonalList *pairs = NULL; + DiagonalList::Element *iter, *lastiter; + long top; + long w; + + if (!dpstates[i][j].visible) { + return; + } + top = j; + w = dpstates[i][j].weight; + if (k - j > 1) { + if (!dpstates[j][k].visible) { + return; + } + w += dpstates[j][k].weight + 1; + } + if (j - i > 1) { + pairs = &(dpstates[i][j].pairs); + iter = pairs->back(); + lastiter = pairs->back(); + while (iter != pairs->front()) { + iter--; + if (!IsReflex(vertices[iter->get().index2].p, vertices[j].p, vertices[k].p)) { + lastiter = iter; + } else { + break; + } + } + if (lastiter == pairs->back()) { + w++; + } else { + if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->get().index1].p)) { + w++; + } else { + top = lastiter->get().index1; + } + } + } + UpdateState(i, k, w, top, j, dpstates); +} + +void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { + DiagonalList *pairs = NULL; + DiagonalList::Element *iter, *lastiter; + long top; + long w; + + if (!dpstates[j][k].visible) { + return; + } + top = j; + w = dpstates[j][k].weight; + + if (j - i > 1) { + if (!dpstates[i][j].visible) { + return; + } + w += dpstates[i][j].weight + 1; + } + if (k - j > 1) { + pairs = &(dpstates[j][k].pairs); + + iter = pairs->front(); + if ((!pairs->is_empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p))) { + lastiter = iter; + while (iter) { + if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p)) { + lastiter = iter; + iter = iter->next(); + } else { + break; + } + } + if (IsReflex(vertices[lastiter->get().index2].p, vertices[k].p, vertices[i].p)) { + w++; + } else { + top = lastiter->get().index2; + } + } else { + w++; + } + } + UpdateState(i, k, w, j, top, dpstates); +} + +int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) { + if (!poly->Valid()) { + return 0; + } + + TPPLPoint p1, p2, p3, p4; + PartitionVertex *vertices = NULL; + DPState2 **dpstates = NULL; + long i, j, k, n, gap; + DiagonalList diagonals, diagonals2; + Diagonal diagonal, newdiagonal; + DiagonalList *pairs = NULL, *pairs2 = NULL; + DiagonalList::Element *iter, *iter2; + int ret; + TPPLPoly newpoly; + List<long> indices; + List<long>::Element *iiter; + bool ijreal, jkreal; + + n = poly->GetNumPoints(); + vertices = new PartitionVertex[n]; + + dpstates = new DPState2 *[n]; + for (i = 0; i < n; i++) { + dpstates[i] = new DPState2[n]; + } + + // Initialize vertex information. + for (i = 0; i < n; i++) { + vertices[i].p = poly->GetPoint(i); + vertices[i].isActive = true; + if (i == 0) { + vertices[i].previous = &(vertices[n - 1]); + } else { + vertices[i].previous = &(vertices[i - 1]); + } + if (i == (poly->GetNumPoints() - 1)) { + vertices[i].next = &(vertices[0]); + } else { + vertices[i].next = &(vertices[i + 1]); + } + } + for (i = 1; i < n; i++) { + UpdateVertexReflexity(&(vertices[i])); + } + + // Initialize states and visibility. + for (i = 0; i < (n - 1); i++) { + p1 = poly->GetPoint(i); + for (j = i + 1; j < n; j++) { + dpstates[i][j].visible = true; + if (j == i + 1) { + dpstates[i][j].weight = 0; + } else { + dpstates[i][j].weight = 2147483647; + } + if (j != (i + 1)) { + p2 = poly->GetPoint(j); + + // Visibility check. + if (!InCone(&vertices[i], p2)) { + dpstates[i][j].visible = false; + continue; + } + if (!InCone(&vertices[j], p1)) { + dpstates[i][j].visible = false; + continue; + } + + for (k = 0; k < n; k++) { + p3 = poly->GetPoint(k); + if (k == (n - 1)) { + p4 = poly->GetPoint(0); + } else { + p4 = poly->GetPoint(k + 1); + } + if (Intersects(p1, p2, p3, p4)) { + dpstates[i][j].visible = false; + break; + } + } + } + } + } + for (i = 0; i < (n - 2); i++) { + j = i + 2; + if (dpstates[i][j].visible) { + dpstates[i][j].weight = 0; + newdiagonal.index1 = i + 1; + newdiagonal.index2 = i + 1; + dpstates[i][j].pairs.push_back(newdiagonal); + } + } + + dpstates[0][n - 1].visible = true; + vertices[0].isConvex = false; // By convention. + + for (gap = 3; gap < n; gap++) { + for (i = 0; i < n - gap; i++) { + if (vertices[i].isConvex) { + continue; + } + k = i + gap; + if (dpstates[i][k].visible) { + if (!vertices[k].isConvex) { + for (j = i + 1; j < k; j++) { + TypeA(i, j, k, vertices, dpstates); + } + } else { + for (j = i + 1; j < (k - 1); j++) { + if (vertices[j].isConvex) { + continue; + } + TypeA(i, j, k, vertices, dpstates); + } + TypeA(i, k - 1, k, vertices, dpstates); + } + } + } + for (k = gap; k < n; k++) { + if (vertices[k].isConvex) { + continue; + } + i = k - gap; + if ((vertices[i].isConvex) && (dpstates[i][k].visible)) { + TypeB(i, i + 1, k, vertices, dpstates); + for (j = i + 2; j < k; j++) { + if (vertices[j].isConvex) { + continue; + } + TypeB(i, j, k, vertices, dpstates); + } + } + } + } + + // Recover solution. + ret = 1; + newdiagonal.index1 = 0; + newdiagonal.index2 = n - 1; + diagonals.push_front(newdiagonal); + while (!diagonals.is_empty()) { + diagonal = diagonals.front()->get(); + diagonals.pop_front(); + if ((diagonal.index2 - diagonal.index1) <= 1) { + continue; + } + pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); + if (pairs->is_empty()) { + ret = 0; + break; + } + if (!vertices[diagonal.index1].isConvex) { + iter = pairs->back(); + iter--; + j = iter->get().index2; + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + diagonals.push_front(newdiagonal); + if ((j - diagonal.index1) > 1) { + if (iter->get().index1 != iter->get().index2) { + pairs2 = &(dpstates[diagonal.index1][j].pairs); + while (1) { + if (pairs2->is_empty()) { + ret = 0; + break; + } + iter2 = pairs2->back(); + iter2--; + if (iter->get().index1 != iter2->get().index1) { + pairs2->pop_back(); + } else { + break; + } + } + if (ret == 0) { + break; + } + } + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + diagonals.push_front(newdiagonal); + } + } else { + iter = pairs->front(); + j = iter->get().index1; + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + diagonals.push_front(newdiagonal); + if ((diagonal.index2 - j) > 1) { + if (iter->get().index1 != iter->get().index2) { + pairs2 = &(dpstates[j][diagonal.index2].pairs); + while (1) { + if (pairs2->is_empty()) { + ret = 0; + break; + } + iter2 = pairs2->front(); + if (iter->get().index2 != iter2->get().index2) { + pairs2->pop_front(); + } else { + break; + } + } + if (ret == 0) { + break; + } + } + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + diagonals.push_front(newdiagonal); + } + } + } + + if (ret == 0) { + for (i = 0; i < n; i++) { + delete[] dpstates[i]; + } + delete[] dpstates; + delete[] vertices; + + return ret; + } + + newdiagonal.index1 = 0; + newdiagonal.index2 = n - 1; + diagonals.push_front(newdiagonal); + while (!diagonals.is_empty()) { + diagonal = diagonals.front()->get(); + diagonals.pop_front(); + if ((diagonal.index2 - diagonal.index1) <= 1) { + continue; + } + + indices.clear(); + diagonals2.clear(); + indices.push_back(diagonal.index1); + indices.push_back(diagonal.index2); + diagonals2.push_front(diagonal); + + while (!diagonals2.is_empty()) { + diagonal = diagonals2.front()->get(); + diagonals2.pop_front(); + if ((diagonal.index2 - diagonal.index1) <= 1) { + continue; + } + ijreal = true; + jkreal = true; + pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); + if (!vertices[diagonal.index1].isConvex) { + iter = pairs->back(); + iter--; + j = iter->get().index2; + if (iter->get().index1 != iter->get().index2) { + ijreal = false; + } + } else { + iter = pairs->front(); + j = iter->get().index1; + if (iter->get().index1 != iter->get().index2) { + jkreal = false; + } + } + + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + if (ijreal) { + diagonals.push_back(newdiagonal); + } else { + diagonals2.push_back(newdiagonal); + } + + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + if (jkreal) { + diagonals.push_back(newdiagonal); + } else { + diagonals2.push_back(newdiagonal); + } + + indices.push_back(j); + } + + //std::sort(indices.begin(), indices.end()); + indices.sort(); + newpoly.Init((long)indices.size()); + k = 0; + for (iiter = indices.front(); iiter != indices.back(); iiter = iiter->next()) { + newpoly[k] = vertices[iiter->get()].p; + k++; + } + parts->push_back(newpoly); + } + + for (i = 0; i < n; i++) { + delete[] dpstates[i]; + } + delete[] dpstates; + delete[] vertices; + + return ret; +} + +// Creates a monotone partition of a list of polygons that +// can contain holes. Triangulates a set of polygons by +// first partitioning them into monotone polygons. +// Time complexity: O(n*log(n)), n is the number of vertices. +// Space complexity: O(n) +// The algorithm used here is outlined in the book +// "Computational Geometry: Algorithms and Applications" +// by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars. +int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys) { + TPPLPolyList::Element *iter; + MonotoneVertex *vertices = NULL; + long i, numvertices, vindex, vindex2, newnumvertices, maxnumvertices; + long polystartindex, polyendindex; + TPPLPoly *poly = NULL; + MonotoneVertex *v = NULL, *v2 = NULL, *vprev = NULL, *vnext = NULL; + ScanLineEdge newedge; + bool error = false; + + numvertices = 0; + for (iter = inpolys->front(); iter; iter++) { + numvertices += iter->get().GetNumPoints(); + } + + maxnumvertices = numvertices * 3; + vertices = new MonotoneVertex[maxnumvertices]; + newnumvertices = numvertices; + + polystartindex = 0; + for (iter = inpolys->front(); iter; iter++) { + poly = &(iter->get()); + polyendindex = polystartindex + poly->GetNumPoints() - 1; + for (i = 0; i < poly->GetNumPoints(); i++) { + vertices[i + polystartindex].p = poly->GetPoint(i); + if (i == 0) { + vertices[i + polystartindex].previous = polyendindex; + } else { + vertices[i + polystartindex].previous = i + polystartindex - 1; + } + if (i == (poly->GetNumPoints() - 1)) { + vertices[i + polystartindex].next = polystartindex; + } else { + vertices[i + polystartindex].next = i + polystartindex + 1; + } + } + polystartindex = polyendindex + 1; + } + + // Construct the priority queue. + long *priority = new long[numvertices]; + for (i = 0; i < numvertices; i++) { + priority[i] = i; + } + std::sort(priority, &(priority[numvertices]), VertexSorter(vertices)); + + // Determine vertex types. + TPPLVertexType *vertextypes = new TPPLVertexType[maxnumvertices]; + for (i = 0; i < numvertices; i++) { + v = &(vertices[i]); + vprev = &(vertices[v->previous]); + vnext = &(vertices[v->next]); + + if (Below(vprev->p, v->p) && Below(vnext->p, v->p)) { + if (IsConvex(vnext->p, vprev->p, v->p)) { + vertextypes[i] = TPPL_VERTEXTYPE_START; + } else { + vertextypes[i] = TPPL_VERTEXTYPE_SPLIT; + } + } else if (Below(v->p, vprev->p) && Below(v->p, vnext->p)) { + if (IsConvex(vnext->p, vprev->p, v->p)) { + vertextypes[i] = TPPL_VERTEXTYPE_END; + } else { + vertextypes[i] = TPPL_VERTEXTYPE_MERGE; + } + } else { + vertextypes[i] = TPPL_VERTEXTYPE_REGULAR; + } + } + + // Helpers. + long *helpers = new long[maxnumvertices]; + + // Binary search tree that holds edges intersecting the scanline. + // Note that while set doesn't actually have to be implemented as + // a tree, complexity requirements for operations are the same as + // for the balanced binary search tree. + Set<ScanLineEdge> edgeTree; + // Store iterators to the edge tree elements. + // This makes deleting existing edges much faster. + Set<ScanLineEdge>::Element **edgeTreeIterators, *edgeIter; + edgeTreeIterators = new Set<ScanLineEdge>::Element *[maxnumvertices]; + //Pair<Set<ScanLineEdge>::iterator, bool> edgeTreeRet; + for (i = 0; i < numvertices; i++) { + edgeTreeIterators[i] = nullptr; + } + + // For each vertex. + for (i = 0; i < numvertices; i++) { + vindex = priority[i]; + v = &(vertices[vindex]); + vindex2 = vindex; + v2 = v; + + // Depending on the vertex type, do the appropriate action. + // Comments in the following sections are copied from + // "Computational Geometry: Algorithms and Applications". + // Notation: e_i = e subscript i, v_i = v subscript i, etc. + switch (vertextypes[vindex]) { + case TPPL_VERTEXTYPE_START: + // Insert e_i in T and set helper(e_i) to v_i. + newedge.p1 = v->p; + newedge.p2 = vertices[v->next].p; + newedge.index = vindex; + //edgeTreeRet = edgeTree.insert(newedge); + //edgeTreeIterators[vindex] = edgeTreeRet.first; + edgeTreeIterators[vindex] = edgeTree.insert(newedge); + helpers[vindex] = vindex; + break; + + case TPPL_VERTEXTYPE_END: + if (edgeTreeIterators[v->previous] == edgeTree.back()) { + error = true; + break; + } + // If helper(e_i - 1) is a merge vertex + if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting vi to helper(e_i - 1) in D. + AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + // Delete e_i - 1 from T + edgeTree.erase(edgeTreeIterators[v->previous]); + break; + + case TPPL_VERTEXTYPE_SPLIT: + // Search in T to find the edge e_j directly left of v_i. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); + if (edgeIter == edgeTree.front()) { + error = true; + break; + } + edgeIter--; + // Insert the diagonal connecting vi to helper(e_j) in D. + AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices - 2; + v2 = &(vertices[vindex2]); + // helper(e_j) in v_i. + helpers[edgeIter->get().index] = vindex; + // Insert e_i in T and set helper(e_i) to v_i. + newedge.p1 = v2->p; + newedge.p2 = vertices[v2->next].p; + newedge.index = vindex2; + //edgeTreeRet = edgeTree.insert(newedge); + //edgeTreeIterators[vindex2] = edgeTreeRet.first; + edgeTreeIterators[vindex2] = edgeTree.insert(newedge); + helpers[vindex2] = vindex2; + break; + + case TPPL_VERTEXTYPE_MERGE: + if (edgeTreeIterators[v->previous] == edgeTree.back()) { + error = true; + break; + } + // if helper(e_i - 1) is a merge vertex + if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting vi to helper(e_i - 1) in D. + AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices - 2; + v2 = &(vertices[vindex2]); + } + // Delete e_i - 1 from T. + edgeTree.erase(edgeTreeIterators[v->previous]); + // Search in T to find the edge e_j directly left of v_i. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); + if (edgeIter == edgeTree.front()) { + error = true; + break; + } + edgeIter--; + // If helper(e_j) is a merge vertex. + if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting v_i to helper(e_j) in D. + AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->get().index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + // helper(e_j) <- v_i + helpers[edgeIter->get().index] = vindex2; + break; + + case TPPL_VERTEXTYPE_REGULAR: + // If the interior of P lies to the right of v_i. + if (Below(v->p, vertices[v->previous].p)) { + if (edgeTreeIterators[v->previous] == edgeTree.back()) { + error = true; + break; + } + // If helper(e_i - 1) is a merge vertex. + if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting v_i to helper(e_i - 1) in D. + AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices - 2; + v2 = &(vertices[vindex2]); + } + // Delete e_i - 1 from T. + edgeTree.erase(edgeTreeIterators[v->previous]); + // Insert e_i in T and set helper(e_i) to v_i. + newedge.p1 = v2->p; + newedge.p2 = vertices[v2->next].p; + newedge.index = vindex2; + //edgeTreeRet = edgeTree.insert(newedge); + //edgeTreeIterators[vindex2] = edgeTreeRet.first; + edgeTreeIterators[vindex2] = edgeTree.insert(newedge); + helpers[vindex2] = vindex; + } else { + // Search in T to find the edge e_j directly left of v_i. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); + if (edgeIter == edgeTree.front()) { + error = true; + break; + } + edgeIter = edgeIter->prev(); + // If helper(e_j) is a merge vertex. + if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) { + // Insert the diagonal connecting v_i to helper(e_j) in D. + AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + // helper(e_j) <- v_i. + helpers[edgeIter->get().index] = vindex; + } + break; + } + + if (error) + break; + } + + char *used = new char[newnumvertices]; + memset(used, 0, newnumvertices * sizeof(char)); + + if (!error) { + // Return result. + long size; + TPPLPoly mpoly; + for (i = 0; i < newnumvertices; i++) { + if (used[i]) { + continue; + } + v = &(vertices[i]); + vnext = &(vertices[v->next]); + size = 1; + while (vnext != v) { + vnext = &(vertices[vnext->next]); + size++; + } + mpoly.Init(size); + v = &(vertices[i]); + mpoly[0] = v->p; + vnext = &(vertices[v->next]); + size = 1; + used[i] = 1; + used[v->next] = 1; + while (vnext != v) { + mpoly[size] = vnext->p; + used[vnext->next] = 1; + vnext = &(vertices[vnext->next]); + size++; + } + monotonePolys->push_back(mpoly); + } + } + + // Cleanup. + delete[] vertices; + delete[] priority; + delete[] vertextypes; + delete[] edgeTreeIterators; + delete[] helpers; + delete[] used; + + if (error) { + return 0; + } else { + return 1; + } +} + +// Adds a diagonal to the doubly-connected list of vertices. +void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, + TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators, + Set<ScanLineEdge> *edgeTree, long *helpers) { + long newindex1, newindex2; + + newindex1 = *numvertices; + (*numvertices)++; + newindex2 = *numvertices; + (*numvertices)++; + + vertices[newindex1].p = vertices[index1].p; + vertices[newindex2].p = vertices[index2].p; + + vertices[newindex2].next = vertices[index2].next; + vertices[newindex1].next = vertices[index1].next; + + vertices[vertices[index2].next].previous = newindex2; + vertices[vertices[index1].next].previous = newindex1; + + vertices[index1].next = newindex2; + vertices[newindex2].previous = index1; + + vertices[index2].next = newindex1; + vertices[newindex1].previous = index2; + + // Update all relevant structures. + vertextypes[newindex1] = vertextypes[index1]; + edgeTreeIterators[newindex1] = edgeTreeIterators[index1]; + helpers[newindex1] = helpers[index1]; + if (edgeTreeIterators[newindex1] != edgeTree->back()) { + edgeTreeIterators[newindex1]->get().index = newindex1; + } + vertextypes[newindex2] = vertextypes[index2]; + edgeTreeIterators[newindex2] = edgeTreeIterators[index2]; + helpers[newindex2] = helpers[index2]; + if (edgeTreeIterators[newindex2] != edgeTree->back()) { + edgeTreeIterators[newindex2]->get().index = newindex2; + } +} + +bool TPPLPartition::Below(TPPLPoint &p1, TPPLPoint &p2) { + if (p1.y < p2.y) { + return true; + } else if (p1.y == p2.y) { + if (p1.x < p2.x) { + return true; + } + } + return false; +} + +// Sorts in the falling order of y values, if y is equal, x is used instead. +bool TPPLPartition::VertexSorter::operator()(long index1, long index2) { + if (vertices[index1].p.y > vertices[index2].p.y) { + return true; + } else if (vertices[index1].p.y == vertices[index2].p.y) { + if (vertices[index1].p.x > vertices[index2].p.x) { + return true; + } + } + return false; +} + +bool TPPLPartition::ScanLineEdge::IsConvex(const TPPLPoint &p1, const TPPLPoint &p2, const TPPLPoint &p3) const { + tppl_float tmp; + tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y); + if (tmp > 0) { + return 1; + } + + return 0; +} + +bool TPPLPartition::ScanLineEdge::operator<(const ScanLineEdge &other) const { + if (other.p1.y == other.p2.y) { + if (p1.y == p2.y) { + return (p1.y < other.p1.y); + } + return IsConvex(p1, p2, other.p1); + } else if (p1.y == p2.y) { + return !IsConvex(other.p1, other.p2, p1); + } else if (p1.y < other.p1.y) { + return !IsConvex(other.p1, other.p2, p1); + } else { + return IsConvex(p1, p2, other.p1); + } +} + +// Triangulates monotone polygon. +// Time complexity: O(n) +// Space complexity: O(n) +int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles) { + if (!inPoly->Valid()) { + return 0; + } + + long i, i2, j, topindex, bottomindex, leftindex, rightindex, vindex; + TPPLPoint *points = NULL; + long numpoints; + TPPLPoly triangle; + + numpoints = inPoly->GetNumPoints(); + points = inPoly->GetPoints(); + + // Trivial case. + if (numpoints == 3) { + triangles->push_back(*inPoly); + return 1; + } + + topindex = 0; + bottomindex = 0; + for (i = 1; i < numpoints; i++) { + if (Below(points[i], points[bottomindex])) { + bottomindex = i; + } + if (Below(points[topindex], points[i])) { + topindex = i; + } + } + + // Check if the poly is really monotone. + i = topindex; + while (i != bottomindex) { + i2 = i + 1; + if (i2 >= numpoints) { + i2 = 0; + } + if (!Below(points[i2], points[i])) { + return 0; + } + i = i2; + } + i = bottomindex; + while (i != topindex) { + i2 = i + 1; + if (i2 >= numpoints) { + i2 = 0; + } + if (!Below(points[i], points[i2])) { + return 0; + } + i = i2; + } + + char *vertextypes = new char[numpoints]; + long *priority = new long[numpoints]; + + // Merge left and right vertex chains. + priority[0] = topindex; + vertextypes[topindex] = 0; + leftindex = topindex + 1; + if (leftindex >= numpoints) { + leftindex = 0; + } + rightindex = topindex - 1; + if (rightindex < 0) { + rightindex = numpoints - 1; + } + for (i = 1; i < (numpoints - 1); i++) { + if (leftindex == bottomindex) { + priority[i] = rightindex; + rightindex--; + if (rightindex < 0) { + rightindex = numpoints - 1; + } + vertextypes[priority[i]] = -1; + } else if (rightindex == bottomindex) { + priority[i] = leftindex; + leftindex++; + if (leftindex >= numpoints) { + leftindex = 0; + } + vertextypes[priority[i]] = 1; + } else { + if (Below(points[leftindex], points[rightindex])) { + priority[i] = rightindex; + rightindex--; + if (rightindex < 0) { + rightindex = numpoints - 1; + } + vertextypes[priority[i]] = -1; + } else { + priority[i] = leftindex; + leftindex++; + if (leftindex >= numpoints) { + leftindex = 0; + } + vertextypes[priority[i]] = 1; + } + } + } + priority[i] = bottomindex; + vertextypes[bottomindex] = 0; + + long *stack = new long[numpoints]; + long stackptr = 0; + + stack[0] = priority[0]; + stack[1] = priority[1]; + stackptr = 2; + + // For each vertex from top to bottom trim as many triangles as possible. + for (i = 2; i < (numpoints - 1); i++) { + vindex = priority[i]; + if (vertextypes[vindex] != vertextypes[stack[stackptr - 1]]) { + for (j = 0; j < (stackptr - 1); j++) { + if (vertextypes[vindex] == 1) { + triangle.Triangle(points[stack[j + 1]], points[stack[j]], points[vindex]); + } else { + triangle.Triangle(points[stack[j]], points[stack[j + 1]], points[vindex]); + } + triangles->push_back(triangle); + } + stack[0] = priority[i - 1]; + stack[1] = priority[i]; + stackptr = 2; + } else { + stackptr--; + while (stackptr > 0) { + if (vertextypes[vindex] == 1) { + if (IsConvex(points[vindex], points[stack[stackptr - 1]], points[stack[stackptr]])) { + triangle.Triangle(points[vindex], points[stack[stackptr - 1]], points[stack[stackptr]]); + triangles->push_back(triangle); + stackptr--; + } else { + break; + } + } else { + if (IsConvex(points[vindex], points[stack[stackptr]], points[stack[stackptr - 1]])) { + triangle.Triangle(points[vindex], points[stack[stackptr]], points[stack[stackptr - 1]]); + triangles->push_back(triangle); + stackptr--; + } else { + break; + } + } + } + stackptr++; + stack[stackptr] = vindex; + stackptr++; + } + } + vindex = priority[i]; + for (j = 0; j < (stackptr - 1); j++) { + if (vertextypes[stack[j + 1]] == 1) { + triangle.Triangle(points[stack[j]], points[stack[j + 1]], points[vindex]); + } else { + triangle.Triangle(points[stack[j + 1]], points[stack[j]], points[vindex]); + } + triangles->push_back(triangle); + } + + delete[] priority; + delete[] vertextypes; + delete[] stack; + + return 1; +} + +int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) { + TPPLPolyList monotone; + TPPLPolyList::Element *iter; + + if (!MonotonePartition(inpolys, &monotone)) { + return 0; + } + for (iter = monotone.front(); iter; iter = iter->next()) { + if (!TriangulateMonotone(&(iter->get()), triangles)) { + return 0; + } + } + return 1; +} + +int TPPLPartition::Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles) { + TPPLPolyList polys; + polys.push_back(*poly); + + return Triangulate_MONO(&polys, triangles); +} diff --git a/thirdparty/misc/polypartition.h b/thirdparty/misc/polypartition.h new file mode 100644 index 0000000000..b2d905a3ef --- /dev/null +++ b/thirdparty/misc/polypartition.h @@ -0,0 +1,378 @@ +/*************************************************************************/ +/* Copyright (c) 2011-2021 Ivan Fratric and contributors. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef POLYPARTITION_H +#define POLYPARTITION_H + +#include "core/math/vector2.h" +#include "core/templates/list.h" +#include "core/templates/set.h" + +typedef double tppl_float; + +enum TPPLOrientation { + TPPL_ORIENTATION_CW = -1, + TPPL_ORIENTATION_NONE = 0, + TPPL_ORIENTATION_CCW = 1, +}; + +enum TPPLVertexType { + TPPL_VERTEXTYPE_REGULAR = 0, + TPPL_VERTEXTYPE_START = 1, + TPPL_VERTEXTYPE_END = 2, + TPPL_VERTEXTYPE_SPLIT = 3, + TPPL_VERTEXTYPE_MERGE = 4, +}; + +// 2D point structure. +typedef Vector2 TPPLPoint; + +// Polygon implemented as an array of points with a "hole" flag. +class TPPLPoly { + protected: + TPPLPoint *points; + long numpoints; + bool hole; + + public: + // Constructors and destructors. + TPPLPoly(); + ~TPPLPoly(); + + TPPLPoly(const TPPLPoly &src); + TPPLPoly &operator=(const TPPLPoly &src); + + // Getters and setters. + long GetNumPoints() const { + return numpoints; + } + + bool IsHole() const { + return hole; + } + + void SetHole(bool hole) { + this->hole = hole; + } + + TPPLPoint &GetPoint(long i) { + return points[i]; + } + + const TPPLPoint &GetPoint(long i) const { + return points[i]; + } + + TPPLPoint *GetPoints() { + return points; + } + + TPPLPoint &operator[](int i) { + return points[i]; + } + + const TPPLPoint &operator[](int i) const { + return points[i]; + } + + // Clears the polygon points. + void Clear(); + + // Inits the polygon with numpoints vertices. + void Init(long numpoints); + + // Creates a triangle with points p1, p2, and p3. + void Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3); + + // Inverts the orfer of vertices. + void Invert(); + + // Returns the orientation of the polygon. + // Possible values: + // TPPL_ORIENTATION_CCW: Polygon vertices are in counter-clockwise order. + // TPPL_ORIENTATION_CW: Polygon vertices are in clockwise order. + // TPPL_ORIENTATION_NONE: The polygon has no (measurable) area. + TPPLOrientation GetOrientation() const; + + // Sets the polygon orientation. + // Possible values: + // TPPL_ORIENTATION_CCW: Sets vertices in counter-clockwise order. + // TPPL_ORIENTATION_CW: Sets vertices in clockwise order. + // TPPL_ORIENTATION_NONE: Reverses the orientation of the vertices if there + // is one, otherwise does nothing (if orientation is already NONE). + void SetOrientation(TPPLOrientation orientation); + + // Checks whether a polygon is valid or not. + inline bool Valid() const { return this->numpoints >= 3; } +}; + +#ifdef TPPL_ALLOCATOR +typedef List<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList; +#else +typedef List<TPPLPoly> TPPLPolyList; +#endif + +class TPPLPartition { + protected: + struct PartitionVertex { + bool isActive; + bool isConvex; + bool isEar; + + TPPLPoint p; + tppl_float angle; + PartitionVertex *previous; + PartitionVertex *next; + + PartitionVertex(); + }; + + struct MonotoneVertex { + TPPLPoint p; + long previous; + long next; + }; + + class VertexSorter { + MonotoneVertex *vertices; + +public: + VertexSorter(MonotoneVertex *v) : + vertices(v) {} + bool operator()(long index1, long index2); + }; + + struct Diagonal { + long index1; + long index2; + }; + +#ifdef TPPL_ALLOCATOR + typedef List<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList; +#else + typedef List<Diagonal> DiagonalList; +#endif + + // Dynamic programming state for minimum-weight triangulation. + struct DPState { + bool visible; + tppl_float weight; + long bestvertex; + }; + + // Dynamic programming state for convex partitioning. + struct DPState2 { + bool visible; + long weight; + DiagonalList pairs; + }; + + // Edge that intersects the scanline. + struct ScanLineEdge { + mutable long index; + TPPLPoint p1; + TPPLPoint p2; + + // Determines if the edge is to the left of another edge. + bool operator<(const ScanLineEdge &other) const; + + bool IsConvex(const TPPLPoint &p1, const TPPLPoint &p2, const TPPLPoint &p3) const; + }; + + // Standard helper functions. + bool IsConvex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3); + bool IsReflex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3); + bool IsInside(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p); + + bool InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p); + bool InCone(PartitionVertex *v, TPPLPoint &p); + + int Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22); + + TPPLPoint Normalize(const TPPLPoint &p); + tppl_float Distance(const TPPLPoint &p1, const TPPLPoint &p2); + + // Helper functions for Triangulate_EC. + void UpdateVertexReflexity(PartitionVertex *v); + void UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices); + + // Helper functions for ConvexPartition_OPT. + void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates); + void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); + void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); + + // Helper functions for MonotonePartition. + bool Below(TPPLPoint &p1, TPPLPoint &p2); + void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, + TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators, + Set<ScanLineEdge> *edgeTree, long *helpers); + + // Triangulates a monotone polygon, used in Triangulate_MONO. + int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles); + + public: + // Simple heuristic procedure for removing holes from a list of polygons. + // It works by creating a diagonal from the right-most hole vertex + // to some other visible vertex. + // Time complexity: O(h*(n^2)), h is the # of holes, n is the # of vertices. + // Space complexity: O(n) + // params: + // inpolys: + // A list of polygons that can contain holes. + // Vertices of all non-hole polys have to be in counter-clockwise order. + // Vertices of all hole polys have to be in clockwise order. + // outpolys: + // A list of polygons without holes. + // Returns 1 on success, 0 on failure. + int RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys); + + // Triangulates a polygon by ear clipping. + // Time complexity: O(n^2), n is the number of vertices. + // Space complexity: O(n) + // params: + // poly: + // An input polygon to be triangulated. + // Vertices have to be in counter-clockwise order. + // triangles: + // A list of triangles (result). + // Returns 1 on success, 0 on failure. + int Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles); + + // Triangulates a list of polygons that may contain holes by ear clipping + // algorithm. It first calls RemoveHoles to get rid of the holes, and then + // calls Triangulate_EC for each resulting polygon. + // Time complexity: O(h*(n^2)), h is the # of holes, n is the # of vertices. + // Space complexity: O(n) + // params: + // inpolys: + // A list of polygons to be triangulated (can contain holes). + // Vertices of all non-hole polys have to be in counter-clockwise order. + // Vertices of all hole polys have to be in clockwise order. + // triangles: + // A list of triangles (result). + // Returns 1 on success, 0 on failure. + int Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles); + + // Creates an optimal polygon triangulation in terms of minimal edge length. + // Time complexity: O(n^3), n is the number of vertices + // Space complexity: O(n^2) + // params: + // poly: + // An input polygon to be triangulated. + // Vertices have to be in counter-clockwise order. + // triangles: + // A list of triangles (result). + // Returns 1 on success, 0 on failure. + int Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles); + + // Triangulates a polygon by first partitioning it into monotone polygons. + // Time complexity: O(n*log(n)), n is the number of vertices. + // Space complexity: O(n) + // params: + // poly: + // An input polygon to be triangulated. + // Vertices have to be in counter-clockwise order. + // triangles: + // A list of triangles (result). + // Returns 1 on success, 0 on failure. + int Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles); + + // Triangulates a list of polygons by first + // partitioning them into monotone polygons. + // Time complexity: O(n*log(n)), n is the number of vertices. + // Space complexity: O(n) + // params: + // inpolys: + // A list of polygons to be triangulated (can contain holes). + // Vertices of all non-hole polys have to be in counter-clockwise order. + // Vertices of all hole polys have to be in clockwise order. + // triangles: + // A list of triangles (result). + // Returns 1 on success, 0 on failure. + int Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles); + + // Creates a monotone partition of a list of polygons that + // can contain holes. Triangulates a set of polygons by + // first partitioning them into monotone polygons. + // Time complexity: O(n*log(n)), n is the number of vertices. + // Space complexity: O(n) + // params: + // inpolys: + // A list of polygons to be triangulated (can contain holes). + // Vertices of all non-hole polys have to be in counter-clockwise order. + // Vertices of all hole polys have to be in clockwise order. + // monotonePolys: + // A list of monotone polygons (result). + // Returns 1 on success, 0 on failure. + int MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys); + + // Partitions a polygon into convex polygons by using the + // Hertel-Mehlhorn algorithm. The algorithm gives at most four times + // the number of parts as the optimal algorithm, however, in practice + // it works much better than that and often gives optimal partition. + // It uses triangulation obtained by ear clipping as intermediate result. + // Time complexity O(n^2), n is the number of vertices. + // Space complexity: O(n) + // params: + // poly: + // An input polygon to be partitioned. + // Vertices have to be in counter-clockwise order. + // parts: + // Resulting list of convex polygons. + // Returns 1 on success, 0 on failure. + int ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts); + + // Partitions a list of polygons into convex parts by using the + // Hertel-Mehlhorn algorithm. The algorithm gives at most four times + // the number of parts as the optimal algorithm, however, in practice + // it works much better than that and often gives optimal partition. + // It uses triangulation obtained by ear clipping as intermediate result. + // Time complexity O(n^2), n is the number of vertices. + // Space complexity: O(n) + // params: + // inpolys: + // An input list of polygons to be partitioned. Vertices of + // all non-hole polys have to be in counter-clockwise order. + // Vertices of all hole polys have to be in clockwise order. + // parts: + // Resulting list of convex polygons. + // Returns 1 on success, 0 on failure. + int ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts); + + // Optimal convex partitioning (in terms of number of resulting + // convex polygons) using the Keil-Snoeyink algorithm. + // For reference, see M. Keil, J. Snoeyink, "On the time bound for + // convex decomposition of simple polygons", 1998. + // Time complexity O(n^3), n is the number of vertices. + // Space complexity: O(n^3) + // params: + // poly: + // An input polygon to be partitioned. + // Vertices have to be in counter-clockwise order. + // parts: + // Resulting list of convex polygons. + // Returns 1 on success, 0 on failure. + int ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts); +}; + +#endif diff --git a/thirdparty/misc/r128.h b/thirdparty/misc/r128.h index 1f7aab78fb..a345cc47ba 100644 --- a/thirdparty/misc/r128.h +++ b/thirdparty/misc/r128.h @@ -1,5 +1,5 @@ /* -r128.h: 128-bit (64.64) signed fixed-point arithmetic. Version 1.4.3 +r128.h: 128-bit (64.64) signed fixed-point arithmetic. Version 1.4.4 COMPILATION ----------- @@ -76,8 +76,8 @@ OTHER DEALINGS IN THE SOFTWARE. # include <stdint.h> # define R128_S32 int32_t # define R128_U32 uint32_t -# define R128_S64 int64_t -# define R128_U64 uint64_t +# define R128_S64 long long +# define R128_U64 unsigned long long # define R128_LIT_S64(x) x##ll # define R128_LIT_U64(x) x##ull #endif @@ -701,7 +701,7 @@ static R128_U32 r128__udiv64(R128_U32 nlo, R128_U32 nhi, R128_U32 d, R128_U32 *r return (R128_U32)(n64 / d); # endif } -#elif !defined(_M_X64) || defined(R128_STDC_ONLY) +#elif defined(R128_STDC_ONLY) || !R128_INTEL #define r128__umul64(a, b) ((a) * (R128_U64)(b)) static R128_U32 r128__udiv64(R128_U32 nlo, R128_U32 nhi, R128_U32 d, R128_U32 *rem) { @@ -799,7 +799,7 @@ static void r128__umul128(R128 *dst, R128_U64 a, R128_U64 b) // MSVC x64 provides neither inline assembly nor (pre-2019) a div intrinsic, so we do fake // "inline assembly" to avoid long division or outline assembly. #pragma code_seg(".text") -__declspec(allocate(".text")) static const unsigned char r128__udiv128Code[] = { +__declspec(allocate(".text") align(16)) static const unsigned char r128__udiv128Code[] = { 0x48, 0x8B, 0xC1, //mov rax, rcx 0x49, 0xF7, 0xF0, //div rax, r8 0x49, 0x89, 0x11, //mov qword ptr [r9], rdx diff --git a/thirdparty/misc/triangulator.cpp b/thirdparty/misc/triangulator.cpp deleted file mode 100644 index d6b63c6638..0000000000 --- a/thirdparty/misc/triangulator.cpp +++ /dev/null @@ -1,1550 +0,0 @@ -//Copyright (C) 2011 by Ivan Fratric -// -//Permission is hereby granted, free of charge, to any person obtaining a copy -//of this software and associated documentation files (the "Software"), to deal -//in the Software without restriction, including without limitation the rights -//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//copies of the Software, and to permit persons to whom the Software is -//furnished to do so, subject to the following conditions: -// -//The above copyright notice and this permission notice shall be included in -//all copies or substantial portions of the Software. -// -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -//THE SOFTWARE. - - -#include <stdio.h> -#include <string.h> -#include <math.h> - -#include "triangulator.h" - - -#define TRIANGULATOR_VERTEXTYPE_REGULAR 0 -#define TRIANGULATOR_VERTEXTYPE_START 1 -#define TRIANGULATOR_VERTEXTYPE_END 2 -#define TRIANGULATOR_VERTEXTYPE_SPLIT 3 -#define TRIANGULATOR_VERTEXTYPE_MERGE 4 - -TriangulatorPoly::TriangulatorPoly() { - hole = false; - numpoints = 0; - points = NULL; -} - -TriangulatorPoly::~TriangulatorPoly() { - if(points) delete [] points; -} - -void TriangulatorPoly::Clear() { - if(points) delete [] points; - hole = false; - numpoints = 0; - points = NULL; -} - -void TriangulatorPoly::Init(long numpoints) { - Clear(); - this->numpoints = numpoints; - points = new Vector2[numpoints]; -} - -void TriangulatorPoly::Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3) { - Init(3); - points[0] = p1; - points[1] = p2; - points[2] = p3; -} - -TriangulatorPoly::TriangulatorPoly(const TriangulatorPoly &src) { - hole = src.hole; - numpoints = src.numpoints; - points = new Vector2[numpoints]; - memcpy(points, src.points, numpoints*sizeof(Vector2)); -} - -TriangulatorPoly& TriangulatorPoly::operator=(const TriangulatorPoly &src) { - Clear(); - hole = src.hole; - numpoints = src.numpoints; - points = new Vector2[numpoints]; - memcpy(points, src.points, numpoints*sizeof(Vector2)); - return *this; -} - -int TriangulatorPoly::GetOrientation() { - long i1,i2; - real_t area = 0; - for(i1=0; i1<numpoints; i1++) { - i2 = i1+1; - if(i2 == numpoints) i2 = 0; - area += points[i1].x * points[i2].y - points[i1].y * points[i2].x; - } - if(area>0) return TRIANGULATOR_CCW; - if(area<0) return TRIANGULATOR_CW; - return 0; -} - -void TriangulatorPoly::SetOrientation(int orientation) { - int polyorientation = GetOrientation(); - if(polyorientation&&(polyorientation!=orientation)) { - Invert(); - } -} - -void TriangulatorPoly::Invert() { - long i; - Vector2 *invpoints; - - invpoints = new Vector2[numpoints]; - for(i=0;i<numpoints;i++) { - invpoints[i] = points[numpoints-i-1]; - } - - delete [] points; - points = invpoints; -} - -Vector2 TriangulatorPartition::Normalize(const Vector2 &p) { - Vector2 r; - real_t n = sqrt(p.x*p.x + p.y*p.y); - if(n!=0) { - r = p/n; - } else { - r.x = 0; - r.y = 0; - } - return r; -} - -real_t TriangulatorPartition::Distance(const Vector2 &p1, const Vector2 &p2) { - real_t dx,dy; - dx = p2.x - p1.x; - dy = p2.y - p1.y; - return(sqrt(dx*dx + dy*dy)); -} - -//checks if two lines intersect -int TriangulatorPartition::Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22) { - if((p11.x == p21.x)&&(p11.y == p21.y)) return 0; - if((p11.x == p22.x)&&(p11.y == p22.y)) return 0; - if((p12.x == p21.x)&&(p12.y == p21.y)) return 0; - if((p12.x == p22.x)&&(p12.y == p22.y)) return 0; - - Vector2 v1ort,v2ort,v; - real_t dot11,dot12,dot21,dot22; - - v1ort.x = p12.y-p11.y; - v1ort.y = p11.x-p12.x; - - v2ort.x = p22.y-p21.y; - v2ort.y = p21.x-p22.x; - - v = p21-p11; - dot21 = v.x*v1ort.x + v.y*v1ort.y; - v = p22-p11; - dot22 = v.x*v1ort.x + v.y*v1ort.y; - - v = p11-p21; - dot11 = v.x*v2ort.x + v.y*v2ort.y; - v = p12-p21; - dot12 = v.x*v2ort.x + v.y*v2ort.y; - - if(dot11*dot12>0) return 0; - if(dot21*dot22>0) return 0; - - return 1; -} - -//removes holes from inpolys by merging them with non-holes -int TriangulatorPartition::RemoveHoles(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *outpolys) { - List<TriangulatorPoly> polys; - List<TriangulatorPoly>::Element *holeiter,*polyiter,*iter,*iter2; - long i,i2,holepointindex,polypointindex; - Vector2 holepoint,polypoint,bestpolypoint; - Vector2 linep1,linep2; - Vector2 v1,v2; - TriangulatorPoly newpoly; - bool hasholes; - bool pointvisible; - bool pointfound; - - //check for trivial case (no holes) - hasholes = false; - for(iter = inpolys->front(); iter; iter=iter->next()) { - if(iter->get().IsHole()) { - hasholes = true; - break; - } - } - if(!hasholes) { - for(iter = inpolys->front(); iter; iter=iter->next()) { - outpolys->push_back(iter->get()); - } - return 1; - } - - polys = *inpolys; - - while(1) { - //find the hole point with the largest x - hasholes = false; - for(iter = polys.front(); iter; iter=iter->next()) { - if(!iter->get().IsHole()) continue; - - if(!hasholes) { - hasholes = true; - holeiter = iter; - holepointindex = 0; - } - - for(i=0; i < iter->get().GetNumPoints(); i++) { - if(iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) { - holeiter = iter; - holepointindex = i; - } - } - } - if(!hasholes) break; - holepoint = holeiter->get().GetPoint(holepointindex); - - pointfound = false; - for(iter = polys.front(); iter; iter=iter->next()) { - if(iter->get().IsHole()) continue; - for(i=0; i < iter->get().GetNumPoints(); i++) { - if(iter->get().GetPoint(i).x <= holepoint.x) continue; - if(!InCone(iter->get().GetPoint((i+iter->get().GetNumPoints()-1)%(iter->get().GetNumPoints())), - iter->get().GetPoint(i), - iter->get().GetPoint((i+1)%(iter->get().GetNumPoints())), - holepoint)) - continue; - polypoint = iter->get().GetPoint(i); - if(pointfound) { - v1 = Normalize(polypoint-holepoint); - v2 = Normalize(bestpolypoint-holepoint); - if(v2.x > v1.x) continue; - } - pointvisible = true; - for(iter2 = polys.front(); iter2; iter2=iter2->next()) { - if(iter2->get().IsHole()) continue; - for(i2=0; i2 < iter2->get().GetNumPoints(); i2++) { - linep1 = iter2->get().GetPoint(i2); - linep2 = iter2->get().GetPoint((i2+1)%(iter2->get().GetNumPoints())); - if(Intersects(holepoint,polypoint,linep1,linep2)) { - pointvisible = false; - break; - } - } - if(!pointvisible) break; - } - if(pointvisible) { - pointfound = true; - bestpolypoint = polypoint; - polyiter = iter; - polypointindex = i; - } - } - } - - if(!pointfound) return 0; - - newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2); - i2 = 0; - for(i=0;i<=polypointindex;i++) { - newpoly[i2] = polyiter->get().GetPoint(i); - i2++; - } - for(i=0;i<=holeiter->get().GetNumPoints();i++) { - newpoly[i2] = holeiter->get().GetPoint((i+holepointindex)%holeiter->get().GetNumPoints()); - i2++; - } - for(i=polypointindex;i<polyiter->get().GetNumPoints();i++) { - newpoly[i2] = polyiter->get().GetPoint(i); - i2++; - } - - polys.erase(holeiter); - polys.erase(polyiter); - polys.push_back(newpoly); - } - - for(iter = polys.front(); iter; iter=iter->next()) { - outpolys->push_back(iter->get()); - } - - return 1; -} - -bool TriangulatorPartition::IsConvex(Vector2& p1, Vector2& p2, Vector2& p3) { - real_t tmp; - tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); - if(tmp>0) return 1; - else return 0; -} - -bool TriangulatorPartition::IsReflex(Vector2& p1, Vector2& p2, Vector2& p3) { - real_t tmp; - tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); - if(tmp<0) return 1; - else return 0; -} - -bool TriangulatorPartition::IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p) { - if(IsConvex(p1,p,p2)) return false; - if(IsConvex(p2,p,p3)) return false; - if(IsConvex(p3,p,p1)) return false; - return true; -} - -bool TriangulatorPartition::InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p) { - bool convex; - - convex = IsConvex(p1,p2,p3); - - if(convex) { - if(!IsConvex(p1,p2,p)) return false; - if(!IsConvex(p2,p3,p)) return false; - return true; - } else { - if(IsConvex(p1,p2,p)) return true; - if(IsConvex(p2,p3,p)) return true; - return false; - } -} - -bool TriangulatorPartition::InCone(PartitionVertex *v, Vector2 &p) { - Vector2 p1,p2,p3; - - p1 = v->previous->p; - p2 = v->p; - p3 = v->next->p; - - return InCone(p1,p2,p3,p); -} - -void TriangulatorPartition::UpdateVertexReflexity(PartitionVertex *v) { - PartitionVertex *v1,*v3; - v1 = v->previous; - v3 = v->next; - v->isConvex = !IsReflex(v1->p,v->p,v3->p); -} - -void TriangulatorPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) { - long i; - PartitionVertex *v1,*v3; - Vector2 vec1,vec3; - - v1 = v->previous; - v3 = v->next; - - v->isConvex = IsConvex(v1->p,v->p,v3->p); - - vec1 = Normalize(v1->p - v->p); - vec3 = Normalize(v3->p - v->p); - v->angle = vec1.x*vec3.x + vec1.y*vec3.y; - - if(v->isConvex) { - v->isEar = true; - for(i=0;i<numvertices;i++) { - if((vertices[i].p.x==v->p.x)&&(vertices[i].p.y==v->p.y)) continue; - if((vertices[i].p.x==v1->p.x)&&(vertices[i].p.y==v1->p.y)) continue; - if((vertices[i].p.x==v3->p.x)&&(vertices[i].p.y==v3->p.y)) continue; - if(IsInside(v1->p,v->p,v3->p,vertices[i].p)) { - v->isEar = false; - break; - } - } - } else { - v->isEar = false; - } -} - -//triangulation by ear removal -int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles) { - long numvertices; - PartitionVertex *vertices; - PartitionVertex *ear; - TriangulatorPoly triangle; - long i,j; - bool earfound; - - if(poly->GetNumPoints() < 3) return 0; - if(poly->GetNumPoints() == 3) { - triangles->push_back(*poly); - return 1; - } - - numvertices = poly->GetNumPoints(); - - vertices = new PartitionVertex[numvertices]; - for(i=0;i<numvertices;i++) { - vertices[i].isActive = true; - vertices[i].p = poly->GetPoint(i); - if(i==(numvertices-1)) vertices[i].next=&(vertices[0]); - else vertices[i].next=&(vertices[i+1]); - if(i==0) vertices[i].previous = &(vertices[numvertices-1]); - else vertices[i].previous = &(vertices[i-1]); - } - for(i=0;i<numvertices;i++) { - UpdateVertex(&vertices[i],vertices,numvertices); - } - - for(i=0;i<numvertices-3;i++) { - earfound = false; - //find the most extruded ear - for(j=0;j<numvertices;j++) { - if(!vertices[j].isActive) continue; - if(!vertices[j].isEar) continue; - if(!earfound) { - earfound = true; - ear = &(vertices[j]); - } else { - if(vertices[j].angle > ear->angle) { - ear = &(vertices[j]); - } - } - } - if(!earfound) { - delete [] vertices; - return 0; - } - - triangle.Triangle(ear->previous->p,ear->p,ear->next->p); - triangles->push_back(triangle); - - ear->isActive = false; - ear->previous->next = ear->next; - ear->next->previous = ear->previous; - - if(i==numvertices-4) break; - - UpdateVertex(ear->previous,vertices,numvertices); - UpdateVertex(ear->next,vertices,numvertices); - } - for(i=0;i<numvertices;i++) { - if(vertices[i].isActive) { - triangle.Triangle(vertices[i].previous->p,vertices[i].p,vertices[i].next->p); - triangles->push_back(triangle); - break; - } - } - - delete [] vertices; - - return 1; -} - -int TriangulatorPartition::Triangulate_EC(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles) { - List<TriangulatorPoly> outpolys; - List<TriangulatorPoly>::Element*iter; - - if(!RemoveHoles(inpolys,&outpolys)) return 0; - for(iter=outpolys.front();iter;iter=iter->next()) { - if(!Triangulate_EC(&(iter->get()),triangles)) return 0; - } - return 1; -} - -int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, List<TriangulatorPoly> *parts) { - List<TriangulatorPoly> triangles; - List<TriangulatorPoly>::Element *iter1,*iter2; - TriangulatorPoly *poly1,*poly2; - TriangulatorPoly newpoly; - Vector2 d1,d2,p1,p2,p3; - long i11,i12,i21,i22,i13,i23,j,k; - bool isdiagonal; - long numreflex; - - //check if the poly is already convex - numreflex = 0; - for(i11=0;i11<poly->GetNumPoints();i11++) { - if(i11==0) i12 = poly->GetNumPoints()-1; - else i12=i11-1; - if(i11==(poly->GetNumPoints()-1)) i13=0; - else i13=i11+1; - if(IsReflex(poly->GetPoint(i12),poly->GetPoint(i11),poly->GetPoint(i13))) { - numreflex = 1; - break; - } - } - if(numreflex == 0) { - parts->push_back(*poly); - return 1; - } - - if(!Triangulate_EC(poly,&triangles)) return 0; - - for(iter1 = triangles.front(); iter1 ; iter1=iter1->next()) { - poly1 = &(iter1->get()); - for(i11=0;i11<poly1->GetNumPoints();i11++) { - d1 = poly1->GetPoint(i11); - i12 = (i11+1)%(poly1->GetNumPoints()); - d2 = poly1->GetPoint(i12); - - isdiagonal = false; - for(iter2 = iter1; iter2 ; iter2=iter2->next()) { - if(iter1 == iter2) continue; - poly2 = &(iter2->get()); - - for(i21=0;i21<poly2->GetNumPoints();i21++) { - if((d2.x != poly2->GetPoint(i21).x)||(d2.y != poly2->GetPoint(i21).y)) continue; - i22 = (i21+1)%(poly2->GetNumPoints()); - if((d1.x != poly2->GetPoint(i22).x)||(d1.y != poly2->GetPoint(i22).y)) continue; - isdiagonal = true; - break; - } - if(isdiagonal) break; - } - - if(!isdiagonal) continue; - - p2 = poly1->GetPoint(i11); - if(i11 == 0) i13 = poly1->GetNumPoints()-1; - else i13 = i11-1; - p1 = poly1->GetPoint(i13); - if(i22 == (poly2->GetNumPoints()-1)) i23 = 0; - else i23 = i22+1; - p3 = poly2->GetPoint(i23); - - if(!IsConvex(p1,p2,p3)) continue; - - p2 = poly1->GetPoint(i12); - if(i12 == (poly1->GetNumPoints()-1)) i13 = 0; - else i13 = i12+1; - p3 = poly1->GetPoint(i13); - if(i21 == 0) i23 = poly2->GetNumPoints()-1; - else i23 = i21-1; - p1 = poly2->GetPoint(i23); - - if(!IsConvex(p1,p2,p3)) continue; - - newpoly.Init(poly1->GetNumPoints()+poly2->GetNumPoints()-2); - k = 0; - for(j=i12;j!=i11;j=(j+1)%(poly1->GetNumPoints())) { - newpoly[k] = poly1->GetPoint(j); - k++; - } - for(j=i22;j!=i21;j=(j+1)%(poly2->GetNumPoints())) { - newpoly[k] = poly2->GetPoint(j); - k++; - } - - triangles.erase(iter2); - iter1->get() = newpoly; - poly1 = &(iter1->get()); - i11 = -1; - - continue; - } - } - - for(iter1 = triangles.front(); iter1 ; iter1=iter1->next()) { - parts->push_back(iter1->get()); - } - - return 1; -} - -int TriangulatorPartition::ConvexPartition_HM(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *parts) { - List<TriangulatorPoly> outpolys; - List<TriangulatorPoly>::Element* iter; - - if(!RemoveHoles(inpolys,&outpolys)) return 0; - for(iter=outpolys.front();iter;iter=iter->next()) { - if(!ConvexPartition_HM(&(iter->get()),parts)) return 0; - } - return 1; -} - -//minimum-weight polygon triangulation by dynamic programming -//O(n^3) time complexity -//O(n^2) space complexity -int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles) { - long i,j,k,gap,n; - DPState **dpstates; - Vector2 p1,p2,p3,p4; - long bestvertex; - real_t weight,minweight,d1,d2; - Diagonal diagonal,newdiagonal; - List<Diagonal> diagonals; - TriangulatorPoly triangle; - int ret = 1; - - n = poly->GetNumPoints(); - dpstates = new DPState *[n]; - for(i=1;i<n;i++) { - dpstates[i] = new DPState[i]; - } - - //init states and visibility - for(i=0;i<(n-1);i++) { - p1 = poly->GetPoint(i); - for(j=i+1;j<n;j++) { - dpstates[j][i].visible = true; - dpstates[j][i].weight = 0; - dpstates[j][i].bestvertex = -1; - if(j!=(i+1)) { - p2 = poly->GetPoint(j); - - //visibility check - if(i==0) p3 = poly->GetPoint(n-1); - else p3 = poly->GetPoint(i-1); - if(i==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(i+1); - if(!InCone(p3,p1,p4,p2)) { - dpstates[j][i].visible = false; - continue; - } - - if(j==0) p3 = poly->GetPoint(n-1); - else p3 = poly->GetPoint(j-1); - if(j==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(j+1); - if(!InCone(p3,p2,p4,p1)) { - dpstates[j][i].visible = false; - continue; - } - - for(k=0;k<n;k++) { - p3 = poly->GetPoint(k); - if(k==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(k+1); - if(Intersects(p1,p2,p3,p4)) { - dpstates[j][i].visible = false; - break; - } - } - } - } - } - dpstates[n-1][0].visible = true; - dpstates[n-1][0].weight = 0; - dpstates[n-1][0].bestvertex = -1; - - for(gap = 2; gap<n; gap++) { - for(i=0; i<(n-gap); i++) { - j = i+gap; - if(!dpstates[j][i].visible) continue; - bestvertex = -1; - for(k=(i+1);k<j;k++) { - if(!dpstates[k][i].visible) continue; - if(!dpstates[j][k].visible) continue; - - if(k<=(i+1)) d1=0; - else d1 = Distance(poly->GetPoint(i),poly->GetPoint(k)); - if(j<=(k+1)) d2=0; - else d2 = Distance(poly->GetPoint(k),poly->GetPoint(j)); - - weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2; - - if((bestvertex == -1)||(weight<minweight)) { - bestvertex = k; - minweight = weight; - } - } - if(bestvertex == -1) { - for(i=1;i<n;i++) { - delete [] dpstates[i]; - } - delete [] dpstates; - - return 0; - } - - dpstates[j][i].bestvertex = bestvertex; - dpstates[j][i].weight = minweight; - } - } - - newdiagonal.index1 = 0; - newdiagonal.index2 = n-1; - diagonals.push_back(newdiagonal); - while(!diagonals.is_empty()) { - diagonal = (diagonals.front()->get()); - diagonals.pop_front(); - bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex; - if(bestvertex == -1) { - ret = 0; - break; - } - triangle.Triangle(poly->GetPoint(diagonal.index1),poly->GetPoint(bestvertex),poly->GetPoint(diagonal.index2)); - triangles->push_back(triangle); - if(bestvertex > (diagonal.index1+1)) { - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = bestvertex; - diagonals.push_back(newdiagonal); - } - if(diagonal.index2 > (bestvertex+1)) { - newdiagonal.index1 = bestvertex; - newdiagonal.index2 = diagonal.index2; - diagonals.push_back(newdiagonal); - } - } - - for(i=1;i<n;i++) { - delete [] dpstates[i]; - } - delete [] dpstates; - - return ret; -} - -void TriangulatorPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates) { - Diagonal newdiagonal; - List<Diagonal> *pairs; - long w2; - - w2 = dpstates[a][b].weight; - if(w>w2) return; - - pairs = &(dpstates[a][b].pairs); - newdiagonal.index1 = i; - newdiagonal.index2 = j; - - if(w<w2) { - pairs->clear(); - pairs->push_front(newdiagonal); - dpstates[a][b].weight = w; - } else { - if((!pairs->is_empty())&&(i <= pairs->front()->get().index1)) return; - while((!pairs->is_empty())&&(pairs->front()->get().index2 >= j)) pairs->pop_front(); - pairs->push_front(newdiagonal); - } -} - -void TriangulatorPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { - List<Diagonal> *pairs; - List<Diagonal>::Element *iter,*lastiter; - long top; - long w; - - if(!dpstates[i][j].visible) return; - top = j; - w = dpstates[i][j].weight; - if(k-j > 1) { - if (!dpstates[j][k].visible) return; - w += dpstates[j][k].weight + 1; - } - if(j-i > 1) { - pairs = &(dpstates[i][j].pairs); - iter = NULL; - lastiter = NULL; - while(iter!=pairs->front()) { - if (!iter) - iter=pairs->back(); - else - iter=iter->prev(); - - if(!IsReflex(vertices[iter->get().index2].p,vertices[j].p,vertices[k].p)) lastiter = iter; - else break; - } - if(lastiter == NULL) w++; - else { - if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->get().index1].p)) w++; - else top = lastiter->get().index1; - } - } - UpdateState(i,k,w,top,j,dpstates); -} - -void TriangulatorPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { - List<Diagonal> *pairs; - List<Diagonal>::Element* iter,*lastiter; - long top; - long w; - - if(!dpstates[j][k].visible) return; - top = j; - w = dpstates[j][k].weight; - - if (j-i > 1) { - if (!dpstates[i][j].visible) return; - w += dpstates[i][j].weight + 1; - } - if (k-j > 1) { - pairs = &(dpstates[j][k].pairs); - - iter = pairs->front(); - if((!pairs->is_empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->get().index1].p))) { - lastiter = iter; - while(iter!=NULL) { - if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->get().index1].p)) { - lastiter = iter; - iter=iter->next(); - } - else break; - } - if(IsReflex(vertices[lastiter->get().index2].p,vertices[k].p,vertices[i].p)) w++; - else top = lastiter->get().index2; - } else w++; - } - UpdateState(i,k,w,j,top,dpstates); -} - -int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *parts) { - Vector2 p1,p2,p3,p4; - PartitionVertex *vertices; - DPState2 **dpstates; - long i,j,k,n,gap; - List<Diagonal> diagonals,diagonals2; - Diagonal diagonal,newdiagonal; - List<Diagonal> *pairs,*pairs2; - List<Diagonal>::Element* iter,*iter2; - int ret; - TriangulatorPoly newpoly; - List<long> indices; - List<long>::Element* iiter; - bool ijreal,jkreal; - - n = poly->GetNumPoints(); - vertices = new PartitionVertex[n]; - - dpstates = new DPState2 *[n]; - for(i=0;i<n;i++) { - dpstates[i] = new DPState2[n]; - } - - //init vertex information - for(i=0;i<n;i++) { - vertices[i].p = poly->GetPoint(i); - vertices[i].isActive = true; - if(i==0) vertices[i].previous = &(vertices[n-1]); - else vertices[i].previous = &(vertices[i-1]); - if(i==(poly->GetNumPoints()-1)) vertices[i].next = &(vertices[0]); - else vertices[i].next = &(vertices[i+1]); - } - for(i=1;i<n;i++) { - UpdateVertexReflexity(&(vertices[i])); - } - - //init states and visibility - for(i=0;i<(n-1);i++) { - p1 = poly->GetPoint(i); - for(j=i+1;j<n;j++) { - dpstates[i][j].visible = true; - if(j==i+1) { - dpstates[i][j].weight = 0; - } else { - dpstates[i][j].weight = 2147483647; - } - if(j!=(i+1)) { - p2 = poly->GetPoint(j); - - //visibility check - if(!InCone(&vertices[i],p2)) { - dpstates[i][j].visible = false; - continue; - } - if(!InCone(&vertices[j],p1)) { - dpstates[i][j].visible = false; - continue; - } - - for(k=0;k<n;k++) { - p3 = poly->GetPoint(k); - if(k==(n-1)) p4 = poly->GetPoint(0); - else p4 = poly->GetPoint(k+1); - if(Intersects(p1,p2,p3,p4)) { - dpstates[i][j].visible = false; - break; - } - } - } - } - } - for(i=0;i<(n-2);i++) { - j = i+2; - if(dpstates[i][j].visible) { - dpstates[i][j].weight = 0; - newdiagonal.index1 = i+1; - newdiagonal.index2 = i+1; - dpstates[i][j].pairs.push_back(newdiagonal); - } - } - - dpstates[0][n-1].visible = true; - vertices[0].isConvex = false; //by convention - - for(gap=3; gap<n; gap++) { - for(i=0;i<n-gap;i++) { - if(vertices[i].isConvex) continue; - k = i+gap; - if(dpstates[i][k].visible) { - if(!vertices[k].isConvex) { - for(j=i+1;j<k;j++) TypeA(i,j,k,vertices,dpstates); - } else { - for(j=i+1;j<(k-1);j++) { - if(vertices[j].isConvex) continue; - TypeA(i,j,k,vertices,dpstates); - } - TypeA(i,k-1,k,vertices,dpstates); - } - } - } - for(k=gap;k<n;k++) { - if(vertices[k].isConvex) continue; - i = k-gap; - if((vertices[i].isConvex)&&(dpstates[i][k].visible)) { - TypeB(i,i+1,k,vertices,dpstates); - for(j=i+2;j<k;j++) { - if(vertices[j].isConvex) continue; - TypeB(i,j,k,vertices,dpstates); - } - } - } - } - - - //recover solution - ret = 1; - newdiagonal.index1 = 0; - newdiagonal.index2 = n-1; - diagonals.push_front(newdiagonal); - while(!diagonals.is_empty()) { - diagonal = (diagonals.front()->get()); - diagonals.pop_front(); - if((diagonal.index2 - diagonal.index1) <=1) continue; - pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); - if(pairs->is_empty()) { - ret = 0; - break; - } - if(!vertices[diagonal.index1].isConvex) { - iter = pairs->back(); - - j = iter->get().index2; - newdiagonal.index1 = j; - newdiagonal.index2 = diagonal.index2; - diagonals.push_front(newdiagonal); - if((j - diagonal.index1)>1) { - if(iter->get().index1 != iter->get().index2) { - pairs2 = &(dpstates[diagonal.index1][j].pairs); - while(1) { - if(pairs2->is_empty()) { - ret = 0; - break; - } - iter2 = pairs2->back(); - - if(iter->get().index1 != iter2->get().index1) pairs2->pop_back(); - else break; - } - if(ret == 0) break; - } - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = j; - diagonals.push_front(newdiagonal); - } - } else { - iter = pairs->front(); - j = iter->get().index1; - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = j; - diagonals.push_front(newdiagonal); - if((diagonal.index2 - j) > 1) { - if(iter->get().index1 != iter->get().index2) { - pairs2 = &(dpstates[j][diagonal.index2].pairs); - while(1) { - if(pairs2->is_empty()) { - ret = 0; - break; - } - iter2 = pairs2->front(); - if(iter->get().index2 != iter2->get().index2) pairs2->pop_front(); - else break; - } - if(ret == 0) break; - } - newdiagonal.index1 = j; - newdiagonal.index2 = diagonal.index2; - diagonals.push_front(newdiagonal); - } - } - } - - if(ret == 0) { - for(i=0;i<n;i++) { - delete [] dpstates[i]; - } - delete [] dpstates; - delete [] vertices; - - return ret; - } - - newdiagonal.index1 = 0; - newdiagonal.index2 = n-1; - diagonals.push_front(newdiagonal); - while(!diagonals.is_empty()) { - diagonal = (diagonals.front())->get(); - diagonals.pop_front(); - if((diagonal.index2 - diagonal.index1) <= 1) continue; - - indices.clear(); - diagonals2.clear(); - indices.push_back(diagonal.index1); - indices.push_back(diagonal.index2); - diagonals2.push_front(diagonal); - - while(!diagonals2.is_empty()) { - diagonal = (diagonals2.front()->get()); - diagonals2.pop_front(); - if((diagonal.index2 - diagonal.index1) <= 1) continue; - ijreal = true; - jkreal = true; - pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); - if(!vertices[diagonal.index1].isConvex) { - iter = pairs->back(); - j = iter->get().index2; - if(iter->get().index1 != iter->get().index2) ijreal = false; - } else { - iter = pairs->front(); - j = iter->get().index1; - if(iter->get().index1 != iter->get().index2) jkreal = false; - } - - newdiagonal.index1 = diagonal.index1; - newdiagonal.index2 = j; - if(ijreal) { - diagonals.push_back(newdiagonal); - } else { - diagonals2.push_back(newdiagonal); - } - - newdiagonal.index1 = j; - newdiagonal.index2 = diagonal.index2; - if(jkreal) { - diagonals.push_back(newdiagonal); - } else { - diagonals2.push_back(newdiagonal); - } - - indices.push_back(j); - } - - indices.sort(); - newpoly.Init((long)indices.size()); - k=0; - for(iiter = indices.front();iiter;iiter=iiter->next()) { - newpoly[k] = vertices[iiter->get()].p; - k++; - } - parts->push_back(newpoly); - } - - for(i=0;i<n;i++) { - delete [] dpstates[i]; - } - delete [] dpstates; - delete [] vertices; - - return ret; -} - -//triangulates a set of polygons by first partitioning them into monotone polygons -//O(n*log(n)) time complexity, O(n) space complexity -//the algorithm used here is outlined in the book -//"Computational Geometry: Algorithms and Applications" -//by Mark de Berg, Otfried Cheong, Marc van Kreveld and Mark Overmars -int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *monotonePolys) { - List<TriangulatorPoly>::Element *iter; - MonotoneVertex *vertices; - long i,numvertices,vindex,vindex2,newnumvertices,maxnumvertices; - long polystartindex, polyendindex; - TriangulatorPoly *poly; - MonotoneVertex *v,*v2,*vprev,*vnext; - ScanLineEdge newedge; - bool error = false; - - numvertices = 0; - for(iter = inpolys->front(); iter ; iter=iter->next()) { - numvertices += iter->get().GetNumPoints(); - } - - maxnumvertices = numvertices*3; - vertices = new MonotoneVertex[maxnumvertices]; - newnumvertices = numvertices; - - polystartindex = 0; - for(iter = inpolys->front(); iter ; iter=iter->next()) { - poly = &(iter->get()); - polyendindex = polystartindex + poly->GetNumPoints()-1; - for(i=0;i<poly->GetNumPoints();i++) { - vertices[i+polystartindex].p = poly->GetPoint(i); - if(i==0) vertices[i+polystartindex].previous = polyendindex; - else vertices[i+polystartindex].previous = i+polystartindex-1; - if(i==(poly->GetNumPoints()-1)) vertices[i+polystartindex].next = polystartindex; - else vertices[i+polystartindex].next = i+polystartindex+1; - } - polystartindex = polyendindex+1; - } - - //construct the priority queue - long *priority = new long [numvertices]; - for(i=0;i<numvertices;i++) priority[i] = i; - SortArray<long,VertexSorter> sorter; - sorter.compare.vertices=vertices; - sorter.sort(priority,numvertices); - - //determine vertex types - char *vertextypes = new char[maxnumvertices]; - for(i=0;i<numvertices;i++) { - v = &(vertices[i]); - vprev = &(vertices[v->previous]); - vnext = &(vertices[v->next]); - - if(Below(vprev->p,v->p)&&Below(vnext->p,v->p)) { - if(IsConvex(vnext->p,vprev->p,v->p)) { - vertextypes[i] = TRIANGULATOR_VERTEXTYPE_START; - } else { - vertextypes[i] = TRIANGULATOR_VERTEXTYPE_SPLIT; - } - } else if(Below(v->p,vprev->p)&&Below(v->p,vnext->p)) { - if(IsConvex(vnext->p,vprev->p,v->p)) - { - vertextypes[i] = TRIANGULATOR_VERTEXTYPE_END; - } else { - vertextypes[i] = TRIANGULATOR_VERTEXTYPE_MERGE; - } - } else { - vertextypes[i] = TRIANGULATOR_VERTEXTYPE_REGULAR; - } - } - - //helpers - long *helpers = new long[maxnumvertices]; - - //binary search tree that holds edges intersecting the scanline - //note that while set doesn't actually have to be implemented as a tree - //complexity requirements for operations are the same as for the balanced binary search tree - Set<ScanLineEdge> edgeTree; - //store iterators to the edge tree elements - //this makes deleting existing edges much faster - Set<ScanLineEdge>::Element **edgeTreeIterators,*edgeIter; - edgeTreeIterators = new Set<ScanLineEdge>::Element*[maxnumvertices]; - //Pair<Set<ScanLineEdge>::Element*,bool> edgeTreeRet; - for(i = 0; i<numvertices; i++) edgeTreeIterators[i] = NULL; - - //for each vertex - for(i=0;i<numvertices;i++) { - vindex = priority[i]; - v = &(vertices[vindex]); - vindex2 = vindex; - v2 = v; - - //depending on the vertex type, do the appropriate action - //comments in the following sections are copied from "Computational Geometry: Algorithms and Applications" - switch(vertextypes[vindex]) { - case TRIANGULATOR_VERTEXTYPE_START: - //Insert ei in T and set helper(ei) to vi. - newedge.p1 = v->p; - newedge.p2 = vertices[v->next].p; - newedge.index = vindex; - edgeTreeIterators[vindex] = edgeTree.insert(newedge); - helpers[vindex] = vindex; - break; - - case TRIANGULATOR_VERTEXTYPE_END: - //if helper(ei-1) is a merge vertex - if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(ei-1) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - } - //Delete ei-1 from T - edgeTree.erase(edgeTreeIterators[v->previous]); - break; - - case TRIANGULATOR_VERTEXTYPE_SPLIT: - //Search in T to find the edge e j directly left of vi. - newedge.p1 = v->p; - newedge.p2 = v->p; - edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.front()) { - error = true; - break; - } - edgeIter=edgeIter->prev(); - //Insert the diagonal connecting vi to helper(ej) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->get().index], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - vindex2 = newnumvertices-2; - v2 = &(vertices[vindex2]); - //helper(e j)�vi - helpers[edgeIter->get().index] = vindex; - //Insert ei in T and set helper(ei) to vi. - newedge.p1 = v2->p; - newedge.p2 = vertices[v2->next].p; - newedge.index = vindex2; - - edgeTreeIterators[vindex2] = edgeTree.insert(newedge); - helpers[vindex2] = vindex2; - break; - - case TRIANGULATOR_VERTEXTYPE_MERGE: - //if helper(ei-1) is a merge vertex - if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(ei-1) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - vindex2 = newnumvertices-2; - v2 = &(vertices[vindex2]); - } - //Delete ei-1 from T. - edgeTree.erase(edgeTreeIterators[v->previous]); - //Search in T to find the edge e j directly left of vi. - newedge.p1 = v->p; - newedge.p2 = v->p; - edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.front()) { - error = true; - break; - } - edgeIter=edgeIter->prev(); - //if helper(ej) is a merge vertex - if(vertextypes[helpers[edgeIter->get().index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(e j) in D. - AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->get().index], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - } - //helper(e j)�vi - helpers[edgeIter->get().index] = vindex2; - break; - - case TRIANGULATOR_VERTEXTYPE_REGULAR: - //if the interior of P lies to the right of vi - if(Below(v->p,vertices[v->previous].p)) { - //if helper(ei-1) is a merge vertex - if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(ei-1) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - vindex2 = newnumvertices-2; - v2 = &(vertices[vindex2]); - } - //Delete ei-1 from T. - edgeTree.erase(edgeTreeIterators[v->previous]); - //Insert ei in T and set helper(ei) to vi. - newedge.p1 = v2->p; - newedge.p2 = vertices[v2->next].p; - newedge.index = vindex2; - edgeTreeIterators[vindex2] = edgeTree.insert(newedge); - helpers[vindex2] = vindex; - } else { - //Search in T to find the edge ej directly left of vi. - newedge.p1 = v->p; - newedge.p2 = v->p; - edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.front()) { - error = true; - break; - } - edgeIter=edgeIter->prev(); - //if helper(ej) is a merge vertex - if(vertextypes[helpers[edgeIter->get().index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { - //Insert the diagonal connecting vi to helper(e j) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->get().index], - vertextypes, edgeTreeIterators, &edgeTree, helpers); - } - //helper(e j)�vi - helpers[edgeIter->get().index] = vindex; - } - break; - } - - if(error) break; - } - - char *used = new char[newnumvertices]; - memset(used,0,newnumvertices*sizeof(char)); - - if(!error) { - //return result - long size; - TriangulatorPoly mpoly; - for(i=0;i<newnumvertices;i++) { - if(used[i]) continue; - v = &(vertices[i]); - vnext = &(vertices[v->next]); - size = 1; - while(vnext!=v) { - vnext = &(vertices[vnext->next]); - size++; - } - mpoly.Init(size); - v = &(vertices[i]); - mpoly[0] = v->p; - vnext = &(vertices[v->next]); - size = 1; - used[i] = 1; - used[v->next] = 1; - while(vnext!=v) { - mpoly[size] = vnext->p; - used[vnext->next] = 1; - vnext = &(vertices[vnext->next]); - size++; - } - monotonePolys->push_back(mpoly); - } - } - - //cleanup - delete [] vertices; - delete [] priority; - delete [] vertextypes; - delete [] edgeTreeIterators; - delete [] helpers; - delete [] used; - - if(error) { - return 0; - } else { - return 1; - } -} - -//adds a diagonal to the doubly-connected list of vertices -void TriangulatorPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, - char *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators, - Set<ScanLineEdge> *edgeTree, long *helpers) -{ - long newindex1,newindex2; - - newindex1 = *numvertices; - (*numvertices)++; - newindex2 = *numvertices; - (*numvertices)++; - - vertices[newindex1].p = vertices[index1].p; - vertices[newindex2].p = vertices[index2].p; - - vertices[newindex2].next = vertices[index2].next; - vertices[newindex1].next = vertices[index1].next; - - vertices[vertices[index2].next].previous = newindex2; - vertices[vertices[index1].next].previous = newindex1; - - vertices[index1].next = newindex2; - vertices[newindex2].previous = index1; - - vertices[index2].next = newindex1; - vertices[newindex1].previous = index2; - - //update all relevant structures - vertextypes[newindex1] = vertextypes[index1]; - edgeTreeIterators[newindex1] = edgeTreeIterators[index1]; - helpers[newindex1] = helpers[index1]; - if(edgeTreeIterators[newindex1] != NULL) - edgeTreeIterators[newindex1]->get().index = newindex1; - vertextypes[newindex2] = vertextypes[index2]; - edgeTreeIterators[newindex2] = edgeTreeIterators[index2]; - helpers[newindex2] = helpers[index2]; - if(edgeTreeIterators[newindex2] != NULL) - edgeTreeIterators[newindex2]->get().index = newindex2; -} - -bool TriangulatorPartition::Below(Vector2 &p1, Vector2 &p2) { - if(p1.y < p2.y) return true; - else if(p1.y == p2.y) { - if(p1.x < p2.x) return true; - } - return false; -} - - - - - -//sorts in the falling order of y values, if y is equal, x is used instead -bool TriangulatorPartition::VertexSorter::operator() (long index1, long index2) const { - if(vertices[index1].p.y > vertices[index2].p.y) return true; - else if(vertices[index1].p.y == vertices[index2].p.y) { - if(vertices[index1].p.x > vertices[index2].p.x) return true; - } - return false; -} - -bool TriangulatorPartition::ScanLineEdge::IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const { - real_t tmp; - tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); - if(tmp>0) return 1; - else return 0; -} - -bool TriangulatorPartition::ScanLineEdge::operator < (const ScanLineEdge & other) const { - if(other.p1.y == other.p2.y) { - if(p1.y == p2.y) { - if(p1.y < other.p1.y) return true; - else return false; - } - if(IsConvex(p1,p2,other.p1)) return true; - else return false; - } else if(p1.y == p2.y) { - if(IsConvex(other.p1,other.p2,p1)) return false; - else return true; - } else if(p1.y < other.p1.y) { - if(IsConvex(other.p1,other.p2,p1)) return false; - else return true; - } else { - if(IsConvex(p1,p2,other.p1)) return true; - else return false; - } -} - -//triangulates monotone polygon -//O(n) time, O(n) space complexity -int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, List<TriangulatorPoly> *triangles) { - long i,i2,j,topindex,bottomindex,leftindex,rightindex,vindex; - Vector2 *points; - long numpoints; - TriangulatorPoly triangle; - - numpoints = inPoly->GetNumPoints(); - points = inPoly->GetPoints(); - - //trivial calses - if(numpoints < 3) return 0; - if(numpoints == 3) { - triangles->push_back(*inPoly); - } - - topindex = 0; bottomindex=0; - for(i=1;i<numpoints;i++) { - if(Below(points[i],points[bottomindex])) bottomindex = i; - if(Below(points[topindex],points[i])) topindex = i; - } - - //check if the poly is really monotone - i = topindex; - while(i!=bottomindex) { - i2 = i+1; if(i2>=numpoints) i2 = 0; - if(!Below(points[i2],points[i])) return 0; - i = i2; - } - i = bottomindex; - while(i!=topindex) { - i2 = i+1; if(i2>=numpoints) i2 = 0; - if(!Below(points[i],points[i2])) return 0; - i = i2; - } - - char *vertextypes = new char[numpoints]; - long *priority = new long[numpoints]; - - //merge left and right vertex chains - priority[0] = topindex; - vertextypes[topindex] = 0; - leftindex = topindex+1; if(leftindex>=numpoints) leftindex = 0; - rightindex = topindex-1; if(rightindex<0) rightindex = numpoints-1; - for(i=1;i<(numpoints-1);i++) { - if(leftindex==bottomindex) { - priority[i] = rightindex; - rightindex--; if(rightindex<0) rightindex = numpoints-1; - vertextypes[priority[i]] = -1; - } else if(rightindex==bottomindex) { - priority[i] = leftindex; - leftindex++; if(leftindex>=numpoints) leftindex = 0; - vertextypes[priority[i]] = 1; - } else { - if(Below(points[leftindex],points[rightindex])) { - priority[i] = rightindex; - rightindex--; if(rightindex<0) rightindex = numpoints-1; - vertextypes[priority[i]] = -1; - } else { - priority[i] = leftindex; - leftindex++; if(leftindex>=numpoints) leftindex = 0; - vertextypes[priority[i]] = 1; - } - } - } - priority[i] = bottomindex; - vertextypes[bottomindex] = 0; - - long *stack = new long[numpoints]; - long stackptr = 0; - - stack[0] = priority[0]; - stack[1] = priority[1]; - stackptr = 2; - - //for each vertex from top to bottom trim as many triangles as possible - for(i=2;i<(numpoints-1);i++) { - vindex = priority[i]; - if(vertextypes[vindex]!=vertextypes[stack[stackptr-1]]) { - for(j=0;j<(stackptr-1);j++) { - if(vertextypes[vindex]==1) { - triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]); - } else { - triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]); - } - triangles->push_back(triangle); - } - stack[0] = priority[i-1]; - stack[1] = priority[i]; - stackptr = 2; - } else { - stackptr--; - while(stackptr>0) { - if(vertextypes[vindex]==1) { - if(IsConvex(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]])) { - triangle.Triangle(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]]); - triangles->push_back(triangle); - stackptr--; - } else { - break; - } - } else { - if(IsConvex(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]])) { - triangle.Triangle(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]]); - triangles->push_back(triangle); - stackptr--; - } else { - break; - } - } - } - stackptr++; - stack[stackptr] = vindex; - stackptr++; - } - } - vindex = priority[i]; - for(j=0;j<(stackptr-1);j++) { - if(vertextypes[stack[j+1]]==1) { - triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]); - } else { - triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]); - } - triangles->push_back(triangle); - } - - delete [] priority; - delete [] vertextypes; - delete [] stack; - - return 1; -} - -int TriangulatorPartition::Triangulate_MONO(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles) { - List<TriangulatorPoly> monotone; - List<TriangulatorPoly>::Element* iter; - - if(!MonotonePartition(inpolys,&monotone)) return 0; - for(iter = monotone.front(); iter;iter=iter->next()) { - if(!TriangulateMonotone(&(iter->get()),triangles)) return 0; - } - return 1; -} - -int TriangulatorPartition::Triangulate_MONO(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles) { - List<TriangulatorPoly> polys; - polys.push_back(*poly); - - return Triangulate_MONO(&polys, triangles); -} diff --git a/thirdparty/misc/triangulator.h b/thirdparty/misc/triangulator.h deleted file mode 100644 index 24b79e7d34..0000000000 --- a/thirdparty/misc/triangulator.h +++ /dev/null @@ -1,306 +0,0 @@ -//Copyright (C) 2011 by Ivan Fratric -// -//Permission is hereby granted, free of charge, to any person obtaining a copy -//of this software and associated documentation files (the "Software"), to deal -//in the Software without restriction, including without limitation the rights -//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//copies of the Software, and to permit persons to whom the Software is -//furnished to do so, subject to the following conditions: -// -//The above copyright notice and this permission notice shall be included in -//all copies or substantial portions of the Software. -// -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -//THE SOFTWARE. - -#ifndef TRIANGULATOR_H -#define TRIANGULATOR_H - -#include "core/templates/list.h" -#include "core/math/vector2.h" -#include "core/templates/set.h" - -//2D point structure - -#define TRIANGULATOR_CCW 1 -#define TRIANGULATOR_CW -1 -//Polygon implemented as an array of points with a 'hole' flag -class TriangulatorPoly { -protected: - - - - Vector2 *points; - long numpoints; - bool hole; - -public: - - //constructors/destructors - TriangulatorPoly(); - ~TriangulatorPoly(); - - TriangulatorPoly(const TriangulatorPoly &src); - TriangulatorPoly& operator=(const TriangulatorPoly &src); - - //getters and setters - long GetNumPoints() { - return numpoints; - } - - bool IsHole() { - return hole; - } - - void SetHole(bool hole) { - this->hole = hole; - } - - Vector2 &GetPoint(long i) { - return points[i]; - } - - Vector2 *GetPoints() { - return points; - } - - Vector2& operator[] (int i) { - return points[i]; - } - - //clears the polygon points - void Clear(); - - //inits the polygon with numpoints vertices - void Init(long numpoints); - - //creates a triangle with points p1,p2,p3 - void Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3); - - //inverts the orfer of vertices - void Invert(); - - //returns the orientation of the polygon - //possible values: - // Triangulator_CCW : polygon vertices are in counter-clockwise order - // Triangulator_CW : polygon vertices are in clockwise order - // 0 : the polygon has no (measurable) area - int GetOrientation(); - - //sets the polygon orientation - //orientation can be - // Triangulator_CCW : sets vertices in counter-clockwise order - // Triangulator_CW : sets vertices in clockwise order - void SetOrientation(int orientation); -}; - -class TriangulatorPartition { -protected: - struct PartitionVertex { - bool isActive; - bool isConvex; - bool isEar; - - Vector2 p; - real_t angle; - PartitionVertex *previous; - PartitionVertex *next; - }; - - struct MonotoneVertex { - Vector2 p; - long previous; - long next; - }; - - struct VertexSorter{ - mutable MonotoneVertex *vertices; - bool operator() (long index1, long index2) const; - }; - - struct Diagonal { - long index1; - long index2; - }; - - //dynamic programming state for minimum-weight triangulation - struct DPState { - bool visible; - real_t weight; - long bestvertex; - }; - - //dynamic programming state for convex partitioning - struct DPState2 { - bool visible; - long weight; - List<Diagonal> pairs; - }; - - //edge that intersects the scanline - struct ScanLineEdge { - mutable long index; - Vector2 p1; - Vector2 p2; - - //determines if the edge is to the left of another edge - bool operator< (const ScanLineEdge & other) const; - - bool IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const; - }; - - //standard helper functions - bool IsConvex(Vector2& p1, Vector2& p2, Vector2& p3); - bool IsReflex(Vector2& p1, Vector2& p2, Vector2& p3); - bool IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p); - - bool InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p); - bool InCone(PartitionVertex *v, Vector2 &p); - - int Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22); - - Vector2 Normalize(const Vector2 &p); - real_t Distance(const Vector2 &p1, const Vector2 &p2); - - //helper functions for Triangulate_EC - void UpdateVertexReflexity(PartitionVertex *v); - void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices); - - //helper functions for ConvexPartition_OPT - void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates); - void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); - void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); - - //helper functions for MonotonePartition - bool Below(Vector2 &p1, Vector2 &p2); - void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, - char *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators, - Set<ScanLineEdge> *edgeTree, long *helpers); - - //triangulates a monotone polygon, used in Triangulate_MONO - int TriangulateMonotone(TriangulatorPoly *inPoly, List<TriangulatorPoly> *triangles); - -public: - - //simple heuristic procedure for removing holes from a list of polygons - //works by creating a diagonal from the rightmost hole vertex to some visible vertex - //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons that can contain holes - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // outpolys : a list of polygons without holes - //returns 1 on success, 0 on failure - int RemoveHoles(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *outpolys); - - //triangulates a polygon by ear clipping - //time complexity O(n^2), n is the number of vertices - //space complexity: O(n) - //params: - // poly : an input polygon to be triangulated - // vertices have to be in counter-clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_EC(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles); - - //triangulates a list of polygons that may contain holes by ear clipping algorithm - //first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon - //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons to be triangulated (can contain holes) - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_EC(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles); - - //creates an optimal polygon triangulation in terms of minimal edge length - //time complexity: O(n^3), n is the number of vertices - //space complexity: O(n^2) - //params: - // poly : an input polygon to be triangulated - // vertices have to be in counter-clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles); - - //triangulates a polygons by firstly partitioning it into monotone polygons - //time complexity: O(n*log(n)), n is the number of vertices - //space complexity: O(n) - //params: - // poly : an input polygon to be triangulated - // vertices have to be in counter-clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_MONO(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles); - - //triangulates a list of polygons by firstly partitioning them into monotone polygons - //time complexity: O(n*log(n)), n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons to be triangulated (can contain holes) - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // triangles : a list of triangles (result) - //returns 1 on success, 0 on failure - int Triangulate_MONO(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles); - - //creates a monotone partition of a list of polygons that can contain holes - //time complexity: O(n*log(n)), n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : a list of polygons to be triangulated (can contain holes) - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // monotonePolys : a list of monotone polygons (result) - //returns 1 on success, 0 on failure - int MonotonePartition(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *monotonePolys); - - //partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm - //the algorithm gives at most four times the number of parts as the optimal algorithm - //however, in practice it works much better than that and often gives optimal partition - //uses triangulation obtained by ear clipping as intermediate result - //time complexity O(n^2), n is the number of vertices - //space complexity: O(n) - //params: - // poly : an input polygon to be partitioned - // vertices have to be in counter-clockwise order - // parts : resulting list of convex polygons - //returns 1 on success, 0 on failure - int ConvexPartition_HM(TriangulatorPoly *poly, List<TriangulatorPoly> *parts); - - //partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm - //the algorithm gives at most four times the number of parts as the optimal algorithm - //however, in practice it works much better than that and often gives optimal partition - //uses triangulation obtained by ear clipping as intermediate result - //time complexity O(n^2), n is the number of vertices - //space complexity: O(n) - //params: - // inpolys : an input list of polygons to be partitioned - // vertices of all non-hole polys have to be in counter-clockwise order - // vertices of all hole polys have to be in clockwise order - // parts : resulting list of convex polygons - //returns 1 on success, 0 on failure - int ConvexPartition_HM(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *parts); - - //optimal convex partitioning (in terms of number of resulting convex polygons) - //using the Keil-Snoeyink algorithm - //M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998 - //time complexity O(n^3), n is the number of vertices - //space complexity: O(n^3) - // poly : an input polygon to be partitioned - // vertices have to be in counter-clockwise order - // parts : resulting list of convex polygons - //returns 1 on success, 0 on failure - int ConvexPartition_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *parts); -}; - - -#endif diff --git a/thirdparty/opus/celt/arm/arm2gnu.pl b/thirdparty/opus/celt/arm/arm2gnu.pl deleted file mode 100755 index 6c922ac819..0000000000 --- a/thirdparty/opus/celt/arm/arm2gnu.pl +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/perl -# Copyright (C) 2002-2013 Xiph.org Foundation -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -my $bigend; # little/big endian -my $nxstack; -my $apple = 0; -my $symprefix = ""; - -$nxstack = 0; - -eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}' - if $running_under_some_shell; - -while ($ARGV[0] =~ /^-/) { - $_ = shift; - last if /^--$/; - if (/^-n$/) { - $nflag++; - next; - } - if (/^--apple$/) { - $apple = 1; - $symprefix = "_"; - next; - } - die "I don't recognize this switch: $_\\n"; -} -$printit++ unless $nflag; - -$\ = "\n"; # automatically add newline on print -$n=0; - -$thumb = 0; # ARM mode by default, not Thumb. -@proc_stack = (); - -printf (" .syntax unified\n"); - -LINE: -while (<>) { - - # For ADRLs we need to add a new line after the substituted one. - $addPadding = 0; - - # First, we do not dare to touch *anything* inside double quotes, do we? - # Second, if you want a dollar character in the string, - # insert two of them -- that's how ARM C and assembler treat strings. - s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next }; - s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next }; - s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next }; - # If there's nothing on a line but a comment, don't try to apply any further - # substitutions (this is a cheap hack to avoid mucking up the license header) - s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next }; - # If substituted -- leave immediately ! - - s/@/,:/; - s/;/@/; - while ( /@.*'/ ) { - s/(@.*)'/$1/g; - } - s/\{FALSE\}/0/g; - s/\{TRUE\}/1/g; - s/\{(\w\w\w\w+)\}/$1/g; - s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/; - s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/; - s/\bIMPORT\b/.extern/; - s/\bEXPORT\b\s*/.global $symprefix/; - s/^(\s+)\[/$1IF/; - s/^(\s+)\|/$1ELSE/; - s/^(\s+)\]/$1ENDIF/; - s/IF *:DEF:/ .ifdef/; - s/IF *:LNOT: *:DEF:/ .ifndef/; - s/ELSE/ .else/; - s/ENDIF/ .endif/; - - if( /\bIF\b/ ) { - s/\bIF\b/ .if/; - s/=/==/; - } - if ( $n == 2) { - s/\$/\\/g; - } - if ($n == 1) { - s/\$//g; - s/label//g; - $n = 2; - } - if ( /MACRO/ ) { - s/MACRO *\n/.macro/; - $n=1; - } - if ( /\bMEND\b/ ) { - s/\bMEND\b/.endm/; - $n=0; - } - - # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there. - # - if ( /\bAREA\b/ ) { - my $align; - $align = "2"; - if ( /ALIGN=(\d+)/ ) { - $align = $1; - } - if ( /CODE/ ) { - $nxstack = 1; - } - s/^(.+)CODE(.+)READONLY(.*)/ .text/; - s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/; - s/^(.+)\|\|\.data\|\|(.+)/ .data/; - s/^(.+)\|\|\.bss\|\|(.+)/ .bss/; - s/$/; .p2align $align/; - # Enable NEON instructions but don't produce a binary that requires - # ARMv7. RVCT does not have equivalent directives, so we just do this - # for all CODE areas. - if ( /.text/ ) { - # Separating .arch, .fpu, etc., by semicolons does not work (gas - # thinks the semicolon is part of the arch name, even when there's - # whitespace separating them). Sadly this means our line numbers - # won't match the original source file (we could use the .line - # directive, which is documented to be obsolete, but then gdb will - # show the wrong line in the translated source file). - s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/ unless ($apple); - } - } - - s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3|| - s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2|| - s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2|| - s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/; - s/^(\s+)\%(\s)/ .space $1/; - - s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123 - s/\bCODE32\b/.code 32/ && do {$thumb = 0}; - s/\bCODE16\b/.code 16/ && do {$thumb = 1}; - if (/\bPROC\b/) - { - my $prefix; - my $proc; - /^([A-Za-z_\.]\w+)\b/; - $proc = $1; - $prefix = ""; - if ($proc) - { - $prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc) unless ($apple); - # Make sure we $prefix isn't empty here (for the $apple case). - # We handle mangling the label here, make sure it doesn't match - # the label handling below (if $prefix would be empty). - $prefix = "; "; - push(@proc_stack, $proc); - s/^[A-Za-z_\.]\w+/$symprefix$&:/; - } - $prefix = $prefix."\t.thumb_func; " if ($thumb); - s/\bPROC\b/@ $&/; - $_ = $prefix.$_; - } - s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/; - s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/; - if (/\bENDP\b/) - { - my $proc; - s/\bENDP\b/@ $&/; - $proc = pop(@proc_stack); - $_ = "\t.size $proc, .-$proc".$_ if ($proc && !$apple); - } - s/\bSUBT\b/@ $&/; - s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25 - s/\bKEEP\b/@ $&/; - s/\bEXPORTAS\b/@ $&/; - s/\|\|(.)+\bEQU\b/@ $&/; - s/\|\|([\w\$]+)\|\|/$1/; - s/\bENTRY\b/@ $&/; - s/\bASSERT\b/@ $&/; - s/\bGBLL\b/@ $&/; - s/\bGBLA\b/@ $&/; - s/^\W+OPT\b/@ $&/; - s/:OR:/|/g; - s/:SHL:/<</g; - s/:SHR:/>>/g; - s/:AND:/&/g; - s/:LAND:/&&/g; - s/CPSR/cpsr/; - s/SPSR/spsr/; - s/ALIGN$/.balign 4/; - s/ALIGN\s+([0-9x]+)$/.balign $1/; - s/psr_cxsf/psr_all/; - s/LTORG/.ltorg/; - s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/; - s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/; - s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/; - s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/; - - # {PC} + 0xdeadfeed --> . + 0xdeadfeed - s/\{PC\} \+/ \. +/; - - # Single hex constant on the line ! - # - # >>> NOTE <<< - # Double-precision floats in gcc are always mixed-endian, which means - # bytes in two words are little-endian, but words are big-endian. - # So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address - # and 0xfeed0000 at high address. - # - s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/; - # Only decimal constants on the line, no hex ! - s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/; - - # Single hex constant on the line ! -# s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/; - # Only decimal constants on the line, no hex ! -# s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/; - s/\bDCFS[ \t]+0x/.word 0x/; - s/\bDCFS\b/.float/; - - s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/; - s/\bDCD\b/.word/; - s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/; - s/\bDCW\b/.short/; - s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/; - s/\bDCB\b/.byte/; - s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/; - s/^[A-Za-z_\.]\w+/$&:/; - s/^(\d+)/$1:/; - s/\%(\d+)/$1b_or_f/; - s/\%[Bb](\d+)/$1b/; - s/\%[Ff](\d+)/$1f/; - s/\%[Ff][Tt](\d+)/$1f/; - s/&([\dA-Fa-f]+)/0x$1/; - if ( /\b2_[01]+\b/ ) { - s/\b2_([01]+)\b/conv$1&&&&/g; - while ( /[01][01][01][01]&&&&/ ) { - s/0000&&&&/&&&&0/g; - s/0001&&&&/&&&&1/g; - s/0010&&&&/&&&&2/g; - s/0011&&&&/&&&&3/g; - s/0100&&&&/&&&&4/g; - s/0101&&&&/&&&&5/g; - s/0110&&&&/&&&&6/g; - s/0111&&&&/&&&&7/g; - s/1000&&&&/&&&&8/g; - s/1001&&&&/&&&&9/g; - s/1010&&&&/&&&&A/g; - s/1011&&&&/&&&&B/g; - s/1100&&&&/&&&&C/g; - s/1101&&&&/&&&&D/g; - s/1110&&&&/&&&&E/g; - s/1111&&&&/&&&&F/g; - } - s/000&&&&/&&&&0/g; - s/001&&&&/&&&&1/g; - s/010&&&&/&&&&2/g; - s/011&&&&/&&&&3/g; - s/100&&&&/&&&&4/g; - s/101&&&&/&&&&5/g; - s/110&&&&/&&&&6/g; - s/111&&&&/&&&&7/g; - s/00&&&&/&&&&0/g; - s/01&&&&/&&&&1/g; - s/10&&&&/&&&&2/g; - s/11&&&&/&&&&3/g; - s/0&&&&/&&&&0/g; - s/1&&&&/&&&&1/g; - s/conv&&&&/0x/g; - } - - if ( /commandline/) - { - if( /-bigend/) - { - $bigend=1; - } - } - - if ( /\bDCDU\b/ ) - { - my $cmd=$_; - my $value; - my $prefix; - my $w1; - my $w2; - my $w3; - my $w4; - - s/\s+DCDU\b/@ $&/; - - $cmd =~ /\bDCDU\b\s+0x(\d+)/; - $value = $1; - $value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/; - $w1 = $1; - $w2 = $2; - $w3 = $3; - $w4 = $4; - - if( $bigend ne "") - { - # big endian - $prefix = "\t.byte\t0x".$w1.";". - "\t.byte\t0x".$w2.";". - "\t.byte\t0x".$w3.";". - "\t.byte\t0x".$w4."; "; - } - else - { - # little endian - $prefix = "\t.byte\t0x".$w4.";". - "\t.byte\t0x".$w3.";". - "\t.byte\t0x".$w2.";". - "\t.byte\t0x".$w1."; "; - } - $_=$prefix.$_; - } - - if ( /\badrl\b/i ) - { - s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i; - $addPadding = 1; - } - s/\bEND\b/@ END/; -} continue { - printf ("%s", $_) if $printit; - if ($addPadding != 0) - { - printf (" mov r0,r0\n"); - $addPadding = 0; - } -} -#If we had a code section, mark that this object doesn't need an executable -# stack. -if ($nxstack && !$apple) { - printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n"); -} diff --git a/thirdparty/pcre2/AUTHORS b/thirdparty/pcre2/AUTHORS index 8d4e15a247..f001cb770e 100644 --- a/thirdparty/pcre2/AUTHORS +++ b/thirdparty/pcre2/AUTHORS @@ -2,13 +2,13 @@ THE MAIN PCRE2 LIBRARY CODE --------------------------- Written by: Philip Hazel -Email local part: ph10 -Email domain: cam.ac.uk +Email local part: Philip.Hazel +Email domain: gmail.com University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2019 University of Cambridge +Copyright (c) 1997-2020 University of Cambridge All rights reserved @@ -19,7 +19,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2019 Zoltan Herczeg +Copyright(c) 2010-2020 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2019 Zoltan Herczeg +Copyright(c) 2009-2020 Zoltan Herczeg All rights reserved. #### diff --git a/thirdparty/pcre2/LICENCE b/thirdparty/pcre2/LICENCE index 142b3b3f9a..155d073127 100644 --- a/thirdparty/pcre2/LICENCE +++ b/thirdparty/pcre2/LICENCE @@ -20,13 +20,13 @@ THE BASIC LIBRARY FUNCTIONS --------------------------- Written by: Philip Hazel -Email local part: ph10 -Email domain: cam.ac.uk +Email local part: Philip.Hazel +Email domain: gmail.com University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2019 University of Cambridge +Copyright (c) 1997-2020 University of Cambridge All rights reserved. @@ -37,7 +37,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2010-2019 Zoltan Herczeg +Copyright(c) 2010-2020 Zoltan Herczeg All rights reserved. @@ -48,7 +48,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2009-2019 Zoltan Herczeg +Copyright(c) 2009-2020 Zoltan Herczeg All rights reserved. diff --git a/thirdparty/pcre2/src/config.h b/thirdparty/pcre2/src/config.h index 787bb9c999..10f4104790 100644 --- a/thirdparty/pcre2/src/config.h +++ b/thirdparty/pcre2/src/config.h @@ -52,6 +52,9 @@ sure both macros are undefined; an emulation function will then be used. */ LF does in an ASCII/Unicode environment. */ /* #undef EBCDIC_NL25 */ +/* Define this if your compiler supports __attribute__((uninitialized)) */ +/* #undef HAVE_ATTRIBUTE_UNINITIALIZED */ + /* Define to 1 if you have the `bcopy' function. */ /* #undef HAVE_BCOPY */ @@ -76,6 +79,9 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to 1 if you have the <limits.h> header file. */ /* #undef HAVE_LIMITS_H */ +/* Define to 1 if you have the `memfd_create' function. */ +/* #undef HAVE_MEMFD_CREATE */ + /* Define to 1 if you have the `memmove' function. */ /* #undef HAVE_MEMMOVE */ @@ -218,7 +224,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_NAME "PCRE2" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE2 10.34" +#define PACKAGE_STRING "PCRE2 10.36" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre2" @@ -227,7 +233,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "10.34" +#define PACKAGE_VERSION "10.36" /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested parentheses (of any kind) in a pattern. This limits the amount of system @@ -352,7 +358,7 @@ sure both macros are undefined; an emulation function will then be used. */ #endif /* Version number of package */ -#define VERSION "10.34" +#define VERSION "10.36" /* Define to 1 if on MINIX. */ /* #undef _MINIX */ diff --git a/thirdparty/pcre2/src/pcre2.h b/thirdparty/pcre2/src/pcre2.h index cb9d61a35b..f204ec8180 100644 --- a/thirdparty/pcre2/src/pcre2.h +++ b/thirdparty/pcre2/src/pcre2.h @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, second API, to be #included by applications that call PCRE2 functions. - Copyright (c) 2016-2019 University of Cambridge + Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 34 +#define PCRE2_MINOR 36 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2019-11-21 +#define PCRE2_DATE 2020-12-04 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -181,6 +181,9 @@ pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */ #define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */ #define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */ #define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u +#define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */ +#define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */ +#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */ /* Options for pcre2_pattern_convert(). */ @@ -445,6 +448,7 @@ released, the numbers must not be changed. */ #define PCRE2_CONFIG_HEAPLIMIT 12 #define PCRE2_CONFIG_NEVER_BACKSLASH_C 13 #define PCRE2_CONFIG_COMPILED_WIDTHS 14 +#define PCRE2_CONFIG_TABLES_LENGTH 15 /* Types for code units in patterns and subject strings. */ diff --git a/thirdparty/pcre2/src/pcre2_auto_possess.c b/thirdparty/pcre2/src/pcre2_auto_possess.c index 5b95b9b8a8..c64cf856d1 100644 --- a/thirdparty/pcre2/src/pcre2_auto_possess.c +++ b/thirdparty/pcre2/src/pcre2_auto_possess.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -292,6 +292,7 @@ possessification, and if so, fills a list with its properties. Arguments: code points to start of expression utf TRUE if in UTF mode + ucp TRUE if in UCP mode fcc points to the case-flipping table list points to output list list[0] will be filled with the opcode @@ -304,7 +305,7 @@ Returns: points to the start of the next opcode if *code is accepted */ static PCRE2_SPTR -get_chr_property_list(PCRE2_SPTR code, BOOL utf, const uint8_t *fcc, +get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc, uint32_t *list) { PCRE2_UCHAR c = *code; @@ -316,7 +317,8 @@ uint32_t chr; uint32_t *clist_dest; const uint32_t *clist_src; #else -(void)utf; /* Suppress "unused parameter" compiler warning */ +(void)utf; /* Suppress "unused parameter" compiler warnings */ +(void)ucp; #endif list[0] = c; @@ -396,7 +398,7 @@ switch(c) list[2] = chr; #ifdef SUPPORT_UNICODE - if (chr < 128 || (chr < 256 && !utf)) + if (chr < 128 || (chr < 256 && !utf && !ucp)) list[3] = fcc[chr]; else list[3] = UCD_OTHERCASE(chr); @@ -503,6 +505,7 @@ which case the base cannot be possessified. Arguments: code points to the byte code utf TRUE in UTF mode + ucp TRUE in UCP mode cb compile data block base_list the data list of the base opcode base_end the end of the base opcode @@ -512,7 +515,7 @@ Returns: TRUE if the auto-possessification is possible */ static BOOL -compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb, +compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb, const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit) { PCRE2_UCHAR c; @@ -651,7 +654,7 @@ for(;;) while (*next_code == OP_ALT) { - if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit)) + if (!compare_opcodes(code, utf, ucp, cb, base_list, base_end, rec_limit)) return FALSE; code = next_code + 1 + LINK_SIZE; next_code += GET(next_code, 1); @@ -672,7 +675,8 @@ for(;;) /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */ next_code += 1 + LINK_SIZE; - if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit)) + if (!compare_opcodes(next_code, utf, ucp, cb, base_list, base_end, + rec_limit)) return FALSE; code += PRIV(OP_lengths)[c]; @@ -688,7 +692,7 @@ for(;;) /* We now have the next appropriate opcode to compare with the base. Check for a supported opcode, and load its properties. */ - code = get_chr_property_list(code, utf, cb->fcc, list); + code = get_chr_property_list(code, utf, ucp, cb->fcc, list); if (code == NULL) return FALSE; /* Unsupported */ /* If either opcode is a small character list, set pointers for comparing @@ -1100,7 +1104,6 @@ leaving the remainder of the pattern unpossessified. Arguments: code points to start of the byte code - utf TRUE in UTF mode cb compile data block Returns: 0 for success @@ -1108,13 +1111,15 @@ Returns: 0 for success */ int -PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb) +PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb) { PCRE2_UCHAR c; PCRE2_SPTR end; PCRE2_UCHAR *repeat_opcode; uint32_t list[8]; int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */ +BOOL utf = (cb->external_options & PCRE2_UTF) != 0; +BOOL ucp = (cb->external_options & PCRE2_UCP) != 0; for (;;) { @@ -1126,10 +1131,11 @@ for (;;) { c -= get_repeat_base(c) - OP_STAR; end = (c <= OP_MINUPTO) ? - get_chr_property_list(code, utf, cb->fcc, list) : NULL; + get_chr_property_list(code, utf, ucp, cb->fcc, list) : NULL; list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO; - if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit)) + if (end != NULL && compare_opcodes(end, utf, ucp, cb, list, end, + &rec_limit)) { switch(c) { @@ -1181,11 +1187,11 @@ for (;;) if (c >= OP_CRSTAR && c <= OP_CRMINRANGE) { /* end must not be NULL. */ - end = get_chr_property_list(code, utf, cb->fcc, list); + end = get_chr_property_list(code, utf, ucp, cb->fcc, list); list[1] = (c & 1) == 0; - if (compare_opcodes(end, utf, cb, list, end, &rec_limit)) + if (compare_opcodes(end, utf, ucp, cb, list, end, &rec_limit)) { switch (c) { diff --git a/thirdparty/pcre2/src/pcre2_chartables.c b/thirdparty/pcre2/src/pcre2_chartables.c index 0e07edb494..861914d1ac 100644 --- a/thirdparty/pcre2/src/pcre2_chartables.c +++ b/thirdparty/pcre2/src/pcre2_chartables.c @@ -2,17 +2,21 @@ * Perl-Compatible Regular Expressions * *************************************************/ -/* This file was automatically written by the dftables auxiliary +/* This file was automatically written by the pcre2_dftables auxiliary program. It contains character tables that are used when no external tables are passed to PCRE2 by the application that calls it. The tables are used only for characters whose code values are less than 256. */ -/*The dftables program (which is distributed with PCRE2) can be used to -build alternative versions of this file. This is necessary if you are +/* This set of tables was written in the C locale. */ + +/* The pcre2_ftables program (which is distributed with PCRE2) can be used +to build alternative versions of this file. This is necessary if you are running in an EBCDIC environment, or if you want to default to a different -encoding, for example ISO-8859-1. When dftables is run, it creates these -tables in the current locale. This happens automatically if PCRE2 is -configured with --enable-rebuild-chartables. */ +encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates +these tables in the "C" locale by default. This happens automatically if +PCRE2 is configured with --enable-rebuild-chartables. However, you can run +pcre2_dftables manually with the -L option to build tables using the LC_ALL +locale. */ /* The following #include is present because without it gcc 4.x may remove the array definition from the final binary if PCRE2 is built into a static @@ -102,54 +106,54 @@ const uint8_t PRIV(default_tables)[] = { /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, -graph print, punct, and cntrl. Other classes are built from combinations. */ +graph, print, punct, and cntrl. Other classes are built from combinations. */ - 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, /* space */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* xdigit */ 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* digit */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* upper */ 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* lower */ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* word */ 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, /* graph */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, /* print */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, + 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, /* punct */ 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, /* cntrl */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff --git a/thirdparty/pcre2/src/pcre2_compile.c b/thirdparty/pcre2/src/pcre2_compile.c index f2e6b6b5bd..e811f12f02 100644 --- a/thirdparty/pcre2/src/pcre2_compile.c +++ b/thirdparty/pcre2/src/pcre2_compile.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -1202,7 +1202,7 @@ in the decoded tables. */ if ((code->flags & PCRE2_DEREF_TABLES) != 0) { - ref_count = (PCRE2_SIZE *)(code->tables + tables_length); + ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH); (*ref_count)++; } @@ -1232,15 +1232,15 @@ if (newcode == NULL) return NULL; memcpy(newcode, code, code->blocksize); newcode->executable_jit = NULL; -newtables = code->memctl.malloc(tables_length + sizeof(PCRE2_SIZE), +newtables = code->memctl.malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), code->memctl.memory_data); if (newtables == NULL) { code->memctl.free((void *)newcode, code->memctl.memory_data); return NULL; } -memcpy(newtables, code->tables, tables_length); -ref_count = (PCRE2_SIZE *)(newtables + tables_length); +memcpy(newtables, code->tables, TABLES_LENGTH); +ref_count = (PCRE2_SIZE *)(newtables + TABLES_LENGTH); *ref_count = 1; newcode->tables = newtables; @@ -1270,7 +1270,7 @@ if (code != NULL) be freed when there are no more references to them. The *ref_count should always be > 0. */ - ref_count = (PCRE2_SIZE *)(code->tables + tables_length); + ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH); if (*ref_count > 0) { (*ref_count)--; @@ -2344,7 +2344,7 @@ if (ptr > *nameptr + MAX_NAME_SIZE) *errorcodeptr = ERR48; goto FAILED; } -*namelenptr = ptr - *nameptr; +*namelenptr = (uint32_t)(ptr - *nameptr); /* Subpattern names must not be empty, and their terminator is checked here. (What follows a verb or alpha assertion name is checked separately.) */ @@ -3653,7 +3653,7 @@ while (ptr < ptrend) if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS; /* If ( is not followed by ? it is either a capture or a special verb or an - alpha assertion. */ + alpha assertion or a positive non-atomic lookahead. */ if (*ptr != CHAR_QUESTION_MARK) { @@ -3685,10 +3685,10 @@ while (ptr < ptrend) break; /* Handle "alpha assertions" such as (*pla:...). Most of these are - synonyms for the historical symbolic assertions, but the script run ones - are new. They are distinguished by starting with a lower case letter. - Checking both ends of the alphabet makes this work in all character - codes. */ + synonyms for the historical symbolic assertions, but the script run and + non-atomic lookaround ones are new. They are distinguished by starting + with a lower case letter. Checking both ends of the alphabet makes this + work in all character codes. */ else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0) { @@ -3747,9 +3747,7 @@ while (ptr < ptrend) goto POSITIVE_LOOK_AHEAD; case META_LOOKAHEAD_NA: - *parsed_pattern++ = meta; - ptr++; - goto POST_ASSERTION; + goto POSITIVE_NONATOMIC_LOOK_AHEAD; case META_LOOKAHEADNOT: goto NEGATIVE_LOOK_AHEAD; @@ -4333,6 +4331,7 @@ while (ptr < ptrend) { if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION; minor = (*ptr++ - CHAR_0) * 10; + if (ptr >= ptrend) goto BAD_VERSION_CONDITION; if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0; if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS) goto BAD_VERSION_CONDITION; @@ -4438,6 +4437,12 @@ while (ptr < ptrend) ptr++; goto POST_ASSERTION; + case CHAR_ASTERISK: + POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (?* */ + *parsed_pattern++ = META_LOOKAHEAD_NA; + ptr++; + goto POST_ASSERTION; + case CHAR_EXCLAMATION_MARK: NEGATIVE_LOOK_AHEAD: /* Come from (*nla: */ *parsed_pattern++ = META_LOOKAHEADNOT; @@ -4447,20 +4452,23 @@ while (ptr < ptrend) /* ---- Lookbehind assertions ---- */ - /* (?< followed by = or ! is a lookbehind assertion. Otherwise (?< is the - start of the name of a capturing group. */ + /* (?< followed by = or ! or * is a lookbehind assertion. Otherwise (?< + is the start of the name of a capturing group. */ case CHAR_LESS_THAN_SIGN: if (ptrend - ptr <= 1 || - (ptr[1] != CHAR_EQUALS_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK)) + (ptr[1] != CHAR_EQUALS_SIGN && + ptr[1] != CHAR_EXCLAMATION_MARK && + ptr[1] != CHAR_ASTERISK)) { terminator = CHAR_GREATER_THAN_SIGN; goto DEFINE_NAME; } *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)? - META_LOOKBEHIND : META_LOOKBEHINDNOT; + META_LOOKBEHIND : (ptr[1] == CHAR_EXCLAMATION_MARK)? + META_LOOKBEHINDNOT : META_LOOKBEHIND_NA; - POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */ + POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */ *has_lookbehind = TRUE; offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2); PUTOFFSET(offset, parsed_pattern); @@ -4633,8 +4641,6 @@ while (ptr < ptrend) *parsed_pattern++ = META_KET; } - - if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; else top_nest--; } @@ -4899,7 +4905,7 @@ range. */ if ((options & PCRE2_CASELESS) != 0) { #ifdef SUPPORT_UNICODE - if ((options & PCRE2_UTF) != 0) + if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0) { int rc; uint32_t oc, od; @@ -5314,7 +5320,8 @@ dynamically as we process the pattern. */ #ifdef SUPPORT_UNICODE BOOL utf = (options & PCRE2_UTF) != 0; -#else /* No UTF support */ +BOOL ucp = (options & PCRE2_UCP) != 0; +#else /* No Unicode support */ BOOL utf = FALSE; #endif @@ -5559,12 +5566,12 @@ for (;; pptr++) zerofirstcu = firstcu; zerofirstcuflags = firstcuflags; - /* For caseless UTF mode, check whether this character has more than - one other case. If so, generate a special OP_NOTPROP item instead of + /* For caseless UTF or UCP mode, check whether this character has more + than one other case. If so, generate a special OP_NOTPROP item instead of OP_NOTI. */ #ifdef SUPPORT_UNICODE - if (utf && (options & PCRE2_CASELESS) != 0 && + if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 && (d = UCD_CASESET(c)) != 0) { *code++ = OP_NOTPROP; @@ -5597,7 +5604,7 @@ for (;; pptr++) uint32_t d; #ifdef SUPPORT_UNICODE - if (utf && c > 127) d = UCD_OTHERCASE(c); else + if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else #endif { #if PCRE2_CODE_UNIT_WIDTH != 8 @@ -6671,23 +6678,11 @@ for (;; pptr++) } /* For a back reference, update the back reference map and the - maximum back reference. Then, for each group, we must check to - see if it is recursive, that is, it is inside the group that it - references. A flag is set so that the group can be made atomic. - */ + maximum back reference. */ cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1; if (groupnumber > cb->top_backref) cb->top_backref = groupnumber; - - for (oc = cb->open_caps; oc != NULL; oc = oc->next) - { - if (oc->number == groupnumber) - { - oc->flag = TRUE; - break; - } - } } } @@ -7081,15 +7076,18 @@ for (;; pptr++) previous[GET(previous, 1)] != OP_ALT) goto END_REPEAT; - /* There is no sense in actually repeating assertions. The only - potential use of repetition is in cases when the assertion is optional. - Therefore, if the minimum is greater than zero, just ignore the repeat. - If the maximum is not zero or one, set it to 1. */ + /* Perl allows all assertions to be quantified, and when they contain + capturing parentheses and/or are optional there are potential uses for + this feature. PCRE2 used to force the maximum quantifier to 1 on the + invalid grounds that further repetition was never useful. This was + always a bit pointless, since an assertion could be wrapped with a + repeated group to achieve the effect. General repetition is now + permitted, but if the maximum is unlimited it is set to one more than + the minimum. */ if (op_previous < OP_ONCE) /* Assertion */ { - if (repeat_min > 0) goto END_REPEAT; - if (repeat_max > 1) repeat_max = 1; + if (repeat_max == REPEAT_UNLIMITED) repeat_max = repeat_min + 1; } /* The case of a zero minimum is special because of the need to stick @@ -7682,19 +7680,6 @@ for (;; pptr++) cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1; if (meta_arg > cb->top_backref) cb->top_backref = meta_arg; - - /* Check to see if this back reference is recursive, that it, it - is inside the group that it references. A flag is set so that the - group can be made atomic. */ - - for (oc = cb->open_caps; oc != NULL; oc = oc->next) - { - if (oc->number == meta_arg) - { - oc->flag = TRUE; - break; - } - } break; @@ -7840,11 +7825,12 @@ for (;; pptr++) NORMAL_CHAR_SET: /* Character is already in meta */ matched_char = TRUE; - /* For caseless UTF mode, check whether this character has more than one - other case. If so, generate a special OP_PROP item instead of OP_CHARI. */ + /* For caseless UTF or UCP mode, check whether this character has more than + one other case. If so, generate a special OP_PROP item instead of OP_CHARI. + */ #ifdef SUPPORT_UNICODE - if (utf && (options & PCRE2_CASELESS) != 0) + if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) { uint32_t caseset = UCD_CASESET(meta); if (caseset != 0) @@ -8053,7 +8039,6 @@ if (*code == OP_CBRA) capnumber = GET2(code, 1 + LINK_SIZE); capitem.number = capnumber; capitem.next = cb->open_caps; - capitem.flag = FALSE; capitem.assert_depth = cb->assert_depth; cb->open_caps = &capitem; } @@ -8182,26 +8167,9 @@ for (;;) PUT(code, 1, (int)(code - start_bracket)); code += 1 + LINK_SIZE; - /* If it was a capturing subpattern, check to see if it contained any - recursive back references. If so, we must wrap it in atomic brackets. In - any event, remove the block from the chain. */ + /* If it was a capturing subpattern, remove the block from the chain. */ - if (capnumber > 0) - { - if (cb->open_caps->flag) - { - (void)memmove(start_bracket + 1 + LINK_SIZE, start_bracket, - CU2BYTES(code - start_bracket)); - *start_bracket = OP_ONCE; - code += 1 + LINK_SIZE; - PUT(start_bracket, 1, (int)(code - start_bracket)); - *code = OP_KET; - PUT(code, 1, (int)(code - start_bracket)); - code += 1 + LINK_SIZE; - length += 2 + 2*LINK_SIZE; - } - cb->open_caps = cb->open_caps->next; - } + if (capnumber > 0) cb->open_caps = cb->open_caps->next; /* Set values to pass back */ @@ -8836,9 +8804,10 @@ memset(slot + IMM2_SIZE + length, 0, /* This function is called to skip parts of the parsed pattern when finding the length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find -the end of the branch, it is called to skip over an internal lookaround, and it -is also called to skip to the end of a class, during which it will never -encounter nested groups (but there's no need to have special code for that). +the end of the branch, it is called to skip over an internal lookaround or +(DEFINE) group, and it is also called to skip to the end of a class, during +which it will never encounter nested groups (but there's no need to have +special code for that). When called to find the end of a branch or group, pptr must point to the first meta code inside the branch, not the branch-starting code. In other cases it @@ -9316,14 +9285,21 @@ for (;; pptr++) itemlength = grouplength; break; - /* Check nested groups - advance past the initial data for each type and - then seek a fixed length with get_grouplength(). */ + /* A (DEFINE) group is never obeyed inline and so it does not contribute to + the length of this branch. Skip from the following item to the next + unpaired ket. */ + + case META_COND_DEFINE: + pptr = parsed_skip(pptr + 1, PSKIP_KET); + break; + + /* Check other nested groups - advance past the initial data for each type + and then seek a fixed length with get_grouplength(). */ case META_COND_NAME: case META_COND_NUMBER: case META_COND_RNAME: case META_COND_RNUMBER: - case META_COND_DEFINE: pptr += 2 + SIZEOFFSET; goto CHECK_GROUP; @@ -9580,6 +9556,10 @@ for (; *pptr != META_END; pptr++) break; case META_COND_DEFINE: + pptr += SIZEOFFSET; + nestlevel++; + break; + case META_COND_NAME: case META_COND_NUMBER: case META_COND_RNAME: @@ -9660,6 +9640,7 @@ pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options, int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext) { BOOL utf; /* Set TRUE for UTF mode */ +BOOL ucp; /* Set TRUE for UCP mode */ BOOL has_lookbehind = FALSE; /* Set TRUE if a lookbehind is found */ BOOL zero_terminated; /* Set TRUE for zero-terminated pattern */ pcre2_real_code *re = NULL; /* What we will return */ @@ -9947,8 +9928,8 @@ if (utf) /* Check UCP lockout. */ -if ((cb.external_options & (PCRE2_UCP|PCRE2_NEVER_UCP)) == - (PCRE2_UCP|PCRE2_NEVER_UCP)) +ucp = (cb.external_options & PCRE2_UCP) != 0; +if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0) { errorcode = ERR75; goto HAD_EARLY_ERROR; @@ -10324,7 +10305,7 @@ function call. */ if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0) { PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart; - if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80; + if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80; } /* Failed to compile, or error while post-processing. */ @@ -10372,21 +10353,25 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) if ((firstcuflags & REQ_CASELESS) != 0) { - if (firstcu < 128 || (!utf && firstcu < 255)) + if (firstcu < 128 || (!utf && !ucp && firstcu < 255)) { if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS; } - /* The first code unit is > 128 in UTF mode, or > 255 otherwise. In - 8-bit UTF mode, codepoints in the range 128-255 are introductory code - points and cannot have another case. In 16-bit and 32-bit modes, we can - check wide characters when UTF (and therefore UCP) is supported. */ + /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise. + In 8-bit UTF mode, codepoints in the range 128-255 are introductory code + points and cannot have another case, but if UCP is set they may do. */ -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - else if (firstcu <= MAX_UTF_CODE_POINT && +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + else if (ucp && !utf && UCD_OTHERCASE(firstcu) != firstcu) + re->flags |= PCRE2_FIRSTCASELESS; +#else + else if ((utf || ucp) && firstcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(firstcu) != firstcu) re->flags |= PCRE2_FIRSTCASELESS; #endif +#endif /* SUPPORT_UNICODE */ } } @@ -10435,14 +10420,20 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) if ((reqcuflags & REQ_CASELESS) != 0) { - if (reqcu < 128 || (!utf && reqcu < 255)) + if (reqcu < 128 || (!utf && !ucp && reqcu < 255)) { if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS; } -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu) - re->flags |= PCRE2_LASTCASELESS; +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + else if (ucp && !utf && UCD_OTHERCASE(reqcu) != reqcu) + re->flags |= PCRE2_LASTCASELESS; +#else + else if ((utf || ucp) && reqcu <= MAX_UTF_CODE_POINT && + UCD_OTHERCASE(reqcu) != reqcu) + re->flags |= PCRE2_LASTCASELESS; #endif +#endif /* SUPPORT_UNICODE */ } } } diff --git a/thirdparty/pcre2/src/pcre2_config.c b/thirdparty/pcre2/src/pcre2_config.c index e487b10220..5ef103caf7 100644 --- a/thirdparty/pcre2/src/pcre2_config.c +++ b/thirdparty/pcre2/src/pcre2_config.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -43,7 +43,8 @@ POSSIBILITY OF SUCH DAMAGE. #endif /* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes -its value gets changed by pcre2_internal.h to be in code units. */ +its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to +be in code units. */ static int configured_link_size = LINK_SIZE; @@ -94,6 +95,7 @@ if (where == NULL) /* Requests a length */ case PCRE2_CONFIG_NEWLINE: case PCRE2_CONFIG_PARENSLIMIT: case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */ + case PCRE2_CONFIG_TABLES_LENGTH: case PCRE2_CONFIG_UNICODE: return sizeof(uint32_t); @@ -191,6 +193,10 @@ switch (what) *((uint32_t *)where) = 0; break; + case PCRE2_CONFIG_TABLES_LENGTH: + *((uint32_t *)where) = TABLES_LENGTH; + break; + case PCRE2_CONFIG_UNICODE_VERSION: { #if defined SUPPORT_UNICODE diff --git a/thirdparty/pcre2/src/pcre2_dfa_match.c b/thirdparty/pcre2/src/pcre2_dfa_match.c index 7d8ffe8a3e..625695b7cb 100644 --- a/thirdparty/pcre2/src/pcre2_dfa_match.c +++ b/thirdparty/pcre2/src/pcre2_dfa_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -548,6 +548,7 @@ PCRE2_SPTR start_code = mb->start_code; #ifdef SUPPORT_UNICODE BOOL utf = (mb->poptions & PCRE2_UTF) != 0; +BOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0; #else BOOL utf = FALSE; #endif @@ -2190,7 +2191,7 @@ for (;;) if (clen == 0) break; #ifdef SUPPORT_UNICODE - if (utf) + if (utf_or_ucp) { if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else { @@ -2204,7 +2205,7 @@ for (;;) } else #endif /* SUPPORT_UNICODE */ - /* Not UTF mode */ + /* Not UTF or UCP mode */ { if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d)) { ADD_NEW(state_offset + 2, 0); } @@ -2339,7 +2340,7 @@ for (;;) { uint32_t otherd; #ifdef SUPPORT_UNICODE - if (utf && d >= 128) + if (utf_or_ucp && d >= 128) otherd = UCD_OTHERCASE(d); else #endif /* SUPPORT_UNICODE */ @@ -2374,7 +2375,7 @@ for (;;) if (caseless) { #ifdef SUPPORT_UNICODE - if (utf && d >= 128) + if (utf_or_ucp && d >= 128) otherd = UCD_OTHERCASE(d); else #endif /* SUPPORT_UNICODE */ @@ -2417,7 +2418,7 @@ for (;;) if (caseless) { #ifdef SUPPORT_UNICODE - if (utf && d >= 128) + if (utf_or_ucp && d >= 128) otherd = UCD_OTHERCASE(d); else #endif /* SUPPORT_UNICODE */ @@ -2458,7 +2459,7 @@ for (;;) if (caseless) { #ifdef SUPPORT_UNICODE - if (utf && d >= 128) + if (utf_or_ucp && d >= 128) otherd = UCD_OTHERCASE(d); else #endif /* SUPPORT_UNICODE */ @@ -2491,7 +2492,7 @@ for (;;) if (caseless) { #ifdef SUPPORT_UNICODE - if (utf && d >= 128) + if (utf_or_ucp && d >= 128) otherd = UCD_OTHERCASE(d); else #endif /* SUPPORT_UNICODE */ @@ -2531,7 +2532,7 @@ for (;;) if (caseless) { #ifdef SUPPORT_UNICODE - if (utf && d >= 128) + if (utf_or_ucp && d >= 128) otherd = UCD_OTHERCASE(d); else #endif /* SUPPORT_UNICODE */ @@ -3526,10 +3527,15 @@ if ((re->flags & PCRE2_FIRSTSET) != 0) if ((re->flags & PCRE2_FIRSTCASELESS) != 0) { first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && first_cu > 127) +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0) + first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu); +#else + if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0)) first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu); #endif +#endif /* SUPPORT_UNICODE */ } } else @@ -3545,9 +3551,15 @@ if ((re->flags & PCRE2_LASTSET) != 0) if ((re->flags & PCRE2_LASTCASELESS) != 0) { req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && req_cu > 127) req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu); +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0) + req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu); +#else + if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0)) + req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu); #endif +#endif /* SUPPORT_UNICODE */ } } diff --git a/thirdparty/pcre2/src/pcre2_internal.h b/thirdparty/pcre2/src/pcre2_internal.h index fe8ffe5c80..d8fad1e93b 100644 --- a/thirdparty/pcre2/src/pcre2_internal.h +++ b/thirdparty/pcre2/src/pcre2_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -76,6 +76,17 @@ typedef int BOOL; #include <valgrind/memcheck.h> #endif +/* -ftrivial-auto-var-init support supports initializing all local variables +to avoid some classes of bug, but this can cause an unacceptable slowdown +for large on-stack arrays in hot functions. This macro lets us annotate +such arrays. */ + +#ifdef HAVE_ATTRIBUTE_UNINITIALIZED +#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized)) +#else +#define PCRE2_KEEP_UNINITIALIZED +#endif + /* Older versions of MSVC lack snprintf(). This define allows for warning/error-free compilation and testing with MSVC compilers back to at least MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */ @@ -579,7 +590,7 @@ total length of the tables. */ #define fcc_offset 256 /* Flip case */ #define cbits_offset 512 /* Character classes */ #define ctypes_offset (cbits_offset + cbit_length) /* Character types */ -#define tables_length (ctypes_offset + 256) +#define TABLES_LENGTH (ctypes_offset + 256) /* -------------------- Character and string names ------------------------ */ @@ -1759,13 +1770,11 @@ typedef struct pcre2_memctl { /* Structure for building a chain of open capturing subpatterns during compiling, so that instructions to close them can be compiled when (*ACCEPT) is -encountered. This is also used to identify subpatterns that contain recursive -back references to themselves, so that they can be made atomic. */ +encountered. */ typedef struct open_capitem { struct open_capitem *next; /* Chain link */ uint16_t number; /* Capture number */ - uint16_t flag; /* Set TRUE if recursive back ref */ uint16_t assert_depth; /* Assertion depth when opened */ } open_capitem; @@ -1954,7 +1963,7 @@ is available. */ #define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_) #define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_) -extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL, +extern int _pcre2_auto_possessify(PCRE2_UCHAR *, const compile_block *); extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *, int *, uint32_t, uint32_t, BOOL, compile_block *); diff --git a/thirdparty/pcre2/src/pcre2_jit_compile.c b/thirdparty/pcre2/src/pcre2_jit_compile.c index f564127c2a..1977d28aa5 100644 --- a/thirdparty/pcre2/src/pcre2_jit_compile.c +++ b/thirdparty/pcre2/src/pcre2_jit_compile.c @@ -223,6 +223,12 @@ enum control_types { type_then_trap = 1 }; +enum early_fail_types { + type_skip = 0, + type_fail = 1, + type_fail_range = 2 +}; + typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args); /* The following structure is the key data type for the recursive @@ -405,8 +411,8 @@ typedef struct compiler_common { /* Fast forward skipping byte code pointer. */ PCRE2_SPTR fast_forward_bc_ptr; /* Locals used by fast fail optimization. */ - sljit_s32 fast_fail_start_ptr; - sljit_s32 fast_fail_end_ptr; + sljit_s32 early_fail_start_ptr; + sljit_s32 early_fail_end_ptr; /* Flipped and lower case tables. */ const sljit_u8 *fcc; @@ -476,7 +482,7 @@ typedef struct compiler_common { #ifdef SUPPORT_UNICODE BOOL utf; BOOL invalid_utf; - BOOL use_ucp; + BOOL ucp; /* Points to saving area for iref. */ sljit_s32 iref_ptr; jump_list *getucd; @@ -607,6 +613,8 @@ the start pointers when the end of the capturing group has not yet reached. */ sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) +#define OP_SRC(op, src, srcw) \ + sljit_emit_op_src(compiler, (op), (src), (srcw)) #define LABEL() \ sljit_emit_label(compiler) #define JUMP(type) \ @@ -823,7 +831,7 @@ the start pointers when the end of the capturing group has not yet reached. */ static PCRE2_SPTR bracketend(PCRE2_SPTR cc) { -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do cc += GET(cc, 1); while (*cc == OP_ALT); SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); cc += 1 + LINK_SIZE; @@ -833,7 +841,7 @@ return cc; static int no_alternatives(PCRE2_SPTR cc) { int count = 0; -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do { cc += GET(cc, 1); @@ -918,6 +926,8 @@ switch(*cc) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -1050,8 +1060,7 @@ switch(*cc) return cc + 1 + 2 + cc[1]; default: - /* Unsupported opcodes: OP_ASSERT_NA and OP_ASSERTBACK_NA */ - /* SLJIT_UNREACHABLE(); */ + SLJIT_UNREACHABLE(); return NULL; } } @@ -1061,6 +1070,7 @@ static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPT int count; PCRE2_SPTR slot; PCRE2_SPTR assert_back_end = cc - 1; +PCRE2_SPTR assert_na_end = cc - 1; /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ while (cc < ccend) @@ -1087,6 +1097,14 @@ while (cc < ccend) cc += 1 + IMM2_SIZE; break; + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: + slot = bracketend(cc); + if (slot > assert_na_end) + assert_na_end = slot; + cc += 1 + LINK_SIZE; + break; + case OP_CBRAPOS: case OP_SCBRAPOS: common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; @@ -1154,6 +1172,9 @@ while (cc < ccend) case OP_COMMIT_ARG: case OP_PRUNE_ARG: + if (cc < assert_na_end) + return FALSE; + /* Fall through */ case OP_MARK: if (common->mark_ptr == 0) { @@ -1172,6 +1193,8 @@ while (cc < ccend) case OP_SKIP: if (cc < assert_back_end) common->has_skip_in_assert_back = TRUE; + if (cc < assert_na_end) + return FALSE; cc += 1; break; @@ -1180,9 +1203,19 @@ while (cc < ccend) common->has_skip_arg = TRUE; if (cc < assert_back_end) common->has_skip_in_assert_back = TRUE; + if (cc < assert_na_end) + return FALSE; cc += 1 + 2 + cc[1]; break; + case OP_PRUNE: + case OP_COMMIT: + case OP_ASSERT_ACCEPT: + if (cc < assert_na_end) + return FALSE; + cc++; + break; + default: cc = next_opcode(common, cc); if (cc == NULL) @@ -1193,183 +1226,355 @@ while (cc < ccend) return TRUE; } -static BOOL is_accelerated_repeat(PCRE2_SPTR cc) +#define EARLY_FAIL_ENHANCE_MAX (1 + 1) + +/* +start: + 0 - skip / early fail allowed + 1 - only early fail with range allowed + >1 - (start - 1) early fail is processed + +return: current number of iterators enhanced with fast fail +*/ +static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth, int start) { -switch(*cc) - { - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI); +PCRE2_SPTR next_alt; +PCRE2_SPTR end; +PCRE2_SPTR accelerated_start; +int result = 0; +int count; +BOOL fast_forward_allowed = TRUE; - case OP_STAR: - case OP_MINSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_POSSTAR: - case OP_POSPLUS: +SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA); +SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0); +SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX); - case OP_STARI: - case OP_MINSTARI: - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSSTARI: - case OP_POSPLUSI: +do + { + count = start; + next_alt = cc + GET(cc, 1); + cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0); - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTPOSSTAR: - case OP_NOTPOSPLUS: + while (TRUE) + { + accelerated_start = NULL; - case OP_NOTSTARI: - case OP_NOTMINSTARI: - case OP_NOTPLUSI: - case OP_NOTMINPLUSI: - case OP_NOTPOSSTARI: - case OP_NOTPOSPLUSI: - return TRUE; + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + fast_forward_allowed = FALSE; + cc++; + continue; - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_XCLASS: - cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(PCRE2_UCHAR))); -#else - cc += (1 + (32 / sizeof(PCRE2_UCHAR))); + case OP_ANYNL: + case OP_EXTUNI: + fast_forward_allowed = FALSE; + if (count == 0) + count = 1; + cc++; + continue; + + case OP_NOTPROP: + case OP_PROP: + fast_forward_allowed = FALSE; + cc += 1 + 2; + continue; + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + fast_forward_allowed = FALSE; + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif + continue; - switch(*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - return TRUE; - } - break; - } -return FALSE; -} + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + /* The type or prop opcode is skipped in the next iteration. */ + cc += 1; -static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start) -{ -PCRE2_SPTR cc = common->start; -PCRE2_SPTR end; + if (cc[0] != OP_ANYNL && cc[0] != OP_EXTUNI) + { + accelerated_start = cc - 1; + break; + } -/* Skip not repeated brackets. */ -while (TRUE) - { - switch(*cc) - { - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - /* Zero width assertions. */ - cc++; - continue; - } + if (count == 0) + count = 1; + fast_forward_allowed = FALSE; + continue; - if (*cc != OP_BRA && *cc != OP_CBRA) - break; + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + cc += IMM2_SIZE; + /* Fall through */ + + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + /* The type or prop opcode is skipped in the next iteration. */ + fast_forward_allowed = FALSE; + if (count == 0) + count = 1; + cc += 1; + continue; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSSTAR: + case OP_POSPLUS: + + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSSTARI: + case OP_POSPLUSI: + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + accelerated_start = cc; + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; - end = cc + GET(cc, 1); - if (*end != OP_KET || PRIVATE_DATA(end) != 0) - return FALSE; - if (*cc == OP_CBRA) - { - if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - return FALSE; - cc += IMM2_SIZE; - } - cc += 1 + LINK_SIZE; - } + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSUPTO: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSUPTOI: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSUPTO: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSUPTOI: + cc += IMM2_SIZE; + /* Fall through */ + + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSQUERY: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + fast_forward_allowed = FALSE; + if (count == 0) + count = 1; + cc += 2; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + continue; -if (is_accelerated_repeat(cc)) - { - common->fast_forward_bc_ptr = cc; - common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; - *private_data_start += sizeof(sljit_sw); - return TRUE; - } -return FALSE; -} + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_XCLASS: + accelerated_start = cc; + cc += ((*cc == OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR)))); +#else + accelerated_start = cc; + cc += (1 + (32 / sizeof(PCRE2_UCHAR))); +#endif -static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth) -{ - PCRE2_SPTR next_alt; + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + cc++; + break; - SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA); + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + cc += 2 * IMM2_SIZE; + /* Fall through */ + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + cc++; + if (count == 0) + count = 1; + /* Fall through */ + default: + accelerated_start = NULL; + fast_forward_allowed = FALSE; + continue; + } + break; - if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - return; + case OP_ONCE: + case OP_BRA: + case OP_CBRA: + end = cc + GET(cc, 1); - next_alt = bracketend(cc) - (1 + LINK_SIZE); - if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0) - return; + if (*end == OP_KET && PRIVATE_DATA(end) == 0) + { + if (*cc == OP_CBRA) + { + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + break; + cc += IMM2_SIZE; + } - do - { - next_alt = cc + GET(cc, 1); + cc += 1 + LINK_SIZE; + continue; + } - cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0); + fast_forward_allowed = FALSE; + if (depth >= 4) + break; - while (TRUE) - { - switch(*cc) + end = bracketend(cc) - (1 + LINK_SIZE); + if (*end != OP_KET || PRIVATE_DATA(end) != 0) + break; + + if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + break; + + count = detect_early_fail(common, cc, private_data_start, depth + 1, count); + if (count < EARLY_FAIL_ENHANCE_MAX) { - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - /* Zero width assertions. */ - cc++; + cc = end + (1 + LINK_SIZE); continue; } break; - } - if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA)) - detect_fast_fail(common, cc, private_data_start, depth - 1); + case OP_KET: + SLJIT_ASSERT(PRIVATE_DATA(cc) == 0); + if (cc >= next_alt) + break; + cc += 1 + LINK_SIZE; + continue; + } - if (is_accelerated_repeat(cc)) + if (accelerated_start != NULL) { - common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; + if (count == 0) + { + count++; - if (common->fast_fail_start_ptr == 0) - common->fast_fail_start_ptr = *private_data_start; + if (fast_forward_allowed && *next_alt == OP_KET) + { + common->fast_forward_bc_ptr = accelerated_start; + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip; + *private_data_start += sizeof(sljit_sw); + } + else + { + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail; - *private_data_start += sizeof(sljit_sw); - common->fast_fail_end_ptr = *private_data_start; + if (common->early_fail_start_ptr == 0) + common->early_fail_start_ptr = *private_data_start; - if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) - return; + *private_data_start += sizeof(sljit_sw); + common->early_fail_end_ptr = *private_data_start; + + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return EARLY_FAIL_ENHANCE_MAX; + } + } + else + { + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range; + + if (common->early_fail_start_ptr == 0) + common->early_fail_start_ptr = *private_data_start; + + *private_data_start += 2 * sizeof(sljit_sw); + common->early_fail_end_ptr = *private_data_start; + + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return EARLY_FAIL_ENHANCE_MAX; + } + + count++; + + if (count < EARLY_FAIL_ENHANCE_MAX) + continue; } - cc = next_alt; + break; } - while (*cc == OP_ALT); + + if (*cc != OP_ALT && *cc != OP_KET) + result = EARLY_FAIL_ENHANCE_MAX; + else if (result < count) + result = count; + + fast_forward_allowed = FALSE; + cc = next_alt; + } +while (*cc == OP_ALT); + +return result; } static int get_class_iterator_size(PCRE2_SPTR cc) @@ -1586,6 +1791,8 @@ while (cc < ccend) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRAPOS: @@ -1627,57 +1834,57 @@ while (cc < ccend) case OP_BRAZERO: case OP_BRAMINZERO: case OP_BRAPOSZERO: - repeat_check = FALSE; size = 1; + repeat_check = FALSE; break; CASE_ITERATOR_PRIVATE_DATA_1 - space = 1; size = -2; + space = 1; break; CASE_ITERATOR_PRIVATE_DATA_2A - space = 2; size = -2; + space = 2; break; CASE_ITERATOR_PRIVATE_DATA_2B - space = 2; size = -(2 + IMM2_SIZE); + space = 2; break; CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - space = 1; size = 1; + space = 1; break; CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + size = 1; if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) space = 2; - size = 1; break; case OP_TYPEUPTO: + size = 1 + IMM2_SIZE; if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) space = 2; - size = 1 + IMM2_SIZE; break; case OP_TYPEMINUPTO: - space = 2; size = 1 + IMM2_SIZE; + space = 2; break; case OP_CLASS: case OP_NCLASS: - space = get_class_iterator_size(cc + size); size = 1 + 32 / sizeof(PCRE2_UCHAR); + space = get_class_iterator_size(cc + size); break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - space = get_class_iterator_size(cc + size); size = GET(cc, 1); + space = get_class_iterator_size(cc + size); break; #endif @@ -2163,6 +2370,8 @@ while (cc < ccend) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRAPOS: @@ -2487,6 +2696,8 @@ while (cc < ccend) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRAPOS: @@ -2660,8 +2871,8 @@ while (cc < ccend) } if (common->control_head_ptr != 0 && !control_head_found) { - shared_srcw[0] = common->control_head_ptr; - shared_count = 1; + private_srcw[0] = common->control_head_ptr; + private_count = 1; control_head_found = TRUE; } cc += 1 + 2 + cc[1]; @@ -2671,8 +2882,8 @@ while (cc < ccend) SLJIT_ASSERT(common->control_head_ptr != 0); if (!control_head_found) { - shared_srcw[0] = common->control_head_ptr; - shared_count = 1; + private_srcw[0] = common->control_head_ptr; + private_count = 1; control_head_found = TRUE; } cc++; @@ -2756,7 +2967,7 @@ PCRE2_SPTR end = bracketend(cc); BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; /* Assert captures then. */ -if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) +if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) current_offset = NULL; /* Conditional block does not. */ if (*cc == OP_COND || *cc == OP_SCOND) @@ -2768,7 +2979,7 @@ if (has_alternatives) while (cc < end) { - if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) + if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) cc = set_then_offsets(common, cc, current_offset); else { @@ -2938,16 +3149,54 @@ else } } -static SLJIT_INLINE void reset_fast_fail(compiler_common *common) +static SLJIT_INLINE void reset_early_fail(compiler_common *common) { DEFINE_COMPILER; +sljit_u32 size = (sljit_u32)(common->early_fail_end_ptr - common->early_fail_start_ptr); +sljit_u32 uncleared_size; +sljit_s32 src = SLJIT_IMM; sljit_s32 i; +struct sljit_label *loop; + +SLJIT_ASSERT(common->early_fail_start_ptr < common->early_fail_end_ptr); + +if (size == sizeof(sljit_sw)) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->early_fail_start_ptr, SLJIT_IMM, 0); + return; + } + +if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER)) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); + src = TMP3; + } + +if (size <= 6 * sizeof(sljit_sw)) + { + for (i = common->early_fail_start_ptr; i < common->early_fail_end_ptr; i += sizeof(sljit_sw)) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, src, 0); + return; + } -SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr); +GET_LOCAL_BASE(TMP1, 0, common->early_fail_start_ptr); -OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw)) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0); +uncleared_size = ((size / sizeof(sljit_sw)) % 3) * sizeof(sljit_sw); + +OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, size - uncleared_size); + +loop = LABEL(); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -2 * (sljit_sw)sizeof(sljit_sw), src, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -1 * (sljit_sw)sizeof(sljit_sw), src, 0); +CMPTO(SLJIT_LESS, TMP1, 0, TMP2, 0, loop); + +if (uncleared_size >= sizeof(sljit_sw)) + OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0); + +if (uncleared_size >= 2 * sizeof(sljit_sw)) + OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), sizeof(sljit_sw), src, 0); } static SLJIT_INLINE void do_reset_match(compiler_common *common, int length) @@ -3193,16 +3442,19 @@ static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR unsigned int c; #ifdef SUPPORT_UNICODE -if (common->utf) +if (common->utf || common->ucp) { - GETCHAR(c, cc); - if (c > 127) + if (common->utf) { - return c != UCD_OTHERCASE(c); + GETCHAR(c, cc); } -#if PCRE2_CODE_UNIT_WIDTH != 8 + else + c = *cc; + + if (c > 127) + return c != UCD_OTHERCASE(c); + return common->fcc[c] != c; -#endif } else #endif @@ -3214,10 +3466,8 @@ static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigne { /* Returns with the othercase. */ #ifdef SUPPORT_UNICODE -if (common->utf && c > 127) - { +if ((common->utf || common->ucp) && c > 127) return UCD_OTHERCASE(c); - } #endif return TABLE_GET(c, common->fcc, c); } @@ -3231,15 +3481,19 @@ int n; #endif #ifdef SUPPORT_UNICODE -if (common->utf) +if (common->utf || common->ucp) { - GETCHAR(c, cc); + if (common->utf) + { + GETCHAR(c, cc); + } + else + c = *cc; + if (c <= 127) oc = common->fcc[c]; else - { oc = UCD_OTHERCASE(c); - } } else { @@ -4083,7 +4337,7 @@ jump = JUMP(SLJIT_NOT_ZERO); /* Two byte sequence. */ OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3000); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); @@ -4096,7 +4350,7 @@ jump = JUMP(SLJIT_NOT_ZERO); /* Three byte sequence. */ OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0000); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Four byte sequence. */ JUMPHERE(jump); @@ -4106,7 +4360,7 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfreadtype8(compiler_common *common) @@ -4131,18 +4385,18 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(compare); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* We only have types for characters less than 256. */ JUMPHERE(jump); OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfreadchar_invalid(compiler_common *common) @@ -4182,7 +4436,7 @@ OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); jump = JUMP(SLJIT_NOT_ZERO); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump); @@ -4225,7 +4479,7 @@ if (has_cmov) } else exit_invalid[4] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump); @@ -4254,7 +4508,7 @@ else exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(buffer_end_close); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); @@ -4271,7 +4525,7 @@ exit_invalid[8] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); jump = JUMP(SLJIT_NOT_ZERO); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Three-byte sequence. */ JUMPHERE(jump); @@ -4301,7 +4555,7 @@ for (i = 0; i < 11; i++) sljit_set_label(exit_invalid[i], exit_invalid_label); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfreadnewline_invalid(compiler_common *common) @@ -4324,7 +4578,14 @@ if (common->nltype != NLTYPE_ANY) /* All newlines are ascii, just skip intermediate octets. */ jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); loop = LABEL(); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)) == SLJIT_SUCCESS) + sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + else + { + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0); CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -4332,7 +4593,7 @@ if (common->nltype != NLTYPE_ANY) JUMPHERE(jump[0]); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); - sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); return; } @@ -4363,14 +4624,14 @@ JUMPHERE(jump[0]); JUMPHERE(jump[4]); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Two byte long newline: 0x85. */ JUMPHERE(jump[1]); CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x85, skip_start); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x85); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Three byte long newlines: 0x2028 and 0x2029. */ JUMPHERE(jump[2]); @@ -4385,7 +4646,7 @@ CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40, skip_start); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0x2000); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfmoveback_invalid(compiler_common *common) @@ -4414,7 +4675,7 @@ jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x20); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Three-byte sequence. */ JUMPHERE(jump); @@ -4427,7 +4688,7 @@ jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x10); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Four-byte sequence. */ JUMPHERE(jump); @@ -4440,7 +4701,7 @@ exit_invalid[3] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x05); exit_ok_label = LABEL(); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); /* Two-byte sequence. */ JUMPHERE(buffer_start_close); @@ -4470,7 +4731,7 @@ sljit_set_label(exit_invalid[5], exit_invalid_label); sljit_set_label(exit_invalid[6], exit_invalid_label); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(exit_invalid[4]); /* -2 + 4 = 2 */ @@ -4481,7 +4742,7 @@ for (i = 0; i < 4; i++) sljit_set_label(exit_invalid[i], exit_invalid_label); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(4)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfpeakcharback(compiler_common *common) @@ -4518,7 +4779,7 @@ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfpeakcharback_invalid(compiler_common *common) @@ -4548,7 +4809,7 @@ two_byte_entry = LABEL(); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); /* If TMP1 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump[1]); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80); @@ -4586,7 +4847,7 @@ if (has_cmov) else exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump[1]); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0 - 0x80); @@ -4612,7 +4873,7 @@ else exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump[0]); OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -4635,7 +4896,7 @@ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0); CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x10, three_byte_entry); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump[0]); exit_invalid[7] = CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0); @@ -4650,7 +4911,7 @@ for (i = 0; i < 8; i++) sljit_set_label(exit_invalid[i], exit_invalid_label); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ @@ -4680,13 +4941,13 @@ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000); exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(exit_invalid[0]); JUMPHERE(exit_invalid[1]); JUMPHERE(exit_invalid[2]); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfreadnewline_invalid(compiler_common *common) @@ -4713,12 +4974,12 @@ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(exit_invalid[0]); JUMPHERE(exit_invalid[1]); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfmoveback_invalid(compiler_common *common) @@ -4738,7 +4999,7 @@ exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(exit_invalid[0]); JUMPHERE(exit_invalid[1]); @@ -4746,7 +5007,7 @@ JUMPHERE(exit_invalid[2]); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_utfpeakcharback_invalid(compiler_common *common) @@ -4771,14 +5032,14 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); JUMPHERE(jump); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(exit_invalid[0]); JUMPHERE(exit_invalid[1]); JUMPHERE(exit_invalid[2]); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } #endif /* PCRE2_CODE_UNIT_WIDTH == 16 */ @@ -4824,7 +5085,7 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_getucdtype(compiler_common *common) @@ -4871,7 +5132,7 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } #endif /* SUPPORT_UNICODE */ @@ -5159,6 +5420,8 @@ while (TRUE) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: cc = bracketend(cc); continue; @@ -5458,7 +5721,12 @@ while (TRUE) #endif { chr = *cc; - othercase[0] = TABLE_GET(chr, common->fcc, chr); +#ifdef SUPPORT_UNICODE + if (common->ucp && chr > 127) + othercase[0] = UCD_OTHERCASE(chr); + else +#endif + othercase[0] = TABLE_GET(chr, common->fcc, chr); } } else @@ -5887,8 +6155,8 @@ oc = first_char; if ((common->re->flags & PCRE2_FIRSTCASELESS) != 0) { oc = TABLE_GET(first_char, common->fcc, first_char); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (first_char > 127 && common->utf) +#if defined SUPPORT_UNICODE + if (first_char > 127 && (common->utf || common->ucp)) oc = UCD_OTHERCASE(first_char); #endif } @@ -5900,9 +6168,9 @@ static SLJIT_INLINE void fast_forward_newline(compiler_common *common) { DEFINE_COMPILER; struct sljit_label *loop; -struct sljit_jump *lastchar; +struct sljit_jump *lastchar = NULL; struct sljit_jump *firstchar; -struct sljit_jump *quit; +struct sljit_jump *quit = NULL; struct sljit_jump *foundcr = NULL; struct sljit_jump *notfoundnl; jump_list *newline = NULL; @@ -5915,39 +6183,71 @@ if (common->match_end_ptr != 0) if (common->nltype == NLTYPE_FIXED && common->newline > 255) { - lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - if (HAS_VIRTUAL_REGISTERS) +#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD + if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && common->mode == PCRE2_JIT_COMPLETE) { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + } + firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + + fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); } else +#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */ { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - } - firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + } + firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL); #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); #endif - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - loop = LABEL(); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); + loop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); + CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); + + JUMPHERE(quit); + JUMPHERE(lastchar); + } - JUMPHERE(quit); JUMPHERE(firstchar); - JUMPHERE(lastchar); if (common->match_end_ptr != 0) OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); @@ -5964,22 +6264,59 @@ else /* Example: match /^/ to \r\n from offset 1. */ firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); -move_back(common, NULL, FALSE); + +if (common->nltype == NLTYPE_ANY) + move_back(common, NULL, FALSE); +else + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); loop = LABEL(); common->ff_newline_shortcut = loop; -read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE); -lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) - foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); -check_newlinechar(common, common->nltype, &newline, FALSE); -set_jumps(newline, loop); +#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD +if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common->nltype == NLTYPE_ANYCRLF)) + { + if (common->nltype == NLTYPE_ANYCRLF) + { + fast_forward_char_simd(common, CHAR_CR, CHAR_LF, 0); + if (common->mode != PCRE2_JIT_COMPLETE) + lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + } + else + { + fast_forward_char_simd(common, common->newline, common->newline, 0); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + if (common->mode != PCRE2_JIT_COMPLETE) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); + CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + } + } + } +else +#endif /* JIT_HAS_FAST_FORWARD_CHAR_SIMD */ + { + read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE); + lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + check_newlinechar(common, common->nltype, &newline, FALSE); + set_jumps(newline, loop); + } if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) { - quit = JUMP(SLJIT_JUMP); - JUMPHERE(foundcr); + if (quit == NULL) + { + quit = JUMP(SLJIT_JUMP); + JUMPHERE(foundcr); + } + notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); @@ -5991,7 +6328,9 @@ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) JUMPHERE(notfoundnl); JUMPHERE(quit); } -JUMPHERE(lastchar); + +if (lastchar) + JUMPHERE(lastchar); JUMPHERE(firstchar); if (common->match_end_ptr != 0) @@ -6072,67 +6411,80 @@ if (common->match_end_ptr != 0) OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); } -static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar) +static SLJIT_INLINE jump_list *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar) { DEFINE_COMPILER; struct sljit_label *loop; struct sljit_jump *toolong; -struct sljit_jump *alreadyfound; +struct sljit_jump *already_found; struct sljit_jump *found; -struct sljit_jump *foundoc = NULL; -struct sljit_jump *notfound; +struct sljit_jump *found_oc = NULL; +jump_list *not_found = NULL; sljit_u32 oc, bit; SLJIT_ASSERT(common->req_char_ptr != 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); -OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_CU_MAX); -toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0); -alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(REQ_CU_MAX) * 100); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); +toolong = CMP(SLJIT_LESS, TMP2, 0, STR_END, 0); +already_found = CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0); if (has_firstchar) OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); else OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); -loop = LABEL(); -notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0); - -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); oc = req_char; if (caseless) { oc = TABLE_GET(req_char, common->fcc, req_char); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (req_char > 127 && common->utf) +#if defined SUPPORT_UNICODE + if (req_char > 127 && (common->utf || common->ucp)) oc = UCD_OTHERCASE(req_char); #endif } -if (req_char == oc) - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); + +#ifdef JIT_HAS_FAST_REQUESTED_CHAR_SIMD +if (JIT_HAS_FAST_REQUESTED_CHAR_SIMD) + { + not_found = fast_requested_char_simd(common, req_char, oc); + } else +#endif { - bit = req_char ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); - } + loop = LABEL(); + add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); + + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); + + if (req_char == oc) + found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); else { - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); - foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc); + bit = req_char ^ oc; + if (is_powerof2(bit)) + { + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); + found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); + } + else + { + found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); + found_oc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc); + } } + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPTO(SLJIT_JUMP, loop); + + JUMPHERE(found); + if (found_oc) + JUMPHERE(found_oc); } -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); -JUMPTO(SLJIT_JUMP, loop); -JUMPHERE(found); -if (foundoc) - JUMPHERE(foundoc); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0); -JUMPHERE(alreadyfound); + +JUMPHERE(already_found); JUMPHERE(toolong); -return notfound; +return not_found; } static void do_revertframes(compiler_common *common) @@ -6170,7 +6522,7 @@ JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0); /* End of reverting values. */ -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump); OP1(SLJIT_NEG, TMP2, 0, TMP2, 0); @@ -6219,9 +6571,11 @@ if (common->invalid_utf) if (common->mode != PCRE2_JIT_COMPLETE) { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); move_back(common, NULL, TRUE); check_start_used_ptr(common); + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); } } @@ -6240,7 +6594,7 @@ else /* Testing char type. */ #ifdef SUPPORT_UNICODE -if (common->use_ucp) +if (common->ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); @@ -6286,7 +6640,7 @@ peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2); valid_utf = LABEL(); -if (common->use_ucp) +if (common->ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); @@ -6326,7 +6680,7 @@ set_jumps(skipread_list, LABEL()); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0); -sljit_emit_fast_return(compiler, TMP1, 0); +OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); #ifdef SUPPORT_UNICODE if (common->invalid_utf) @@ -6338,12 +6692,12 @@ if (common->invalid_utf) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1); - sljit_emit_fast_return(compiler, TMP1, 0); + OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); set_jumps(invalid_utf2, LABEL()); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); - sljit_emit_fast_return(compiler, TMP1, 0); + OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } #endif /* SUPPORT_UNICODE */ } @@ -6633,7 +6987,7 @@ if (common->utf) #endif #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void check_hspace(compiler_common *common) @@ -6672,7 +7026,7 @@ if (common->utf) #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void check_vspace(compiler_common *common) @@ -6700,7 +7054,7 @@ if (common->utf) #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */ OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); } static void do_casefulcmp(compiler_common *common) @@ -6780,7 +7134,7 @@ if (char1_reg == STR_END) OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0); } -sljit_emit_fast_return(compiler, TMP1, 0); +OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } static void do_caselesscmp(compiler_common *common) @@ -6878,7 +7232,7 @@ if (char2_reg == STACK_TOP) } OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); -sljit_emit_fast_return(compiler, TMP1, 0); +OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, @@ -7189,7 +7543,13 @@ cc = ccbegin; if ((cc[-1] & XCL_NOT) != 0) read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); else + { +#ifdef SUPPORT_UNICODE + read_char(common, min, max, (needstype || needsscript) ? backtracks : NULL, 0); +#else /* !SUPPORT_UNICODE */ read_char(common, min, max, NULL, 0); +#endif /* SUPPORT_UNICODE */ + } if ((cc[-1] & XCL_HASPROP) == 0) { @@ -7275,16 +7635,11 @@ if (needstype || needsscript) /* Before anything else, we deal with scripts. */ if (needsscript) { -// PH hacking - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0); + OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); - // OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); ccbegin = cc; @@ -7319,41 +7674,52 @@ if (needstype || needsscript) } cc = ccbegin; - } - if (needschar) - OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + if (needstype) + { + /* TMP2 has already been shifted by 2 */ + if (!needschar) + { + OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + } + else + { + OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - if (needstype) + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + typereg = RETURN_ADDR; + } + } + else if (needschar) + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + } + else if (needstype) { + OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); + if (!needschar) { -// PH hacking - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP1, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0); - -// OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); } else { -// PH hacking - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); - - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); typereg = RETURN_ADDR; } } + else if (needschar) + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); } #endif /* SUPPORT_UNICODE */ @@ -8728,16 +9094,13 @@ if (common->utf && *cc == OP_REFI) CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); -// PH hacking OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); - + OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records)); @@ -9597,7 +9960,8 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) } else { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + SLJIT_ASSERT(extrasize == 3); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); } } @@ -9929,7 +10293,7 @@ if (opcode == OP_CBRA || opcode == OP_SCBRA) BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; matchingpath += IMM2_SIZE; } -else if (opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) +else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { /* Other brackets simply allocate the next entry. */ private_data_ptr = PRIVATE_DATA(ccbegin); @@ -10114,7 +10478,7 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } } -else if (opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) +else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { /* Saving the previous value. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); @@ -10240,6 +10604,9 @@ compile_matchingpath(common, matchingpath, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; +if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + if (opcode == OP_ONCE) match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); @@ -10840,8 +11207,8 @@ backtrack_common *backtrack; PCRE2_UCHAR opcode; PCRE2_UCHAR type; sljit_u32 max = 0, exact; -BOOL fast_fail; -sljit_s32 fast_str_ptr; +sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1); +sljit_s32 early_fail_type; BOOL charpos_enabled; PCRE2_UCHAR charpos_char; unsigned int charpos_othercasebit; @@ -10855,21 +11222,27 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); int tmp_base, tmp_offset; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +BOOL use_tmp; +#endif PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL); -fast_str_ptr = PRIVATE_DATA(cc + 1); -fast_fail = TRUE; +early_fail_type = (early_fail_ptr & 0x7); +early_fail_ptr >>= 3; -SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr); +/* During recursion, these optimizations are disabled. */ +if (common->early_fail_start_ptr == 0) + { + early_fail_ptr = 0; + early_fail_type = type_skip; + } -if (cc == common->fast_forward_bc_ptr) - fast_fail = FALSE; -else if (common->fast_fail_start_ptr == 0) - fast_str_ptr = 0; +SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0 + || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr)); -SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0 - || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr)); +if (early_fail_type == type_fail) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); @@ -10884,13 +11257,11 @@ else tmp_offset = POSSESSIVE0; } -if (fast_fail && fast_str_ptr != 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr)); - /* Handle fixed part first. */ if (exact > 1) { - SLJIT_ASSERT(fast_str_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); + if (common->mode == PCRE2_JIT_COMPLETE #ifdef SUPPORT_UNICODE && !common->utf @@ -10915,18 +11286,31 @@ if (exact > 1) } } else if (exact == 1) + { compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + if (early_fail_type == type_fail_range) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0); + OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0); + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); + + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw), STR_PTR, 0); + } + } + switch(opcode) { case OP_STAR: case OP_UPTO: - SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR); + SLJIT_ASSERT(early_fail_ptr == 0 || opcode == OP_STAR); if (type == OP_ANYNL || type == OP_EXTUNI) { SLJIT_ASSERT(private_data_ptr == 0); - SLJIT_ASSERT(fast_str_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); @@ -10945,7 +11329,7 @@ switch(opcode) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); } - /* We cannot use TMP3 because of this allocate_stack. */ + /* We cannot use TMP3 because of allocate_stack. */ allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, label); @@ -10971,8 +11355,8 @@ switch(opcode) OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); process_partial_match(common); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; } @@ -11002,8 +11386,8 @@ switch(opcode) OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; } @@ -11030,7 +11414,7 @@ switch(opcode) if (charpos_enabled) { charpos_char = end[1]; - /* Consumpe the OP_CHAR opcode. */ + /* Consume the OP_CHAR opcode. */ end += 2; #if PCRE2_CODE_UNIT_WIDTH == 8 SLJIT_ASSERT((charpos_othercasebit >> 8) == 0); @@ -11062,8 +11446,8 @@ switch(opcode) add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); } compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); JUMPHERE(jump); detect_partial_match(common, &backtrack->topbacktracks); @@ -11076,6 +11460,7 @@ switch(opcode) allocate_stack(common, 2); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + if (opcode == OP_UPTO) { OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); @@ -11085,53 +11470,55 @@ switch(opcode) /* Search the last instance of charpos_char. */ label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); detect_partial_match(common, &no_match); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); if (charpos_othercasebit != 0) OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + if (opcode == OP_STAR) { CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); } else { jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); JUMPHERE(jump); - } - - if (opcode == OP_UPTO) - { OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } - else - JUMPTO(SLJIT_JUMP, label); set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_ADD, STR_PTR, 0, base, offset0, SLJIT_IMM, IN_UCHARS(1)); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); } -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - else if (common->utf) + else { if (private_data_ptr == 0) allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR); + SLJIT_ASSERT(!use_tmp || tmp_base == TMP3); + if (common->utf) + OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0); +#endif if (opcode == OP_UPTO) OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); detect_partial_match(common, &no_match); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0); +#endif if (opcode == OP_UPTO) { @@ -11142,39 +11529,29 @@ switch(opcode) detect_partial_match_to(common, label); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - } + set_jumps(no_char1_match, LABEL()); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + { + set_jumps(no_match, LABEL()); + if (use_tmp) + { + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + OP1(SLJIT_MOV, base, offset0, TMP3, 0); + } + else + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + } + else #endif - else - { - if (private_data_ptr == 0) - allocate_stack(common, 2); - - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - - detect_partial_match(common, &no_match); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - if (opcode == OP_UPTO) { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); } - detect_partial_match_to(common, label); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - - set_jumps(no_char1_match, LABEL()); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); } BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); @@ -11185,12 +11562,12 @@ switch(opcode) allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; case OP_MINUPTO: - SLJIT_ASSERT(fast_str_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 2); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); @@ -11200,7 +11577,7 @@ switch(opcode) case OP_QUERY: case OP_MINQUERY: - SLJIT_ASSERT(fast_str_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); @@ -11221,8 +11598,8 @@ switch(opcode) { OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); process_partial_match(common); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0); break; } @@ -11238,16 +11615,17 @@ switch(opcode) set_jumps(no_match, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); - if (fast_str_ptr != 0) + if (early_fail_ptr != 0) { - if (tmp_base == TMP3) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, TMP3, 0); + if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, TMP3, 0); else - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); } break; } #endif + detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); @@ -11257,12 +11635,12 @@ switch(opcode) set_jumps(no_char1_match, LABEL()); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_match, LABEL()); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; case OP_POSUPTO: - SLJIT_ASSERT(fast_str_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (common->utf) { @@ -11298,9 +11676,6 @@ switch(opcode) process_partial_match(common); JUMPHERE(jump); } - - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); break; } @@ -11320,7 +11695,7 @@ switch(opcode) break; case OP_POSQUERY: - SLJIT_ASSERT(fast_str_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); compile_char1_matchingpath(common, type, cc, &no_match, TRUE); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); @@ -11695,6 +12070,8 @@ while (cc < ccend) count_match(common); break; + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -12232,6 +12609,7 @@ else if (has_alternatives) SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label); sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL()); + sljit_emit_op0(compiler, SLJIT_ENDBR); } else next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); @@ -12298,6 +12676,9 @@ if (has_alternatives) if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; + if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + if (opcode == OP_SCRIPT_RUN) match_script_run_common(common, private_data_ptr, current); } @@ -12379,7 +12760,10 @@ if (has_alternatives) } } else + { sljit_set_put_label(put_label, LABEL()); + sljit_emit_op0(compiler, SLJIT_ENDBR); + } } COMPILE_BACKTRACKINGPATH(current->top); @@ -12427,7 +12811,7 @@ if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); } } -else if (opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) +else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); @@ -12775,6 +13159,8 @@ while (current) compile_assert_backtrackingpath(common, current); break; + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -12872,7 +13258,7 @@ jump_list *match = NULL; struct sljit_jump *next_alt = NULL; struct sljit_jump *accept_exit = NULL; struct sljit_label *quit; -struct sljit_put_label *put_label; +struct sljit_put_label *put_label = NULL; /* Recurse captures then. */ common->then_trap = NULL; @@ -12969,6 +13355,7 @@ while (1) { sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0); sljit_set_put_label(put_label, LABEL()); + sljit_emit_op0(compiler, SLJIT_ENDBR); } else next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); @@ -12977,7 +13364,10 @@ while (1) free_stack(common, has_accept ? 2 : 1); } else if (alt_max > 3) + { sljit_set_put_label(put_label, LABEL()); + sljit_emit_op0(compiler, SLJIT_ENDBR); + } else { JUMPHERE(next_alt); @@ -13011,7 +13401,7 @@ copy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1)); free_stack(common, private_data_size + local_size); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); -sljit_emit_fast_return(compiler, TMP2, 0); +OP_SRC(SLJIT_FAST_RETURN, TMP2, 0); if (common->quit != NULL) { @@ -13036,7 +13426,7 @@ if (has_accept) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1)); free_stack(common, private_data_size + local_size); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); - sljit_emit_fast_return(compiler, TMP2, 0); + OP_SRC(SLJIT_FAST_RETURN, TMP2, 0); } if (common->accept != NULL) @@ -13060,7 +13450,7 @@ copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, priva OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), STACK(local_size - 1)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1); -sljit_emit_fast_return(compiler, TMP2, 0); +OP_SRC(SLJIT_FAST_RETURN, TMP2, 0); } #undef COMPILE_BACKTRACKINGPATH @@ -13092,9 +13482,9 @@ struct sljit_label *reset_match_label; struct sljit_label *quit_label; struct sljit_jump *jump; struct sljit_jump *minlength_check_failed = NULL; -struct sljit_jump *reqbyte_notfound = NULL; struct sljit_jump *empty_match = NULL; struct sljit_jump *end_anchor_failed = NULL; +jump_list *reqcu_not_found = NULL; SLJIT_ASSERT(tables); @@ -13122,8 +13512,8 @@ common->read_only_data_head = NULL; common->fcc = tables + fcc_offset; common->lcc = (sljit_sw)(tables + lcc_offset); common->mode = mode; -common->might_be_empty = re->minlength == 0; -common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY) != 0; +common->might_be_empty = (re->minlength == 0) || (re->flags & PCRE2_MATCH_EMPTY); +common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY); common->nltype = NLTYPE_FIXED; switch(re->newline_convention) { @@ -13160,7 +13550,7 @@ common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0; #ifdef SUPPORT_UNICODE /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ common->utf = (re->overall_options & PCRE2_UTF) != 0; -common->use_ucp = (re->overall_options & PCRE2_UCP) != 0; +common->ucp = (re->overall_options & PCRE2_UCP) != 0; if (common->utf) { if (common->nltype == NLTYPE_ANY) @@ -13272,13 +13662,10 @@ memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); set_private_data_ptrs(common, &private_data_size, ccend); -if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) - { - if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back) - detect_fast_fail(common, common->start, &private_data_size, 4); - } +if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back) + detect_early_fail(common, common->start, &private_data_size, 0, 0); -SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr); +SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr); if (private_data_size > SLJIT_MAX_LOCAL_SIZE) { @@ -13294,7 +13681,7 @@ if (common->has_then) set_then_offsets(common, common->start, NULL); } -compiler = sljit_create_compiler(allocator_data); +compiler = sljit_create_compiler(allocator_data, NULL); if (!compiler) { SLJIT_FREE(common->optimized_cbracket, allocator_data); @@ -13322,8 +13709,8 @@ OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_sta OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0); -if (common->fast_fail_start_ptr < common->fast_fail_end_ptr) - reset_fast_fail(common); +if (common->early_fail_start_ptr < common->early_fail_end_ptr) + reset_early_fail(common); if (mode == PCRE2_JIT_PARTIAL_SOFT) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); @@ -13360,7 +13747,7 @@ if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PC minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0); } if (common->req_char_ptr != 0) - reqbyte_notfound = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0); + reqcu_not_found = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0); /* Store the current STR_PTR in OVECTOR(0). */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); @@ -13369,7 +13756,7 @@ OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH); if (common->capture_last_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0); if (common->fast_forward_bc_ptr != NULL) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3, STR_PTR, 0); if (common->start_ptr != OVECTOR(0)) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0); @@ -13416,6 +13803,8 @@ if (common->abort != NULL) set_jumps(common->abort, common->abort_label); if (minlength_check_failed != NULL) SET_LABEL(minlength_check_failed, common->abort_label); + +sljit_emit_op0(compiler, SLJIT_SKIP_FRAMES_BEFORE_RETURN); sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); if (common->failed_match != NULL) @@ -13468,7 +13857,7 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0) } OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), - (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr); + (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3) : common->start_ptr); if ((re->overall_options & PCRE2_ANCHORED) == 0) { @@ -13493,8 +13882,8 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) } /* No more remaining characters. */ -if (reqbyte_notfound != NULL) - JUMPHERE(reqbyte_notfound); +if (reqcu_not_found != NULL) + set_jumps(reqcu_not_found, LABEL()); if (mode == PCRE2_JIT_PARTIAL_SOFT) CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel); @@ -13519,8 +13908,8 @@ if (common->might_be_empty) } common->fast_forward_bc_ptr = NULL; -common->fast_fail_start_ptr = 0; -common->fast_fail_end_ptr = 0; +common->early_fail_start_ptr = 0; +common->early_fail_end_ptr = 0; common->currententry = common->entries; common->local_quit_available = TRUE; quit_label = common->quit_label; @@ -13563,7 +13952,7 @@ OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); -sljit_emit_fast_return(compiler, TMP1, 0); +OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); /* Allocation failed. */ JUMPHERE(jump); @@ -13694,7 +14083,7 @@ else { /* This case is highly unlikely since we just recently freed a lot of memory. Not impossible though. */ - sljit_free_code(executable_func); + sljit_free_code(executable_func, NULL); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } @@ -13742,11 +14131,6 @@ pcre2_jit_compile(pcre2_code *code, uint32_t options) { pcre2_real_code *re = (pcre2_real_code *)code; -#ifdef SUPPORT_JIT -executable_functions *functions = (executable_functions *)re->executable_jit; -static int executable_allocator_is_working = 0; -#endif - if (code == NULL) return PCRE2_ERROR_NULL; @@ -13779,6 +14163,11 @@ actions are needed: avoid compiler warnings. */ +#ifdef SUPPORT_JIT +executable_functions *functions = (executable_functions *)re->executable_jit; +static int executable_allocator_is_working = 0; +#endif + if ((options & PCRE2_JIT_INVALID_UTF) != 0) { if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0) @@ -13808,13 +14197,13 @@ if (executable_allocator_is_working == 0) /* Checks whether the executable allocator is working. This check might run multiple times in multi-threaded environments, but the result should not be affected by it. */ - void *ptr = SLJIT_MALLOC_EXEC(32); + void *ptr = SLJIT_MALLOC_EXEC(32, NULL); executable_allocator_is_working = -1; if (ptr != NULL) { - SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr)); + SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL); executable_allocator_is_working = 1; } } diff --git a/thirdparty/pcre2/src/pcre2_jit_misc.c b/thirdparty/pcre2/src/pcre2_jit_misc.c index efdb05580f..ec924e0f9b 100644 --- a/thirdparty/pcre2/src/pcre2_jit_misc.c +++ b/thirdparty/pcre2/src/pcre2_jit_misc.c @@ -89,7 +89,7 @@ int i; for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) { if (functions->executable_funcs[i] != NULL) - sljit_free_code(functions->executable_funcs[i]); + sljit_free_code(functions->executable_funcs[i], NULL); PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data); } @@ -145,6 +145,11 @@ maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext); if (jit_stack == NULL) return NULL; jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl); +if (jit_stack->stack == NULL) + { + jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); + return NULL; + } return jit_stack; #endif diff --git a/thirdparty/pcre2/src/pcre2_jit_neon_inc.h b/thirdparty/pcre2/src/pcre2_jit_neon_inc.h index 55b1f32ac9..150da29eba 100644 --- a/thirdparty/pcre2/src/pcre2_jit_neon_inc.h +++ b/thirdparty/pcre2/src/pcre2_jit_neon_inc.h @@ -87,6 +87,10 @@ static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_u { quad_word qw; int_char ic; + +SLJIT_UNUSED_ARG(offs1); +SLJIT_UNUSED_ARG(offs2); + ic.x = chars; #if defined(FFCS) @@ -117,11 +121,16 @@ PCRE2_UCHAR char2a = ic.c.c3; # ifdef FFCPS_CHAR1A2A cmp1a = VDUPQ(char1a); cmp2a = VDUPQ(char2a); +cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ +cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ # else PCRE2_UCHAR char1b = ic.c.c2; PCRE2_UCHAR char2b = ic.c.c4; if (char1a == char1b) + { cmp1a = VDUPQ(char1a); + cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ + } else { sljit_u32 bit1 = char1a ^ char1b; @@ -140,7 +149,10 @@ else } if (char2a == char2b) + { cmp2a = VDUPQ(char2a); + cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ + } else { sljit_u32 bit2 = char2a ^ char2b; @@ -208,8 +220,16 @@ if (p1 < str_ptr) else data2 = shift_left_n_lanes(data, offs1 - offs2); -data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); -data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); +if (compare1_type == compare_match1) + data = VCEQQ(data, cmp1a); +else + data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); + +if (compare2_type == compare_match1) + data2 = VCEQQ(data2, cmp2a); +else + data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); + vect_t eq = VANDQ(data, data2); #endif @@ -275,8 +295,14 @@ while (str_ptr < str_end) data = VCEQQ(data, cmp1a); data2 = VCEQQ(data2, cmp2a); # else - data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); - data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); + if (compare1_type == compare_match1) + data = VCEQQ(data, cmp1a); + else + data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); + if (compare2_type == compare_match1) + data2 = VCEQQ(data2, cmp2a); + else + data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); # endif eq = VANDQ(data, data2); diff --git a/thirdparty/pcre2/src/pcre2_jit_simd_inc.h b/thirdparty/pcre2/src/pcre2_jit_simd_inc.h index f7d56b29f8..5673d338c0 100644 --- a/thirdparty/pcre2/src/pcre2_jit_simd_inc.h +++ b/thirdparty/pcre2/src/pcre2_jit_simd_inc.h @@ -344,6 +344,136 @@ if (common->utf && offset > 0) #endif } +#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) + +static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +jump_list *not_found = NULL; +sse2_compare_type compare_type = sse2_compare_match1; +sljit_u8 instruction[8]; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 data_ind = 0; +sljit_s32 tmp_ind = 1; +sljit_s32 cmp1_ind = 2; +sljit_s32 cmp2_ind = 3; +sljit_u32 bit = 0; +int i; + +if (char1 != char2) + { + bit = char1 ^ char2; + compare_type = sse2_compare_match1i; + + if (!is_powerof2(bit)) + { + bit = 0; + compare_type = sse2_compare_match2; + } + } + +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); +OP1(SLJIT_MOV, TMP2, 0, TMP1, 0); +OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); + +SLJIT_ASSERT(tmp1_reg_ind < 8); + +/* MOVD xmm, r/m32 */ +instruction[0] = 0x66; +instruction[1] = 0x0f; +instruction[2] = 0x6e; +instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + + /* MOVD xmm, r/m32 */ + instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); + +/* PSHUFD xmm1, xmm2/m128, imm8 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0x70; +instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind; +instruction[4] = 0; +sljit_emit_op_custom(compiler, instruction, 5); + +if (char1 != char2) + { + /* PSHUFD xmm1, xmm2/m128, imm8 */ + instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); + +load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +for (i = 0; i < 4; i++) + fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* PMOVMSKB reg, xmm */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Second part (aligned) */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); + +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +for (i = 0; i < 4; i++) + fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* PMOVMSKB reg, xmm */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(quit); + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0); +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); + +OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); +return not_found; +} + #ifndef _WIN64 static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void) diff --git a/thirdparty/pcre2/src/pcre2_maketables.c b/thirdparty/pcre2/src/pcre2_maketables.c index 8c93b4b573..56d2494023 100644 --- a/thirdparty/pcre2/src/pcre2_maketables.c +++ b/thirdparty/pcre2/src/pcre2_maketables.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -41,10 +41,11 @@ POSSIBILITY OF SUCH DAMAGE. /* This module contains the external function pcre2_maketables(), which builds character tables for PCRE2 in the current locale. The file is compiled on its -own as part of the PCRE2 library. However, it is also included in the -compilation of dftables.c, in which case the macro DFTABLES is defined. */ +own as part of the PCRE2 library. It is also included in the compilation of +pcre2_dftables.c as a freestanding program, in which case the macro +PCRE2_DFTABLES is defined. */ -#ifndef DFTABLES +#ifndef PCRE2_DFTABLES /* Compiling the library */ # ifdef HAVE_CONFIG_H # include "config.h" # endif @@ -61,28 +62,29 @@ compilation of dftables.c, in which case the macro DFTABLES is defined. */ a pointer to them. They are build using the ctype functions, and consequently their contents will depend upon the current locale setting. When compiled as part of the library, the store is obtained via a general context malloc, if -supplied, but when DFTABLES is defined (when compiling the dftables auxiliary -program) malloc() is used, and the function has a different name so as not to -clash with the prototype in pcre2.h. +supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables +freestanding auxiliary program) malloc() is used, and the function has a +different name so as not to clash with the prototype in pcre2.h. -Arguments: none when DFTABLES is defined - else a PCRE2 general context or NULL +Arguments: none when PCRE2_DFTABLES is defined + else a PCRE2 general context or NULL Returns: pointer to the contiguous block of data + else NULL if memory allocation failed */ -#ifdef DFTABLES /* Included in freestanding dftables.c program */ +#ifdef PCRE2_DFTABLES /* Included in freestanding pcre2_dftables program */ static const uint8_t *maketables(void) { -uint8_t *yield = (uint8_t *)malloc(tables_length); +uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH); -#else /* Not DFTABLES, compiling the library */ +#else /* Not PCRE2_DFTABLES, that is, compiling the library */ PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION pcre2_maketables(pcre2_general_context *gcontext) { uint8_t *yield = (uint8_t *)((gcontext != NULL)? - gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) : - malloc(tables_length)); -#endif /* DFTABLES */ + gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) : + malloc(TABLES_LENGTH)); +#endif /* PCRE2_DFTABLES */ int i; uint8_t *p; @@ -103,8 +105,8 @@ exclusive ones - in some locales things may be different. Note that the table for "space" includes everything "isspace" gives, including VT in the default locale. This makes it work for the POSIX class [:space:]. -From release 8.34 is is also correct for Perl space, because Perl added VT at -release 5.18. +From PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl +space, because Perl added VT at release 5.18. Note also that it is possible for a character to be alnum or alpha without being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the @@ -114,24 +116,24 @@ test for alnum specially. */ memset(p, 0, cbit_length); for (i = 0; i < 256; i++) { - if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7); - if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7); - if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7); - if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7); - if (i == '_') p[cbit_word + i/8] |= 1u << (i&7); - if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7); - if (isxdigit(i))p[cbit_xdigit + i/8] |= 1u << (i&7); - if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7); - if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7); - if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7); - if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7); + if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7); + if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7); + if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7); + if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7); + if (i == '_') p[cbit_word + i/8] |= 1u << (i&7); + if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7); + if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7); + if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7); + if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7); + if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7); + if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7); } p += cbit_length; /* Finally, the character type table. In this, we used to exclude VT from the white space chars, because Perl didn't recognize it as such for \s and for -comments within regexes. However, Perl changed at release 5.18, so PCRE changed -at release 8.34. */ +comments within regexes. However, Perl changed at release 5.18, so PCRE1 +changed at release 8.34 and it's always been this way for PCRE2. */ for (i = 0; i < 256; i++) { @@ -147,7 +149,7 @@ for (i = 0; i < 256; i++) return yield; } -#ifndef DFTABLES +#ifndef PCRE2_DFTABLES /* Compiling the library */ PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables) { diff --git a/thirdparty/pcre2/src/pcre2_match.c b/thirdparty/pcre2/src/pcre2_match.c index 48e7b9dbb2..e3f78c2ca3 100644 --- a/thirdparty/pcre2/src/pcre2_match.c +++ b/thirdparty/pcre2/src/pcre2_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2015-2019 University of Cambridge + New API code Copyright (c) 2015-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -381,8 +381,12 @@ length = Fovector[offset+1] - Fovector[offset]; if (caseless) { #if defined SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UTF) != 0) + BOOL utf = (mb->poptions & PCRE2_UTF) != 0; + + if (utf || (mb->poptions & PCRE2_UCP) != 0) { + PCRE2_SPTR endptr = p + length; + /* Match characters up to the end of the reference. NOTE: the number of code units matched may differ, because in UTF-8 there are some characters whose upper and lower case codes have different numbers of bytes. For @@ -390,16 +394,25 @@ if (caseless) bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a sequence of two of the latter. It is important, therefore, to check the length along the reference, not along the subject (earlier code did this - wrong). */ + wrong). UCP without uses Unicode properties but without UTF encoding. */ - PCRE2_SPTR endptr = p + length; while (p < endptr) { uint32_t c, d; const ucd_record *ur; if (eptr >= mb->end_subject) return 1; /* Partial match */ - GETCHARINC(c, eptr); - GETCHARINC(d, p); + + if (utf) + { + GETCHARINC(c, eptr); + GETCHARINC(d, p); + } + else + { + c = *eptr++; + d = *p++; + } + ur = GET_UCD(d); if (c != d && c != (uint32_t)((int)d + ur->other_case)) { @@ -415,7 +428,7 @@ if (caseless) else #endif - /* Not in UTF mode */ + /* Not in UTF or UCP mode */ { for (; length > 0; length--) { @@ -432,7 +445,8 @@ if (caseless) } /* In the caseful case, we can just compare the code units, whether or not we -are in UTF mode. When partial matching, we have to do this unit-by-unit. */ +are in UTF and/or UCP mode. When partial matching, we have to do this unit by +unit. */ else { @@ -574,8 +588,8 @@ match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, PCRE2_SIZE *ovector, heapframe *F; /* Current frame pointer */ heapframe *N = NULL; /* Temporary frame pointers */ heapframe *P = NULL; -heapframe *assert_accept_frame; /* For passing back the frame with captures */ -PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */ +heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */ +PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */ /* Local variables that do not need to be preserved over calls to RRMATCH(). */ @@ -598,12 +612,13 @@ BOOL condition; /* Used in conditional groups */ BOOL cur_is_word; /* Used in "word" tests */ BOOL prev_is_word; /* Used in "word" tests */ -/* UTF flag */ +/* UTF and UCP flags */ #ifdef SUPPORT_UNICODE BOOL utf = (mb->poptions & PCRE2_UTF) != 0; +BOOL ucp = (mb->poptions & PCRE2_UCP) != 0; #else -BOOL utf = FALSE; +BOOL utf = FALSE; /* Required for convenience even when no Unicode support */ #endif /* This is the length of the last part of a backtracking frame that must be @@ -928,6 +943,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); } else #endif + /* Not UTF mode */ { if (mb->end_subject - Feptr < 1) @@ -987,10 +1003,30 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH); } } + + /* If UCP is set without UTF we must do the same as above, but with one + character per code unit. */ + + else if (ucp) + { + uint32_t cc = UCHAR21(Feptr); + fc = Fecode[1]; + if (fc < 128) + { + if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH); + } + else + { + if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH); + } + Feptr++; + Fecode += 2; + } + else #endif /* SUPPORT_UNICODE */ - /* Not UTF mode; use the table for characters < 256. */ + /* Not UTF or UCP mode; use the table for characters < 256. */ { if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1]) != TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH); @@ -1010,6 +1046,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } + #ifdef SUPPORT_UNICODE if (utf) { @@ -1026,15 +1063,42 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (ch > 127) ch = UCD_OTHERCASE(ch); else - ch = TABLE_GET(ch, mb->fcc, ch); + ch = (mb->fcc)[ch]; + if (ch == fc) RRETURN(MATCH_NOMATCH); + } + } + + /* UCP without UTF is as above, but with one character per code unit. */ + + else if (ucp) + { + uint32_t ch; + fc = UCHAR21INC(Feptr); + ch = Fecode[1]; + Fecode += 2; + + if (ch == fc) + { + RRETURN(MATCH_NOMATCH); /* Caseful match */ + } + else if (Fop == OP_NOTI) /* If caseless */ + { + if (ch > 127) + ch = UCD_OTHERCASE(ch); + else + ch = (mb->fcc)[ch]; if (ch == fc) RRETURN(MATCH_NOMATCH); } } + else #endif /* SUPPORT_UNICODE */ + + /* Neither UTF nor UCP is set */ + { uint32_t ch = Fecode[1]; - fc = *Feptr++; + fc = UCHAR21INC(Feptr); if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc)) RRETURN(MATCH_NOMATCH); Fecode += 2; @@ -1244,7 +1308,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); #endif /* SUPPORT_UNICODE */ /* When not in UTF mode, load a single-code-unit character. Then proceed as - above. */ + above, using Unicode casing if either UTF or UCP is set. */ Lc = *Fecode++; @@ -1253,11 +1317,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (Fop >= OP_STARI) { #if PCRE2_CODE_UNIT_WIDTH == 8 - /* Lc must be < 128 in UTF-8 mode. */ +#ifdef SUPPORT_UNICODE + if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc); + else +#endif /* SUPPORT_UNICODE */ + /* Lc will be < 128 in UTF-8 mode. */ Loc = mb->fcc[Lc]; #else /* 16-bit & 32-bit */ #ifdef SUPPORT_UNICODE - if (utf && Lc > 127) Loc = UCD_OTHERCASE(Lc); + if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc); else #endif /* SUPPORT_UNICODE */ Loc = TABLE_GET(Lc, mb->fcc, Lc); @@ -1490,7 +1558,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (Fop >= OP_NOTSTARI) /* Caseless */ { #ifdef SUPPORT_UNICODE - if (utf && Lc > 127) + if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc); else #endif /* SUPPORT_UNICODE */ @@ -6045,11 +6113,10 @@ BOOL firstline; BOOL has_first_cu = FALSE; BOOL has_req_cu = FALSE; BOOL startline; -BOOL utf; #if PCRE2_CODE_UNIT_WIDTH == 8 -BOOL memchr_not_found_first_cu = FALSE; -BOOL memchr_not_found_first_cu2 = FALSE; +BOOL memchr_not_found_first_cu; +BOOL memchr_not_found_first_cu2; #endif PCRE2_UCHAR first_cu = 0; @@ -6069,13 +6136,19 @@ PCRE2_SPTR match_partial; BOOL use_jit; #endif +/* This flag is needed even when Unicode is not supported for convenience +(it is used by the IS_NEWLINE macro). */ + +BOOL utf = FALSE; + #ifdef SUPPORT_UNICODE +BOOL ucp = FALSE; BOOL allow_invalid; uint32_t fragment_options = 0; #ifdef SUPPORT_JIT BOOL jit_checked_utf = FALSE; #endif -#endif +#endif /* SUPPORT_UNICODE */ PCRE2_SIZE frame_size; @@ -6091,7 +6164,8 @@ proves to be too small, it is replaced by a larger one on the heap. To get a vector of the size required that is aligned for pointers, allocate it as a vector of pointers. */ -PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)]; +PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)] + PCRE2_KEEP_UNINITIALIZED; mb->stack_frames = (heapframe *)stack_frames_vector; /* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated @@ -6147,12 +6221,13 @@ use_jit = (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0); #endif -/* Initialize UTF parameters. */ +/* Initialize UTF/UCP parameters. */ -utf = (re->overall_options & PCRE2_UTF) != 0; #ifdef SUPPORT_UNICODE +utf = (re->overall_options & PCRE2_UTF) != 0; allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0; -#endif +ucp = (re->overall_options & PCRE2_UCP) != 0; +#endif /* SUPPORT_UNICODE */ /* Convert the partial matching flags into an integer. */ @@ -6589,9 +6664,13 @@ if ((re->flags & PCRE2_FIRSTSET) != 0) if ((re->flags & PCRE2_FIRSTCASELESS) != 0) { first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu); +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu); +#else + if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu); #endif +#endif /* SUPPORT_UNICODE */ } } else @@ -6607,9 +6686,13 @@ if ((re->flags & PCRE2_LASTSET) != 0) if ((re->flags & PCRE2_LASTCASELESS) != 0) { req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu); +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu); +#else + if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu); #endif +#endif /* SUPPORT_UNICODE */ } } @@ -6626,6 +6709,11 @@ FRAGMENT_RESTART: start_partial = match_partial = NULL; mb->hitend = FALSE; +#if PCRE2_CODE_UNIT_WIDTH == 8 +memchr_not_found_first_cu = FALSE; +memchr_not_found_first_cu2 = FALSE; +#endif + for(;;) { PCRE2_SPTR new_start_match; @@ -6756,15 +6844,16 @@ for(;;) #endif } - /* If we can't find the required code unit, having reached the true end - of the subject, break the bumpalong loop, to force a match failure, - except when doing partial matching, when we let the next cycle run at - the end of the subject. To see why, consider the pattern /(?<=abc)def/, - which partially matches "abc", even though the string does not contain - the starting character "d". If we have not reached the true end of the - subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified) - we also let the cycle run, because the matching string is legitimately - allowed to start with the first code unit of a newline. */ + /* If we can't find the required first code unit, having reached the + true end of the subject, break the bumpalong loop, to force a match + failure, except when doing partial matching, when we let the next cycle + run at the end of the subject. To see why, consider the pattern + /(?<=abc)def/, which partially matches "abc", even though the string + does not contain the starting character "d". If we have not reached the + true end of the subject (PCRE2_FIRSTLINE caused end_subject to be + temporarily modified) we also let the cycle run, because the matching + string is legitimately allowed to start with the first code unit of a + newline. */ if (mb->partial == 0 && start_match >= mb->end_subject) { @@ -7103,6 +7192,7 @@ if (utf && end_subject != true_end_subject && starting code units in 8-bit and 16-bit modes. */ start_match = end_subject + 1; + #if PCRE2_CODE_UNIT_WIDTH != 32 while (start_match < true_end_subject && NOT_FIRSTCU(*start_match)) start_match++; diff --git a/thirdparty/pcre2/src/pcre2_serialize.c b/thirdparty/pcre2/src/pcre2_serialize.c index cec1a035d1..ba17a26d2e 100644 --- a/thirdparty/pcre2/src/pcre2_serialize.c +++ b/thirdparty/pcre2/src/pcre2_serialize.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -90,7 +90,7 @@ if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL) if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; /* Compute total size. */ -total_size = sizeof(pcre2_serialized_data) + tables_length; +total_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH; tables = NULL; for (i = 0; i < number_of_codes; i++) @@ -121,8 +121,8 @@ data->number_of_codes = number_of_codes; /* Copy all compiled code data. */ dst_bytes = bytes + sizeof(pcre2_serialized_data); -memcpy(dst_bytes, tables, tables_length); -dst_bytes += tables_length; +memcpy(dst_bytes, tables, TABLES_LENGTH); +dst_bytes += TABLES_LENGTH; for (i = 0; i < number_of_codes; i++) { @@ -189,12 +189,12 @@ src_bytes = bytes + sizeof(pcre2_serialized_data); /* Decode tables. The reference count for the tables is stored immediately following them. */ -tables = memctl->malloc(tables_length + sizeof(PCRE2_SIZE), memctl->memory_data); +tables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data); if (tables == NULL) return PCRE2_ERROR_NOMEMORY; -memcpy(tables, src_bytes, tables_length); -*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes; -src_bytes += tables_length; +memcpy(tables, src_bytes, TABLES_LENGTH); +*(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes; +src_bytes += TABLES_LENGTH; /* Decode the byte stream. We must not try to read the size from the compiled code block in the stream, because it might be unaligned, which causes errors on diff --git a/thirdparty/pcre2/src/pcre2_study.c b/thirdparty/pcre2/src/pcre2_study.c index 2883868618..9bbb37570f 100644 --- a/thirdparty/pcre2/src/pcre2_study.c +++ b/thirdparty/pcre2/src/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ collecting data (e.g. minimum matching length). */ /* Returns from set_start_bits() */ -enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; +enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN, SSB_TOODEEP }; /************************************************* @@ -772,15 +772,19 @@ Arguments: p points to the first code unit of the character caseless TRUE if caseless utf TRUE for UTF mode + ucp TRUE for UCP mode Returns: pointer after the character */ static PCRE2_SPTR -set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf) +set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf, + BOOL ucp) { uint32_t c = *p++; /* First code unit */ -(void)utf; /* Stop compiler warning when UTF not supported */ + +(void)utf; /* Stop compiler warnings when UTF not supported */ +(void)ucp; /* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for 0xff. */ @@ -810,22 +814,26 @@ if (utf) if (caseless) { #ifdef SUPPORT_UNICODE - if (utf) + if (utf || ucp) { -#if PCRE2_CODE_UNIT_WIDTH == 8 - PCRE2_UCHAR buff[6]; c = UCD_OTHERCASE(c); - (void)PRIV(ord2utf)(c, buff); - SET_BIT(buff[0]); +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (utf) + { + PCRE2_UCHAR buff[6]; + (void)PRIV(ord2utf)(c, buff); + SET_BIT(buff[0]); + } + else if (c < 256) SET_BIT(c); #else /* 16-bit or 32-bit mode */ - c = UCD_OTHERCASE(c); if (c > 0xff) SET_BIT(0xff); else SET_BIT(c); #endif } + else #endif /* SUPPORT_UNICODE */ - /* Not UTF */ + /* Not UTF or UCP */ if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]); } @@ -924,19 +932,26 @@ The SSB_CONTINUE return is useful for parenthesized groups in patterns such as must continue at the outer level to find at least one mandatory code unit. At the outermost level, this function fails unless the result is SSB_DONE. +We restrict recursion (for nested groups) to 1000 to avoid stack overflow +issues. + Arguments: re points to the compiled regex block code points to an expression utf TRUE if in UTF mode + ucp TRUE if in UCP mode + depthptr pointer to recurse depth Returns: SSB_FAIL => Failed to find any starting code units SSB_DONE => Found mandatory starting code units SSB_CONTINUE => Found optional starting code units SSB_UNKNOWN => Hit an unrecognized opcode + SSB_TOODEEP => Recursion is too deep */ static int -set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf) +set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf, BOOL ucp, + int *depthptr) { uint32_t c; int yield = SSB_DONE; @@ -947,6 +962,9 @@ int table_limit = utf? 16:32; int table_limit = 32; #endif +*depthptr += 1; +if (*depthptr > 1000) return SSB_TOODEEP; + do { BOOL try_next = TRUE; @@ -1103,13 +1121,17 @@ do case OP_SCRIPT_RUN: case OP_ASSERT: case OP_ASSERT_NA: - rc = set_start_bits(re, tcode, utf); - if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; - if (rc == SSB_DONE) try_next = FALSE; else + rc = set_start_bits(re, tcode, utf, ucp, depthptr); + if (rc == SSB_DONE) + { + try_next = FALSE; + } + else if (rc == SSB_CONTINUE) { do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; } + else return rc; /* FAIL, UNKNOWN, or TOODEEP */ break; /* If we hit ALT or KET, it means we haven't found anything mandatory in @@ -1155,8 +1177,8 @@ do case OP_BRAZERO: case OP_BRAMINZERO: case OP_BRAPOSZERO: - rc = set_start_bits(re, ++tcode, utf); - if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; + rc = set_start_bits(re, ++tcode, utf, ucp, depthptr); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN || rc == SSB_TOODEEP) return rc; do tcode += GET(tcode,1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; @@ -1177,7 +1199,7 @@ do case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: - tcode = set_table_bit(re, tcode + 1, FALSE, utf); + tcode = set_table_bit(re, tcode + 1, FALSE, utf, ucp); break; case OP_STARI: @@ -1186,7 +1208,7 @@ do case OP_QUERYI: case OP_MINQUERYI: case OP_POSQUERYI: - tcode = set_table_bit(re, tcode + 1, TRUE, utf); + tcode = set_table_bit(re, tcode + 1, TRUE, utf, ucp); break; /* Single-char upto sets the bit and tries the next */ @@ -1194,13 +1216,13 @@ do case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: - tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf); + tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf, ucp); break; case OP_UPTOI: case OP_MINUPTOI: case OP_POSUPTOI: - tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf); + tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf, ucp); break; /* At least one single char sets the bit and stops */ @@ -1212,7 +1234,7 @@ do case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: - (void)set_table_bit(re, tcode + 1, FALSE, utf); + (void)set_table_bit(re, tcode + 1, FALSE, utf, ucp); try_next = FALSE; break; @@ -1223,7 +1245,7 @@ do case OP_PLUSI: case OP_MINPLUSI: case OP_POSPLUSI: - (void)set_table_bit(re, tcode + 1, TRUE, utf); + (void)set_table_bit(re, tcode + 1, TRUE, utf, ucp); try_next = FALSE; break; @@ -1652,6 +1674,7 @@ PRIV(study)(pcre2_real_code *re) int count = 0; PCRE2_UCHAR *code; BOOL utf = (re->overall_options & PCRE2_UTF) != 0; +BOOL ucp = (re->overall_options & PCRE2_UCP) != 0; /* Find start of compiled code */ @@ -1664,7 +1687,8 @@ code units. */ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) { - int rc = set_start_bits(re, code, utf); + int depth = 0; + int rc = set_start_bits(re, code, utf, ucp, &depth); if (rc == SSB_UNKNOWN) return 1; /* If a list of starting code units was set up, scan the list to see if only @@ -1712,27 +1736,27 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) } /* c contains the code unit value, in the range 0-255. In 8-bit UTF - mode, only values < 128 can be used. */ + mode, only values < 128 can be used. In all the other cases, c is a + character value. */ #if PCRE2_CODE_UNIT_WIDTH == 8 - if (c > 127) goto DONE; + if (utf && c > 127) goto DONE; #endif - if (a < 0) a = c; /* First one found */ + if (a < 0) a = c; /* First one found, save in a */ else if (b < 0) /* Second one found */ { int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c); #ifdef SUPPORT_UNICODE -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (utf && UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */ -#else /* 16-bit or 32-bit */ - if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */ - if (utf && c > 127) d = UCD_OTHERCASE(c); -#endif /* Code width */ + if (utf || ucp) + { + if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */ + if (c > 127) d = UCD_OTHERCASE(c); + } #endif /* SUPPORT_UNICODE */ - if (d != a) goto DONE; /* Not other case of a */ - b = c; + if (d != a) goto DONE; /* Not the other case of a */ + b = c; /* Save second in b */ } else goto DONE; /* More than two characters found */ } diff --git a/thirdparty/pcre2/src/pcre2_substitute.c b/thirdparty/pcre2/src/pcre2_substitute.c index ec3dd66df9..981a106a9f 100644 --- a/thirdparty/pcre2/src/pcre2_substitute.c +++ b/thirdparty/pcre2/src/pcre2_substitute.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2019 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -49,8 +49,9 @@ POSSIBILITY OF SUCH DAMAGE. #define SUBSTITUTE_OPTIONS \ (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \ - PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_UNKNOWN_UNSET| \ - PCRE2_SUBSTITUTE_UNSET_EMPTY) + PCRE2_SUBSTITUTE_LITERAL|PCRE2_SUBSTITUTE_MATCHED| \ + PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_REPLACEMENT_ONLY| \ + PCRE2_SUBSTITUTE_UNKNOWN_UNSET|PCRE2_SUBSTITUTE_UNSET_EMPTY) @@ -194,6 +195,7 @@ overflow, either give an error immediately, or keep on, accumulating the length. */ #define CHECKMEMCPY(from,length) \ + { \ if (!overflowed && lengthleft < length) \ { \ if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ @@ -209,7 +211,8 @@ length. */ memcpy(buffer + buff_offset, from, CU2BYTES(length)); \ buff_offset += length; \ lengthleft -= length; \ - } + } \ + } /* Here's the function */ @@ -226,11 +229,14 @@ int forcecasereset = 0; uint32_t ovector_count; uint32_t goptions = 0; uint32_t suboptions; -BOOL match_data_created = FALSE; -BOOL literal = FALSE; +pcre2_match_data *internal_match_data = NULL; +BOOL escaped_literal = FALSE; BOOL overflowed = FALSE; +BOOL use_existing_match; +BOOL replacement_only; #ifdef SUPPORT_UNICODE BOOL utf = (code->overall_options & PCRE2_UTF) != 0; +BOOL ucp = (code->overall_options & PCRE2_UCP) != 0; #endif PCRE2_UCHAR temp[6]; PCRE2_SPTR ptr; @@ -248,23 +254,54 @@ lengthleft = buff_length = *blength; *blength = PCRE2_UNSET; ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET; -/* Partial matching is not valid. This must come after setting *blength to +/* Partial matching is not valid. This must come after setting *blength to PCRE2_UNSET, so as not to imply an offset in the replacement. */ if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0) return PCRE2_ERROR_BADOPTION; -/* If no match data block is provided, create one. */ +/* Check for using a match that has already happened. Note that the subject +pointer in the match data may be NULL after a no-match. */ + +use_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0); +replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0); + +/* If starting from an existing match, there must be an externally provided +match data block. We create an internal match_data block in two cases: (a) an +external one is not supplied (and we are not starting from an existing match); +(b) an existing match is to be used for the first substitution. In the latter +case, we copy the existing match into the internal block. This ensures that no +changes are made to the existing match data block. */ if (match_data == NULL) { + pcre2_general_context *gcontext; + if (use_existing_match) return PCRE2_ERROR_NULL; + gcontext = (mcontext == NULL)? + (pcre2_general_context *)code : + (pcre2_general_context *)mcontext; + match_data = internal_match_data = + pcre2_match_data_create_from_pattern(code, gcontext); + if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; + } + +else if (use_existing_match) + { pcre2_general_context *gcontext = (mcontext == NULL)? (pcre2_general_context *)code : (pcre2_general_context *)mcontext; - match_data = pcre2_match_data_create_from_pattern(code, gcontext); - if (match_data == NULL) return PCRE2_ERROR_NOMEMORY; - match_data_created = TRUE; + int pairs = (code->top_bracket + 1 < match_data->oveccount)? + code->top_bracket + 1 : match_data->oveccount; + internal_match_data = pcre2_match_data_create(match_data->oveccount, + gcontext); + if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; + memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector) + + 2*pairs*sizeof(PCRE2_SIZE)); + match_data = internal_match_data; } + +/* Remember ovector details */ + ovector = pcre2_get_ovector_pointer(match_data); ovector_count = pcre2_get_ovector_count(match_data); @@ -286,7 +323,7 @@ repend = replacement + rlength; #ifdef SUPPORT_UNICODE if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) { - rc = PRIV(valid_utf)(replacement, rlength, &(match_data->rightchar)); + rc = PRIV(valid_utf)(replacement, rlength, &(match_data->startchar)); if (rc != 0) { match_data->leftchar = 0; @@ -300,7 +337,7 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) suboptions = options & SUBSTITUTE_OPTIONS; options &= ~SUBSTITUTE_OPTIONS; -/* Copy up to the start offset */ +/* Error if the start match offset is greater than the length of the subject. */ if (start_offset > length) { @@ -308,9 +345,13 @@ if (start_offset > length) rc = PCRE2_ERROR_BADOFFSET; goto EXIT; } -CHECKMEMCPY(subject, start_offset); -/* Loop for global substituting. */ +/* Copy up to the start offset, unless only the replacement is required. */ + +if (!replacement_only) CHECKMEMCPY(subject, start_offset); + +/* Loop for global substituting. If PCRE2_SUBSTITUTE_MATCHED is set, the first +match is taken from the match_data that was passed in. */ subs = 0; do @@ -318,7 +359,12 @@ do PCRE2_SPTR ptrstack[PTR_STACK_SIZE]; uint32_t ptrstackptr = 0; - rc = pcre2_match(code, subject, length, start_offset, options|goptions, + if (use_existing_match) + { + rc = match_data->rc; + use_existing_match = FALSE; + } + else rc = pcre2_match(code, subject, length, start_offset, options|goptions, match_data, mcontext); #ifdef SUPPORT_UNICODE @@ -364,44 +410,44 @@ do #endif } - /* Copy what we have advanced past, reset the special global options, and - continue to the next match. */ + /* Copy what we have advanced past (unless not required), reset the special + global options, and continue to the next match. */ fraglength = start_offset - save_start; - CHECKMEMCPY(subject + save_start, fraglength); + if (!replacement_only) CHECKMEMCPY(subject + save_start, fraglength); goptions = 0; continue; } /* Handle a successful match. Matches that use \K to end before they start or start before the current point in the subject are not supported. */ - + if (ovector[1] < ovector[0] || ovector[0] < start_offset) { rc = PCRE2_ERROR_BADSUBSPATTERN; goto EXIT; } - - /* Check for the same match as previous. This is legitimate after matching an + + /* Check for the same match as previous. This is legitimate after matching an empty string that starts after the initial match offset. We have tried again at the match point in case the pattern is one like /(?<=\G.)/ which can never match at its starting point, so running the match achieves the bumpalong. If we do get the same (null) match at the original match point, it isn't such a pattern, so we now do the empty string magic. In all other cases, a repeat match should never occur. */ - + if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1]) - { - if (ovector[0] == ovector[1] && ovecsave[2] != start_offset) - { - goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; - ovecsave[2] = start_offset; - continue; /* Back to the top of the loop */ + { + if (ovector[0] == ovector[1] && ovecsave[2] != start_offset) + { + goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; + ovecsave[2] = start_offset; + continue; /* Back to the top of the loop */ } rc = PCRE2_ERROR_INTERNAL_DUPMATCH; - goto EXIT; - } - + goto EXIT; + } + /* Count substitutions with a paranoid check for integer overflow; surely no real call to this function would ever hit this! */ @@ -412,21 +458,30 @@ do } subs++; - /* Copy the text leading up to the match, and remember where the insert - begins and how many ovector pairs are set. */ + /* Copy the text leading up to the match (unless not required), and remember + where the insert begins and how many ovector pairs are set. */ if (rc == 0) rc = ovector_count; fraglength = ovector[0] - start_offset; - CHECKMEMCPY(subject + start_offset, fraglength); + if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength); scb.output_offsets[0] = buff_offset; scb.oveccount = rc; - /* Process the replacement string. Literal mode is set by \Q, but only in - extended mode when backslashes are being interpreted. In extended mode we - must handle nested substrings that are to be reprocessed. */ + /* Process the replacement string. If the entire replacement is literal, just + copy it with length check. */ ptr = replacement; - for (;;) + if ((suboptions & PCRE2_SUBSTITUTE_LITERAL) != 0) + { + CHECKMEMCPY(ptr, rlength); + } + + /* Within a non-literal replacement, which must be scanned character by + character, local literal mode can be set by \Q, but only in extended mode + when backslashes are being interpreted. In extended mode we must handle + nested substrings that are to be reprocessed. */ + + else for (;;) { uint32_t ch; unsigned int chlen; @@ -443,11 +498,11 @@ do /* Handle the next character */ - if (literal) + if (escaped_literal) { if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E) { - literal = FALSE; + escaped_literal = FALSE; ptr += 2; continue; } @@ -704,7 +759,7 @@ do if (forcecase != 0) { #ifdef SUPPORT_UNICODE - if (utf) + if (utf || ucp) { uint32_t type = UCD_CHARTYPE(ch); if (PRIV(ucp_gentype)[type] == ucp_L && @@ -784,7 +839,7 @@ do continue; case ESC_Q: - literal = TRUE; + escaped_literal = TRUE; continue; case 0: /* Data character */ @@ -806,7 +861,7 @@ do if (forcecase != 0) { #ifdef SUPPORT_UNICODE - if (utf) + if (utf || ucp) { uint32_t type = UCD_CHARTYPE(ch); if (PRIV(ucp_gentype)[type] == ucp_L && @@ -835,53 +890,59 @@ do } /* End handling a literal code unit */ } /* End of loop for scanning the replacement. */ - /* The replacement has been copied to the output, or its size has been - remembered. Do the callout if there is one and we have done an actual + /* The replacement has been copied to the output, or its size has been + remembered. Do the callout if there is one and we have done an actual replacement. */ - + if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL) { - scb.subscount = subs; + scb.subscount = subs; scb.output_offsets[1] = buff_offset; - rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data); + rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data); - /* A non-zero return means cancel this substitution. Instead, copy the + /* A non-zero return means cancel this substitution. Instead, copy the matched string fragment. */ if (rc != 0) { PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0]; PCRE2_SIZE oldlength = ovector[1] - ovector[0]; - + buff_offset -= newlength; lengthleft += newlength; - CHECKMEMCPY(subject + ovector[0], oldlength); - + if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength); + /* A negative return means do not do any more. */ - + if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL); } - } - + } + /* Save the details of this match. See above for how this data is used. If we - matched an empty string, do the magic for global matches. Finally, update the - start offset to point to the rest of the subject string. */ - - ovecsave[0] = ovector[0]; - ovecsave[1] = ovector[1]; + matched an empty string, do the magic for global matches. Update the start + offset to point to the rest of the subject string. If we re-used an existing + match for the first match, switch to the internal match data block. */ + + ovecsave[0] = ovector[0]; + ovecsave[1] = ovector[1]; ovecsave[2] = start_offset; - + goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 : PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART; start_offset = ovector[1]; } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */ -/* Copy the rest of the subject. */ +/* Copy the rest of the subject unless not required, and terminate the output +with a binary zero. */ + +if (!replacement_only) + { + fraglength = length - start_offset; + CHECKMEMCPY(subject + start_offset, fraglength); + } -fraglength = length - start_offset; -CHECKMEMCPY(subject + start_offset, fraglength); temp[0] = 0; -CHECKMEMCPY(temp , 1); +CHECKMEMCPY(temp, 1); /* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set, and matching has carried on after a full buffer, in order to compute the length @@ -903,7 +964,7 @@ else } EXIT: -if (match_data_created) pcre2_match_data_free(match_data); +if (internal_match_data != NULL) pcre2_match_data_free(internal_match_data); else match_data->rc = rc; return rc; diff --git a/thirdparty/pcre2/src/pcre2_tables.c b/thirdparty/pcre2/src/pcre2_tables.c index 25531d98c6..b10de45efb 100644 --- a/thirdparty/pcre2/src/pcre2_tables.c +++ b/thirdparty/pcre2/src/pcre2_tables.c @@ -265,6 +265,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0" #define STRING_Cham0 STR_C STR_h STR_a STR_m "\0" #define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0" +#define STRING_Chorasmian0 STR_C STR_h STR_o STR_r STR_a STR_s STR_m STR_i STR_a STR_n "\0" #define STRING_Cn0 STR_C STR_n "\0" #define STRING_Co0 STR_C STR_o "\0" #define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0" @@ -275,6 +276,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0" #define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0" #define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0" +#define STRING_Dives_Akuru0 STR_D STR_i STR_v STR_e STR_s STR_UNDERSCORE STR_A STR_k STR_u STR_r STR_u "\0" #define STRING_Dogra0 STR_D STR_o STR_g STR_r STR_a "\0" #define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0" #define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0" @@ -306,6 +308,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0" #define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0" #define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0" +#define STRING_Khitan_Small_Script0 STR_K STR_h STR_i STR_t STR_a STR_n STR_UNDERSCORE STR_S STR_m STR_a STR_l STR_l STR_UNDERSCORE STR_S STR_c STR_r STR_i STR_p STR_t "\0" #define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0" #define STRING_Khojki0 STR_K STR_h STR_o STR_j STR_k STR_i "\0" #define STRING_Khudawadi0 STR_K STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0" @@ -429,6 +432,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Xsp0 STR_X STR_s STR_p "\0" #define STRING_Xuc0 STR_X STR_u STR_c "\0" #define STRING_Xwd0 STR_X STR_w STR_d "\0" +#define STRING_Yezidi0 STR_Y STR_e STR_z STR_i STR_d STR_i "\0" #define STRING_Yi0 STR_Y STR_i "\0" #define STRING_Z0 STR_Z "\0" #define STRING_Zanabazar_Square0 STR_Z STR_a STR_n STR_a STR_b STR_a STR_z STR_a STR_r STR_UNDERSCORE STR_S STR_q STR_u STR_a STR_r STR_e "\0" @@ -464,6 +468,7 @@ const char PRIV(utt_names)[] = STRING_Chakma0 STRING_Cham0 STRING_Cherokee0 + STRING_Chorasmian0 STRING_Cn0 STRING_Co0 STRING_Common0 @@ -474,6 +479,7 @@ const char PRIV(utt_names)[] = STRING_Cyrillic0 STRING_Deseret0 STRING_Devanagari0 + STRING_Dives_Akuru0 STRING_Dogra0 STRING_Duployan0 STRING_Egyptian_Hieroglyphs0 @@ -505,6 +511,7 @@ const char PRIV(utt_names)[] = STRING_Katakana0 STRING_Kayah_Li0 STRING_Kharoshthi0 + STRING_Khitan_Small_Script0 STRING_Khmer0 STRING_Khojki0 STRING_Khudawadi0 @@ -628,6 +635,7 @@ const char PRIV(utt_names)[] = STRING_Xsp0 STRING_Xuc0 STRING_Xwd0 + STRING_Yezidi0 STRING_Yi0 STRING_Z0 STRING_Zanabazar_Square0 @@ -663,176 +671,180 @@ const ucp_type_table PRIV(utt)[] = { { 203, PT_SC, ucp_Chakma }, { 210, PT_SC, ucp_Cham }, { 215, PT_SC, ucp_Cherokee }, - { 224, PT_PC, ucp_Cn }, - { 227, PT_PC, ucp_Co }, - { 230, PT_SC, ucp_Common }, - { 237, PT_SC, ucp_Coptic }, - { 244, PT_PC, ucp_Cs }, - { 247, PT_SC, ucp_Cuneiform }, - { 257, PT_SC, ucp_Cypriot }, - { 265, PT_SC, ucp_Cyrillic }, - { 274, PT_SC, ucp_Deseret }, - { 282, PT_SC, ucp_Devanagari }, - { 293, PT_SC, ucp_Dogra }, - { 299, PT_SC, ucp_Duployan }, - { 308, PT_SC, ucp_Egyptian_Hieroglyphs }, - { 329, PT_SC, ucp_Elbasan }, - { 337, PT_SC, ucp_Elymaic }, - { 345, PT_SC, ucp_Ethiopic }, - { 354, PT_SC, ucp_Georgian }, - { 363, PT_SC, ucp_Glagolitic }, - { 374, PT_SC, ucp_Gothic }, - { 381, PT_SC, ucp_Grantha }, - { 389, PT_SC, ucp_Greek }, - { 395, PT_SC, ucp_Gujarati }, - { 404, PT_SC, ucp_Gunjala_Gondi }, - { 418, PT_SC, ucp_Gurmukhi }, - { 427, PT_SC, ucp_Han }, - { 431, PT_SC, ucp_Hangul }, - { 438, PT_SC, ucp_Hanifi_Rohingya }, - { 454, PT_SC, ucp_Hanunoo }, - { 462, PT_SC, ucp_Hatran }, - { 469, PT_SC, ucp_Hebrew }, - { 476, PT_SC, ucp_Hiragana }, - { 485, PT_SC, ucp_Imperial_Aramaic }, - { 502, PT_SC, ucp_Inherited }, - { 512, PT_SC, ucp_Inscriptional_Pahlavi }, - { 534, PT_SC, ucp_Inscriptional_Parthian }, - { 557, PT_SC, ucp_Javanese }, - { 566, PT_SC, ucp_Kaithi }, - { 573, PT_SC, ucp_Kannada }, - { 581, PT_SC, ucp_Katakana }, - { 590, PT_SC, ucp_Kayah_Li }, - { 599, PT_SC, ucp_Kharoshthi }, - { 610, PT_SC, ucp_Khmer }, - { 616, PT_SC, ucp_Khojki }, - { 623, PT_SC, ucp_Khudawadi }, - { 633, PT_GC, ucp_L }, - { 635, PT_LAMP, 0 }, - { 638, PT_SC, ucp_Lao }, - { 642, PT_SC, ucp_Latin }, - { 648, PT_SC, ucp_Lepcha }, - { 655, PT_SC, ucp_Limbu }, - { 661, PT_SC, ucp_Linear_A }, - { 670, PT_SC, ucp_Linear_B }, - { 679, PT_SC, ucp_Lisu }, - { 684, PT_PC, ucp_Ll }, - { 687, PT_PC, ucp_Lm }, - { 690, PT_PC, ucp_Lo }, - { 693, PT_PC, ucp_Lt }, - { 696, PT_PC, ucp_Lu }, - { 699, PT_SC, ucp_Lycian }, - { 706, PT_SC, ucp_Lydian }, - { 713, PT_GC, ucp_M }, - { 715, PT_SC, ucp_Mahajani }, - { 724, PT_SC, ucp_Makasar }, - { 732, PT_SC, ucp_Malayalam }, - { 742, PT_SC, ucp_Mandaic }, - { 750, PT_SC, ucp_Manichaean }, - { 761, PT_SC, ucp_Marchen }, - { 769, PT_SC, ucp_Masaram_Gondi }, - { 783, PT_PC, ucp_Mc }, - { 786, PT_PC, ucp_Me }, - { 789, PT_SC, ucp_Medefaidrin }, - { 801, PT_SC, ucp_Meetei_Mayek }, - { 814, PT_SC, ucp_Mende_Kikakui }, - { 828, PT_SC, ucp_Meroitic_Cursive }, - { 845, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 866, PT_SC, ucp_Miao }, - { 871, PT_PC, ucp_Mn }, - { 874, PT_SC, ucp_Modi }, - { 879, PT_SC, ucp_Mongolian }, - { 889, PT_SC, ucp_Mro }, - { 893, PT_SC, ucp_Multani }, - { 901, PT_SC, ucp_Myanmar }, - { 909, PT_GC, ucp_N }, - { 911, PT_SC, ucp_Nabataean }, - { 921, PT_SC, ucp_Nandinagari }, - { 933, PT_PC, ucp_Nd }, - { 936, PT_SC, ucp_New_Tai_Lue }, - { 948, PT_SC, ucp_Newa }, - { 953, PT_SC, ucp_Nko }, - { 957, PT_PC, ucp_Nl }, - { 960, PT_PC, ucp_No }, - { 963, PT_SC, ucp_Nushu }, - { 969, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 992, PT_SC, ucp_Ogham }, - { 998, PT_SC, ucp_Ol_Chiki }, - { 1007, PT_SC, ucp_Old_Hungarian }, - { 1021, PT_SC, ucp_Old_Italic }, - { 1032, PT_SC, ucp_Old_North_Arabian }, - { 1050, PT_SC, ucp_Old_Permic }, - { 1061, PT_SC, ucp_Old_Persian }, - { 1073, PT_SC, ucp_Old_Sogdian }, - { 1085, PT_SC, ucp_Old_South_Arabian }, - { 1103, PT_SC, ucp_Old_Turkic }, - { 1114, PT_SC, ucp_Oriya }, - { 1120, PT_SC, ucp_Osage }, - { 1126, PT_SC, ucp_Osmanya }, - { 1134, PT_GC, ucp_P }, - { 1136, PT_SC, ucp_Pahawh_Hmong }, - { 1149, PT_SC, ucp_Palmyrene }, - { 1159, PT_SC, ucp_Pau_Cin_Hau }, - { 1171, PT_PC, ucp_Pc }, - { 1174, PT_PC, ucp_Pd }, - { 1177, PT_PC, ucp_Pe }, - { 1180, PT_PC, ucp_Pf }, - { 1183, PT_SC, ucp_Phags_Pa }, - { 1192, PT_SC, ucp_Phoenician }, - { 1203, PT_PC, ucp_Pi }, - { 1206, PT_PC, ucp_Po }, - { 1209, PT_PC, ucp_Ps }, - { 1212, PT_SC, ucp_Psalter_Pahlavi }, - { 1228, PT_SC, ucp_Rejang }, - { 1235, PT_SC, ucp_Runic }, - { 1241, PT_GC, ucp_S }, - { 1243, PT_SC, ucp_Samaritan }, - { 1253, PT_SC, ucp_Saurashtra }, - { 1264, PT_PC, ucp_Sc }, - { 1267, PT_SC, ucp_Sharada }, - { 1275, PT_SC, ucp_Shavian }, - { 1283, PT_SC, ucp_Siddham }, - { 1291, PT_SC, ucp_SignWriting }, - { 1303, PT_SC, ucp_Sinhala }, - { 1311, PT_PC, ucp_Sk }, - { 1314, PT_PC, ucp_Sm }, - { 1317, PT_PC, ucp_So }, - { 1320, PT_SC, ucp_Sogdian }, - { 1328, PT_SC, ucp_Sora_Sompeng }, - { 1341, PT_SC, ucp_Soyombo }, - { 1349, PT_SC, ucp_Sundanese }, - { 1359, PT_SC, ucp_Syloti_Nagri }, - { 1372, PT_SC, ucp_Syriac }, - { 1379, PT_SC, ucp_Tagalog }, - { 1387, PT_SC, ucp_Tagbanwa }, - { 1396, PT_SC, ucp_Tai_Le }, - { 1403, PT_SC, ucp_Tai_Tham }, - { 1412, PT_SC, ucp_Tai_Viet }, - { 1421, PT_SC, ucp_Takri }, - { 1427, PT_SC, ucp_Tamil }, - { 1433, PT_SC, ucp_Tangut }, - { 1440, PT_SC, ucp_Telugu }, - { 1447, PT_SC, ucp_Thaana }, - { 1454, PT_SC, ucp_Thai }, - { 1459, PT_SC, ucp_Tibetan }, - { 1467, PT_SC, ucp_Tifinagh }, - { 1476, PT_SC, ucp_Tirhuta }, - { 1484, PT_SC, ucp_Ugaritic }, - { 1493, PT_SC, ucp_Unknown }, - { 1501, PT_SC, ucp_Vai }, - { 1505, PT_SC, ucp_Wancho }, - { 1512, PT_SC, ucp_Warang_Citi }, - { 1524, PT_ALNUM, 0 }, - { 1528, PT_PXSPACE, 0 }, - { 1532, PT_SPACE, 0 }, - { 1536, PT_UCNC, 0 }, - { 1540, PT_WORD, 0 }, - { 1544, PT_SC, ucp_Yi }, - { 1547, PT_GC, ucp_Z }, - { 1549, PT_SC, ucp_Zanabazar_Square }, - { 1566, PT_PC, ucp_Zl }, - { 1569, PT_PC, ucp_Zp }, - { 1572, PT_PC, ucp_Zs } + { 224, PT_SC, ucp_Chorasmian }, + { 235, PT_PC, ucp_Cn }, + { 238, PT_PC, ucp_Co }, + { 241, PT_SC, ucp_Common }, + { 248, PT_SC, ucp_Coptic }, + { 255, PT_PC, ucp_Cs }, + { 258, PT_SC, ucp_Cuneiform }, + { 268, PT_SC, ucp_Cypriot }, + { 276, PT_SC, ucp_Cyrillic }, + { 285, PT_SC, ucp_Deseret }, + { 293, PT_SC, ucp_Devanagari }, + { 304, PT_SC, ucp_Dives_Akuru }, + { 316, PT_SC, ucp_Dogra }, + { 322, PT_SC, ucp_Duployan }, + { 331, PT_SC, ucp_Egyptian_Hieroglyphs }, + { 352, PT_SC, ucp_Elbasan }, + { 360, PT_SC, ucp_Elymaic }, + { 368, PT_SC, ucp_Ethiopic }, + { 377, PT_SC, ucp_Georgian }, + { 386, PT_SC, ucp_Glagolitic }, + { 397, PT_SC, ucp_Gothic }, + { 404, PT_SC, ucp_Grantha }, + { 412, PT_SC, ucp_Greek }, + { 418, PT_SC, ucp_Gujarati }, + { 427, PT_SC, ucp_Gunjala_Gondi }, + { 441, PT_SC, ucp_Gurmukhi }, + { 450, PT_SC, ucp_Han }, + { 454, PT_SC, ucp_Hangul }, + { 461, PT_SC, ucp_Hanifi_Rohingya }, + { 477, PT_SC, ucp_Hanunoo }, + { 485, PT_SC, ucp_Hatran }, + { 492, PT_SC, ucp_Hebrew }, + { 499, PT_SC, ucp_Hiragana }, + { 508, PT_SC, ucp_Imperial_Aramaic }, + { 525, PT_SC, ucp_Inherited }, + { 535, PT_SC, ucp_Inscriptional_Pahlavi }, + { 557, PT_SC, ucp_Inscriptional_Parthian }, + { 580, PT_SC, ucp_Javanese }, + { 589, PT_SC, ucp_Kaithi }, + { 596, PT_SC, ucp_Kannada }, + { 604, PT_SC, ucp_Katakana }, + { 613, PT_SC, ucp_Kayah_Li }, + { 622, PT_SC, ucp_Kharoshthi }, + { 633, PT_SC, ucp_Khitan_Small_Script }, + { 653, PT_SC, ucp_Khmer }, + { 659, PT_SC, ucp_Khojki }, + { 666, PT_SC, ucp_Khudawadi }, + { 676, PT_GC, ucp_L }, + { 678, PT_LAMP, 0 }, + { 681, PT_SC, ucp_Lao }, + { 685, PT_SC, ucp_Latin }, + { 691, PT_SC, ucp_Lepcha }, + { 698, PT_SC, ucp_Limbu }, + { 704, PT_SC, ucp_Linear_A }, + { 713, PT_SC, ucp_Linear_B }, + { 722, PT_SC, ucp_Lisu }, + { 727, PT_PC, ucp_Ll }, + { 730, PT_PC, ucp_Lm }, + { 733, PT_PC, ucp_Lo }, + { 736, PT_PC, ucp_Lt }, + { 739, PT_PC, ucp_Lu }, + { 742, PT_SC, ucp_Lycian }, + { 749, PT_SC, ucp_Lydian }, + { 756, PT_GC, ucp_M }, + { 758, PT_SC, ucp_Mahajani }, + { 767, PT_SC, ucp_Makasar }, + { 775, PT_SC, ucp_Malayalam }, + { 785, PT_SC, ucp_Mandaic }, + { 793, PT_SC, ucp_Manichaean }, + { 804, PT_SC, ucp_Marchen }, + { 812, PT_SC, ucp_Masaram_Gondi }, + { 826, PT_PC, ucp_Mc }, + { 829, PT_PC, ucp_Me }, + { 832, PT_SC, ucp_Medefaidrin }, + { 844, PT_SC, ucp_Meetei_Mayek }, + { 857, PT_SC, ucp_Mende_Kikakui }, + { 871, PT_SC, ucp_Meroitic_Cursive }, + { 888, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 909, PT_SC, ucp_Miao }, + { 914, PT_PC, ucp_Mn }, + { 917, PT_SC, ucp_Modi }, + { 922, PT_SC, ucp_Mongolian }, + { 932, PT_SC, ucp_Mro }, + { 936, PT_SC, ucp_Multani }, + { 944, PT_SC, ucp_Myanmar }, + { 952, PT_GC, ucp_N }, + { 954, PT_SC, ucp_Nabataean }, + { 964, PT_SC, ucp_Nandinagari }, + { 976, PT_PC, ucp_Nd }, + { 979, PT_SC, ucp_New_Tai_Lue }, + { 991, PT_SC, ucp_Newa }, + { 996, PT_SC, ucp_Nko }, + { 1000, PT_PC, ucp_Nl }, + { 1003, PT_PC, ucp_No }, + { 1006, PT_SC, ucp_Nushu }, + { 1012, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 1035, PT_SC, ucp_Ogham }, + { 1041, PT_SC, ucp_Ol_Chiki }, + { 1050, PT_SC, ucp_Old_Hungarian }, + { 1064, PT_SC, ucp_Old_Italic }, + { 1075, PT_SC, ucp_Old_North_Arabian }, + { 1093, PT_SC, ucp_Old_Permic }, + { 1104, PT_SC, ucp_Old_Persian }, + { 1116, PT_SC, ucp_Old_Sogdian }, + { 1128, PT_SC, ucp_Old_South_Arabian }, + { 1146, PT_SC, ucp_Old_Turkic }, + { 1157, PT_SC, ucp_Oriya }, + { 1163, PT_SC, ucp_Osage }, + { 1169, PT_SC, ucp_Osmanya }, + { 1177, PT_GC, ucp_P }, + { 1179, PT_SC, ucp_Pahawh_Hmong }, + { 1192, PT_SC, ucp_Palmyrene }, + { 1202, PT_SC, ucp_Pau_Cin_Hau }, + { 1214, PT_PC, ucp_Pc }, + { 1217, PT_PC, ucp_Pd }, + { 1220, PT_PC, ucp_Pe }, + { 1223, PT_PC, ucp_Pf }, + { 1226, PT_SC, ucp_Phags_Pa }, + { 1235, PT_SC, ucp_Phoenician }, + { 1246, PT_PC, ucp_Pi }, + { 1249, PT_PC, ucp_Po }, + { 1252, PT_PC, ucp_Ps }, + { 1255, PT_SC, ucp_Psalter_Pahlavi }, + { 1271, PT_SC, ucp_Rejang }, + { 1278, PT_SC, ucp_Runic }, + { 1284, PT_GC, ucp_S }, + { 1286, PT_SC, ucp_Samaritan }, + { 1296, PT_SC, ucp_Saurashtra }, + { 1307, PT_PC, ucp_Sc }, + { 1310, PT_SC, ucp_Sharada }, + { 1318, PT_SC, ucp_Shavian }, + { 1326, PT_SC, ucp_Siddham }, + { 1334, PT_SC, ucp_SignWriting }, + { 1346, PT_SC, ucp_Sinhala }, + { 1354, PT_PC, ucp_Sk }, + { 1357, PT_PC, ucp_Sm }, + { 1360, PT_PC, ucp_So }, + { 1363, PT_SC, ucp_Sogdian }, + { 1371, PT_SC, ucp_Sora_Sompeng }, + { 1384, PT_SC, ucp_Soyombo }, + { 1392, PT_SC, ucp_Sundanese }, + { 1402, PT_SC, ucp_Syloti_Nagri }, + { 1415, PT_SC, ucp_Syriac }, + { 1422, PT_SC, ucp_Tagalog }, + { 1430, PT_SC, ucp_Tagbanwa }, + { 1439, PT_SC, ucp_Tai_Le }, + { 1446, PT_SC, ucp_Tai_Tham }, + { 1455, PT_SC, ucp_Tai_Viet }, + { 1464, PT_SC, ucp_Takri }, + { 1470, PT_SC, ucp_Tamil }, + { 1476, PT_SC, ucp_Tangut }, + { 1483, PT_SC, ucp_Telugu }, + { 1490, PT_SC, ucp_Thaana }, + { 1497, PT_SC, ucp_Thai }, + { 1502, PT_SC, ucp_Tibetan }, + { 1510, PT_SC, ucp_Tifinagh }, + { 1519, PT_SC, ucp_Tirhuta }, + { 1527, PT_SC, ucp_Ugaritic }, + { 1536, PT_SC, ucp_Unknown }, + { 1544, PT_SC, ucp_Vai }, + { 1548, PT_SC, ucp_Wancho }, + { 1555, PT_SC, ucp_Warang_Citi }, + { 1567, PT_ALNUM, 0 }, + { 1571, PT_PXSPACE, 0 }, + { 1575, PT_SPACE, 0 }, + { 1579, PT_UCNC, 0 }, + { 1583, PT_WORD, 0 }, + { 1587, PT_SC, ucp_Yezidi }, + { 1594, PT_SC, ucp_Yi }, + { 1597, PT_GC, ucp_Z }, + { 1599, PT_SC, ucp_Zanabazar_Square }, + { 1616, PT_PC, ucp_Zl }, + { 1619, PT_PC, ucp_Zp }, + { 1622, PT_PC, ucp_Zs } }; const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/thirdparty/pcre2/src/pcre2_ucd.c b/thirdparty/pcre2/src/pcre2_ucd.c index 55ba03bd43..46e23ff06b 100644 --- a/thirdparty/pcre2/src/pcre2_ucd.c +++ b/thirdparty/pcre2/src/pcre2_ucd.c @@ -20,7 +20,7 @@ needed. */ /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ -/* Total size: 99316 bytes, block size: 128. */ +/* Total size: 101044 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built, and in PCRE2 that happens automatically with UTF support. @@ -39,7 +39,7 @@ const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; #else -const char *PRIV(unicode_version) = "12.1.0"; +const char *PRIV(unicode_version) = "13.0.0"; /* If the 32-bit library is run in non-32-bit mode, character values greater than 0x10ffff may be encountered. For these we set up a @@ -116,15 +116,16 @@ set of decimal digits. It is used to ensure that all the digits in a script run come from the same set. */ const uint32_t PRIV(ucd_digit_sets)[] = { - 63, /* Number of subsequent values */ + 65, /* Number of subsequent values */ 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef, 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9, 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89, 0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909, 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9, - 0x11739, 0x118e9, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59, 0x1d7d7, - 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959, + 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59, + 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959, + 0x1fbf9, }; /* This vector is a list of lists of scripts for the Script Extension @@ -136,14 +137,14 @@ const uint8_t PRIV(ucd_script_sets)[] = { /* 4 */ 1, 144, 0, /* 7 */ 1, 50, 0, /* 10 */ 1, 56, 0, - /* 13 */ 2, 17, 0, - /* 16 */ 3, 15, 0, - /* 19 */ 4, 23, 0, - /* 22 */ 6, 84, 0, - /* 25 */ 12, 36, 0, - /* 28 */ 13, 18, 0, - /* 31 */ 13, 34, 0, - /* 34 */ 13, 118, 0, + /* 13 */ 3, 15, 0, + /* 16 */ 4, 23, 0, + /* 19 */ 6, 84, 0, + /* 22 */ 12, 36, 0, + /* 25 */ 13, 18, 0, + /* 28 */ 13, 34, 0, + /* 31 */ 13, 118, 0, + /* 34 */ 13, 50, 0, /* 37 */ 15, 107, 0, /* 40 */ 15, 150, 0, /* 43 */ 15, 100, 0, @@ -152,35 +153,37 @@ const uint8_t PRIV(ucd_script_sets)[] = { /* 52 */ 107, 54, 0, /* 55 */ 21, 108, 0, /* 58 */ 22, 129, 0, - /* 61 */ 27, 30, 0, - /* 64 */ 29, 150, 0, - /* 67 */ 34, 38, 0, - /* 70 */ 38, 65, 0, - /* 73 */ 1, 50, 56, 0, - /* 77 */ 3, 96, 49, 0, - /* 81 */ 96, 39, 53, 0, - /* 85 */ 12, 110, 36, 0, - /* 89 */ 15, 107, 29, 0, - /* 93 */ 15, 107, 34, 0, - /* 97 */ 23, 27, 30, 0, - /* 101 */ 69, 34, 39, 0, - /* 105 */ 1, 144, 50, 56, 0, - /* 110 */ 3, 15, 107, 29, 0, - /* 115 */ 7, 25, 52, 51, 0, - /* 120 */ 15, 142, 85, 111, 0, - /* 125 */ 4, 24, 23, 27, 30, 0, - /* 131 */ 4, 24, 23, 27, 30, 61, 0, - /* 138 */ 15, 29, 37, 44, 54, 55, 0, - /* 145 */ 132, 1, 95, 112, 121, 144, 148, 50, 0, - /* 154 */ 3, 15, 107, 29, 150, 44, 55, 124, 0, - /* 163 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0, - /* 175 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0, - /* 188 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0, - /* 202 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 150, 109, 102, 124, 0, - /* 216 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 150, 109, 102, 124, 0, - /* 231 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0, - /* 252 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 35, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0, - /* 274 */ + /* 61 */ 23, 34, 0, + /* 64 */ 27, 30, 0, + /* 67 */ 29, 150, 0, + /* 70 */ 34, 38, 0, + /* 73 */ 38, 65, 0, + /* 76 */ 1, 50, 56, 0, + /* 80 */ 1, 56, 156, 0, + /* 84 */ 3, 96, 49, 0, + /* 88 */ 96, 39, 53, 0, + /* 92 */ 12, 110, 36, 0, + /* 96 */ 15, 107, 29, 0, + /* 100 */ 15, 107, 34, 0, + /* 104 */ 23, 27, 30, 0, + /* 108 */ 69, 34, 39, 0, + /* 112 */ 3, 15, 107, 29, 0, + /* 117 */ 7, 25, 52, 51, 0, + /* 122 */ 15, 142, 85, 111, 0, + /* 127 */ 1, 144, 50, 56, 156, 0, + /* 133 */ 4, 24, 23, 27, 30, 0, + /* 139 */ 4, 24, 23, 27, 30, 61, 0, + /* 146 */ 15, 29, 37, 44, 54, 55, 0, + /* 153 */ 132, 1, 95, 112, 121, 144, 148, 50, 0, + /* 162 */ 3, 15, 107, 29, 150, 44, 55, 124, 0, + /* 171 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0, + /* 183 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0, + /* 196 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0, + /* 210 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 150, 109, 102, 124, 0, + /* 224 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 150, 109, 102, 124, 0, + /* 239 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0, + /* 260 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 35, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0, + /* 282 */ }; /* These are the main two-stage UCD tables. The fields in each record are: @@ -189,7 +192,7 @@ offset to multichar other cases or zero (8 bits), offset to other case or zero (32 bits, signed), script extension (16 bits, signed), and a dummy 16-bit field to make the whole thing a multiple of 4 bytes. */ -const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ +const ucd_record PRIV(ucd_records)[] = { /* 11700 bytes, record size 12 */ { 10, 0, 2, 0, 0, 10, 256, }, /* 0 */ { 10, 0, 2, 0, 0, 10, 0, }, /* 1 */ { 10, 0, 1, 0, 0, 10, 0, }, /* 2 */ @@ -387,9 +390,9 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ { 13, 9, 12, 88, 1, 13, 0, }, /* 194 */ { 13, 5, 12, 88, -1, 13, 0, }, /* 195 */ { 13, 26, 12, 0, 0, 13, 0, }, /* 196 */ - { 13, 12, 3, 0, 0, -34, 0, }, /* 197 */ - { 13, 12, 3, 0, 0, -28, 0, }, /* 198 */ - { 28, 12, 3, 0, 0, -31, 0, }, /* 199 */ + { 13, 12, 3, 0, 0, -31, 0, }, /* 197 */ + { 13, 12, 3, 0, 0, -25, 0, }, /* 198 */ + { 28, 12, 3, 0, 0, -28, 0, }, /* 199 */ { 13, 11, 3, 0, 0, 13, 0, }, /* 200 */ { 13, 9, 12, 0, 15, 13, 0, }, /* 201 */ { 13, 5, 12, 0, -15, 13, 0, }, /* 202 */ @@ -398,281 +401,281 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ { 2, 21, 12, 0, 0, 2, 0, }, /* 205 */ { 2, 5, 12, 0, 0, 2, 0, }, /* 206 */ { 2, 5, 12, 0, -48, 2, 0, }, /* 207 */ - { 10, 21, 12, 0, 0, -13, 0, }, /* 208 */ - { 2, 17, 12, 0, 0, 2, 0, }, /* 209 */ - { 2, 26, 12, 0, 0, 2, 0, }, /* 210 */ - { 2, 23, 12, 0, 0, 2, 0, }, /* 211 */ - { 26, 12, 3, 0, 0, 26, 0, }, /* 212 */ - { 26, 17, 12, 0, 0, 26, 0, }, /* 213 */ - { 26, 21, 12, 0, 0, 26, 0, }, /* 214 */ - { 26, 7, 12, 0, 0, 26, 0, }, /* 215 */ - { 1, 1, 4, 0, 0, 1, 0, }, /* 216 */ - { 10, 1, 4, 0, 0, 10, 0, }, /* 217 */ - { 1, 25, 12, 0, 0, 1, 0, }, /* 218 */ - { 1, 21, 12, 0, 0, 1, 0, }, /* 219 */ - { 1, 23, 12, 0, 0, 1, 0, }, /* 220 */ - { 10, 21, 12, 0, 0, -105, 0, }, /* 221 */ - { 1, 26, 12, 0, 0, 1, 0, }, /* 222 */ - { 1, 12, 3, 0, 0, 1, 0, }, /* 223 */ - { 1, 1, 2, 0, 0, -73, 0, }, /* 224 */ - { 1, 7, 12, 0, 0, 1, 0, }, /* 225 */ - { 10, 6, 12, 0, 0, -145, 0, }, /* 226 */ - { 28, 12, 3, 0, 0, -7, 0, }, /* 227 */ - { 1, 13, 12, 0, 0, -10, 0, }, /* 228 */ - { 1, 21, 12, 0, 0, -4, 0, }, /* 229 */ - { 1, 6, 12, 0, 0, 1, 0, }, /* 230 */ - { 1, 13, 12, 0, 0, 1, 0, }, /* 231 */ - { 50, 21, 12, 0, 0, 50, 0, }, /* 232 */ - { 50, 1, 4, 0, 0, 50, 0, }, /* 233 */ - { 50, 7, 12, 0, 0, 50, 0, }, /* 234 */ - { 50, 12, 3, 0, 0, 50, 0, }, /* 235 */ - { 56, 7, 12, 0, 0, 56, 0, }, /* 236 */ - { 56, 12, 3, 0, 0, 56, 0, }, /* 237 */ - { 64, 13, 12, 0, 0, 64, 0, }, /* 238 */ - { 64, 7, 12, 0, 0, 64, 0, }, /* 239 */ - { 64, 12, 3, 0, 0, 64, 0, }, /* 240 */ - { 64, 6, 12, 0, 0, 64, 0, }, /* 241 */ - { 64, 26, 12, 0, 0, 64, 0, }, /* 242 */ - { 64, 21, 12, 0, 0, 64, 0, }, /* 243 */ - { 64, 23, 12, 0, 0, 64, 0, }, /* 244 */ - { 90, 7, 12, 0, 0, 90, 0, }, /* 245 */ - { 90, 12, 3, 0, 0, 90, 0, }, /* 246 */ - { 90, 6, 12, 0, 0, 90, 0, }, /* 247 */ - { 90, 21, 12, 0, 0, 90, 0, }, /* 248 */ - { 95, 7, 12, 0, 0, 95, 0, }, /* 249 */ - { 95, 12, 3, 0, 0, 95, 0, }, /* 250 */ - { 95, 21, 12, 0, 0, 95, 0, }, /* 251 */ - { 15, 12, 3, 0, 0, 15, 0, }, /* 252 */ - { 15, 10, 5, 0, 0, 15, 0, }, /* 253 */ - { 15, 7, 12, 0, 0, 15, 0, }, /* 254 */ - { 28, 12, 3, 0, 0, -188, 0, }, /* 255 */ - { 28, 12, 3, 0, 0, -175, 0, }, /* 256 */ - { 10, 21, 12, 0, 0, -231, 0, }, /* 257 */ - { 10, 21, 12, 0, 0, -252, 0, }, /* 258 */ - { 15, 13, 12, 0, 0, -120, 0, }, /* 259 */ - { 15, 21, 12, 0, 0, 15, 0, }, /* 260 */ - { 15, 6, 12, 0, 0, 15, 0, }, /* 261 */ - { 3, 7, 12, 0, 0, 3, 0, }, /* 262 */ - { 3, 12, 3, 0, 0, 3, 0, }, /* 263 */ - { 3, 10, 5, 0, 0, 3, 0, }, /* 264 */ - { 3, 10, 3, 0, 0, 3, 0, }, /* 265 */ - { 3, 13, 12, 0, 0, -77, 0, }, /* 266 */ - { 3, 23, 12, 0, 0, 3, 0, }, /* 267 */ - { 3, 15, 12, 0, 0, 3, 0, }, /* 268 */ - { 3, 26, 12, 0, 0, 3, 0, }, /* 269 */ - { 3, 21, 12, 0, 0, 3, 0, }, /* 270 */ - { 22, 12, 3, 0, 0, 22, 0, }, /* 271 */ - { 22, 10, 5, 0, 0, 22, 0, }, /* 272 */ - { 22, 7, 12, 0, 0, 22, 0, }, /* 273 */ - { 22, 13, 12, 0, 0, -58, 0, }, /* 274 */ - { 22, 21, 12, 0, 0, 22, 0, }, /* 275 */ - { 21, 12, 3, 0, 0, 21, 0, }, /* 276 */ - { 21, 10, 5, 0, 0, 21, 0, }, /* 277 */ - { 21, 7, 12, 0, 0, 21, 0, }, /* 278 */ - { 21, 13, 12, 0, 0, -55, 0, }, /* 279 */ - { 21, 21, 12, 0, 0, 21, 0, }, /* 280 */ - { 21, 23, 12, 0, 0, 21, 0, }, /* 281 */ - { 44, 12, 3, 0, 0, 44, 0, }, /* 282 */ - { 44, 10, 5, 0, 0, 44, 0, }, /* 283 */ - { 44, 7, 12, 0, 0, 44, 0, }, /* 284 */ - { 44, 10, 3, 0, 0, 44, 0, }, /* 285 */ - { 44, 13, 12, 0, 0, 44, 0, }, /* 286 */ - { 44, 26, 12, 0, 0, 44, 0, }, /* 287 */ - { 44, 15, 12, 0, 0, 44, 0, }, /* 288 */ - { 54, 12, 3, 0, 0, 54, 0, }, /* 289 */ - { 54, 7, 12, 0, 0, 54, 0, }, /* 290 */ - { 54, 10, 3, 0, 0, 54, 0, }, /* 291 */ - { 54, 10, 5, 0, 0, 54, 0, }, /* 292 */ - { 54, 13, 12, 0, 0, -52, 0, }, /* 293 */ - { 54, 15, 12, 0, 0, -52, 0, }, /* 294 */ - { 54, 26, 12, 0, 0, -52, 0, }, /* 295 */ - { 54, 26, 12, 0, 0, 54, 0, }, /* 296 */ - { 54, 23, 12, 0, 0, 54, 0, }, /* 297 */ - { 55, 12, 3, 0, 0, 55, 0, }, /* 298 */ - { 55, 10, 5, 0, 0, 55, 0, }, /* 299 */ - { 55, 7, 12, 0, 0, 55, 0, }, /* 300 */ - { 55, 13, 12, 0, 0, 55, 0, }, /* 301 */ - { 55, 21, 12, 0, 0, 55, 0, }, /* 302 */ - { 55, 15, 12, 0, 0, 55, 0, }, /* 303 */ - { 55, 26, 12, 0, 0, 55, 0, }, /* 304 */ - { 29, 7, 12, 0, 0, 29, 0, }, /* 305 */ - { 29, 12, 3, 0, 0, 29, 0, }, /* 306 */ - { 29, 10, 5, 0, 0, 29, 0, }, /* 307 */ - { 29, 21, 12, 0, 0, 29, 0, }, /* 308 */ - { 29, 10, 3, 0, 0, 29, 0, }, /* 309 */ - { 29, 13, 12, 0, 0, -64, 0, }, /* 310 */ - { 37, 12, 3, 0, 0, 37, 0, }, /* 311 */ - { 37, 10, 5, 0, 0, 37, 0, }, /* 312 */ - { 37, 7, 12, 0, 0, 37, 0, }, /* 313 */ - { 37, 10, 3, 0, 0, 37, 0, }, /* 314 */ - { 37, 7, 4, 0, 0, 37, 0, }, /* 315 */ - { 37, 26, 12, 0, 0, 37, 0, }, /* 316 */ - { 37, 15, 12, 0, 0, 37, 0, }, /* 317 */ - { 37, 13, 12, 0, 0, 37, 0, }, /* 318 */ + { 2, 17, 12, 0, 0, 2, 0, }, /* 208 */ + { 2, 26, 12, 0, 0, 2, 0, }, /* 209 */ + { 2, 23, 12, 0, 0, 2, 0, }, /* 210 */ + { 26, 12, 3, 0, 0, 26, 0, }, /* 211 */ + { 26, 17, 12, 0, 0, 26, 0, }, /* 212 */ + { 26, 21, 12, 0, 0, 26, 0, }, /* 213 */ + { 26, 7, 12, 0, 0, 26, 0, }, /* 214 */ + { 1, 1, 4, 0, 0, 1, 0, }, /* 215 */ + { 10, 1, 4, 0, 0, 10, 0, }, /* 216 */ + { 1, 25, 12, 0, 0, 1, 0, }, /* 217 */ + { 1, 21, 12, 0, 0, 1, 0, }, /* 218 */ + { 1, 23, 12, 0, 0, 1, 0, }, /* 219 */ + { 10, 21, 12, 0, 0, -127, 0, }, /* 220 */ + { 1, 26, 12, 0, 0, 1, 0, }, /* 221 */ + { 1, 12, 3, 0, 0, 1, 0, }, /* 222 */ + { 1, 1, 2, 0, 0, -76, 0, }, /* 223 */ + { 1, 7, 12, 0, 0, 1, 0, }, /* 224 */ + { 10, 6, 12, 0, 0, -153, 0, }, /* 225 */ + { 28, 12, 3, 0, 0, -7, 0, }, /* 226 */ + { 1, 13, 12, 0, 0, -80, 0, }, /* 227 */ + { 1, 21, 12, 0, 0, -4, 0, }, /* 228 */ + { 1, 6, 12, 0, 0, 1, 0, }, /* 229 */ + { 1, 13, 12, 0, 0, 1, 0, }, /* 230 */ + { 50, 21, 12, 0, 0, 50, 0, }, /* 231 */ + { 50, 1, 4, 0, 0, 50, 0, }, /* 232 */ + { 50, 7, 12, 0, 0, 50, 0, }, /* 233 */ + { 50, 12, 3, 0, 0, 50, 0, }, /* 234 */ + { 56, 7, 12, 0, 0, 56, 0, }, /* 235 */ + { 56, 12, 3, 0, 0, 56, 0, }, /* 236 */ + { 64, 13, 12, 0, 0, 64, 0, }, /* 237 */ + { 64, 7, 12, 0, 0, 64, 0, }, /* 238 */ + { 64, 12, 3, 0, 0, 64, 0, }, /* 239 */ + { 64, 6, 12, 0, 0, 64, 0, }, /* 240 */ + { 64, 26, 12, 0, 0, 64, 0, }, /* 241 */ + { 64, 21, 12, 0, 0, 64, 0, }, /* 242 */ + { 64, 23, 12, 0, 0, 64, 0, }, /* 243 */ + { 90, 7, 12, 0, 0, 90, 0, }, /* 244 */ + { 90, 12, 3, 0, 0, 90, 0, }, /* 245 */ + { 90, 6, 12, 0, 0, 90, 0, }, /* 246 */ + { 90, 21, 12, 0, 0, 90, 0, }, /* 247 */ + { 95, 7, 12, 0, 0, 95, 0, }, /* 248 */ + { 95, 12, 3, 0, 0, 95, 0, }, /* 249 */ + { 95, 21, 12, 0, 0, 95, 0, }, /* 250 */ + { 15, 12, 3, 0, 0, 15, 0, }, /* 251 */ + { 15, 10, 5, 0, 0, 15, 0, }, /* 252 */ + { 15, 7, 12, 0, 0, 15, 0, }, /* 253 */ + { 28, 12, 3, 0, 0, -196, 0, }, /* 254 */ + { 28, 12, 3, 0, 0, -183, 0, }, /* 255 */ + { 10, 21, 12, 0, 0, -239, 0, }, /* 256 */ + { 10, 21, 12, 0, 0, -260, 0, }, /* 257 */ + { 15, 13, 12, 0, 0, -122, 0, }, /* 258 */ + { 15, 21, 12, 0, 0, 15, 0, }, /* 259 */ + { 15, 6, 12, 0, 0, 15, 0, }, /* 260 */ + { 3, 7, 12, 0, 0, 3, 0, }, /* 261 */ + { 3, 12, 3, 0, 0, 3, 0, }, /* 262 */ + { 3, 10, 5, 0, 0, 3, 0, }, /* 263 */ + { 3, 10, 3, 0, 0, 3, 0, }, /* 264 */ + { 3, 13, 12, 0, 0, -84, 0, }, /* 265 */ + { 3, 23, 12, 0, 0, 3, 0, }, /* 266 */ + { 3, 15, 12, 0, 0, 3, 0, }, /* 267 */ + { 3, 26, 12, 0, 0, 3, 0, }, /* 268 */ + { 3, 21, 12, 0, 0, 3, 0, }, /* 269 */ + { 22, 12, 3, 0, 0, 22, 0, }, /* 270 */ + { 22, 10, 5, 0, 0, 22, 0, }, /* 271 */ + { 22, 7, 12, 0, 0, 22, 0, }, /* 272 */ + { 22, 13, 12, 0, 0, -58, 0, }, /* 273 */ + { 22, 21, 12, 0, 0, 22, 0, }, /* 274 */ + { 21, 12, 3, 0, 0, 21, 0, }, /* 275 */ + { 21, 10, 5, 0, 0, 21, 0, }, /* 276 */ + { 21, 7, 12, 0, 0, 21, 0, }, /* 277 */ + { 21, 13, 12, 0, 0, -55, 0, }, /* 278 */ + { 21, 21, 12, 0, 0, 21, 0, }, /* 279 */ + { 21, 23, 12, 0, 0, 21, 0, }, /* 280 */ + { 44, 12, 3, 0, 0, 44, 0, }, /* 281 */ + { 44, 10, 5, 0, 0, 44, 0, }, /* 282 */ + { 44, 7, 12, 0, 0, 44, 0, }, /* 283 */ + { 44, 10, 3, 0, 0, 44, 0, }, /* 284 */ + { 44, 13, 12, 0, 0, 44, 0, }, /* 285 */ + { 44, 26, 12, 0, 0, 44, 0, }, /* 286 */ + { 44, 15, 12, 0, 0, 44, 0, }, /* 287 */ + { 54, 12, 3, 0, 0, 54, 0, }, /* 288 */ + { 54, 7, 12, 0, 0, 54, 0, }, /* 289 */ + { 54, 10, 3, 0, 0, 54, 0, }, /* 290 */ + { 54, 10, 5, 0, 0, 54, 0, }, /* 291 */ + { 54, 13, 12, 0, 0, -52, 0, }, /* 292 */ + { 54, 15, 12, 0, 0, -52, 0, }, /* 293 */ + { 54, 26, 12, 0, 0, -52, 0, }, /* 294 */ + { 54, 26, 12, 0, 0, 54, 0, }, /* 295 */ + { 54, 23, 12, 0, 0, 54, 0, }, /* 296 */ + { 55, 12, 3, 0, 0, 55, 0, }, /* 297 */ + { 55, 10, 5, 0, 0, 55, 0, }, /* 298 */ + { 55, 7, 12, 0, 0, 55, 0, }, /* 299 */ + { 55, 13, 12, 0, 0, 55, 0, }, /* 300 */ + { 55, 21, 12, 0, 0, 55, 0, }, /* 301 */ + { 55, 15, 12, 0, 0, 55, 0, }, /* 302 */ + { 55, 26, 12, 0, 0, 55, 0, }, /* 303 */ + { 29, 7, 12, 0, 0, 29, 0, }, /* 304 */ + { 29, 12, 3, 0, 0, 29, 0, }, /* 305 */ + { 29, 10, 5, 0, 0, 29, 0, }, /* 306 */ + { 29, 21, 12, 0, 0, 29, 0, }, /* 307 */ + { 29, 10, 3, 0, 0, 29, 0, }, /* 308 */ + { 29, 13, 12, 0, 0, -67, 0, }, /* 309 */ + { 37, 12, 3, 0, 0, 37, 0, }, /* 310 */ + { 37, 10, 5, 0, 0, 37, 0, }, /* 311 */ + { 37, 7, 12, 0, 0, 37, 0, }, /* 312 */ + { 37, 10, 3, 0, 0, 37, 0, }, /* 313 */ + { 37, 7, 4, 0, 0, 37, 0, }, /* 314 */ + { 37, 26, 12, 0, 0, 37, 0, }, /* 315 */ + { 37, 15, 12, 0, 0, 37, 0, }, /* 316 */ + { 37, 13, 12, 0, 0, 37, 0, }, /* 317 */ + { 48, 12, 3, 0, 0, 48, 0, }, /* 318 */ { 48, 10, 5, 0, 0, 48, 0, }, /* 319 */ { 48, 7, 12, 0, 0, 48, 0, }, /* 320 */ - { 48, 12, 3, 0, 0, 48, 0, }, /* 321 */ - { 48, 10, 3, 0, 0, 48, 0, }, /* 322 */ - { 48, 13, 12, 0, 0, 48, 0, }, /* 323 */ - { 48, 21, 12, 0, 0, 48, 0, }, /* 324 */ - { 57, 7, 12, 0, 0, 57, 0, }, /* 325 */ - { 57, 12, 3, 0, 0, 57, 0, }, /* 326 */ - { 57, 7, 5, 0, 0, 57, 0, }, /* 327 */ - { 57, 6, 12, 0, 0, 57, 0, }, /* 328 */ - { 57, 21, 12, 0, 0, 57, 0, }, /* 329 */ - { 57, 13, 12, 0, 0, 57, 0, }, /* 330 */ - { 33, 7, 12, 0, 0, 33, 0, }, /* 331 */ - { 33, 12, 3, 0, 0, 33, 0, }, /* 332 */ - { 33, 7, 5, 0, 0, 33, 0, }, /* 333 */ - { 33, 6, 12, 0, 0, 33, 0, }, /* 334 */ - { 33, 13, 12, 0, 0, 33, 0, }, /* 335 */ - { 58, 7, 12, 0, 0, 58, 0, }, /* 336 */ - { 58, 26, 12, 0, 0, 58, 0, }, /* 337 */ - { 58, 21, 12, 0, 0, 58, 0, }, /* 338 */ - { 58, 12, 3, 0, 0, 58, 0, }, /* 339 */ - { 58, 13, 12, 0, 0, 58, 0, }, /* 340 */ - { 58, 15, 12, 0, 0, 58, 0, }, /* 341 */ - { 58, 22, 12, 0, 0, 58, 0, }, /* 342 */ - { 58, 18, 12, 0, 0, 58, 0, }, /* 343 */ - { 58, 10, 5, 0, 0, 58, 0, }, /* 344 */ - { 39, 7, 12, 0, 0, 39, 0, }, /* 345 */ - { 39, 10, 12, 0, 0, 39, 0, }, /* 346 */ - { 39, 12, 3, 0, 0, 39, 0, }, /* 347 */ - { 39, 10, 5, 0, 0, 39, 0, }, /* 348 */ - { 39, 13, 12, 0, 0, -81, 0, }, /* 349 */ - { 39, 21, 12, 0, 0, 39, 0, }, /* 350 */ - { 39, 13, 12, 0, 0, 39, 0, }, /* 351 */ - { 39, 26, 12, 0, 0, 39, 0, }, /* 352 */ - { 17, 9, 12, 0, 7264, 17, 0, }, /* 353 */ - { 17, 5, 12, 0, 3008, 17, 0, }, /* 354 */ - { 10, 21, 12, 0, 0, -49, 0, }, /* 355 */ - { 17, 6, 12, 0, 0, 17, 0, }, /* 356 */ - { 24, 7, 6, 0, 0, 24, 0, }, /* 357 */ - { 24, 7, 7, 0, 0, 24, 0, }, /* 358 */ - { 24, 7, 8, 0, 0, 24, 0, }, /* 359 */ - { 16, 7, 12, 0, 0, 16, 0, }, /* 360 */ - { 16, 12, 3, 0, 0, 16, 0, }, /* 361 */ - { 16, 21, 12, 0, 0, 16, 0, }, /* 362 */ - { 16, 15, 12, 0, 0, 16, 0, }, /* 363 */ - { 16, 26, 12, 0, 0, 16, 0, }, /* 364 */ - { 9, 9, 12, 0, 38864, 9, 0, }, /* 365 */ - { 9, 9, 12, 0, 8, 9, 0, }, /* 366 */ - { 9, 5, 12, 0, -8, 9, 0, }, /* 367 */ - { 8, 17, 12, 0, 0, 8, 0, }, /* 368 */ - { 8, 7, 12, 0, 0, 8, 0, }, /* 369 */ - { 8, 26, 12, 0, 0, 8, 0, }, /* 370 */ - { 8, 21, 12, 0, 0, 8, 0, }, /* 371 */ - { 41, 29, 12, 0, 0, 41, 0, }, /* 372 */ - { 41, 7, 12, 0, 0, 41, 0, }, /* 373 */ - { 41, 22, 12, 0, 0, 41, 0, }, /* 374 */ - { 41, 18, 12, 0, 0, 41, 0, }, /* 375 */ - { 46, 7, 12, 0, 0, 46, 0, }, /* 376 */ - { 46, 14, 12, 0, 0, 46, 0, }, /* 377 */ - { 51, 7, 12, 0, 0, 51, 0, }, /* 378 */ - { 51, 12, 3, 0, 0, 51, 0, }, /* 379 */ - { 25, 7, 12, 0, 0, 25, 0, }, /* 380 */ - { 25, 12, 3, 0, 0, 25, 0, }, /* 381 */ - { 10, 21, 12, 0, 0, -115, 0, }, /* 382 */ - { 7, 7, 12, 0, 0, 7, 0, }, /* 383 */ - { 7, 12, 3, 0, 0, 7, 0, }, /* 384 */ - { 52, 7, 12, 0, 0, 52, 0, }, /* 385 */ - { 52, 12, 3, 0, 0, 52, 0, }, /* 386 */ - { 32, 7, 12, 0, 0, 32, 0, }, /* 387 */ - { 32, 12, 3, 0, 0, 32, 0, }, /* 388 */ - { 32, 10, 5, 0, 0, 32, 0, }, /* 389 */ - { 32, 21, 12, 0, 0, 32, 0, }, /* 390 */ - { 32, 6, 12, 0, 0, 32, 0, }, /* 391 */ - { 32, 23, 12, 0, 0, 32, 0, }, /* 392 */ - { 32, 13, 12, 0, 0, 32, 0, }, /* 393 */ - { 32, 15, 12, 0, 0, 32, 0, }, /* 394 */ - { 38, 21, 12, 0, 0, 38, 0, }, /* 395 */ - { 10, 21, 12, 0, 0, -70, 0, }, /* 396 */ - { 38, 17, 12, 0, 0, 38, 0, }, /* 397 */ - { 38, 12, 3, 0, 0, 38, 0, }, /* 398 */ - { 38, 1, 2, 0, 0, 38, 0, }, /* 399 */ - { 38, 13, 12, 0, 0, 38, 0, }, /* 400 */ - { 38, 7, 12, 0, 0, 38, 0, }, /* 401 */ - { 38, 6, 12, 0, 0, 38, 0, }, /* 402 */ - { 35, 7, 12, 0, 0, 35, 0, }, /* 403 */ - { 35, 12, 3, 0, 0, 35, 0, }, /* 404 */ - { 35, 10, 5, 0, 0, 35, 0, }, /* 405 */ - { 35, 26, 12, 0, 0, 35, 0, }, /* 406 */ - { 35, 21, 12, 0, 0, 35, 0, }, /* 407 */ - { 35, 13, 12, 0, 0, 35, 0, }, /* 408 */ - { 53, 7, 12, 0, 0, 53, 0, }, /* 409 */ - { 40, 7, 12, 0, 0, 40, 0, }, /* 410 */ - { 40, 13, 12, 0, 0, 40, 0, }, /* 411 */ - { 40, 15, 12, 0, 0, 40, 0, }, /* 412 */ - { 40, 26, 12, 0, 0, 40, 0, }, /* 413 */ - { 32, 26, 12, 0, 0, 32, 0, }, /* 414 */ - { 6, 7, 12, 0, 0, 6, 0, }, /* 415 */ - { 6, 12, 3, 0, 0, 6, 0, }, /* 416 */ - { 6, 10, 5, 0, 0, 6, 0, }, /* 417 */ - { 6, 21, 12, 0, 0, 6, 0, }, /* 418 */ - { 91, 7, 12, 0, 0, 91, 0, }, /* 419 */ - { 91, 10, 5, 0, 0, 91, 0, }, /* 420 */ - { 91, 12, 3, 0, 0, 91, 0, }, /* 421 */ - { 91, 10, 12, 0, 0, 91, 0, }, /* 422 */ - { 91, 13, 12, 0, 0, 91, 0, }, /* 423 */ - { 91, 21, 12, 0, 0, 91, 0, }, /* 424 */ - { 91, 6, 12, 0, 0, 91, 0, }, /* 425 */ - { 28, 11, 3, 0, 0, 28, 0, }, /* 426 */ - { 62, 12, 3, 0, 0, 62, 0, }, /* 427 */ - { 62, 10, 5, 0, 0, 62, 0, }, /* 428 */ - { 62, 7, 12, 0, 0, 62, 0, }, /* 429 */ - { 62, 10, 3, 0, 0, 62, 0, }, /* 430 */ - { 62, 13, 12, 0, 0, 62, 0, }, /* 431 */ - { 62, 21, 12, 0, 0, 62, 0, }, /* 432 */ - { 62, 26, 12, 0, 0, 62, 0, }, /* 433 */ - { 76, 12, 3, 0, 0, 76, 0, }, /* 434 */ - { 76, 10, 5, 0, 0, 76, 0, }, /* 435 */ - { 76, 7, 12, 0, 0, 76, 0, }, /* 436 */ - { 76, 13, 12, 0, 0, 76, 0, }, /* 437 */ - { 93, 7, 12, 0, 0, 93, 0, }, /* 438 */ - { 93, 12, 3, 0, 0, 93, 0, }, /* 439 */ - { 93, 10, 5, 0, 0, 93, 0, }, /* 440 */ - { 93, 21, 12, 0, 0, 93, 0, }, /* 441 */ - { 70, 7, 12, 0, 0, 70, 0, }, /* 442 */ - { 70, 10, 5, 0, 0, 70, 0, }, /* 443 */ - { 70, 12, 3, 0, 0, 70, 0, }, /* 444 */ - { 70, 21, 12, 0, 0, 70, 0, }, /* 445 */ - { 70, 13, 12, 0, 0, 70, 0, }, /* 446 */ - { 73, 13, 12, 0, 0, 73, 0, }, /* 447 */ - { 73, 7, 12, 0, 0, 73, 0, }, /* 448 */ - { 73, 6, 12, 0, 0, 73, 0, }, /* 449 */ - { 73, 21, 12, 0, 0, 73, 0, }, /* 450 */ - { 13, 5, 12, 63, -6222, 13, 0, }, /* 451 */ - { 13, 5, 12, 67, -6221, 13, 0, }, /* 452 */ - { 13, 5, 12, 71, -6212, 13, 0, }, /* 453 */ - { 13, 5, 12, 75, -6210, 13, 0, }, /* 454 */ - { 13, 5, 12, 79, -6210, 13, 0, }, /* 455 */ - { 13, 5, 12, 79, -6211, 13, 0, }, /* 456 */ - { 13, 5, 12, 84, -6204, 13, 0, }, /* 457 */ - { 13, 5, 12, 88, -6180, 13, 0, }, /* 458 */ - { 13, 5, 12, 108, 35267, 13, 0, }, /* 459 */ - { 17, 9, 12, 0, -3008, 17, 0, }, /* 460 */ - { 76, 21, 12, 0, 0, 76, 0, }, /* 461 */ - { 28, 12, 3, 0, 0, -110, 0, }, /* 462 */ - { 28, 12, 3, 0, 0, 15, 0, }, /* 463 */ - { 10, 21, 12, 0, 0, -37, 0, }, /* 464 */ - { 28, 12, 3, 0, 0, -16, 0, }, /* 465 */ - { 28, 12, 3, 0, 0, -43, 0, }, /* 466 */ - { 28, 12, 3, 0, 0, -138, 0, }, /* 467 */ - { 10, 10, 5, 0, 0, -16, 0, }, /* 468 */ - { 10, 7, 12, 0, 0, -40, 0, }, /* 469 */ - { 10, 7, 12, 0, 0, -16, 0, }, /* 470 */ - { 10, 7, 12, 0, 0, 15, 0, }, /* 471 */ - { 10, 7, 12, 0, 0, -154, 0, }, /* 472 */ - { 10, 7, 12, 0, 0, -37, 0, }, /* 473 */ - { 28, 12, 3, 0, 0, -89, 0, }, /* 474 */ - { 10, 10, 5, 0, 0, 3, 0, }, /* 475 */ - { 28, 12, 3, 0, 0, -37, 0, }, /* 476 */ - { 10, 7, 12, 0, 0, 150, 0, }, /* 477 */ - { 13, 5, 12, 0, 0, 13, 0, }, /* 478 */ - { 13, 6, 12, 0, 0, 13, 0, }, /* 479 */ - { 34, 5, 12, 0, 35332, 34, 0, }, /* 480 */ - { 34, 5, 12, 0, 3814, 34, 0, }, /* 481 */ - { 34, 5, 12, 0, 35384, 34, 0, }, /* 482 */ + { 48, 10, 3, 0, 0, 48, 0, }, /* 321 */ + { 48, 13, 12, 0, 0, 48, 0, }, /* 322 */ + { 48, 21, 12, 0, 0, 48, 0, }, /* 323 */ + { 57, 7, 12, 0, 0, 57, 0, }, /* 324 */ + { 57, 12, 3, 0, 0, 57, 0, }, /* 325 */ + { 57, 7, 5, 0, 0, 57, 0, }, /* 326 */ + { 57, 6, 12, 0, 0, 57, 0, }, /* 327 */ + { 57, 21, 12, 0, 0, 57, 0, }, /* 328 */ + { 57, 13, 12, 0, 0, 57, 0, }, /* 329 */ + { 33, 7, 12, 0, 0, 33, 0, }, /* 330 */ + { 33, 12, 3, 0, 0, 33, 0, }, /* 331 */ + { 33, 7, 5, 0, 0, 33, 0, }, /* 332 */ + { 33, 6, 12, 0, 0, 33, 0, }, /* 333 */ + { 33, 13, 12, 0, 0, 33, 0, }, /* 334 */ + { 58, 7, 12, 0, 0, 58, 0, }, /* 335 */ + { 58, 26, 12, 0, 0, 58, 0, }, /* 336 */ + { 58, 21, 12, 0, 0, 58, 0, }, /* 337 */ + { 58, 12, 3, 0, 0, 58, 0, }, /* 338 */ + { 58, 13, 12, 0, 0, 58, 0, }, /* 339 */ + { 58, 15, 12, 0, 0, 58, 0, }, /* 340 */ + { 58, 22, 12, 0, 0, 58, 0, }, /* 341 */ + { 58, 18, 12, 0, 0, 58, 0, }, /* 342 */ + { 58, 10, 5, 0, 0, 58, 0, }, /* 343 */ + { 39, 7, 12, 0, 0, 39, 0, }, /* 344 */ + { 39, 10, 12, 0, 0, 39, 0, }, /* 345 */ + { 39, 12, 3, 0, 0, 39, 0, }, /* 346 */ + { 39, 10, 5, 0, 0, 39, 0, }, /* 347 */ + { 39, 13, 12, 0, 0, -88, 0, }, /* 348 */ + { 39, 21, 12, 0, 0, 39, 0, }, /* 349 */ + { 39, 13, 12, 0, 0, 39, 0, }, /* 350 */ + { 39, 26, 12, 0, 0, 39, 0, }, /* 351 */ + { 17, 9, 12, 0, 7264, 17, 0, }, /* 352 */ + { 17, 5, 12, 0, 3008, 17, 0, }, /* 353 */ + { 10, 21, 12, 0, 0, -49, 0, }, /* 354 */ + { 17, 6, 12, 0, 0, 17, 0, }, /* 355 */ + { 24, 7, 6, 0, 0, 24, 0, }, /* 356 */ + { 24, 7, 7, 0, 0, 24, 0, }, /* 357 */ + { 24, 7, 8, 0, 0, 24, 0, }, /* 358 */ + { 16, 7, 12, 0, 0, 16, 0, }, /* 359 */ + { 16, 12, 3, 0, 0, 16, 0, }, /* 360 */ + { 16, 21, 12, 0, 0, 16, 0, }, /* 361 */ + { 16, 15, 12, 0, 0, 16, 0, }, /* 362 */ + { 16, 26, 12, 0, 0, 16, 0, }, /* 363 */ + { 9, 9, 12, 0, 38864, 9, 0, }, /* 364 */ + { 9, 9, 12, 0, 8, 9, 0, }, /* 365 */ + { 9, 5, 12, 0, -8, 9, 0, }, /* 366 */ + { 8, 17, 12, 0, 0, 8, 0, }, /* 367 */ + { 8, 7, 12, 0, 0, 8, 0, }, /* 368 */ + { 8, 26, 12, 0, 0, 8, 0, }, /* 369 */ + { 8, 21, 12, 0, 0, 8, 0, }, /* 370 */ + { 41, 29, 12, 0, 0, 41, 0, }, /* 371 */ + { 41, 7, 12, 0, 0, 41, 0, }, /* 372 */ + { 41, 22, 12, 0, 0, 41, 0, }, /* 373 */ + { 41, 18, 12, 0, 0, 41, 0, }, /* 374 */ + { 46, 7, 12, 0, 0, 46, 0, }, /* 375 */ + { 46, 14, 12, 0, 0, 46, 0, }, /* 376 */ + { 51, 7, 12, 0, 0, 51, 0, }, /* 377 */ + { 51, 12, 3, 0, 0, 51, 0, }, /* 378 */ + { 25, 7, 12, 0, 0, 25, 0, }, /* 379 */ + { 25, 12, 3, 0, 0, 25, 0, }, /* 380 */ + { 10, 21, 12, 0, 0, -117, 0, }, /* 381 */ + { 7, 7, 12, 0, 0, 7, 0, }, /* 382 */ + { 7, 12, 3, 0, 0, 7, 0, }, /* 383 */ + { 52, 7, 12, 0, 0, 52, 0, }, /* 384 */ + { 52, 12, 3, 0, 0, 52, 0, }, /* 385 */ + { 32, 7, 12, 0, 0, 32, 0, }, /* 386 */ + { 32, 12, 3, 0, 0, 32, 0, }, /* 387 */ + { 32, 10, 5, 0, 0, 32, 0, }, /* 388 */ + { 32, 21, 12, 0, 0, 32, 0, }, /* 389 */ + { 32, 6, 12, 0, 0, 32, 0, }, /* 390 */ + { 32, 23, 12, 0, 0, 32, 0, }, /* 391 */ + { 32, 13, 12, 0, 0, 32, 0, }, /* 392 */ + { 32, 15, 12, 0, 0, 32, 0, }, /* 393 */ + { 38, 21, 12, 0, 0, 38, 0, }, /* 394 */ + { 10, 21, 12, 0, 0, -73, 0, }, /* 395 */ + { 38, 17, 12, 0, 0, 38, 0, }, /* 396 */ + { 38, 12, 3, 0, 0, 38, 0, }, /* 397 */ + { 38, 1, 2, 0, 0, 38, 0, }, /* 398 */ + { 38, 13, 12, 0, 0, 38, 0, }, /* 399 */ + { 38, 7, 12, 0, 0, 38, 0, }, /* 400 */ + { 38, 6, 12, 0, 0, 38, 0, }, /* 401 */ + { 35, 7, 12, 0, 0, 35, 0, }, /* 402 */ + { 35, 12, 3, 0, 0, 35, 0, }, /* 403 */ + { 35, 10, 5, 0, 0, 35, 0, }, /* 404 */ + { 35, 26, 12, 0, 0, 35, 0, }, /* 405 */ + { 35, 21, 12, 0, 0, 35, 0, }, /* 406 */ + { 35, 13, 12, 0, 0, 35, 0, }, /* 407 */ + { 53, 7, 12, 0, 0, 53, 0, }, /* 408 */ + { 40, 7, 12, 0, 0, 40, 0, }, /* 409 */ + { 40, 13, 12, 0, 0, 40, 0, }, /* 410 */ + { 40, 15, 12, 0, 0, 40, 0, }, /* 411 */ + { 40, 26, 12, 0, 0, 40, 0, }, /* 412 */ + { 32, 26, 12, 0, 0, 32, 0, }, /* 413 */ + { 6, 7, 12, 0, 0, 6, 0, }, /* 414 */ + { 6, 12, 3, 0, 0, 6, 0, }, /* 415 */ + { 6, 10, 5, 0, 0, 6, 0, }, /* 416 */ + { 6, 21, 12, 0, 0, 6, 0, }, /* 417 */ + { 91, 7, 12, 0, 0, 91, 0, }, /* 418 */ + { 91, 10, 5, 0, 0, 91, 0, }, /* 419 */ + { 91, 12, 3, 0, 0, 91, 0, }, /* 420 */ + { 91, 10, 12, 0, 0, 91, 0, }, /* 421 */ + { 91, 13, 12, 0, 0, 91, 0, }, /* 422 */ + { 91, 21, 12, 0, 0, 91, 0, }, /* 423 */ + { 91, 6, 12, 0, 0, 91, 0, }, /* 424 */ + { 28, 11, 3, 0, 0, 28, 0, }, /* 425 */ + { 62, 12, 3, 0, 0, 62, 0, }, /* 426 */ + { 62, 10, 5, 0, 0, 62, 0, }, /* 427 */ + { 62, 7, 12, 0, 0, 62, 0, }, /* 428 */ + { 62, 10, 3, 0, 0, 62, 0, }, /* 429 */ + { 62, 13, 12, 0, 0, 62, 0, }, /* 430 */ + { 62, 21, 12, 0, 0, 62, 0, }, /* 431 */ + { 62, 26, 12, 0, 0, 62, 0, }, /* 432 */ + { 76, 12, 3, 0, 0, 76, 0, }, /* 433 */ + { 76, 10, 5, 0, 0, 76, 0, }, /* 434 */ + { 76, 7, 12, 0, 0, 76, 0, }, /* 435 */ + { 76, 13, 12, 0, 0, 76, 0, }, /* 436 */ + { 93, 7, 12, 0, 0, 93, 0, }, /* 437 */ + { 93, 12, 3, 0, 0, 93, 0, }, /* 438 */ + { 93, 10, 5, 0, 0, 93, 0, }, /* 439 */ + { 93, 21, 12, 0, 0, 93, 0, }, /* 440 */ + { 70, 7, 12, 0, 0, 70, 0, }, /* 441 */ + { 70, 10, 5, 0, 0, 70, 0, }, /* 442 */ + { 70, 12, 3, 0, 0, 70, 0, }, /* 443 */ + { 70, 21, 12, 0, 0, 70, 0, }, /* 444 */ + { 70, 13, 12, 0, 0, 70, 0, }, /* 445 */ + { 73, 13, 12, 0, 0, 73, 0, }, /* 446 */ + { 73, 7, 12, 0, 0, 73, 0, }, /* 447 */ + { 73, 6, 12, 0, 0, 73, 0, }, /* 448 */ + { 73, 21, 12, 0, 0, 73, 0, }, /* 449 */ + { 13, 5, 12, 63, -6222, 13, 0, }, /* 450 */ + { 13, 5, 12, 67, -6221, 13, 0, }, /* 451 */ + { 13, 5, 12, 71, -6212, 13, 0, }, /* 452 */ + { 13, 5, 12, 75, -6210, 13, 0, }, /* 453 */ + { 13, 5, 12, 79, -6210, 13, 0, }, /* 454 */ + { 13, 5, 12, 79, -6211, 13, 0, }, /* 455 */ + { 13, 5, 12, 84, -6204, 13, 0, }, /* 456 */ + { 13, 5, 12, 88, -6180, 13, 0, }, /* 457 */ + { 13, 5, 12, 108, 35267, 13, 0, }, /* 458 */ + { 17, 9, 12, 0, -3008, 17, 0, }, /* 459 */ + { 76, 21, 12, 0, 0, 76, 0, }, /* 460 */ + { 28, 12, 3, 0, 0, -112, 0, }, /* 461 */ + { 28, 12, 3, 0, 0, 15, 0, }, /* 462 */ + { 10, 21, 12, 0, 0, -37, 0, }, /* 463 */ + { 28, 12, 3, 0, 0, -13, 0, }, /* 464 */ + { 28, 12, 3, 0, 0, -43, 0, }, /* 465 */ + { 28, 12, 3, 0, 0, -146, 0, }, /* 466 */ + { 10, 10, 5, 0, 0, -13, 0, }, /* 467 */ + { 10, 7, 12, 0, 0, -40, 0, }, /* 468 */ + { 10, 7, 12, 0, 0, -13, 0, }, /* 469 */ + { 10, 7, 12, 0, 0, 15, 0, }, /* 470 */ + { 10, 7, 12, 0, 0, -162, 0, }, /* 471 */ + { 10, 7, 12, 0, 0, -37, 0, }, /* 472 */ + { 28, 12, 3, 0, 0, -96, 0, }, /* 473 */ + { 10, 10, 5, 0, 0, 3, 0, }, /* 474 */ + { 28, 12, 3, 0, 0, -37, 0, }, /* 475 */ + { 10, 7, 12, 0, 0, 150, 0, }, /* 476 */ + { 13, 5, 12, 0, 0, 13, 0, }, /* 477 */ + { 13, 6, 12, 0, 0, 13, 0, }, /* 478 */ + { 34, 5, 12, 0, 35332, 34, 0, }, /* 479 */ + { 34, 5, 12, 0, 3814, 34, 0, }, /* 480 */ + { 34, 5, 12, 0, 35384, 34, 0, }, /* 481 */ + { 28, 12, 3, 0, 0, -34, 0, }, /* 482 */ { 34, 9, 12, 92, 1, 34, 0, }, /* 483 */ { 34, 5, 12, 92, -1, 34, 0, }, /* 484 */ { 34, 5, 12, 92, -58, 34, 0, }, /* 485 */ @@ -699,10 +702,10 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ { 28, 1, 13, 0, 0, 28, 0, }, /* 506 */ { 10, 27, 2, 0, 0, 10, 0, }, /* 507 */ { 10, 28, 2, 0, 0, 10, 0, }, /* 508 */ - { 10, 29, 12, 0, 0, -67, 0, }, /* 509 */ + { 10, 29, 12, 0, 0, -70, 0, }, /* 509 */ { 10, 21, 14, 0, 0, 10, 0, }, /* 510 */ { 0, 2, 2, 0, 0, 0, 0, }, /* 511 */ - { 28, 12, 3, 0, 0, -93, 0, }, /* 512 */ + { 28, 12, 3, 0, 0, -100, 0, }, /* 512 */ { 10, 9, 12, 0, 0, 10, 0, }, /* 513 */ { 10, 5, 12, 0, 0, 10, 0, }, /* 514 */ { 20, 9, 12, 96, -7517, 20, 0, }, /* 515 */ @@ -743,31 +746,31 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ { 59, 21, 12, 0, 0, 59, 0, }, /* 550 */ { 59, 12, 3, 0, 0, 59, 0, }, /* 551 */ { 13, 12, 3, 0, 0, 13, 0, }, /* 552 */ - { 10, 21, 12, 0, 0, -28, 0, }, /* 553 */ + { 10, 21, 12, 0, 0, -25, 0, }, /* 553 */ { 23, 26, 12, 0, 0, 23, 0, }, /* 554 */ - { 10, 21, 12, 0, 0, -131, 0, }, /* 555 */ - { 10, 21, 12, 0, 0, -125, 0, }, /* 556 */ + { 10, 21, 12, 0, 0, -139, 0, }, /* 555 */ + { 10, 21, 12, 0, 0, -133, 0, }, /* 556 */ { 23, 6, 12, 0, 0, 23, 0, }, /* 557 */ { 10, 7, 12, 0, 0, 23, 0, }, /* 558 */ { 23, 14, 12, 0, 0, 23, 0, }, /* 559 */ - { 10, 22, 12, 0, 0, -131, 0, }, /* 560 */ - { 10, 18, 12, 0, 0, -131, 0, }, /* 561 */ - { 10, 26, 12, 0, 0, -125, 0, }, /* 562 */ - { 10, 17, 12, 0, 0, -125, 0, }, /* 563 */ - { 10, 22, 12, 0, 0, -125, 0, }, /* 564 */ - { 10, 18, 12, 0, 0, -125, 0, }, /* 565 */ - { 28, 12, 3, 0, 0, -19, 0, }, /* 566 */ + { 10, 22, 12, 0, 0, -139, 0, }, /* 560 */ + { 10, 18, 12, 0, 0, -139, 0, }, /* 561 */ + { 10, 26, 12, 0, 0, -133, 0, }, /* 562 */ + { 10, 17, 12, 0, 0, -133, 0, }, /* 563 */ + { 10, 22, 12, 0, 0, -133, 0, }, /* 564 */ + { 10, 18, 12, 0, 0, -133, 0, }, /* 565 */ + { 28, 12, 3, 0, 0, -16, 0, }, /* 566 */ { 24, 10, 3, 0, 0, 24, 0, }, /* 567 */ - { 10, 17, 14, 0, 0, -125, 0, }, /* 568 */ - { 10, 6, 12, 0, 0, -61, 0, }, /* 569 */ - { 10, 7, 12, 0, 0, -97, 0, }, /* 570 */ - { 10, 21, 14, 0, 0, -97, 0, }, /* 571 */ + { 10, 17, 14, 0, 0, -133, 0, }, /* 568 */ + { 10, 6, 12, 0, 0, -64, 0, }, /* 569 */ + { 10, 7, 12, 0, 0, -104, 0, }, /* 570 */ + { 10, 21, 14, 0, 0, -104, 0, }, /* 571 */ { 10, 26, 12, 0, 0, 23, 0, }, /* 572 */ { 27, 7, 12, 0, 0, 27, 0, }, /* 573 */ - { 28, 12, 3, 0, 0, -61, 0, }, /* 574 */ - { 10, 24, 12, 0, 0, -61, 0, }, /* 575 */ + { 28, 12, 3, 0, 0, -64, 0, }, /* 574 */ + { 10, 24, 12, 0, 0, -64, 0, }, /* 575 */ { 27, 6, 12, 0, 0, 27, 0, }, /* 576 */ - { 10, 17, 12, 0, 0, -61, 0, }, /* 577 */ + { 10, 17, 12, 0, 0, -64, 0, }, /* 577 */ { 30, 7, 12, 0, 0, 30, 0, }, /* 578 */ { 30, 6, 12, 0, 0, 30, 0, }, /* 579 */ { 4, 7, 12, 0, 0, 4, 0, }, /* 580 */ @@ -795,360 +798,376 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ { 79, 14, 12, 0, 0, 79, 0, }, /* 602 */ { 79, 12, 3, 0, 0, 79, 0, }, /* 603 */ { 79, 21, 12, 0, 0, 79, 0, }, /* 604 */ - { 34, 9, 12, 0, -35332, 34, 0, }, /* 605 */ - { 34, 9, 12, 0, -42280, 34, 0, }, /* 606 */ - { 34, 5, 12, 0, 48, 34, 0, }, /* 607 */ - { 34, 9, 12, 0, -42308, 34, 0, }, /* 608 */ - { 34, 9, 12, 0, -42319, 34, 0, }, /* 609 */ - { 34, 9, 12, 0, -42315, 34, 0, }, /* 610 */ - { 34, 9, 12, 0, -42305, 34, 0, }, /* 611 */ - { 34, 9, 12, 0, -42258, 34, 0, }, /* 612 */ - { 34, 9, 12, 0, -42282, 34, 0, }, /* 613 */ - { 34, 9, 12, 0, -42261, 34, 0, }, /* 614 */ - { 34, 9, 12, 0, 928, 34, 0, }, /* 615 */ - { 34, 9, 12, 0, -48, 34, 0, }, /* 616 */ - { 34, 9, 12, 0, -42307, 34, 0, }, /* 617 */ - { 34, 9, 12, 0, -35384, 34, 0, }, /* 618 */ - { 49, 7, 12, 0, 0, 49, 0, }, /* 619 */ - { 49, 12, 3, 0, 0, 49, 0, }, /* 620 */ - { 49, 10, 5, 0, 0, 49, 0, }, /* 621 */ - { 49, 26, 12, 0, 0, 49, 0, }, /* 622 */ - { 10, 15, 12, 0, 0, -216, 0, }, /* 623 */ - { 10, 15, 12, 0, 0, -202, 0, }, /* 624 */ - { 10, 26, 12, 0, 0, -163, 0, }, /* 625 */ - { 10, 23, 12, 0, 0, -163, 0, }, /* 626 */ - { 65, 7, 12, 0, 0, 65, 0, }, /* 627 */ - { 65, 21, 12, 0, 0, 65, 0, }, /* 628 */ - { 75, 10, 5, 0, 0, 75, 0, }, /* 629 */ - { 75, 7, 12, 0, 0, 75, 0, }, /* 630 */ - { 75, 12, 3, 0, 0, 75, 0, }, /* 631 */ - { 75, 21, 12, 0, 0, 75, 0, }, /* 632 */ - { 75, 13, 12, 0, 0, 75, 0, }, /* 633 */ - { 15, 12, 3, 0, 0, -16, 0, }, /* 634 */ - { 15, 7, 12, 0, 0, -46, 0, }, /* 635 */ - { 69, 13, 12, 0, 0, 69, 0, }, /* 636 */ - { 69, 7, 12, 0, 0, 69, 0, }, /* 637 */ - { 69, 12, 3, 0, 0, 69, 0, }, /* 638 */ - { 10, 21, 12, 0, 0, -101, 0, }, /* 639 */ - { 69, 21, 12, 0, 0, 69, 0, }, /* 640 */ - { 74, 7, 12, 0, 0, 74, 0, }, /* 641 */ - { 74, 12, 3, 0, 0, 74, 0, }, /* 642 */ - { 74, 10, 5, 0, 0, 74, 0, }, /* 643 */ - { 74, 21, 12, 0, 0, 74, 0, }, /* 644 */ - { 84, 12, 3, 0, 0, 84, 0, }, /* 645 */ - { 84, 10, 5, 0, 0, 84, 0, }, /* 646 */ - { 84, 7, 12, 0, 0, 84, 0, }, /* 647 */ - { 84, 21, 12, 0, 0, 84, 0, }, /* 648 */ - { 10, 6, 12, 0, 0, -22, 0, }, /* 649 */ - { 84, 13, 12, 0, 0, 84, 0, }, /* 650 */ - { 39, 6, 12, 0, 0, 39, 0, }, /* 651 */ - { 68, 7, 12, 0, 0, 68, 0, }, /* 652 */ - { 68, 12, 3, 0, 0, 68, 0, }, /* 653 */ - { 68, 10, 5, 0, 0, 68, 0, }, /* 654 */ - { 68, 13, 12, 0, 0, 68, 0, }, /* 655 */ - { 68, 21, 12, 0, 0, 68, 0, }, /* 656 */ - { 92, 7, 12, 0, 0, 92, 0, }, /* 657 */ - { 92, 12, 3, 0, 0, 92, 0, }, /* 658 */ - { 92, 6, 12, 0, 0, 92, 0, }, /* 659 */ - { 92, 21, 12, 0, 0, 92, 0, }, /* 660 */ - { 87, 7, 12, 0, 0, 87, 0, }, /* 661 */ - { 87, 10, 5, 0, 0, 87, 0, }, /* 662 */ - { 87, 12, 3, 0, 0, 87, 0, }, /* 663 */ - { 87, 21, 12, 0, 0, 87, 0, }, /* 664 */ - { 87, 6, 12, 0, 0, 87, 0, }, /* 665 */ - { 34, 5, 12, 0, -928, 34, 0, }, /* 666 */ - { 9, 5, 12, 0, -38864, 9, 0, }, /* 667 */ - { 87, 13, 12, 0, 0, 87, 0, }, /* 668 */ - { 24, 7, 9, 0, 0, 24, 0, }, /* 669 */ - { 24, 7, 10, 0, 0, 24, 0, }, /* 670 */ - { 0, 4, 12, 0, 0, 0, 0, }, /* 671 */ - { 0, 3, 12, 0, 0, 0, 0, }, /* 672 */ - { 26, 25, 12, 0, 0, 26, 0, }, /* 673 */ - { 1, 24, 12, 0, 0, 1, 0, }, /* 674 */ - { 1, 7, 12, 0, 0, -10, 0, }, /* 675 */ - { 1, 26, 12, 0, 0, -10, 0, }, /* 676 */ - { 10, 6, 3, 0, 0, -61, 0, }, /* 677 */ - { 36, 7, 12, 0, 0, 36, 0, }, /* 678 */ - { 10, 21, 12, 0, 0, -25, 0, }, /* 679 */ - { 10, 15, 12, 0, 0, -85, 0, }, /* 680 */ - { 10, 26, 12, 0, 0, -25, 0, }, /* 681 */ - { 20, 14, 12, 0, 0, 20, 0, }, /* 682 */ - { 20, 15, 12, 0, 0, 20, 0, }, /* 683 */ - { 20, 26, 12, 0, 0, 20, 0, }, /* 684 */ - { 71, 7, 12, 0, 0, 71, 0, }, /* 685 */ - { 67, 7, 12, 0, 0, 67, 0, }, /* 686 */ - { 28, 12, 3, 0, 0, -1, 0, }, /* 687 */ - { 10, 15, 12, 0, 0, -1, 0, }, /* 688 */ - { 42, 7, 12, 0, 0, 42, 0, }, /* 689 */ - { 42, 15, 12, 0, 0, 42, 0, }, /* 690 */ - { 19, 7, 12, 0, 0, 19, 0, }, /* 691 */ - { 19, 14, 12, 0, 0, 19, 0, }, /* 692 */ - { 118, 7, 12, 0, 0, 118, 0, }, /* 693 */ - { 118, 12, 3, 0, 0, 118, 0, }, /* 694 */ - { 60, 7, 12, 0, 0, 60, 0, }, /* 695 */ - { 60, 21, 12, 0, 0, 60, 0, }, /* 696 */ - { 43, 7, 12, 0, 0, 43, 0, }, /* 697 */ - { 43, 21, 12, 0, 0, 43, 0, }, /* 698 */ - { 43, 14, 12, 0, 0, 43, 0, }, /* 699 */ - { 14, 9, 12, 0, 40, 14, 0, }, /* 700 */ - { 14, 5, 12, 0, -40, 14, 0, }, /* 701 */ - { 47, 7, 12, 0, 0, 47, 0, }, /* 702 */ - { 45, 7, 12, 0, 0, 45, 0, }, /* 703 */ - { 45, 13, 12, 0, 0, 45, 0, }, /* 704 */ - { 136, 9, 12, 0, 40, 136, 0, }, /* 705 */ - { 136, 5, 12, 0, -40, 136, 0, }, /* 706 */ - { 106, 7, 12, 0, 0, 106, 0, }, /* 707 */ - { 104, 7, 12, 0, 0, 104, 0, }, /* 708 */ - { 104, 21, 12, 0, 0, 104, 0, }, /* 709 */ - { 110, 7, 12, 0, 0, 110, 0, }, /* 710 */ - { 12, 7, 12, 0, 0, 12, 0, }, /* 711 */ - { 81, 7, 12, 0, 0, 81, 0, }, /* 712 */ - { 81, 21, 12, 0, 0, 81, 0, }, /* 713 */ - { 81, 15, 12, 0, 0, 81, 0, }, /* 714 */ - { 120, 7, 12, 0, 0, 120, 0, }, /* 715 */ - { 120, 26, 12, 0, 0, 120, 0, }, /* 716 */ - { 120, 15, 12, 0, 0, 120, 0, }, /* 717 */ - { 116, 7, 12, 0, 0, 116, 0, }, /* 718 */ - { 116, 15, 12, 0, 0, 116, 0, }, /* 719 */ - { 128, 7, 12, 0, 0, 128, 0, }, /* 720 */ - { 128, 15, 12, 0, 0, 128, 0, }, /* 721 */ - { 66, 7, 12, 0, 0, 66, 0, }, /* 722 */ - { 66, 15, 12, 0, 0, 66, 0, }, /* 723 */ - { 66, 21, 12, 0, 0, 66, 0, }, /* 724 */ - { 72, 7, 12, 0, 0, 72, 0, }, /* 725 */ - { 72, 21, 12, 0, 0, 72, 0, }, /* 726 */ - { 98, 7, 12, 0, 0, 98, 0, }, /* 727 */ - { 97, 7, 12, 0, 0, 97, 0, }, /* 728 */ - { 97, 15, 12, 0, 0, 97, 0, }, /* 729 */ - { 31, 7, 12, 0, 0, 31, 0, }, /* 730 */ - { 31, 12, 3, 0, 0, 31, 0, }, /* 731 */ - { 31, 15, 12, 0, 0, 31, 0, }, /* 732 */ - { 31, 21, 12, 0, 0, 31, 0, }, /* 733 */ - { 88, 7, 12, 0, 0, 88, 0, }, /* 734 */ - { 88, 15, 12, 0, 0, 88, 0, }, /* 735 */ - { 88, 21, 12, 0, 0, 88, 0, }, /* 736 */ - { 117, 7, 12, 0, 0, 117, 0, }, /* 737 */ - { 117, 15, 12, 0, 0, 117, 0, }, /* 738 */ - { 112, 7, 12, 0, 0, 112, 0, }, /* 739 */ - { 112, 26, 12, 0, 0, 112, 0, }, /* 740 */ - { 112, 12, 3, 0, 0, 112, 0, }, /* 741 */ - { 112, 15, 12, 0, 0, 112, 0, }, /* 742 */ - { 112, 21, 12, 0, 0, 112, 0, }, /* 743 */ - { 78, 7, 12, 0, 0, 78, 0, }, /* 744 */ - { 78, 21, 12, 0, 0, 78, 0, }, /* 745 */ - { 83, 7, 12, 0, 0, 83, 0, }, /* 746 */ - { 83, 15, 12, 0, 0, 83, 0, }, /* 747 */ - { 82, 7, 12, 0, 0, 82, 0, }, /* 748 */ - { 82, 15, 12, 0, 0, 82, 0, }, /* 749 */ - { 121, 7, 12, 0, 0, 121, 0, }, /* 750 */ - { 121, 21, 12, 0, 0, 121, 0, }, /* 751 */ - { 121, 15, 12, 0, 0, 121, 0, }, /* 752 */ - { 89, 7, 12, 0, 0, 89, 0, }, /* 753 */ - { 130, 9, 12, 0, 64, 130, 0, }, /* 754 */ - { 130, 5, 12, 0, -64, 130, 0, }, /* 755 */ - { 130, 15, 12, 0, 0, 130, 0, }, /* 756 */ - { 144, 7, 12, 0, 0, 144, 0, }, /* 757 */ - { 144, 12, 3, 0, 0, 144, 0, }, /* 758 */ - { 144, 13, 12, 0, 0, 144, 0, }, /* 759 */ - { 1, 15, 12, 0, 0, 1, 0, }, /* 760 */ - { 147, 7, 12, 0, 0, 147, 0, }, /* 761 */ - { 147, 15, 12, 0, 0, 147, 0, }, /* 762 */ - { 148, 7, 12, 0, 0, 148, 0, }, /* 763 */ - { 148, 12, 3, 0, 0, 148, 0, }, /* 764 */ - { 148, 15, 12, 0, 0, 148, 0, }, /* 765 */ - { 148, 21, 12, 0, 0, 148, 0, }, /* 766 */ - { 149, 7, 12, 0, 0, 149, 0, }, /* 767 */ - { 94, 10, 5, 0, 0, 94, 0, }, /* 768 */ - { 94, 12, 3, 0, 0, 94, 0, }, /* 769 */ - { 94, 7, 12, 0, 0, 94, 0, }, /* 770 */ - { 94, 21, 12, 0, 0, 94, 0, }, /* 771 */ - { 94, 15, 12, 0, 0, 94, 0, }, /* 772 */ - { 94, 13, 12, 0, 0, 94, 0, }, /* 773 */ - { 85, 12, 3, 0, 0, 85, 0, }, /* 774 */ - { 85, 10, 5, 0, 0, 85, 0, }, /* 775 */ - { 85, 7, 12, 0, 0, 85, 0, }, /* 776 */ - { 85, 21, 12, 0, 0, 85, 0, }, /* 777 */ - { 85, 1, 4, 0, 0, 85, 0, }, /* 778 */ - { 101, 7, 12, 0, 0, 101, 0, }, /* 779 */ - { 101, 13, 12, 0, 0, 101, 0, }, /* 780 */ - { 96, 12, 3, 0, 0, 96, 0, }, /* 781 */ - { 96, 7, 12, 0, 0, 96, 0, }, /* 782 */ - { 96, 10, 5, 0, 0, 96, 0, }, /* 783 */ - { 96, 13, 12, 0, 0, 96, 0, }, /* 784 */ - { 96, 21, 12, 0, 0, 96, 0, }, /* 785 */ - { 111, 7, 12, 0, 0, 111, 0, }, /* 786 */ - { 111, 12, 3, 0, 0, 111, 0, }, /* 787 */ - { 111, 21, 12, 0, 0, 111, 0, }, /* 788 */ - { 100, 12, 3, 0, 0, 100, 0, }, /* 789 */ - { 100, 10, 5, 0, 0, 100, 0, }, /* 790 */ - { 100, 7, 12, 0, 0, 100, 0, }, /* 791 */ - { 100, 7, 4, 0, 0, 100, 0, }, /* 792 */ - { 100, 21, 12, 0, 0, 100, 0, }, /* 793 */ - { 100, 13, 12, 0, 0, 100, 0, }, /* 794 */ - { 48, 15, 12, 0, 0, 48, 0, }, /* 795 */ - { 108, 7, 12, 0, 0, 108, 0, }, /* 796 */ - { 108, 10, 5, 0, 0, 108, 0, }, /* 797 */ - { 108, 12, 3, 0, 0, 108, 0, }, /* 798 */ - { 108, 21, 12, 0, 0, 108, 0, }, /* 799 */ - { 129, 7, 12, 0, 0, 129, 0, }, /* 800 */ - { 129, 21, 12, 0, 0, 129, 0, }, /* 801 */ - { 109, 7, 12, 0, 0, 109, 0, }, /* 802 */ - { 109, 12, 3, 0, 0, 109, 0, }, /* 803 */ - { 109, 10, 5, 0, 0, 109, 0, }, /* 804 */ - { 109, 13, 12, 0, 0, 109, 0, }, /* 805 */ - { 107, 12, 3, 0, 0, 107, 0, }, /* 806 */ - { 107, 12, 3, 0, 0, -52, 0, }, /* 807 */ - { 107, 10, 5, 0, 0, 107, 0, }, /* 808 */ - { 107, 10, 5, 0, 0, -52, 0, }, /* 809 */ - { 107, 7, 12, 0, 0, 107, 0, }, /* 810 */ - { 28, 12, 3, 0, 0, -52, 0, }, /* 811 */ - { 107, 10, 3, 0, 0, 107, 0, }, /* 812 */ - { 135, 7, 12, 0, 0, 135, 0, }, /* 813 */ - { 135, 10, 5, 0, 0, 135, 0, }, /* 814 */ - { 135, 12, 3, 0, 0, 135, 0, }, /* 815 */ - { 135, 21, 12, 0, 0, 135, 0, }, /* 816 */ - { 135, 13, 12, 0, 0, 135, 0, }, /* 817 */ - { 124, 7, 12, 0, 0, 124, 0, }, /* 818 */ - { 124, 10, 3, 0, 0, 124, 0, }, /* 819 */ - { 124, 10, 5, 0, 0, 124, 0, }, /* 820 */ - { 124, 12, 3, 0, 0, 124, 0, }, /* 821 */ - { 124, 21, 12, 0, 0, 124, 0, }, /* 822 */ - { 124, 13, 12, 0, 0, 124, 0, }, /* 823 */ - { 123, 7, 12, 0, 0, 123, 0, }, /* 824 */ - { 123, 10, 3, 0, 0, 123, 0, }, /* 825 */ - { 123, 10, 5, 0, 0, 123, 0, }, /* 826 */ - { 123, 12, 3, 0, 0, 123, 0, }, /* 827 */ - { 123, 21, 12, 0, 0, 123, 0, }, /* 828 */ - { 114, 7, 12, 0, 0, 114, 0, }, /* 829 */ - { 114, 10, 5, 0, 0, 114, 0, }, /* 830 */ - { 114, 12, 3, 0, 0, 114, 0, }, /* 831 */ - { 114, 21, 12, 0, 0, 114, 0, }, /* 832 */ - { 114, 13, 12, 0, 0, 114, 0, }, /* 833 */ - { 102, 7, 12, 0, 0, 102, 0, }, /* 834 */ - { 102, 12, 3, 0, 0, 102, 0, }, /* 835 */ - { 102, 10, 5, 0, 0, 102, 0, }, /* 836 */ - { 102, 13, 12, 0, 0, 102, 0, }, /* 837 */ - { 126, 7, 12, 0, 0, 126, 0, }, /* 838 */ - { 126, 12, 3, 0, 0, 126, 0, }, /* 839 */ - { 126, 10, 5, 0, 0, 126, 0, }, /* 840 */ - { 126, 13, 12, 0, 0, 126, 0, }, /* 841 */ - { 126, 15, 12, 0, 0, 126, 0, }, /* 842 */ - { 126, 21, 12, 0, 0, 126, 0, }, /* 843 */ - { 126, 26, 12, 0, 0, 126, 0, }, /* 844 */ - { 142, 7, 12, 0, 0, 142, 0, }, /* 845 */ - { 142, 10, 5, 0, 0, 142, 0, }, /* 846 */ - { 142, 12, 3, 0, 0, 142, 0, }, /* 847 */ - { 142, 21, 12, 0, 0, 142, 0, }, /* 848 */ - { 125, 9, 12, 0, 32, 125, 0, }, /* 849 */ - { 125, 5, 12, 0, -32, 125, 0, }, /* 850 */ - { 125, 13, 12, 0, 0, 125, 0, }, /* 851 */ - { 125, 15, 12, 0, 0, 125, 0, }, /* 852 */ - { 125, 7, 12, 0, 0, 125, 0, }, /* 853 */ - { 150, 7, 12, 0, 0, 150, 0, }, /* 854 */ - { 150, 10, 5, 0, 0, 150, 0, }, /* 855 */ - { 150, 12, 3, 0, 0, 150, 0, }, /* 856 */ - { 150, 21, 12, 0, 0, 150, 0, }, /* 857 */ - { 141, 7, 12, 0, 0, 141, 0, }, /* 858 */ - { 141, 12, 3, 0, 0, 141, 0, }, /* 859 */ - { 141, 10, 5, 0, 0, 141, 0, }, /* 860 */ - { 141, 7, 4, 0, 0, 141, 0, }, /* 861 */ - { 141, 21, 12, 0, 0, 141, 0, }, /* 862 */ - { 140, 7, 12, 0, 0, 140, 0, }, /* 863 */ - { 140, 12, 3, 0, 0, 140, 0, }, /* 864 */ - { 140, 10, 5, 0, 0, 140, 0, }, /* 865 */ - { 140, 7, 4, 0, 0, 140, 0, }, /* 866 */ - { 140, 21, 12, 0, 0, 140, 0, }, /* 867 */ - { 122, 7, 12, 0, 0, 122, 0, }, /* 868 */ - { 133, 7, 12, 0, 0, 133, 0, }, /* 869 */ - { 133, 10, 5, 0, 0, 133, 0, }, /* 870 */ - { 133, 12, 3, 0, 0, 133, 0, }, /* 871 */ - { 133, 21, 12, 0, 0, 133, 0, }, /* 872 */ - { 133, 13, 12, 0, 0, 133, 0, }, /* 873 */ - { 133, 15, 12, 0, 0, 133, 0, }, /* 874 */ - { 134, 21, 12, 0, 0, 134, 0, }, /* 875 */ - { 134, 7, 12, 0, 0, 134, 0, }, /* 876 */ - { 134, 12, 3, 0, 0, 134, 0, }, /* 877 */ - { 134, 10, 5, 0, 0, 134, 0, }, /* 878 */ - { 138, 7, 12, 0, 0, 138, 0, }, /* 879 */ - { 138, 12, 3, 0, 0, 138, 0, }, /* 880 */ - { 138, 7, 4, 0, 0, 138, 0, }, /* 881 */ - { 138, 13, 12, 0, 0, 138, 0, }, /* 882 */ - { 143, 7, 12, 0, 0, 143, 0, }, /* 883 */ - { 143, 10, 5, 0, 0, 143, 0, }, /* 884 */ - { 143, 12, 3, 0, 0, 143, 0, }, /* 885 */ - { 143, 13, 12, 0, 0, 143, 0, }, /* 886 */ - { 145, 7, 12, 0, 0, 145, 0, }, /* 887 */ - { 145, 12, 3, 0, 0, 145, 0, }, /* 888 */ - { 145, 10, 5, 0, 0, 145, 0, }, /* 889 */ - { 145, 21, 12, 0, 0, 145, 0, }, /* 890 */ - { 54, 15, 12, 0, 0, 54, 0, }, /* 891 */ - { 54, 21, 12, 0, 0, 54, 0, }, /* 892 */ - { 63, 7, 12, 0, 0, 63, 0, }, /* 893 */ - { 63, 14, 12, 0, 0, 63, 0, }, /* 894 */ - { 63, 21, 12, 0, 0, 63, 0, }, /* 895 */ - { 80, 7, 12, 0, 0, 80, 0, }, /* 896 */ - { 80, 1, 2, 0, 0, 80, 0, }, /* 897 */ - { 127, 7, 12, 0, 0, 127, 0, }, /* 898 */ - { 115, 7, 12, 0, 0, 115, 0, }, /* 899 */ - { 115, 13, 12, 0, 0, 115, 0, }, /* 900 */ - { 115, 21, 12, 0, 0, 115, 0, }, /* 901 */ - { 103, 7, 12, 0, 0, 103, 0, }, /* 902 */ - { 103, 12, 3, 0, 0, 103, 0, }, /* 903 */ - { 103, 21, 12, 0, 0, 103, 0, }, /* 904 */ - { 119, 7, 12, 0, 0, 119, 0, }, /* 905 */ - { 119, 12, 3, 0, 0, 119, 0, }, /* 906 */ - { 119, 21, 12, 0, 0, 119, 0, }, /* 907 */ - { 119, 26, 12, 0, 0, 119, 0, }, /* 908 */ - { 119, 6, 12, 0, 0, 119, 0, }, /* 909 */ - { 119, 13, 12, 0, 0, 119, 0, }, /* 910 */ - { 119, 15, 12, 0, 0, 119, 0, }, /* 911 */ - { 146, 9, 12, 0, 32, 146, 0, }, /* 912 */ - { 146, 5, 12, 0, -32, 146, 0, }, /* 913 */ - { 146, 15, 12, 0, 0, 146, 0, }, /* 914 */ - { 146, 21, 12, 0, 0, 146, 0, }, /* 915 */ - { 99, 7, 12, 0, 0, 99, 0, }, /* 916 */ - { 99, 12, 3, 0, 0, 99, 0, }, /* 917 */ - { 99, 10, 5, 0, 0, 99, 0, }, /* 918 */ - { 99, 6, 12, 0, 0, 99, 0, }, /* 919 */ - { 137, 6, 12, 0, 0, 137, 0, }, /* 920 */ - { 139, 6, 12, 0, 0, 139, 0, }, /* 921 */ - { 137, 7, 12, 0, 0, 137, 0, }, /* 922 */ - { 139, 7, 12, 0, 0, 139, 0, }, /* 923 */ - { 105, 7, 12, 0, 0, 105, 0, }, /* 924 */ - { 105, 26, 12, 0, 0, 105, 0, }, /* 925 */ - { 105, 12, 3, 0, 0, 105, 0, }, /* 926 */ - { 105, 21, 12, 0, 0, 105, 0, }, /* 927 */ - { 10, 1, 2, 0, 0, 105, 0, }, /* 928 */ - { 10, 10, 3, 0, 0, 10, 0, }, /* 929 */ - { 10, 10, 5, 0, 0, 10, 0, }, /* 930 */ - { 20, 12, 3, 0, 0, 20, 0, }, /* 931 */ - { 131, 26, 12, 0, 0, 131, 0, }, /* 932 */ - { 131, 12, 3, 0, 0, 131, 0, }, /* 933 */ - { 131, 21, 12, 0, 0, 131, 0, }, /* 934 */ - { 18, 12, 3, 0, 0, 18, 0, }, /* 935 */ - { 151, 7, 12, 0, 0, 151, 0, }, /* 936 */ - { 151, 12, 3, 0, 0, 151, 0, }, /* 937 */ - { 151, 6, 12, 0, 0, 151, 0, }, /* 938 */ - { 151, 13, 12, 0, 0, 151, 0, }, /* 939 */ - { 151, 26, 12, 0, 0, 151, 0, }, /* 940 */ - { 152, 7, 12, 0, 0, 152, 0, }, /* 941 */ - { 152, 12, 3, 0, 0, 152, 0, }, /* 942 */ - { 152, 13, 12, 0, 0, 152, 0, }, /* 943 */ - { 152, 23, 12, 0, 0, 152, 0, }, /* 944 */ - { 113, 7, 12, 0, 0, 113, 0, }, /* 945 */ - { 113, 15, 12, 0, 0, 113, 0, }, /* 946 */ - { 113, 12, 3, 0, 0, 113, 0, }, /* 947 */ - { 132, 9, 12, 0, 34, 132, 0, }, /* 948 */ - { 132, 5, 12, 0, -34, 132, 0, }, /* 949 */ - { 132, 12, 3, 0, 0, 132, 0, }, /* 950 */ - { 132, 6, 12, 0, 0, 132, 0, }, /* 951 */ - { 132, 13, 12, 0, 0, 132, 0, }, /* 952 */ - { 132, 21, 12, 0, 0, 132, 0, }, /* 953 */ - { 0, 2, 14, 0, 0, 0, 0, }, /* 954 */ - { 10, 26, 11, 0, 0, 10, 0, }, /* 955 */ - { 27, 26, 12, 0, 0, 27, 0, }, /* 956 */ - { 10, 24, 3, 0, 0, 10, 0, }, /* 957 */ - { 10, 1, 3, 0, 0, 10, 0, }, /* 958 */ + { 10, 24, 12, 0, 0, -61, 0, }, /* 605 */ + { 34, 9, 12, 0, -35332, 34, 0, }, /* 606 */ + { 34, 9, 12, 0, -42280, 34, 0, }, /* 607 */ + { 34, 5, 12, 0, 48, 34, 0, }, /* 608 */ + { 34, 9, 12, 0, -42308, 34, 0, }, /* 609 */ + { 34, 9, 12, 0, -42319, 34, 0, }, /* 610 */ + { 34, 9, 12, 0, -42315, 34, 0, }, /* 611 */ + { 34, 9, 12, 0, -42305, 34, 0, }, /* 612 */ + { 34, 9, 12, 0, -42258, 34, 0, }, /* 613 */ + { 34, 9, 12, 0, -42282, 34, 0, }, /* 614 */ + { 34, 9, 12, 0, -42261, 34, 0, }, /* 615 */ + { 34, 9, 12, 0, 928, 34, 0, }, /* 616 */ + { 34, 9, 12, 0, -48, 34, 0, }, /* 617 */ + { 34, 9, 12, 0, -42307, 34, 0, }, /* 618 */ + { 34, 9, 12, 0, -35384, 34, 0, }, /* 619 */ + { 49, 7, 12, 0, 0, 49, 0, }, /* 620 */ + { 49, 12, 3, 0, 0, 49, 0, }, /* 621 */ + { 49, 10, 5, 0, 0, 49, 0, }, /* 622 */ + { 49, 26, 12, 0, 0, 49, 0, }, /* 623 */ + { 10, 15, 12, 0, 0, -224, 0, }, /* 624 */ + { 10, 15, 12, 0, 0, -210, 0, }, /* 625 */ + { 10, 26, 12, 0, 0, -171, 0, }, /* 626 */ + { 10, 23, 12, 0, 0, -171, 0, }, /* 627 */ + { 65, 7, 12, 0, 0, 65, 0, }, /* 628 */ + { 65, 21, 12, 0, 0, 65, 0, }, /* 629 */ + { 75, 10, 5, 0, 0, 75, 0, }, /* 630 */ + { 75, 7, 12, 0, 0, 75, 0, }, /* 631 */ + { 75, 12, 3, 0, 0, 75, 0, }, /* 632 */ + { 75, 21, 12, 0, 0, 75, 0, }, /* 633 */ + { 75, 13, 12, 0, 0, 75, 0, }, /* 634 */ + { 15, 12, 3, 0, 0, -13, 0, }, /* 635 */ + { 15, 7, 12, 0, 0, -46, 0, }, /* 636 */ + { 69, 13, 12, 0, 0, 69, 0, }, /* 637 */ + { 69, 7, 12, 0, 0, 69, 0, }, /* 638 */ + { 69, 12, 3, 0, 0, 69, 0, }, /* 639 */ + { 10, 21, 12, 0, 0, -108, 0, }, /* 640 */ + { 69, 21, 12, 0, 0, 69, 0, }, /* 641 */ + { 74, 7, 12, 0, 0, 74, 0, }, /* 642 */ + { 74, 12, 3, 0, 0, 74, 0, }, /* 643 */ + { 74, 10, 5, 0, 0, 74, 0, }, /* 644 */ + { 74, 21, 12, 0, 0, 74, 0, }, /* 645 */ + { 84, 12, 3, 0, 0, 84, 0, }, /* 646 */ + { 84, 10, 5, 0, 0, 84, 0, }, /* 647 */ + { 84, 7, 12, 0, 0, 84, 0, }, /* 648 */ + { 84, 21, 12, 0, 0, 84, 0, }, /* 649 */ + { 10, 6, 12, 0, 0, -19, 0, }, /* 650 */ + { 84, 13, 12, 0, 0, 84, 0, }, /* 651 */ + { 39, 6, 12, 0, 0, 39, 0, }, /* 652 */ + { 68, 7, 12, 0, 0, 68, 0, }, /* 653 */ + { 68, 12, 3, 0, 0, 68, 0, }, /* 654 */ + { 68, 10, 5, 0, 0, 68, 0, }, /* 655 */ + { 68, 13, 12, 0, 0, 68, 0, }, /* 656 */ + { 68, 21, 12, 0, 0, 68, 0, }, /* 657 */ + { 92, 7, 12, 0, 0, 92, 0, }, /* 658 */ + { 92, 12, 3, 0, 0, 92, 0, }, /* 659 */ + { 92, 6, 12, 0, 0, 92, 0, }, /* 660 */ + { 92, 21, 12, 0, 0, 92, 0, }, /* 661 */ + { 87, 7, 12, 0, 0, 87, 0, }, /* 662 */ + { 87, 10, 5, 0, 0, 87, 0, }, /* 663 */ + { 87, 12, 3, 0, 0, 87, 0, }, /* 664 */ + { 87, 21, 12, 0, 0, 87, 0, }, /* 665 */ + { 87, 6, 12, 0, 0, 87, 0, }, /* 666 */ + { 34, 5, 12, 0, -928, 34, 0, }, /* 667 */ + { 9, 5, 12, 0, -38864, 9, 0, }, /* 668 */ + { 87, 13, 12, 0, 0, 87, 0, }, /* 669 */ + { 24, 7, 9, 0, 0, 24, 0, }, /* 670 */ + { 24, 7, 10, 0, 0, 24, 0, }, /* 671 */ + { 0, 4, 12, 0, 0, 0, 0, }, /* 672 */ + { 0, 3, 12, 0, 0, 0, 0, }, /* 673 */ + { 26, 25, 12, 0, 0, 26, 0, }, /* 674 */ + { 1, 24, 12, 0, 0, 1, 0, }, /* 675 */ + { 1, 7, 12, 0, 0, -10, 0, }, /* 676 */ + { 1, 26, 12, 0, 0, -10, 0, }, /* 677 */ + { 10, 6, 3, 0, 0, -64, 0, }, /* 678 */ + { 36, 7, 12, 0, 0, 36, 0, }, /* 679 */ + { 10, 21, 12, 0, 0, -22, 0, }, /* 680 */ + { 10, 15, 12, 0, 0, -92, 0, }, /* 681 */ + { 10, 26, 12, 0, 0, -22, 0, }, /* 682 */ + { 20, 14, 12, 0, 0, 20, 0, }, /* 683 */ + { 20, 15, 12, 0, 0, 20, 0, }, /* 684 */ + { 20, 26, 12, 0, 0, 20, 0, }, /* 685 */ + { 71, 7, 12, 0, 0, 71, 0, }, /* 686 */ + { 67, 7, 12, 0, 0, 67, 0, }, /* 687 */ + { 28, 12, 3, 0, 0, -1, 0, }, /* 688 */ + { 10, 15, 12, 0, 0, -1, 0, }, /* 689 */ + { 42, 7, 12, 0, 0, 42, 0, }, /* 690 */ + { 42, 15, 12, 0, 0, 42, 0, }, /* 691 */ + { 19, 7, 12, 0, 0, 19, 0, }, /* 692 */ + { 19, 14, 12, 0, 0, 19, 0, }, /* 693 */ + { 118, 7, 12, 0, 0, 118, 0, }, /* 694 */ + { 118, 12, 3, 0, 0, 118, 0, }, /* 695 */ + { 60, 7, 12, 0, 0, 60, 0, }, /* 696 */ + { 60, 21, 12, 0, 0, 60, 0, }, /* 697 */ + { 43, 7, 12, 0, 0, 43, 0, }, /* 698 */ + { 43, 21, 12, 0, 0, 43, 0, }, /* 699 */ + { 43, 14, 12, 0, 0, 43, 0, }, /* 700 */ + { 14, 9, 12, 0, 40, 14, 0, }, /* 701 */ + { 14, 5, 12, 0, -40, 14, 0, }, /* 702 */ + { 47, 7, 12, 0, 0, 47, 0, }, /* 703 */ + { 45, 7, 12, 0, 0, 45, 0, }, /* 704 */ + { 45, 13, 12, 0, 0, 45, 0, }, /* 705 */ + { 136, 9, 12, 0, 40, 136, 0, }, /* 706 */ + { 136, 5, 12, 0, -40, 136, 0, }, /* 707 */ + { 106, 7, 12, 0, 0, 106, 0, }, /* 708 */ + { 104, 7, 12, 0, 0, 104, 0, }, /* 709 */ + { 104, 21, 12, 0, 0, 104, 0, }, /* 710 */ + { 110, 7, 12, 0, 0, 110, 0, }, /* 711 */ + { 12, 7, 12, 0, 0, 12, 0, }, /* 712 */ + { 81, 7, 12, 0, 0, 81, 0, }, /* 713 */ + { 81, 21, 12, 0, 0, 81, 0, }, /* 714 */ + { 81, 15, 12, 0, 0, 81, 0, }, /* 715 */ + { 120, 7, 12, 0, 0, 120, 0, }, /* 716 */ + { 120, 26, 12, 0, 0, 120, 0, }, /* 717 */ + { 120, 15, 12, 0, 0, 120, 0, }, /* 718 */ + { 116, 7, 12, 0, 0, 116, 0, }, /* 719 */ + { 116, 15, 12, 0, 0, 116, 0, }, /* 720 */ + { 128, 7, 12, 0, 0, 128, 0, }, /* 721 */ + { 128, 15, 12, 0, 0, 128, 0, }, /* 722 */ + { 66, 7, 12, 0, 0, 66, 0, }, /* 723 */ + { 66, 15, 12, 0, 0, 66, 0, }, /* 724 */ + { 66, 21, 12, 0, 0, 66, 0, }, /* 725 */ + { 72, 7, 12, 0, 0, 72, 0, }, /* 726 */ + { 72, 21, 12, 0, 0, 72, 0, }, /* 727 */ + { 98, 7, 12, 0, 0, 98, 0, }, /* 728 */ + { 97, 7, 12, 0, 0, 97, 0, }, /* 729 */ + { 97, 15, 12, 0, 0, 97, 0, }, /* 730 */ + { 31, 7, 12, 0, 0, 31, 0, }, /* 731 */ + { 31, 12, 3, 0, 0, 31, 0, }, /* 732 */ + { 31, 15, 12, 0, 0, 31, 0, }, /* 733 */ + { 31, 21, 12, 0, 0, 31, 0, }, /* 734 */ + { 88, 7, 12, 0, 0, 88, 0, }, /* 735 */ + { 88, 15, 12, 0, 0, 88, 0, }, /* 736 */ + { 88, 21, 12, 0, 0, 88, 0, }, /* 737 */ + { 117, 7, 12, 0, 0, 117, 0, }, /* 738 */ + { 117, 15, 12, 0, 0, 117, 0, }, /* 739 */ + { 112, 7, 12, 0, 0, 112, 0, }, /* 740 */ + { 112, 26, 12, 0, 0, 112, 0, }, /* 741 */ + { 112, 12, 3, 0, 0, 112, 0, }, /* 742 */ + { 112, 15, 12, 0, 0, 112, 0, }, /* 743 */ + { 112, 21, 12, 0, 0, 112, 0, }, /* 744 */ + { 78, 7, 12, 0, 0, 78, 0, }, /* 745 */ + { 78, 21, 12, 0, 0, 78, 0, }, /* 746 */ + { 83, 7, 12, 0, 0, 83, 0, }, /* 747 */ + { 83, 15, 12, 0, 0, 83, 0, }, /* 748 */ + { 82, 7, 12, 0, 0, 82, 0, }, /* 749 */ + { 82, 15, 12, 0, 0, 82, 0, }, /* 750 */ + { 121, 7, 12, 0, 0, 121, 0, }, /* 751 */ + { 121, 21, 12, 0, 0, 121, 0, }, /* 752 */ + { 121, 15, 12, 0, 0, 121, 0, }, /* 753 */ + { 89, 7, 12, 0, 0, 89, 0, }, /* 754 */ + { 130, 9, 12, 0, 64, 130, 0, }, /* 755 */ + { 130, 5, 12, 0, -64, 130, 0, }, /* 756 */ + { 130, 15, 12, 0, 0, 130, 0, }, /* 757 */ + { 144, 7, 12, 0, 0, 144, 0, }, /* 758 */ + { 144, 12, 3, 0, 0, 144, 0, }, /* 759 */ + { 144, 13, 12, 0, 0, 144, 0, }, /* 760 */ + { 1, 15, 12, 0, 0, 1, 0, }, /* 761 */ + { 156, 7, 12, 0, 0, 156, 0, }, /* 762 */ + { 156, 12, 3, 0, 0, 156, 0, }, /* 763 */ + { 156, 17, 12, 0, 0, 156, 0, }, /* 764 */ + { 147, 7, 12, 0, 0, 147, 0, }, /* 765 */ + { 147, 15, 12, 0, 0, 147, 0, }, /* 766 */ + { 148, 7, 12, 0, 0, 148, 0, }, /* 767 */ + { 148, 12, 3, 0, 0, 148, 0, }, /* 768 */ + { 148, 15, 12, 0, 0, 148, 0, }, /* 769 */ + { 148, 21, 12, 0, 0, 148, 0, }, /* 770 */ + { 153, 7, 12, 0, 0, 153, 0, }, /* 771 */ + { 153, 15, 12, 0, 0, 153, 0, }, /* 772 */ + { 149, 7, 12, 0, 0, 149, 0, }, /* 773 */ + { 94, 10, 5, 0, 0, 94, 0, }, /* 774 */ + { 94, 12, 3, 0, 0, 94, 0, }, /* 775 */ + { 94, 7, 12, 0, 0, 94, 0, }, /* 776 */ + { 94, 21, 12, 0, 0, 94, 0, }, /* 777 */ + { 94, 15, 12, 0, 0, 94, 0, }, /* 778 */ + { 94, 13, 12, 0, 0, 94, 0, }, /* 779 */ + { 85, 12, 3, 0, 0, 85, 0, }, /* 780 */ + { 85, 10, 5, 0, 0, 85, 0, }, /* 781 */ + { 85, 7, 12, 0, 0, 85, 0, }, /* 782 */ + { 85, 21, 12, 0, 0, 85, 0, }, /* 783 */ + { 85, 1, 4, 0, 0, 85, 0, }, /* 784 */ + { 101, 7, 12, 0, 0, 101, 0, }, /* 785 */ + { 101, 13, 12, 0, 0, 101, 0, }, /* 786 */ + { 96, 12, 3, 0, 0, 96, 0, }, /* 787 */ + { 96, 7, 12, 0, 0, 96, 0, }, /* 788 */ + { 96, 10, 5, 0, 0, 96, 0, }, /* 789 */ + { 96, 13, 12, 0, 0, 96, 0, }, /* 790 */ + { 96, 21, 12, 0, 0, 96, 0, }, /* 791 */ + { 111, 7, 12, 0, 0, 111, 0, }, /* 792 */ + { 111, 12, 3, 0, 0, 111, 0, }, /* 793 */ + { 111, 21, 12, 0, 0, 111, 0, }, /* 794 */ + { 100, 12, 3, 0, 0, 100, 0, }, /* 795 */ + { 100, 10, 5, 0, 0, 100, 0, }, /* 796 */ + { 100, 7, 12, 0, 0, 100, 0, }, /* 797 */ + { 100, 7, 4, 0, 0, 100, 0, }, /* 798 */ + { 100, 21, 12, 0, 0, 100, 0, }, /* 799 */ + { 100, 13, 12, 0, 0, 100, 0, }, /* 800 */ + { 48, 15, 12, 0, 0, 48, 0, }, /* 801 */ + { 108, 7, 12, 0, 0, 108, 0, }, /* 802 */ + { 108, 10, 5, 0, 0, 108, 0, }, /* 803 */ + { 108, 12, 3, 0, 0, 108, 0, }, /* 804 */ + { 108, 21, 12, 0, 0, 108, 0, }, /* 805 */ + { 129, 7, 12, 0, 0, 129, 0, }, /* 806 */ + { 129, 21, 12, 0, 0, 129, 0, }, /* 807 */ + { 109, 7, 12, 0, 0, 109, 0, }, /* 808 */ + { 109, 12, 3, 0, 0, 109, 0, }, /* 809 */ + { 109, 10, 5, 0, 0, 109, 0, }, /* 810 */ + { 109, 13, 12, 0, 0, 109, 0, }, /* 811 */ + { 107, 12, 3, 0, 0, 107, 0, }, /* 812 */ + { 107, 12, 3, 0, 0, -52, 0, }, /* 813 */ + { 107, 10, 5, 0, 0, 107, 0, }, /* 814 */ + { 107, 10, 5, 0, 0, -52, 0, }, /* 815 */ + { 107, 7, 12, 0, 0, 107, 0, }, /* 816 */ + { 28, 12, 3, 0, 0, -52, 0, }, /* 817 */ + { 107, 10, 3, 0, 0, 107, 0, }, /* 818 */ + { 135, 7, 12, 0, 0, 135, 0, }, /* 819 */ + { 135, 10, 5, 0, 0, 135, 0, }, /* 820 */ + { 135, 12, 3, 0, 0, 135, 0, }, /* 821 */ + { 135, 21, 12, 0, 0, 135, 0, }, /* 822 */ + { 135, 13, 12, 0, 0, 135, 0, }, /* 823 */ + { 124, 7, 12, 0, 0, 124, 0, }, /* 824 */ + { 124, 10, 3, 0, 0, 124, 0, }, /* 825 */ + { 124, 10, 5, 0, 0, 124, 0, }, /* 826 */ + { 124, 12, 3, 0, 0, 124, 0, }, /* 827 */ + { 124, 21, 12, 0, 0, 124, 0, }, /* 828 */ + { 124, 13, 12, 0, 0, 124, 0, }, /* 829 */ + { 123, 7, 12, 0, 0, 123, 0, }, /* 830 */ + { 123, 10, 3, 0, 0, 123, 0, }, /* 831 */ + { 123, 10, 5, 0, 0, 123, 0, }, /* 832 */ + { 123, 12, 3, 0, 0, 123, 0, }, /* 833 */ + { 123, 21, 12, 0, 0, 123, 0, }, /* 834 */ + { 114, 7, 12, 0, 0, 114, 0, }, /* 835 */ + { 114, 10, 5, 0, 0, 114, 0, }, /* 836 */ + { 114, 12, 3, 0, 0, 114, 0, }, /* 837 */ + { 114, 21, 12, 0, 0, 114, 0, }, /* 838 */ + { 114, 13, 12, 0, 0, 114, 0, }, /* 839 */ + { 102, 7, 12, 0, 0, 102, 0, }, /* 840 */ + { 102, 12, 3, 0, 0, 102, 0, }, /* 841 */ + { 102, 10, 5, 0, 0, 102, 0, }, /* 842 */ + { 102, 13, 12, 0, 0, 102, 0, }, /* 843 */ + { 126, 7, 12, 0, 0, 126, 0, }, /* 844 */ + { 126, 12, 3, 0, 0, 126, 0, }, /* 845 */ + { 126, 10, 5, 0, 0, 126, 0, }, /* 846 */ + { 126, 13, 12, 0, 0, 126, 0, }, /* 847 */ + { 126, 15, 12, 0, 0, 126, 0, }, /* 848 */ + { 126, 21, 12, 0, 0, 126, 0, }, /* 849 */ + { 126, 26, 12, 0, 0, 126, 0, }, /* 850 */ + { 142, 7, 12, 0, 0, 142, 0, }, /* 851 */ + { 142, 10, 5, 0, 0, 142, 0, }, /* 852 */ + { 142, 12, 3, 0, 0, 142, 0, }, /* 853 */ + { 142, 21, 12, 0, 0, 142, 0, }, /* 854 */ + { 125, 9, 12, 0, 32, 125, 0, }, /* 855 */ + { 125, 5, 12, 0, -32, 125, 0, }, /* 856 */ + { 125, 13, 12, 0, 0, 125, 0, }, /* 857 */ + { 125, 15, 12, 0, 0, 125, 0, }, /* 858 */ + { 125, 7, 12, 0, 0, 125, 0, }, /* 859 */ + { 154, 7, 12, 0, 0, 154, 0, }, /* 860 */ + { 154, 10, 3, 0, 0, 154, 0, }, /* 861 */ + { 154, 10, 5, 0, 0, 154, 0, }, /* 862 */ + { 154, 12, 3, 0, 0, 154, 0, }, /* 863 */ + { 154, 7, 4, 0, 0, 154, 0, }, /* 864 */ + { 154, 21, 12, 0, 0, 154, 0, }, /* 865 */ + { 154, 13, 12, 0, 0, 154, 0, }, /* 866 */ + { 150, 7, 12, 0, 0, 150, 0, }, /* 867 */ + { 150, 10, 5, 0, 0, 150, 0, }, /* 868 */ + { 150, 12, 3, 0, 0, 150, 0, }, /* 869 */ + { 150, 21, 12, 0, 0, 150, 0, }, /* 870 */ + { 141, 7, 12, 0, 0, 141, 0, }, /* 871 */ + { 141, 12, 3, 0, 0, 141, 0, }, /* 872 */ + { 141, 10, 5, 0, 0, 141, 0, }, /* 873 */ + { 141, 7, 4, 0, 0, 141, 0, }, /* 874 */ + { 141, 21, 12, 0, 0, 141, 0, }, /* 875 */ + { 140, 7, 12, 0, 0, 140, 0, }, /* 876 */ + { 140, 12, 3, 0, 0, 140, 0, }, /* 877 */ + { 140, 10, 5, 0, 0, 140, 0, }, /* 878 */ + { 140, 7, 4, 0, 0, 140, 0, }, /* 879 */ + { 140, 21, 12, 0, 0, 140, 0, }, /* 880 */ + { 122, 7, 12, 0, 0, 122, 0, }, /* 881 */ + { 133, 7, 12, 0, 0, 133, 0, }, /* 882 */ + { 133, 10, 5, 0, 0, 133, 0, }, /* 883 */ + { 133, 12, 3, 0, 0, 133, 0, }, /* 884 */ + { 133, 21, 12, 0, 0, 133, 0, }, /* 885 */ + { 133, 13, 12, 0, 0, 133, 0, }, /* 886 */ + { 133, 15, 12, 0, 0, 133, 0, }, /* 887 */ + { 134, 21, 12, 0, 0, 134, 0, }, /* 888 */ + { 134, 7, 12, 0, 0, 134, 0, }, /* 889 */ + { 134, 12, 3, 0, 0, 134, 0, }, /* 890 */ + { 134, 10, 5, 0, 0, 134, 0, }, /* 891 */ + { 138, 7, 12, 0, 0, 138, 0, }, /* 892 */ + { 138, 12, 3, 0, 0, 138, 0, }, /* 893 */ + { 138, 7, 4, 0, 0, 138, 0, }, /* 894 */ + { 138, 13, 12, 0, 0, 138, 0, }, /* 895 */ + { 143, 7, 12, 0, 0, 143, 0, }, /* 896 */ + { 143, 10, 5, 0, 0, 143, 0, }, /* 897 */ + { 143, 12, 3, 0, 0, 143, 0, }, /* 898 */ + { 143, 13, 12, 0, 0, 143, 0, }, /* 899 */ + { 145, 7, 12, 0, 0, 145, 0, }, /* 900 */ + { 145, 12, 3, 0, 0, 145, 0, }, /* 901 */ + { 145, 10, 5, 0, 0, 145, 0, }, /* 902 */ + { 145, 21, 12, 0, 0, 145, 0, }, /* 903 */ + { 54, 15, 12, 0, 0, 54, 0, }, /* 904 */ + { 54, 21, 12, 0, 0, 54, 0, }, /* 905 */ + { 63, 7, 12, 0, 0, 63, 0, }, /* 906 */ + { 63, 14, 12, 0, 0, 63, 0, }, /* 907 */ + { 63, 21, 12, 0, 0, 63, 0, }, /* 908 */ + { 80, 7, 12, 0, 0, 80, 0, }, /* 909 */ + { 80, 1, 2, 0, 0, 80, 0, }, /* 910 */ + { 127, 7, 12, 0, 0, 127, 0, }, /* 911 */ + { 115, 7, 12, 0, 0, 115, 0, }, /* 912 */ + { 115, 13, 12, 0, 0, 115, 0, }, /* 913 */ + { 115, 21, 12, 0, 0, 115, 0, }, /* 914 */ + { 103, 7, 12, 0, 0, 103, 0, }, /* 915 */ + { 103, 12, 3, 0, 0, 103, 0, }, /* 916 */ + { 103, 21, 12, 0, 0, 103, 0, }, /* 917 */ + { 119, 7, 12, 0, 0, 119, 0, }, /* 918 */ + { 119, 12, 3, 0, 0, 119, 0, }, /* 919 */ + { 119, 21, 12, 0, 0, 119, 0, }, /* 920 */ + { 119, 26, 12, 0, 0, 119, 0, }, /* 921 */ + { 119, 6, 12, 0, 0, 119, 0, }, /* 922 */ + { 119, 13, 12, 0, 0, 119, 0, }, /* 923 */ + { 119, 15, 12, 0, 0, 119, 0, }, /* 924 */ + { 146, 9, 12, 0, 32, 146, 0, }, /* 925 */ + { 146, 5, 12, 0, -32, 146, 0, }, /* 926 */ + { 146, 15, 12, 0, 0, 146, 0, }, /* 927 */ + { 146, 21, 12, 0, 0, 146, 0, }, /* 928 */ + { 99, 7, 12, 0, 0, 99, 0, }, /* 929 */ + { 99, 12, 3, 0, 0, 99, 0, }, /* 930 */ + { 99, 10, 5, 0, 0, 99, 0, }, /* 931 */ + { 99, 6, 12, 0, 0, 99, 0, }, /* 932 */ + { 137, 6, 12, 0, 0, 137, 0, }, /* 933 */ + { 139, 6, 12, 0, 0, 139, 0, }, /* 934 */ + { 155, 12, 3, 0, 0, 155, 0, }, /* 935 */ + { 23, 10, 5, 0, 0, 23, 0, }, /* 936 */ + { 137, 7, 12, 0, 0, 137, 0, }, /* 937 */ + { 155, 7, 12, 0, 0, 155, 0, }, /* 938 */ + { 139, 7, 12, 0, 0, 139, 0, }, /* 939 */ + { 105, 7, 12, 0, 0, 105, 0, }, /* 940 */ + { 105, 26, 12, 0, 0, 105, 0, }, /* 941 */ + { 105, 12, 3, 0, 0, 105, 0, }, /* 942 */ + { 105, 21, 12, 0, 0, 105, 0, }, /* 943 */ + { 10, 1, 2, 0, 0, 105, 0, }, /* 944 */ + { 10, 10, 3, 0, 0, 10, 0, }, /* 945 */ + { 10, 10, 5, 0, 0, 10, 0, }, /* 946 */ + { 20, 12, 3, 0, 0, 20, 0, }, /* 947 */ + { 131, 26, 12, 0, 0, 131, 0, }, /* 948 */ + { 131, 12, 3, 0, 0, 131, 0, }, /* 949 */ + { 131, 21, 12, 0, 0, 131, 0, }, /* 950 */ + { 18, 12, 3, 0, 0, 18, 0, }, /* 951 */ + { 151, 7, 12, 0, 0, 151, 0, }, /* 952 */ + { 151, 12, 3, 0, 0, 151, 0, }, /* 953 */ + { 151, 6, 12, 0, 0, 151, 0, }, /* 954 */ + { 151, 13, 12, 0, 0, 151, 0, }, /* 955 */ + { 151, 26, 12, 0, 0, 151, 0, }, /* 956 */ + { 152, 7, 12, 0, 0, 152, 0, }, /* 957 */ + { 152, 12, 3, 0, 0, 152, 0, }, /* 958 */ + { 152, 13, 12, 0, 0, 152, 0, }, /* 959 */ + { 152, 23, 12, 0, 0, 152, 0, }, /* 960 */ + { 113, 7, 12, 0, 0, 113, 0, }, /* 961 */ + { 113, 15, 12, 0, 0, 113, 0, }, /* 962 */ + { 113, 12, 3, 0, 0, 113, 0, }, /* 963 */ + { 132, 9, 12, 0, 34, 132, 0, }, /* 964 */ + { 132, 5, 12, 0, -34, 132, 0, }, /* 965 */ + { 132, 12, 3, 0, 0, 132, 0, }, /* 966 */ + { 132, 6, 12, 0, 0, 132, 0, }, /* 967 */ + { 132, 13, 12, 0, 0, 132, 0, }, /* 968 */ + { 132, 21, 12, 0, 0, 132, 0, }, /* 969 */ + { 0, 2, 14, 0, 0, 0, 0, }, /* 970 */ + { 10, 26, 11, 0, 0, 10, 0, }, /* 971 */ + { 27, 26, 12, 0, 0, 27, 0, }, /* 972 */ + { 10, 24, 3, 0, 0, 10, 0, }, /* 973 */ + { 10, 1, 3, 0, 0, 10, 0, }, /* 974 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -1185,37 +1204,37 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F000 */ 126,126, 98, 98,127,128,129,130,131,131,132,133,134,135,136,137, /* U+F800 */ 138,139,140,141,142,143,144,145,146,147,148,142,149,149,150,142, /* U+10000 */ -151,152,153,154,155,156,157,158,159,160,161,142,162,142,163,164, /* U+10800 */ -165,166,167,168,169,170,171,142,172,173,142,174,175,176,177,142, /* U+11000 */ -178,179,142,180,181,182,142,142,183,184,185,186,142,187,142,188, /* U+11800 */ -189,189,189,189,189,189,189,190,191,189,192,142,142,142,142,142, /* U+12000 */ +151,152,153,154,155,156,157,158,159,160,161,142,162,163,164,165, /* U+10800 */ +166,167,168,169,170,171,172,142,173,174,142,175,176,177,178,142, /* U+11000 */ +179,180,181,182,183,184,142,142,185,186,187,188,142,189,142,190, /* U+11800 */ +191,191,191,191,191,191,191,192,193,191,194,142,142,142,142,142, /* U+12000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+12800 */ -193,193,193,193,193,193,193,193,194,142,142,142,142,142,142,142, /* U+13000 */ +195,195,195,195,195,195,195,195,196,142,142,142,142,142,142,142, /* U+13000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+13800 */ -142,142,142,142,142,142,142,142,195,195,195,195,196,142,142,142, /* U+14000 */ +142,142,142,142,142,142,142,142,197,197,197,197,198,142,142,142, /* U+14000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+14800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+16000 */ -197,197,197,197,198,199,200,201,142,142,142,142,202,203,204,205, /* U+16800 */ -206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17000 */ -206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17800 */ -206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,207, /* U+18000 */ -206,206,206,206,206,208,142,142,142,142,142,142,142,142,142,142, /* U+18800 */ +199,199,199,199,200,201,202,203,142,142,142,142,204,205,206,207, /* U+16800 */ +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, /* U+17000 */ +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, /* U+17800 */ +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,209, /* U+18000 */ +208,208,208,208,208,208,210,210,210,211,212,142,142,142,142,142, /* U+18800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A800 */ -209,210,211,212,212,213,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */ -142,142,142,142,142,142,142,142,214,215,142,142,142,142,142,142, /* U+1B800 */ +213,214,215,216,216,217,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */ +142,142,142,142,142,142,142,142,218,219,142,142,142,142,142,142, /* U+1B800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C800 */ - 71,216,217,218,219,220,221,142,222,223,224,225,226,227,228,229, /* U+1D000 */ -230,230,230,230,231,232,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */ -233,142,234,142,142,235,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */ -236,237,238,142,142,142,142,142,239,240,241,142,242,243,142,142, /* U+1E800 */ -244,245,246,247,248,249,250,251,250,250,252,250,253,254,255,256, /* U+1F000 */ -257,258,259,260,261,262,249,249,249,249,249,249,249,249,249,263, /* U+1F800 */ + 71,220,221,222,223,224,225,142,226,227,228,229,230,231,232,233, /* U+1D000 */ +234,234,234,234,235,236,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */ +237,142,238,142,142,239,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */ +240,241,242,142,142,142,142,142,243,244,245,142,246,247,142,142, /* U+1E800 */ +248,249,250,251,252,253,254,255,254,254,256,254,257,258,259,260, /* U+1F000 */ +261,262,263,264,265,266, 71,267,253,253,253,253,253,253,253,268, /* U+1F800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21000 */ @@ -1236,21 +1255,21 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29800 */ - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,264, 98, 98, /* U+2A000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,269, 98, 98, /* U+2A000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2A800 */ - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,265, 98, /* U+2B000 */ -266, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,270, 98, /* U+2B000 */ +271, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2C000 */ - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,267, 98, 98, /* U+2C800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,272, 98, 98, /* U+2C800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2E000 */ - 98, 98, 98, 98, 98, 98, 98,268,142,142,142,142,142,142,142,142, /* U+2E800 */ + 98, 98, 98, 98, 98, 98, 98,273,142,142,142,142,142,142,142,142, /* U+2E800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+2F000 */ - 98, 98, 98, 98,269,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */ -142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30000 */ -142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30800 */ -142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31000 */ + 98, 98, 98, 98,274,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+30000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+30800 */ + 98, 98, 98, 98, 98, 98,275,142,142,142,142,142,142,142,142,142, /* U+31000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+32000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+32800 */ @@ -1600,8 +1619,8 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF800 */ -270,271,272,273,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0000 */ -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0800 */ +276,277,278,279,277,277,277,277,277,277,277,277,277,277,277,277, /* U+E0000 */ +277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, /* U+E0800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2000 */ @@ -1663,7 +1682,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE000 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FF000 */ -126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+FF800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,280, /* U+FF800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100000 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101000 */ @@ -1695,10 +1714,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E000 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10F000 */ -126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+10F800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,280, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 71936 bytes, block = 128 */ /* block 0 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1810,474 +1829,474 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, /* block 11 */ -207,207,207,207,207,207,207,206,206,208,209,120,120,210,210,211, -120,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, -212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, -212,212,212,212,212,212,212,212,212,212,212,212,212,212,213,212, -214,212,212,214,212,212,214,212,120,120,120,120,120,120,120,120, -215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, -215,215,215,215,215,215,215,215,215,215,215,120,120,120,120,215, -215,215,215,214,214,120,120,120,120,120,120,120,120,120,120,120, +207,207,207,207,207,207,207,206,206,205,208,120,120,209,209,210, +120,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,212,211, +213,211,211,213,211,211,213,211,120,120,120,120,120,120,120,120, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,120,120,120,120,214, +214,214,214,213,213,120,120,120,120,120,120,120,120,120,120,120, /* block 12 */ -216,216,216,216,216,217,218,218,218,219,219,220,221,219,222,222, -223,223,223,223,223,223,223,223,223,223,223,221,224,120,219,221, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -226,225,225,225,225,225,225,225,225,225,225,227,227,227,227,227, -227,227,227,227,227,227,223,223,223,223,223,223,223,223,223,223, -228,228,228,228,228,228,228,228,228,228,219,219,219,219,225,225, -227,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +215,215,215,215,215,216,217,217,217,218,218,219,220,218,221,221, +222,222,222,222,222,222,222,222,222,222,222,220,223,120,218,220, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +225,224,224,224,224,224,224,224,224,224,224,226,226,226,226,226, +226,226,226,226,226,226,222,222,222,222,222,222,222,222,222,222, +227,227,227,227,227,227,227,227,227,227,218,218,218,218,224,224, +226,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /* block 13 */ -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,229,225,223,223,223,223,223,223,223,217,222,223, -223,223,223,223,223,230,230,223,223,222,223,223,223,223,225,225, -231,231,231,231,231,231,231,231,231,231,225,225,225,222,222,225, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,228,224,222,222,222,222,222,222,222,216,221,222, +222,222,222,222,222,229,229,222,222,221,222,222,222,222,224,224, +230,230,230,230,230,230,230,230,230,230,224,224,224,221,221,224, /* block 14 */ -232,232,232,232,232,232,232,232,232,232,232,232,232,232,120,233, -234,235,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,120,232, +233,234,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, 234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, -235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, -235,235,235,235,235,235,235,235,235,235,235,120,120,234,234,234, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +234,234,234,234,234,234,234,234,234,234,234,120,120,233,233,233, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /* block 15 */ -236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, -236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, -236,236,236,236,236,236,237,237,237,237,237,237,237,237,237,237, -237,236,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,239, -239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, -239,239,239,239,239,239,239,239,239,239,239,240,240,240,240,240, -240,240,240,240,241,241,242,243,243,243,241,120,120,240,244,244, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236, +236,235,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +237,237,237,237,237,237,237,237,237,237,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,239,239,239,239,239, +239,239,239,239,240,240,241,242,242,242,240,120,120,239,243,243, /* block 16 */ -245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, -245,245,245,245,245,245,246,246,246,246,247,246,246,246,246,246, -246,246,246,246,247,246,246,246,247,246,246,246,246,246,120,120, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,120, -249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, -249,249,249,249,249,249,249,249,249,250,250,250,120,120,251,120, -234,234,234,234,234,234,234,234,234,234,234,120,120,120,120,120, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,245,245,245,245,246,245,245,245,245,245, +245,245,245,245,246,245,245,245,246,245,245,245,245,245,120,120, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,120, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,249,249,249,120,120,250,120, +233,233,233,233,233,233,233,233,233,233,233,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 17 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,120,225,225,225,225,225,225,225,225,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,223,223,223,223,223,223,223,223,223,223,223,223,223, -223,223,217,223,223,223,223,223,223,223,223,223,223,223,223,223, -223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,120,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,120,120,120,120,120,120,120,120, +120,120,120,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,216,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, /* block 18 */ -252,252,252,253,254,254,254,254,254,254,254,254,254,254,254,254, -254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, -254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, -254,254,254,254,254,254,254,254,254,254,252,253,252,254,253,253, -253,252,252,252,252,252,252,252,252,253,253,253,253,252,253,253, -254,255,256,113,113,252,252,252,254,254,254,254,254,254,254,254, -254,254,252,252,257,258,259,259,259,259,259,259,259,259,259,259, -260,261,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +251,251,251,252,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,251,252,251,253,252,252, +252,251,251,251,251,251,251,251,251,252,252,252,252,251,252,252, +253,254,255,113,113,251,251,251,253,253,253,253,253,253,253,253, +253,253,251,251,256,257,258,258,258,258,258,258,258,258,258,258, +259,260,253,253,253,253,253,253,253,253,253,253,253,253,253,253, /* block 19 */ -262,263,264,264,120,262,262,262,262,262,262,262,262,120,120,262, -262,120,120,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,120,262,262,262,262,262,262, -262,120,262,120,120,120,262,262,262,262,120,120,263,262,265,264, -264,263,263,263,263,120,120,264,264,120,120,264,264,263,262,120, -120,120,120,120,120,120,120,265,120,120,120,120,262,262,120,262, -262,262,263,263,120,120,266,266,266,266,266,266,266,266,266,266, -262,262,267,267,268,268,268,268,268,268,269,267,262,270,263,120, +261,262,263,263,120,261,261,261,261,261,261,261,261,120,120,261, +261,120,120,261,261,261,261,261,261,261,261,261,261,261,261,261, +261,261,261,261,261,261,261,261,261,120,261,261,261,261,261,261, +261,120,261,120,120,120,261,261,261,261,120,120,262,261,264,263, +263,262,262,262,262,120,120,263,263,120,120,263,263,262,261,120, +120,120,120,120,120,120,120,264,120,120,120,120,261,261,120,261, +261,261,262,262,120,120,265,265,265,265,265,265,265,265,265,265, +261,261,266,266,267,267,267,267,267,267,268,266,261,269,262,120, /* block 20 */ -120,271,271,272,120,273,273,273,273,273,273,120,120,120,120,273, -273,120,120,273,273,273,273,273,273,273,273,273,273,273,273,273, -273,273,273,273,273,273,273,273,273,120,273,273,273,273,273,273, -273,120,273,273,120,273,273,120,273,273,120,120,271,120,272,272, -272,271,271,120,120,120,120,271,271,120,120,271,271,271,120,120, -120,271,120,120,120,120,120,120,120,273,273,273,273,120,273,120, -120,120,120,120,120,120,274,274,274,274,274,274,274,274,274,274, -271,271,273,273,273,271,275,120,120,120,120,120,120,120,120,120, +120,270,270,271,120,272,272,272,272,272,272,120,120,120,120,272, +272,120,120,272,272,272,272,272,272,272,272,272,272,272,272,272, +272,272,272,272,272,272,272,272,272,120,272,272,272,272,272,272, +272,120,272,272,120,272,272,120,272,272,120,120,270,120,271,271, +271,270,270,120,120,120,120,270,270,120,120,270,270,270,120,120, +120,270,120,120,120,120,120,120,120,272,272,272,272,120,272,120, +120,120,120,120,120,120,273,273,273,273,273,273,273,273,273,273, +270,270,272,272,272,270,274,120,120,120,120,120,120,120,120,120, /* block 21 */ -120,276,276,277,120,278,278,278,278,278,278,278,278,278,120,278, -278,278,120,278,278,278,278,278,278,278,278,278,278,278,278,278, -278,278,278,278,278,278,278,278,278,120,278,278,278,278,278,278, -278,120,278,278,120,278,278,278,278,278,120,120,276,278,277,277, -277,276,276,276,276,276,120,276,276,277,120,277,277,276,120,120, -278,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -278,278,276,276,120,120,279,279,279,279,279,279,279,279,279,279, -280,281,120,120,120,120,120,120,120,278,276,276,276,276,276,276, +120,275,275,276,120,277,277,277,277,277,277,277,277,277,120,277, +277,277,120,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,277,277,277,277,277,277,277,120,277,277,277,277,277,277, +277,120,277,277,120,277,277,277,277,277,120,120,275,277,276,276, +276,275,275,275,275,275,120,275,275,276,120,276,276,275,120,120, +277,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +277,277,275,275,120,120,278,278,278,278,278,278,278,278,278,278, +279,280,120,120,120,120,120,120,120,277,275,275,275,275,275,275, /* block 22 */ -120,282,283,283,120,284,284,284,284,284,284,284,284,120,120,284, -284,120,120,284,284,284,284,284,284,284,284,284,284,284,284,284, -284,284,284,284,284,284,284,284,284,120,284,284,284,284,284,284, -284,120,284,284,120,284,284,284,284,284,120,120,282,284,285,282, -283,282,282,282,282,120,120,283,283,120,120,283,283,282,120,120, -120,120,120,120,120,120,282,285,120,120,120,120,284,284,120,284, -284,284,282,282,120,120,286,286,286,286,286,286,286,286,286,286, -287,284,288,288,288,288,288,288,120,120,120,120,120,120,120,120, +120,281,282,282,120,283,283,283,283,283,283,283,283,120,120,283, +283,120,120,283,283,283,283,283,283,283,283,283,283,283,283,283, +283,283,283,283,283,283,283,283,283,120,283,283,283,283,283,283, +283,120,283,283,120,283,283,283,283,283,120,120,281,283,284,281, +282,281,281,281,281,120,120,282,282,120,120,282,282,281,120,120, +120,120,120,120,120,281,281,284,120,120,120,120,283,283,120,283, +283,283,281,281,120,120,285,285,285,285,285,285,285,285,285,285, +286,283,287,287,287,287,287,287,120,120,120,120,120,120,120,120, /* block 23 */ -120,120,289,290,120,290,290,290,290,290,290,120,120,120,290,290, -290,120,290,290,290,290,120,120,120,290,290,120,290,120,290,290, -120,120,120,290,290,120,120,120,290,290,290,120,120,120,290,290, -290,290,290,290,290,290,290,290,290,290,120,120,120,120,291,292, -289,292,292,120,120,120,292,292,292,120,292,292,292,289,120,120, -290,120,120,120,120,120,120,291,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,293,293,293,293,293,293,293,293,293,293, -294,294,294,295,296,296,296,296,296,297,296,120,120,120,120,120, +120,120,288,289,120,289,289,289,289,289,289,120,120,120,289,289, +289,120,289,289,289,289,120,120,120,289,289,120,289,120,289,289, +120,120,120,289,289,120,120,120,289,289,289,120,120,120,289,289, +289,289,289,289,289,289,289,289,289,289,120,120,120,120,290,291, +288,291,291,120,120,120,291,291,291,120,291,291,291,288,120,120, +289,120,120,120,120,120,120,290,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,292,292,292,292,292,292,292,292,292,292, +293,293,293,294,295,295,295,295,295,296,295,120,120,120,120,120, /* block 24 */ -298,299,299,299,298,300,300,300,300,300,300,300,300,120,300,300, -300,120,300,300,300,300,300,300,300,300,300,300,300,300,300,300, -300,300,300,300,300,300,300,300,300,120,300,300,300,300,300,300, -300,300,300,300,300,300,300,300,300,300,120,120,120,300,298,298, -298,299,299,299,299,120,298,298,298,120,298,298,298,298,120,120, -120,120,120,120,120,298,298,120,300,300,300,120,120,120,120,120, -300,300,298,298,120,120,301,301,301,301,301,301,301,301,301,301, -120,120,120,120,120,120,120,302,303,303,303,303,303,303,303,304, +297,298,298,298,297,299,299,299,299,299,299,299,299,120,299,299, +299,120,299,299,299,299,299,299,299,299,299,299,299,299,299,299, +299,299,299,299,299,299,299,299,299,120,299,299,299,299,299,299, +299,299,299,299,299,299,299,299,299,299,120,120,120,299,297,297, +297,298,298,298,298,120,297,297,297,120,297,297,297,297,120,120, +120,120,120,120,120,297,297,120,299,299,299,120,120,120,120,120, +299,299,297,297,120,120,300,300,300,300,300,300,300,300,300,300, +120,120,120,120,120,120,120,301,302,302,302,302,302,302,302,303, /* block 25 */ -305,306,307,307,308,305,305,305,305,305,305,305,305,120,305,305, -305,120,305,305,305,305,305,305,305,305,305,305,305,305,305,305, -305,305,305,305,305,305,305,305,305,120,305,305,305,305,305,305, -305,305,305,305,120,305,305,305,305,305,120,120,306,305,307,306, -307,307,309,307,307,120,306,307,307,120,307,307,306,306,120,120, -120,120,120,120,120,309,309,120,120,120,120,120,120,120,305,120, -305,305,306,306,120,120,310,310,310,310,310,310,310,310,310,310, -120,305,305,120,120,120,120,120,120,120,120,120,120,120,120,120, +304,305,306,306,307,304,304,304,304,304,304,304,304,120,304,304, +304,120,304,304,304,304,304,304,304,304,304,304,304,304,304,304, +304,304,304,304,304,304,304,304,304,120,304,304,304,304,304,304, +304,304,304,304,120,304,304,304,304,304,120,120,305,304,306,305, +306,306,308,306,306,120,305,306,306,120,306,306,305,305,120,120, +120,120,120,120,120,308,308,120,120,120,120,120,120,120,304,120, +304,304,305,305,120,120,309,309,309,309,309,309,309,309,309,309, +120,304,304,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 26 */ -311,311,312,312,120,313,313,313,313,313,313,313,313,120,313,313, -313,120,313,313,313,313,313,313,313,313,313,313,313,313,313,313, -313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, -313,313,313,313,313,313,313,313,313,313,313,311,311,313,314,312, -312,311,311,311,311,120,312,312,312,120,312,312,312,311,315,316, -120,120,120,120,313,313,313,314,317,317,317,317,317,317,317,313, -313,313,311,311,120,120,318,318,318,318,318,318,318,318,318,318, -317,317,317,317,317,317,317,317,317,316,313,313,313,313,313,313, +310,310,311,311,312,312,312,312,312,312,312,312,312,120,312,312, +312,120,312,312,312,312,312,312,312,312,312,312,312,312,312,312, +312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312, +312,312,312,312,312,312,312,312,312,312,312,310,310,312,313,311, +311,310,310,310,310,120,311,311,311,120,311,311,311,310,314,315, +120,120,120,120,312,312,312,313,316,316,316,316,316,316,316,312, +312,312,310,310,120,120,317,317,317,317,317,317,317,317,317,317, +316,316,316,316,316,316,316,316,316,315,312,312,312,312,312,312, /* block 27 */ -120,120,319,319,120,320,320,320,320,320,320,320,320,320,320,320, +120,318,319,319,120,320,320,320,320,320,320,320,320,320,320,320, 320,320,320,320,320,320,320,120,120,120,320,320,320,320,320,320, 320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320, 320,320,120,320,320,320,320,320,320,320,320,320,120,320,120,120, -320,320,320,320,320,320,320,120,120,120,321,120,120,120,120,322, -319,319,321,321,321,120,321,120,319,319,319,319,319,319,319,322, -120,120,120,120,120,120,323,323,323,323,323,323,323,323,323,323, -120,120,319,319,324,120,120,120,120,120,120,120,120,120,120,120, +320,320,320,320,320,320,320,120,120,120,318,120,120,120,120,321, +319,319,318,318,318,120,318,120,319,319,319,319,319,319,319,321, +120,120,120,120,120,120,322,322,322,322,322,322,322,322,322,322, +120,120,319,319,323,120,120,120,120,120,120,120,120,120,120,120, /* block 28 */ -120,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, -325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, -325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, -325,326,325,327,326,326,326,326,326,326,326,120,120,120,120, 6, -325,325,325,325,325,325,328,326,326,326,326,326,326,326,326,329, -330,330,330,330,330,330,330,330,330,330,329,329,120,120,120,120, +120,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324, +324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324, +324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324, +324,325,324,326,325,325,325,325,325,325,325,120,120,120,120, 6, +324,324,324,324,324,324,327,325,325,325,325,325,325,325,325,328, +329,329,329,329,329,329,329,329,329,329,328,328,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 29 */ -120,331,331,120,331,120,331,331,331,331,331,120,331,331,331,331, -331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331, -331,331,331,331,120,331,120,331,331,331,331,331,331,331,331,331, -331,332,331,333,332,332,332,332,332,332,332,332,332,331,120,120, -331,331,331,331,331,120,334,120,332,332,332,332,332,332,120,120, -335,335,335,335,335,335,335,335,335,335,120,120,331,331,331,331, +120,330,330,120,330,120,330,330,330,330,330,120,330,330,330,330, +330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330, +330,330,330,330,120,330,120,330,330,330,330,330,330,330,330,330, +330,331,330,332,331,331,331,331,331,331,331,331,331,330,120,120, +330,330,330,330,330,120,333,120,331,331,331,331,331,331,120,120, +334,334,334,334,334,334,334,334,334,334,120,120,330,330,330,330, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 30 */ -336,337,337,337,338,338,338,338,338,338,338,338,338,338,338,338, -338,338,338,337,338,337,337,337,339,339,337,337,337,337,337,337, -340,340,340,340,340,340,340,340,340,340,341,341,341,341,341,341, -341,341,341,341,337,339,337,339,337,339,342,343,342,343,344,344, -336,336,336,336,336,336,336,336,120,336,336,336,336,336,336,336, -336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336, -336,336,336,336,336,336,336,336,336,336,336,336,336,120,120,120, -120,339,339,339,339,339,339,339,339,339,339,339,339,339,339,344, +335,336,336,336,337,337,337,337,337,337,337,337,337,337,337,337, +337,337,337,336,337,336,336,336,338,338,336,336,336,336,336,336, +339,339,339,339,339,339,339,339,339,339,340,340,340,340,340,340, +340,340,340,340,336,338,336,338,336,338,341,342,341,342,343,343, +335,335,335,335,335,335,335,335,120,335,335,335,335,335,335,335, +335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335, +335,335,335,335,335,335,335,335,335,335,335,335,335,120,120,120, +120,338,338,338,338,338,338,338,338,338,338,338,338,338,338,343, /* block 31 */ -339,339,339,339,339,338,339,339,336,336,336,336,336,339,339,339, -339,339,339,339,339,339,339,339,120,339,339,339,339,339,339,339, -339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, -339,339,339,339,339,339,339,339,339,339,339,339,339,120,337,337, -337,337,337,337,337,337,339,337,337,337,337,337,337,120,337,337, -338,338,338,338,338, 20, 20, 20, 20,338,338,120,120,120,120,120, +338,338,338,338,338,337,338,338,335,335,335,335,335,338,338,338, +338,338,338,338,338,338,338,338,120,338,338,338,338,338,338,338, +338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338, +338,338,338,338,338,338,338,338,338,338,338,338,338,120,336,336, +336,336,336,336,336,336,338,336,336,336,336,336,336,120,336,336, +337,337,337,337,337, 20, 20, 20, 20,337,337,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 32 */ -345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345, -345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345, -345,345,345,345,345,345,345,345,345,345,345,346,346,347,347,347, -347,348,347,347,347,347,347,347,346,347,347,348,348,347,347,345, -349,349,349,349,349,349,349,349,349,349,350,350,350,350,350,350, -345,345,345,345,345,345,348,348,347,347,345,345,345,345,347,347, -347,345,346,346,346,345,345,346,346,346,346,346,346,346,345,345, -345,347,347,347,347,345,345,345,345,345,345,345,345,345,345,345, +344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, +344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, +344,344,344,344,344,344,344,344,344,344,344,345,345,346,346,346, +346,347,346,346,346,346,346,346,345,346,346,347,347,346,346,344, +348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349, +344,344,344,344,344,344,347,347,346,346,344,344,344,344,346,346, +346,344,345,345,345,344,344,345,345,345,345,345,345,345,344,344, +344,346,346,346,346,344,344,344,344,344,344,344,344,344,344,344, /* block 33 */ -345,345,347,346,348,347,347,346,346,346,346,346,346,347,345,346, -351,351,351,351,351,351,351,351,351,351,346,346,346,347,352,352, +344,344,346,345,347,346,346,345,345,345,345,345,345,346,344,345, +350,350,350,350,350,350,350,350,350,350,345,345,345,346,351,351, +352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352, +352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352, +352,352,352,352,352,352,120,352,120,120,120,120,120,352,120,120, 353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353, 353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353, -353,353,353,353,353,353,120,353,120,120,120,120,120,353,120,120, -354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354, -354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354, -354,354,354,354,354,354,354,354,354,354,354,355,356,354,354,354, +353,353,353,353,353,353,353,353,353,353,353,354,355,353,353,353, /* block 34 */ +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, + +/* block 35 */ 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, -357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, -357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, +357,357,357,357,357,357,357,357,358,358,358,358,358,358,358,358, 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, - -/* block 35 */ 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,359,359,359,359,359,359,359,359, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, + +/* block 36 */ 359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,120,359,359,359,359,120,120, +359,359,359,359,359,359,359,120,359,120,359,359,359,359,120,120, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, - -/* block 36 */ -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120, -360,360,360,360,360,360,360,120,360,120,360,360,360,360,120,120, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, /* block 37 */ -360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,120, -360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +359,359,359,359,359,359,359,359,359,120,359,359,359,359,120,120, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,120, +359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, /* block 38 */ -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,360,360,360,360,120,120,361,361,361, -362,362,362,362,362,362,362,362,362,363,363,363,363,363,363,363, -363,363,363,363,363,363,363,363,363,363,363,363,363,120,120,120, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,120,120,360,360,360, +361,361,361,361,361,361,361,361,361,362,362,362,362,362,362,362, +362,362,362,362,362,362,362,362,362,362,362,362,362,120,120,120, /* block 39 */ -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -364,364,364,364,364,364,364,364,364,364,120,120,120,120,120,120, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -366,366,366,366,366,366,120,120,367,367,367,367,367,367,120,120, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +363,363,363,363,363,363,363,363,363,363,120,120,120,120,120,120, +364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, +364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, +364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, +364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, +364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, +365,365,365,365,365,365,120,120,366,366,366,366,366,366,120,120, /* block 40 */ -368,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +367,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, /* block 41 */ -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, /* block 42 */ -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,370,371,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,369,370,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, /* block 43 */ -372,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -373,373,373,373,373,373,373,373,373,373,373,374,375,120,120,120, -376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, -376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, -376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, -376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, -376,376,376,376,376,376,376,376,376,376,376, 5, 5, 5,377,377, -377,376,376,376,376,376,376,376,376,120,120,120,120,120,120,120, +371,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, +372,372,372,372,372,372,372,372,372,372,372,373,374,120,120,120, +375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375, +375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375, +375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375, +375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375, +375,375,375,375,375,375,375,375,375,375,375, 5, 5, 5,376,376, +376,375,375,375,375,375,375,375,375,120,120,120,120,120,120,120, /* block 44 */ -378,378,378,378,378,378,378,378,378,378,378,378,378,120,378,378, -378,378,379,379,379,120,120,120,120,120,120,120,120,120,120,120, -380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, -380,380,381,381,381,382,382,120,120,120,120,120,120,120,120,120, -383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, -383,383,384,384,120,120,120,120,120,120,120,120,120,120,120,120, -385,385,385,385,385,385,385,385,385,385,385,385,385,120,385,385, -385,120,386,386,120,120,120,120,120,120,120,120,120,120,120,120, +377,377,377,377,377,377,377,377,377,377,377,377,377,120,377,377, +377,377,378,378,378,120,120,120,120,120,120,120,120,120,120,120, +379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379, +379,379,380,380,380,381,381,120,120,120,120,120,120,120,120,120, +382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382, +382,382,383,383,120,120,120,120,120,120,120,120,120,120,120,120, +384,384,384,384,384,384,384,384,384,384,384,384,384,120,384,384, +384,120,385,385,120,120,120,120,120,120,120,120,120,120,120,120, /* block 45 */ -387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, -387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, -387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, -387,387,387,387,388,388,389,388,388,388,388,388,388,388,389,389, -389,389,389,389,389,389,388,389,389,388,388,388,388,388,388,388, -388,388,388,388,390,390,390,391,390,390,390,392,387,388,120,120, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,387,387,388,387,387,387,387,387,387,387,388,388, +388,388,388,388,388,388,387,388,388,387,387,387,387,387,387,387, +387,387,387,387,389,389,389,390,389,389,389,391,386,387,120,120, +392,392,392,392,392,392,392,392,392,392,120,120,120,120,120,120, 393,393,393,393,393,393,393,393,393,393,120,120,120,120,120,120, -394,394,394,394,394,394,394,394,394,394,120,120,120,120,120,120, /* block 46 */ -395,395,396,396,395,396,397,395,395,395,395,398,398,398,399,120, -400,400,400,400,400,400,400,400,400,400,120,120,120,120,120,120, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,402,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,120,120,120,120,120,120,120, +394,394,395,395,394,395,396,394,394,394,394,397,397,397,398,120, +399,399,399,399,399,399,399,399,399,399,120,120,120,120,120,120, +400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, +400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, +400,400,400,401,400,400,400,400,400,400,400,400,400,400,400,400, +400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, +400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, +400,400,400,400,400,400,400,400,400,120,120,120,120,120,120,120, /* block 47 */ -401,401,401,401,401,398,398,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,398,401,120,120,120,120,120, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,120,120,120,120,120,120,120,120,120,120, +400,400,400,400,400,397,397,400,400,400,400,400,400,400,400,400, +400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, +400,400,400,400,400,400,400,400,400,397,400,120,120,120,120,120, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, +368,368,368,368,368,368,120,120,120,120,120,120,120,120,120,120, /* block 48 */ -403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, -403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,120, -404,404,404,405,405,405,405,404,404,405,405,405,120,120,120,120, -405,405,404,405,405,405,405,405,405,404,404,404,120,120,120,120, -406,120,120,120,407,407,408,408,408,408,408,408,408,408,408,408, -409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409, -409,409,409,409,409,409,409,409,409,409,409,409,409,409,120,120, -409,409,409,409,409,120,120,120,120,120,120,120,120,120,120,120, +402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, +402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,120, +403,403,403,404,404,404,404,403,403,404,404,404,120,120,120,120, +404,404,403,404,404,404,404,404,404,403,403,403,120,120,120,120, +405,120,120,120,406,406,407,407,407,407,407,407,407,407,407,407, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,120,120, +408,408,408,408,408,120,120,120,120,120,120,120,120,120,120,120, /* block 49 */ -410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, -410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, -410,410,410,410,410,410,410,410,410,410,410,410,120,120,120,120, -410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, -410,410,410,410,410,410,410,410,410,410,120,120,120,120,120,120, -411,411,411,411,411,411,411,411,411,411,412,120,120,120,413,413, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409, +409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409, +409,409,409,409,409,409,409,409,409,409,409,409,120,120,120,120, +409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409, +409,409,409,409,409,409,409,409,409,409,120,120,120,120,120,120, +410,410,410,410,410,410,410,410,410,410,411,120,120,120,412,412, +413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, +413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, /* block 50 */ -415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, -415,415,415,415,415,415,415,416,416,417,417,416,120,120,418,418, -419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, -419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, -419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, -419,419,419,419,419,420,421,420,421,421,421,421,421,421,421,120, -421,422,421,422,422,421,421,421,421,421,421,421,421,420,420,420, -420,420,420,421,421,421,421,421,421,421,421,421,421,120,120,421, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,415,415,416,416,415,120,120,417,417, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,419,420,419,420,420,420,420,420,420,420,120, +420,421,420,421,421,420,420,420,420,420,420,420,420,419,419,419, +419,419,419,420,420,420,420,420,420,420,420,420,420,120,120,420, /* block 51 */ -423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120, -423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120, -424,424,424,424,424,424,424,425,424,424,424,424,424,424,120,120, -113,113,113,113,113,113,113,113,113,113,113,113,113,113,426,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +422,422,422,422,422,422,422,422,422,422,120,120,120,120,120,120, +422,422,422,422,422,422,422,422,422,422,120,120,120,120,120,120, +423,423,423,423,423,423,423,424,423,423,423,423,423,423,120,120, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,425,113, +113,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 52 */ -427,427,427,427,428,429,429,429,429,429,429,429,429,429,429,429, -429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429, -429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429, -429,429,429,429,427,430,427,427,427,427,427,428,427,428,428,428, -428,428,427,428,428,429,429,429,429,429,429,429,120,120,120,120, -431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432, -432,433,433,433,433,433,433,433,433,433,433,427,427,427,427,427, -427,427,427,427,433,433,433,433,433,433,433,433,433,120,120,120, +426,426,426,426,427,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,426,429,426,426,426,426,426,427,426,427,427,427, +427,427,426,427,427,428,428,428,428,428,428,428,120,120,120,120, +430,430,430,430,430,430,430,430,430,430,431,431,431,431,431,431, +431,432,432,432,432,432,432,432,432,432,432,426,426,426,426,426, +426,426,426,426,432,432,432,432,432,432,432,432,432,120,120,120, /* block 53 */ -434,434,435,436,436,436,436,436,436,436,436,436,436,436,436,436, -436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436, -436,435,434,434,434,434,435,435,434,434,435,434,434,434,436,436, -437,437,437,437,437,437,437,437,437,437,436,436,436,436,436,436, -438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, -438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, -438,438,438,438,438,438,439,440,439,439,440,440,440,439,440,439, -439,439,440,440,120,120,120,120,120,120,120,120,441,441,441,441, +433,433,434,435,435,435,435,435,435,435,435,435,435,435,435,435, +435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435, +435,434,433,433,433,433,434,434,433,433,434,433,433,433,435,435, +436,436,436,436,436,436,436,436,436,436,435,435,435,435,435,435, +437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, +437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, +437,437,437,437,437,437,438,439,438,438,439,439,439,438,439,438, +438,438,439,439,120,120,120,120,120,120,120,120,440,440,440,440, /* block 54 */ -442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442, -442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442, -442,442,442,442,443,443,443,443,443,443,443,443,444,444,444,444, -444,444,444,444,443,443,444,444,120,120,120,445,445,445,445,445, -446,446,446,446,446,446,446,446,446,446,120,120,120,442,442,442, -447,447,447,447,447,447,447,447,447,447,448,448,448,448,448,448, -448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, -448,448,448,448,448,448,448,448,449,449,449,449,449,449,450,450, +441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441, +441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441, +441,441,441,441,442,442,442,442,442,442,442,442,443,443,443,443, +443,443,443,443,442,442,443,443,120,120,120,444,444,444,444,444, +445,445,445,445,445,445,445,445,445,445,120,120,120,441,441,441, +446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447, +447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447, +447,447,447,447,447,447,447,447,448,448,448,448,448,448,449,449, /* block 55 */ -451,452,453,454,455,456,457,458,459,120,120,120,120,120,120,120, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,120,120,460,460,460, -461,461,461,461,461,461,461,461,120,120,120,120,120,120,120,120, -462,463,462,464,463,465,465,466,465,466,467,463,466,466,463,463, -466,468,463,463,463,463,463,463,463,469,470,471,471,465,471,471, -471,471,472,473,474,470,470,475,476,476,477,120,120,120,120,120, +450,451,452,453,454,455,456,457,458,120,120,120,120,120,120,120, +459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459, +459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459, +459,459,459,459,459,459,459,459,459,459,459,120,120,459,459,459, +460,460,460,460,460,460,460,460,120,120,120,120,120,120,120,120, +461,462,461,463,462,464,464,465,464,465,466,462,465,465,462,462, +465,467,462,462,462,462,462,462,462,468,469,470,470,464,470,470, +470,470,471,472,473,469,469,474,475,475,476,120,120,120,120,120, /* block 56 */ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35,128,128,128,128,128,478,110,110,110,110, + 35, 35, 35, 35, 35, 35,128,128,128,128,128,477,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,121,121,121, 121,121,110,110,110,110,121,121,121,121,121, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35,479,480, 35, 35, 35,481, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35,478,479, 35, 35, 35,480, 35, 35, /* block 57 */ - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,482, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,481, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,121, 114,114,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, -113,113,113,113,113,113,113,113,113,113,120,113,113,113,113,113, +113,113,113,113,113,113,113,113,482,113,120,113,113,113,113,113, /* block 58 */ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, @@ -2335,8 +2354,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -113,113,113,113,113,113,113,113,113,113,113,113,113,426,426,426, -426,113,426,426,426,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,425,425,425, +425,113,425,425,425,113,113,113,113,113,113,113,113,113,113,113, 512,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 64 */ @@ -2511,7 +2530,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ /* block 81 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -2550,12 +2569,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 550,120,120,120,120,120,120,120,120,120,120,120,120,120,120,551, /* block 85 */ -360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120, -360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, -360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, -360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, -360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,120,120,120,120,120,120,120,120,120, +359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120, +359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120, +359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120, +359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120, 552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, 552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, @@ -2565,7 +2584,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,111, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 5, 5, 5, 5, 10, 5, 7,553, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + 20, 20, 5,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -2633,7 +2652,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120, 572,572,582,582,582,582,572,572,572,572,572,572,572,572,572,572, 580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, -580,580,580,580,580,580,580,580,580,580,580,120,120,120,120,120, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, 572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, 572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, 572,572,572,572,120,120,120,120,120,120,120,120,120,120,120,120, @@ -2693,7 +2712,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -586,586,586,586,586,586,120,120,120,120,120,120,120,120,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -2707,7 +2726,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,120, /* block 101 */ 587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, @@ -2757,11 +2776,11 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 192,193,192,193,192,193,192,193,192,193,597,598,192,193,192,193, 192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, 192,193,192,193,192,193,192,193,192,193,192,193,192,193,599,198, -200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,479, +200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,478, /* block 106 */ 192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, -192,193,192,193,192,193,192,193,192,193,192,193,479,479,552,552, +192,193,192,193,192,193,192,193,192,193,192,193,478,478,552,552, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, @@ -2770,196 +2789,186 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 603,603,604,604,604,604,604,604,120,120,120,120,120,120,120,120, /* block 107 */ - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +605,605,605,605,605,605,605,605, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111, 15, 15, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, -110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,605, 32, 33, +110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,606, 32, 33, /* block 108 */ - 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,606, 35, 22, - 32, 33, 32, 33,607, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, - 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,608,609,610,611,608, 35, -612,613,614,615, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, -120,120, 32, 33,616,617,618,120,120,120,120,120,120,120,120,120, + 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,607, 35, 22, + 32, 33, 32, 33,608, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, + 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,609,610,611,612,609, 35, +613,614,615,616, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, +120,120, 32, 33,617,618,619, 32, 33, 32, 33,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120, 22,110,110, 35, 22, 22, 22, 22, 22, +120,120,120,120,120, 32, 33, 22,110,110, 35, 22, 22, 22, 22, 22, /* block 109 */ -619,619,620,619,619,619,620,619,619,619,619,620,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,621,621,620,620,621,622,622,622,622,120,120,120,120, -623,623,623,624,624,624,625,625,626,625,120,120,120,120,120,120, -627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, -627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, -627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, -627,627,627,627,628,628,628,628,120,120,120,120,120,120,120,120, +620,620,621,620,620,620,621,620,620,620,620,621,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,622,622,621,621,622,623,623,623,623,621,120,120,120, +624,624,624,625,625,625,626,626,627,626,120,120,120,120,120,120, +628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628, +628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628, +628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628, +628,628,628,628,629,629,629,629,120,120,120,120,120,120,120,120, /* block 110 */ -629,629,630,630,630,630,630,630,630,630,630,630,630,630,630,630, -630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630, -630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630, -630,630,630,630,629,629,629,629,629,629,629,629,629,629,629,629, -629,629,629,629,631,631,120,120,120,120,120,120,120,120,632,632, -633,633,633,633,633,633,633,633,633,633,120,120,120,120,120,120, -252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, -252,634,254,635,254,254,254,254,260,260,260,254,260,254,254,252, +630,630,631,631,631,631,631,631,631,631,631,631,631,631,631,631, +631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631, +631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631, +631,631,631,631,630,630,630,630,630,630,630,630,630,630,630,630, +630,630,630,630,632,632,120,120,120,120,120,120,120,120,633,633, +634,634,634,634,634,634,634,634,634,634,120,120,120,120,120,120, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,635,253,636,253,253,253,253,259,259,259,253,259,253,253,251, /* block 111 */ -636,636,636,636,636,636,636,636,636,636,637,637,637,637,637,637, -637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637, -637,637,637,637,637,637,638,638,638,638,638,638,638,638,639,640, -641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641, -641,641,641,641,641,641,641,642,642,642,642,642,642,642,642,642, -642,642,643,643,120,120,120,120,120,120,120,120,120,120,120,644, -357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, -357,357,357,357,357,357,357,357,357,357,357,357,357,120,120,120, +637,637,637,637,637,637,637,637,637,637,638,638,638,638,638,638, +638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638, +638,638,638,638,638,638,639,639,639,639,639,639,639,639,640,641, +642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642, +642,642,642,642,642,642,642,643,643,643,643,643,643,643,643,643, +643,643,644,644,120,120,120,120,120,120,120,120,120,120,120,645, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,356,356,356,356,356,356,120,120,120, /* block 112 */ -645,645,645,646,647,647,647,647,647,647,647,647,647,647,647,647, -647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647, -647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647, -647,647,647,645,646,646,645,645,645,645,646,646,645,645,646,646, -646,648,648,648,648,648,648,648,648,648,648,648,648,648,120,649, -650,650,650,650,650,650,650,650,650,650,120,120,120,120,648,648, -345,345,345,345,345,347,651,345,345,345,345,345,345,345,345,345, -351,351,351,351,351,351,351,351,351,351,345,345,345,345,345,120, +646,646,646,647,648,648,648,648,648,648,648,648,648,648,648,648, +648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, +648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, +648,648,648,646,647,647,646,646,646,646,647,647,646,646,647,647, +647,649,649,649,649,649,649,649,649,649,649,649,649,649,120,650, +651,651,651,651,651,651,651,651,651,651,120,120,120,120,649,649, +344,344,344,344,344,346,652,344,344,344,344,344,344,344,344,344, +350,350,350,350,350,350,350,350,350,350,344,344,344,344,344,120, /* block 113 */ -652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652, -652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652, -652,652,652,652,652,652,652,652,652,653,653,653,653,653,653,654, -654,653,653,654,654,653,653,120,120,120,120,120,120,120,120,120, -652,652,652,653,652,652,652,652,652,652,652,652,653,654,120,120, -655,655,655,655,655,655,655,655,655,655,120,120,656,656,656,656, -345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345, -651,345,345,345,345,345,345,352,352,352,345,346,347,346,345,345, +653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653, +653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653, +653,653,653,653,653,653,653,653,653,654,654,654,654,654,654,655, +655,654,654,655,655,654,654,120,120,120,120,120,120,120,120,120, +653,653,653,654,653,653,653,653,653,653,653,653,654,655,120,120, +656,656,656,656,656,656,656,656,656,656,120,120,657,657,657,657, +344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, +652,344,344,344,344,344,344,351,351,351,344,345,346,345,344,344, /* block 114 */ -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -658,657,658,658,658,657,657,658,658,657,657,657,657,657,658,658, -657,658,657,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,657,657,659,660,660, -661,661,661,661,661,661,661,661,661,661,661,662,663,663,662,662, -664,664,661,665,665,662,663,120,120,120,120,120,120,120,120,120, +658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, +658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, +658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, +659,658,659,659,659,658,658,659,659,658,658,658,658,658,659,659, +658,659,658,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,658,658,660,661,661, +662,662,662,662,662,662,662,662,662,662,662,663,664,664,663,663, +665,665,662,666,666,663,664,120,120,120,120,120,120,120,120,120, /* block 115 */ -120,360,360,360,360,360,360,120,120,360,360,360,360,360,360,120, -120,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120, -360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, +120,359,359,359,359,359,359,120,120,359,359,359,359,359,359,120, +120,359,359,359,359,359,359,120,120,120,120,120,120,120,120,120, +359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35,666, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110, - 35, 35, 35, 35, 35,128, 35, 35,120,120,120,120,120,120,120,120, -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, + 35, 35, 35,667, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110, + 35, 35, 35, 35, 35,128, 35, 35, 35,110, 15, 15,120,120,120,120, +668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668, /* block 116 */ -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, -661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661, -661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661, -661,661,661,662,662,663,662,662,663,662,662,664,662,663,120,120, -668,668,668,668,668,668,668,668,668,668,120,120,120,120,120,120, +668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668, +668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668, +668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668, +668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668, +662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662, +662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662, +662,662,662,663,663,664,663,663,664,663,663,665,663,664,120,120, +669,669,669,669,669,669,669,669,669,669,120,120,120,120,120,120, /* block 117 */ -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, /* block 118 */ -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, /* block 119 */ -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, /* block 120 */ -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, /* block 121 */ -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, /* block 122 */ -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, - -/* block 123 */ -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, - -/* block 124 */ -670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,120,120,120,120,120,120,120,120,120,120,120,120, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,120,120,120,120,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,120,120,120,120, - -/* block 125 */ +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, + +/* block 123 */ 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, + +/* block 124 */ +671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671, 671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,120,120,120,120,120,120,120,120,120,120,120,120, +357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, +357,357,357,357,357,357,357,120,120,120,120,358,358,358,358,358, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,358,358,358,358,358,120,120,120,120, -/* block 126 */ +/* block 125 */ 672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, 672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, 672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, @@ -2969,6 +2978,16 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, 672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +/* block 126 */ +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, + /* block 127 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, @@ -2991,53 +3010,53 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ /* block 129 */ 35, 35, 35, 35, 35, 35, 35,120,120,120,120,120,120,120,120,120, -120,120,120,206,206,206,206,206,120,120,120,120,120,215,212,215, -215,215,215,215,215,215,215,215,215,673,215,215,215,215,215,215, -215,215,215,215,215,215,215,120,215,215,215,215,215,120,215,120, -215,215,120,215,215,120,215,215,215,215,215,215,215,215,215,215, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +120,120,120,206,206,206,206,206,120,120,120,120,120,214,211,214, +214,214,214,214,214,214,214,214,214,674,214,214,214,214,214,214, +214,214,214,214,214,214,214,120,214,214,214,214,214,120,214,120, +214,214,120,214,214,120,214,214,214,214,214,214,214,214,214,214, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /* block 130 */ -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,674,674,674,674,674,674,674,674,674,674,674,674,674,674, -674,674,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,675,675,675,675,675,675,675,675,675,675,675,675,675,675, +675,675,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /* block 131 */ -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /* block 132 */ -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225, 8, 7, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224, 8, 7, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, /* block 133 */ -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -120,120,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,120,120,120,120,120,120,120,120, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +120,120,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -225,225,675,225,225,225,225,225,225,225,225,225,220,676,120,120, +224,224,676,224,224,224,224,224,224,224,224,224,219,677,120,120, /* block 134 */ 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, @@ -3047,17 +3066,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 8, 7, 8, 7, 8,556,556, 7, 8, 5, 5, 5, 5, 16, 16, 16, 5, 5, 5,120, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5, 5, 5, 9, 10, 9, 9, 9,120, 5, 6, 5, 5,120,120,120,120, -225,225,225,225,225,120,225,225,225,225,225,225,225,225,225,225, +224,224,224,224,224,120,224,224,224,224,224,224,224,224,224,224, /* block 135 */ -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,120,120, 24, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,120,120, 24, /* block 136 */ 120, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5, @@ -3071,7 +3090,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ /* block 137 */ 578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,677,677, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,678,678, 581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, 581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120, 120,120,581,581,581,581,581,581,120,120,581,581,581,581,581,581, @@ -3080,39 +3099,39 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 511,511,511,511,511,511,511,511,511, 24, 24, 24, 20, 20,120,120, /* block 138 */ -678,678,678,678,678,678,678,678,678,678,678,678,120,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,120,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,120,678,678,120,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120, +679,679,679,679,679,679,679,679,679,679,679,679,120,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,120,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,120,679,679,120,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,120,120, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 139 */ -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,678,678,678,678,678,678,678,678,678,678,120,120,120,120,120, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679, +679,679,679,679,679,679,679,679,679,679,679,120,120,120,120,120, /* block 140 */ -679,679,679,120,120,120,120,680,680,680,680,680,680,680,680,680, -680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680, -680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680, -680,680,680,680,120,120,120,681,681,681,681,681,681,681,681,681, -682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, -682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, -682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, -682,682,682,682,682,683,683,683,683,684,684,684,684,684,684,684, +680,680,680,120,120,120,120,681,681,681,681,681,681,681,681,681, +681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681, +681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681, +681,681,681,681,120,120,120,682,682,682,682,682,682,682,682,682, +683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683, +683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683, +683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683, +683,683,683,683,683,684,684,684,684,685,685,685,685,685,685,685, /* block 141 */ -684,684,684,684,684,684,684,684,684,684,683,683,684,684,684,120, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120, -684,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +685,685,685,685,685,685,685,685,685,685,684,684,685,685,685,120, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120, +685,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -3130,159 +3149,159 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 143 */ -685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685, -685,685,685,685,685,685,685,685,685,685,685,685,685,120,120,120, -686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686, 686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686, -686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686, -686,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -687,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688, -688,688,688,688,688,688,688,688,688,688,688,688,120,120,120,120, +686,686,686,686,686,686,686,686,686,686,686,686,686,120,120,120, +687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687, +687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687, +687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687, +687,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +688,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, +689,689,689,689,689,689,689,689,689,689,689,689,120,120,120,120, /* block 144 */ -689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, -689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, -690,690,690,690,120,120,120,120,120,120,120,120,120,689,689,689, -691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691, -691,692,691,691,691,691,691,691,691,691,692,120,120,120,120,120, -693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693, -693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693, -693,693,693,693,693,693,694,694,694,694,694,120,120,120,120,120, +690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690, +690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690, +691,691,691,691,120,120,120,120,120,120,120,120,120,690,690,690, +692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692, +692,693,692,692,692,692,692,692,692,692,693,120,120,120,120,120, +694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694, +694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694, +694,694,694,694,694,694,695,695,695,695,695,120,120,120,120,120, /* block 145 */ -695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695, -695,695,695,695,695,695,695,695,695,695,695,695,695,695,120,696, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,120,120,120,120,697,697,697,697,697,697,697,697, -698,699,699,699,699,699,120,120,120,120,120,120,120,120,120,120, +696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696, +696,696,696,696,696,696,696,696,696,696,696,696,696,696,120,697, +698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698, +698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698, +698,698,698,698,120,120,120,120,698,698,698,698,698,698,698,698, +699,700,700,700,700,700,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 146 */ -700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700, -700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700, -700,700,700,700,700,700,700,700,701,701,701,701,701,701,701,701, 701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701, 701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701, +701,701,701,701,701,701,701,701,702,702,702,702,702,702,702,702, 702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, 702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, -702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, +703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703, +703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703, +703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703, /* block 147 */ -703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703, -703,703,703,703,703,703,703,703,703,703,703,703,703,703,120,120, -704,704,704,704,704,704,704,704,704,704,120,120,120,120,120,120, -705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705, -705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705, -705,705,705,705,120,120,120,120,706,706,706,706,706,706,706,706, +704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704, +704,704,704,704,704,704,704,704,704,704,704,704,704,704,120,120, +705,705,705,705,705,705,705,705,705,705,120,120,120,120,120,120, +706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706, 706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706, -706,706,706,706,706,706,706,706,706,706,706,706,120,120,120,120, +706,706,706,706,120,120,120,120,707,707,707,707,707,707,707,707, +707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +707,707,707,707,707,707,707,707,707,707,707,707,120,120,120,120, /* block 148 */ -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,120,120,120,120,120,120,120,120, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, 708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, 708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,120,120,120,120,120,120,120,120,120,120,120,709, +708,708,708,708,708,708,708,708,120,120,120,120,120,120,120,120, +709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709, +709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709, +709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709, +709,709,709,709,120,120,120,120,120,120,120,120,120,120,120,710, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 149 */ -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, /* block 150 */ -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,710,120,120,120,120,120,120,120,120,120, -710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, -710,710,710,710,710,710,120,120,120,120,120,120,120,120,120,120, -710,710,710,710,710,710,710,710,120,120,120,120,120,120,120,120, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,120,120,120,120,120,120,120,120,120, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,120,120,120,120,120,120,120,120,120,120, +711,711,711,711,711,711,711,711,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 151 */ -711,711,711,711,711,711,120,120,711,120,711,711,711,711,711,711, -711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, -711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, -711,711,711,711,711,711,120,711,711,120,120,120,711,120,120,711, +712,712,712,712,712,712,120,120,712,120,712,712,712,712,712,712, +712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712, 712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712, -712,712,712,712,712,712,120,713,714,714,714,714,714,714,714,714, -715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715, -715,715,715,715,715,715,715,716,716,717,717,717,717,717,717,717, +712,712,712,712,712,712,120,712,712,120,120,120,712,120,120,712, +713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713, +713,713,713,713,713,713,120,714,715,715,715,715,715,715,715,715, +716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, +716,716,716,716,716,716,716,717,717,718,718,718,718,718,718,718, /* block 152 */ -718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718, -718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,120, -120,120,120,120,120,120,120,719,719,719,719,719,719,719,719,719, +719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719, +719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,120, +120,120,120,120,120,120,120,720,720,720,720,720,720,720,720,720, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720, -720,720,720,120,720,720,120,120,120,120,120,721,721,721,721,721, +721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721, +721,721,721,120,721,721,120,120,120,120,120,722,722,722,722,722, /* block 153 */ -722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722, -722,722,722,722,722,722,723,723,723,723,723,723,120,120,120,724, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,120,120,120,120,120,726, +723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +723,723,723,723,723,723,724,724,724,724,724,724,120,120,120,725, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,120,120,120,120,120,727, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 154 */ -727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727, -727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727, 728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728, -728,728,728,728,728,728,728,728,120,120,120,120,729,729,728,728, -729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729, -120,120,729,729,729,729,729,729,729,729,729,729,729,729,729,729, -729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729, +728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728, 729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729, +729,729,729,729,729,729,729,729,120,120,120,120,730,730,729,729, +730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730, +120,120,730,730,730,730,730,730,730,730,730,730,730,730,730,730, +730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730, +730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730, /* block 155 */ -730,731,731,731,120,731,731,120,120,120,120,120,731,731,731,731, -730,730,730,730,120,730,730,730,120,730,730,730,730,730,730,730, -730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730, -730,730,730,730,730,730,120,120,731,731,731,120,120,120,120,731, -732,732,732,732,732,732,732,732,732,120,120,120,120,120,120,120, +731,732,732,732,120,732,732,120,120,120,120,120,732,732,732,732, +731,731,731,731,120,731,731,731,120,731,731,731,731,731,731,731, +731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731, +731,731,731,731,731,731,120,120,732,732,732,120,120,120,120,732, 733,733,733,733,733,733,733,733,733,120,120,120,120,120,120,120, -734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734, -734,734,734,734,734,734,734,734,734,734,734,734,734,735,735,736, +734,734,734,734,734,734,734,734,734,120,120,120,120,120,120,120, +735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735, +735,735,735,735,735,735,735,735,735,735,735,735,735,736,736,737, /* block 156 */ -737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737, -737,737,737,737,737,737,737,737,737,737,737,737,737,738,738,738, +738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738, +738,738,738,738,738,738,738,738,738,738,738,738,738,739,739,739, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -739,739,739,739,739,739,739,739,740,739,739,739,739,739,739,739, -739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739, -739,739,739,739,739,741,741,120,120,120,120,742,742,742,742,742, -743,743,743,743,743,743,743,120,120,120,120,120,120,120,120,120, +740,740,740,740,740,740,740,740,741,740,740,740,740,740,740,740, +740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, +740,740,740,740,740,742,742,120,120,120,120,743,743,743,743,743, +744,744,744,744,744,744,744,120,120,120,120,120,120,120,120,120, /* block 157 */ -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,120,120,120,745,745,745,745,745,745,745, -746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746, -746,746,746,746,746,746,120,120,747,747,747,747,747,747,747,747, -748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748, -748,748,748,120,120,120,120,120,749,749,749,749,749,749,749,749, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,120,120,120,746,746,746,746,746,746,746, +747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747, +747,747,747,747,747,747,120,120,748,748,748,748,748,748,748,748, +749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749, +749,749,749,120,120,120,120,120,750,750,750,750,750,750,750,750, /* block 158 */ -750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750, -750,750,120,120,120,120,120,120,120,751,751,751,751,120,120,120, -120,120,120,120,120,120,120,120,120,752,752,752,752,752,752,752, +751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, +751,751,120,120,120,120,120,120,120,752,752,752,752,120,120,120, +120,120,120,120,120,120,120,120,120,753,753,753,753,753,753,753, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -3290,30 +3309,30 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 159 */ -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,120,120,120,120,120,120,120, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 160 */ -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, -754,754,754,120,120,120,120,120,120,120,120,120,120,120,120,120, 755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755, 755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755, 755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755, -755,755,755,120,120,120,120,120,120,120,756,756,756,756,756,756, +755,755,755,120,120,120,120,120,120,120,120,120,120,120,120,120, +756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, +756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, +756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, +756,756,756,120,120,120,120,120,120,120,757,757,757,757,757,757, /* block 161 */ -757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, -757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, -757,757,757,757,758,758,758,758,120,120,120,120,120,120,120,120, -759,759,759,759,759,759,759,759,759,759,120,120,120,120,120,120, +758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758, +758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758, +758,758,758,758,759,759,759,759,120,120,120,120,120,120,120,120, +760,760,760,760,760,760,760,760,760,760,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -3326,350 +3345,370 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760, -760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,120, +761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761, +761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,120, /* block 163 */ -761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761, -761,761,761,761,761,761,761,761,761,761,761,761,761,762,762,762, -762,762,762,762,762,762,762,761,120,120,120,120,120,120,120,120, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,764,764,764,764,764,764,764,764,764,764, -764,765,765,765,765,766,766,766,766,766,120,120,120,120,120,120, +762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762, +762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762, +762,762,762,762,762,762,762,762,762,762,120,763,763,764,120,120, +762,762,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 164 */ +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,766,766,766, +766,766,766,766,766,766,766,765,120,120,120,120,120,120,120,120, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,768,768,768,768,768,768,768,768,768,768, +768,769,769,769,769,770,770,770,770,770,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 165 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771, +771,771,771,771,771,772,772,772,772,772,772,772,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, -767,767,767,767,767,767,767,120,120,120,120,120,120,120,120,120, - -/* block 165 */ -768,769,768,770,770,770,770,770,770,770,770,770,770,770,770,770, -770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770, -770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770, -770,770,770,770,770,770,770,770,769,769,769,769,769,769,769,769, -769,769,769,769,769,769,769,771,771,771,771,771,771,771,120,120, -120,120,772,772,772,772,772,772,772,772,772,772,772,772,772,772, -772,772,772,772,772,772,773,773,773,773,773,773,773,773,773,773, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,769, +773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773, +773,773,773,773,773,773,773,120,120,120,120,120,120,120,120,120, /* block 166 */ -774,774,775,776,776,776,776,776,776,776,776,776,776,776,776,776, +774,775,774,776,776,776,776,776,776,776,776,776,776,776,776,776, 776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776, 776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776, -775,775,775,774,774,774,774,775,775,774,774,777,777,778,777,777, -777,777,120,120,120,120,120,120,120,120,120,120,120,778,120,120, -779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779, -779,779,779,779,779,779,779,779,779,120,120,120,120,120,120,120, -780,780,780,780,780,780,780,780,780,780,120,120,120,120,120,120, +776,776,776,776,776,776,776,776,775,775,775,775,775,775,775,775, +775,775,775,775,775,775,775,777,777,777,777,777,777,777,120,120, +120,120,778,778,778,778,778,778,778,778,778,778,778,778,778,778, +778,778,778,778,778,778,779,779,779,779,779,779,779,779,779,779, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,775, /* block 167 */ -781,781,781,782,782,782,782,782,782,782,782,782,782,782,782,782, +780,780,781,782,782,782,782,782,782,782,782,782,782,782,782,782, 782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,781,781,781,781,781,783,781,781,781, -781,781,781,781,781,120,784,784,784,784,784,784,784,784,784,784, -785,785,785,785,782,783,783,120,120,120,120,120,120,120,120,120, -786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786, -786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786, -786,786,786,787,788,788,786,120,120,120,120,120,120,120,120,120, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +781,781,781,780,780,780,780,781,781,780,780,783,783,784,783,783, +783,783,120,120,120,120,120,120,120,120,120,120,120,784,120,120, +785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785, +785,785,785,785,785,785,785,785,785,120,120,120,120,120,120,120, +786,786,786,786,786,786,786,786,786,786,120,120,120,120,120,120, /* block 168 */ -789,789,790,791,791,791,791,791,791,791,791,791,791,791,791,791, -791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791, -791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791, -791,791,791,790,790,790,789,789,789,789,789,789,789,789,789,790, -790,791,792,792,791,793,793,793,793,789,789,789,789,793,120,120, -794,794,794,794,794,794,794,794,794,794,791,793,791,793,793,793, -120,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795, -795,795,795,795,795,120,120,120,120,120,120,120,120,120,120,120, +787,787,787,788,788,788,788,788,788,788,788,788,788,788,788,788, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, +788,788,788,788,788,788,788,787,787,787,787,787,789,787,787,787, +787,787,787,787,787,120,790,790,790,790,790,790,790,790,790,790, +791,791,791,791,788,789,789,788,120,120,120,120,120,120,120,120, +792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792, +792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792, +792,792,792,793,794,794,792,120,120,120,120,120,120,120,120,120, /* block 169 */ -796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796, -796,796,120,796,796,796,796,796,796,796,796,796,796,796,796,796, -796,796,796,796,796,796,796,796,796,796,796,796,797,797,797,798, -798,798,797,797,798,797,798,798,799,799,799,799,799,799,798,120, +795,795,796,797,797,797,797,797,797,797,797,797,797,797,797,797, +797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797, +797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797, +797,797,797,796,796,796,795,795,795,795,795,795,795,795,795,796, +796,797,798,798,797,799,799,799,799,795,795,795,795,799,796,795, +800,800,800,800,800,800,800,800,800,800,797,799,797,799,799,799, +120,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, +801,801,801,801,801,120,120,120,120,120,120,120,120,120,120,120, + +/* block 170 */ +802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802, +802,802,120,802,802,802,802,802,802,802,802,802,802,802,802,802, +802,802,802,802,802,802,802,802,802,802,802,802,803,803,803,804, +804,804,803,803,804,803,804,804,805,805,805,805,805,805,804,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 170 */ -800,800,800,800,800,800,800,120,800,120,800,800,800,800,120,800, -800,800,800,800,800,800,800,800,800,800,800,800,800,800,120,800, -800,800,800,800,800,800,800,800,800,801,120,120,120,120,120,120, -802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802, -802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802, -802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,803, -804,804,804,803,803,803,803,803,803,803,803,120,120,120,120,120, -805,805,805,805,805,805,805,805,805,805,120,120,120,120,120,120, - /* block 171 */ -806,807,808,809,120,810,810,810,810,810,810,810,810,120,120,810, -810,120,120,810,810,810,810,810,810,810,810,810,810,810,810,810, -810,810,810,810,810,810,810,810,810,120,810,810,810,810,810,810, -810,120,810,810,120,810,810,810,810,810,120,811,807,810,812,808, -806,808,808,808,808,120,120,808,808,120,120,808,808,808,120,120, -810,120,120,120,120,120,120,812,120,120,120,120,120,810,810,810, -810,810,808,808,120,120,806,806,806,806,806,806,806,120,120,120, -806,806,806,806,806,120,120,120,120,120,120,120,120,120,120,120, +806,806,806,806,806,806,806,120,806,120,806,806,806,806,120,806, +806,806,806,806,806,806,806,806,806,806,806,806,806,806,120,806, +806,806,806,806,806,806,806,806,806,807,120,120,120,120,120,120, +808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808, +808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808, +808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,809, +810,810,810,809,809,809,809,809,809,809,809,120,120,120,120,120, +811,811,811,811,811,811,811,811,811,811,120,120,120,120,120,120, /* block 172 */ -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, -813,813,813,813,813,814,814,814,815,815,815,815,815,815,815,815, -814,814,815,815,815,814,815,813,813,813,813,816,816,816,816,816, -817,817,817,817,817,817,817,817,817,817,120,816,120,816,815,813, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +812,813,814,815,120,816,816,816,816,816,816,816,816,120,120,816, +816,120,120,816,816,816,816,816,816,816,816,816,816,816,816,816, +816,816,816,816,816,816,816,816,816,120,816,816,816,816,816,816, +816,120,816,816,120,816,816,816,816,816,120,817,813,816,818,814, +812,814,814,814,814,120,120,814,814,120,120,814,814,814,120,120, +816,120,120,120,120,120,120,818,120,120,120,120,120,816,816,816, +816,816,814,814,120,120,812,812,812,812,812,812,812,120,120,120, +812,812,812,812,812,120,120,120,120,120,120,120,120,120,120,120, /* block 173 */ -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -819,820,820,821,821,821,821,821,821,820,821,820,820,819,820,821, -821,820,821,821,818,818,822,818,120,120,120,120,120,120,120,120, -823,823,823,823,823,823,823,823,823,823,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,819,820,820,820,821,821,821,821,821,821,821,821, +820,820,821,821,821,820,821,819,819,819,819,822,822,822,822,822, +823,823,823,823,823,823,823,823,823,823,822,822,120,822,821,819, +819,819,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 174 */ 824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, 824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,825, -826,826,827,827,827,827,120,120,826,826,826,826,827,827,826,827, -827,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,824,824,824,824,827,827,120,120, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +825,826,826,827,827,827,827,827,827,826,827,826,826,825,826,827, +827,826,827,827,824,824,828,824,120,120,120,120,120,120,120,120, +829,829,829,829,829,829,829,829,829,829,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 175 */ -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -830,830,830,831,831,831,831,831,831,831,831,830,830,831,830,831, -831,832,832,832,829,120,120,120,120,120,120,120,120,120,120,120, -833,833,833,833,833,833,833,833,833,833,120,120,120,120,120,120, -395,395,395,395,395,395,395,395,395,395,395,395,395,120,120,120, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,831, +832,832,833,833,833,833,120,120,832,832,832,832,833,833,832,833, +833,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,830,830,830,830,833,833,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 176 */ -834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, -834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, -834,834,834,834,834,834,834,834,834,834,834,835,836,835,836,836, -835,835,835,835,835,835,836,835,834,120,120,120,120,120,120,120, -837,837,837,837,837,837,837,837,837,837,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, +835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, +835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, +836,836,836,837,837,837,837,837,837,837,837,836,836,837,836,837, +837,838,838,838,835,120,120,120,120,120,120,120,120,120,120,120, +839,839,839,839,839,839,839,839,839,839,120,120,120,120,120,120, +394,394,394,394,394,394,394,394,394,394,394,394,394,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 177 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,120,120,839,839,839, -840,840,839,839,839,839,840,839,839,839,839,839,120,120,120,120, -841,841,841,841,841,841,841,841,841,841,842,842,843,843,843,844, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,841,842,841,842,842, +841,841,841,841,841,841,842,841,840,120,120,120,120,120,120,120, +843,843,843,843,843,843,843,843,843,843,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 178 */ -845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, -845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, -845,845,845,845,845,845,845,845,845,845,845,845,846,846,846,847, -847,847,847,847,847,847,847,847,846,847,847,848,120,120,120,120, +844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844, +844,844,844,844,844,844,844,844,844,844,844,120,120,845,845,845, +846,846,845,845,845,845,846,845,845,845,845,845,120,120,120,120, +847,847,847,847,847,847,847,847,847,847,848,848,849,849,849,850, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 179 */ +851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851, +851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851, +851,851,851,851,851,851,851,851,851,851,851,851,852,852,852,853, +853,853,853,853,853,853,853,853,852,853,853,854,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, -849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, -850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850, -850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850, -851,851,851,851,851,851,851,851,851,851,852,852,852,852,852,852, -852,852,852,120,120,120,120,120,120,120,120,120,120,120,120,853, /* block 180 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -854,854,854,854,854,854,854,854,120,120,854,854,854,854,854,854, -854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854, -854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854, -854,855,855,855,856,856,856,856,120,120,856,856,855,855,855,855, -856,854,857,854,855,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855, +855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855, +856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856, +856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856, +857,857,857,857,857,857,857,857,857,857,858,858,858,858,858,858, +858,858,858,120,120,120,120,120,120,120,120,120,120,120,120,859, /* block 181 */ -858,859,859,859,859,859,859,859,859,859,859,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,859,859,859,859,859,859,860,861,859,859,859,859,862, -862,862,862,862,862,862,862,859,120,120,120,120,120,120,120,120, -863,864,864,864,864,864,864,865,865,864,864,864,863,863,863,863, -863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863, -863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863, +860,860,860,860,860,860,860,120,120,860,120,120,860,860,860,860, +860,860,860,860,120,860,860,120,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +861,862,862,862,862,862,120,862,862,120,120,863,863,862,863,864, +862,864,862,863,865,865,865,120,120,120,120,120,120,120,120,120, +866,866,866,866,866,866,866,866,866,866,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 182 */ -863,863,863,863,866,866,866,866,866,866,864,864,864,864,864,864, -864,864,864,864,864,864,864,865,864,864,867,867,867,863,867,867, -867,867,867,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868, -868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868, -868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868, -868,868,868,868,868,868,868,868,868,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +867,867,867,867,867,867,867,867,120,120,867,867,867,867,867,867, +867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,867, +867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,867, +867,868,868,868,869,869,869,869,120,120,869,869,868,868,868,868, +869,867,870,867,868,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 183 */ -869,869,869,869,869,869,869,869,869,120,869,869,869,869,869,869, -869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869, -869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,870, -871,871,871,871,871,871,871,120,871,871,871,871,871,871,870,871, -869,872,872,872,872,872,120,120,120,120,120,120,120,120,120,120, -873,873,873,873,873,873,873,873,873,873,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,120,120,120, -875,875,876,876,876,876,876,876,876,876,876,876,876,876,876,876, +871,872,872,872,872,872,872,872,872,872,872,871,871,871,871,871, +871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,871, +871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,871, +871,871,871,872,872,872,872,872,872,873,874,872,872,872,872,875, +875,875,875,875,875,875,875,872,120,120,120,120,120,120,120,120, +876,877,877,877,877,877,877,878,878,877,877,877,876,876,876,876, +876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, +876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, /* block 184 */ -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -120,120,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,120,878,877,877,877,877,877,877, -877,878,877,877,878,877,877,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +876,876,876,876,879,879,879,879,879,879,877,877,877,877,877,877, +877,877,877,877,877,877,877,878,877,877,880,880,880,876,880,880, +880,880,880,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881, +881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881, +881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881, +881,881,881,881,881,881,881,881,881,120,120,120,120,120,120,120, /* block 185 */ -879,879,879,879,879,879,879,120,879,879,120,879,879,879,879,879, -879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879, -879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879, -879,880,880,880,880,880,880,120,120,120,880,120,880,880,120,880, -880,880,880,880,880,880,881,880,120,120,120,120,120,120,120,120, -882,882,882,882,882,882,882,882,882,882,120,120,120,120,120,120, -883,883,883,883,883,883,120,883,883,120,883,883,883,883,883,883, -883,883,883,883,883,883,883,883,883,883,883,883,883,883,883,883, +882,882,882,882,882,882,882,882,882,120,882,882,882,882,882,882, +882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,882, +882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,883, +884,884,884,884,884,884,884,120,884,884,884,884,884,884,883,884, +882,885,885,885,885,885,120,120,120,120,120,120,120,120,120,120, +886,886,886,886,886,886,886,886,886,886,887,887,887,887,887,887, +887,887,887,887,887,887,887,887,887,887,887,887,887,120,120,120, +888,888,889,889,889,889,889,889,889,889,889,889,889,889,889,889, /* block 186 */ -883,883,883,883,883,883,883,883,883,883,884,884,884,884,884,120, -885,885,120,884,884,885,884,885,883,120,120,120,120,120,120,120, -886,886,886,886,886,886,886,886,886,886,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +889,889,889,889,889,889,889,889,889,889,889,889,889,889,889,889, +120,120,890,890,890,890,890,890,890,890,890,890,890,890,890,890, +890,890,890,890,890,890,890,890,120,891,890,890,890,890,890,890, +890,891,890,890,891,890,890,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 187 */ +892,892,892,892,892,892,892,120,892,892,120,892,892,892,892,892, +892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892, +892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892, +892,893,893,893,893,893,893,120,120,120,893,120,893,893,120,893, +893,893,893,893,893,893,894,893,120,120,120,120,120,120,120,120, +895,895,895,895,895,895,895,895,895,895,120,120,120,120,120,120, +896,896,896,896,896,896,120,896,896,120,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, + +/* block 188 */ +896,896,896,896,896,896,896,896,896,896,897,897,897,897,897,120, +898,898,120,897,897,898,897,898,896,120,120,120,120,120,120,120, +899,899,899,899,899,899,899,899,899,899,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -887,887,887,887,887,887,887,887,887,887,887,887,887,887,887,887, -887,887,887,888,888,889,889,890,890,120,120,120,120,120,120,120, -/* block 188 */ -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +/* block 189 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -294,294,891,294,891,296,296,296,296,296,296,296,296,297,297,297, -297,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, -296,296,120,120,120,120,120,120,120,120,120,120,120,120,120,892, - -/* block 189 */ -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, - -/* block 190 */ -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, +900,900,900,901,901,902,902,903,903,120,120,120,120,120,120,120, + +/* block 190 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +590,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,904, +293,293,904,293,904,295,295,295,295,295,295,295,295,296,296,296, +296,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295, +295,295,120,120,120,120,120,120,120,120,120,120,120,120,120,905, /* block 191 */ -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,120, -895,895,895,895,895,120,120,120,120,120,120,120,120,120,120,120, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, /* block 192 */ -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,120,120,120,120,120,120,120,120,120,120,120,120, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 193 */ -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,120, +908,908,908,908,908,120,120,120,120,120,120,120,120,120,120,120, /* block 194 */ -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,120, -897,897,897,897,897,897,897,897,897,120,120,120,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906, +906,906,906,906,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 195 */ -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, /* block 196 */ -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, -898,898,898,898,898,898,898,120,120,120,120,120,120,120,120,120, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,120, +910,910,910,910,910,910,910,910,910,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 197 */ +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, + +/* block 198 */ +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 199 */ 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, @@ -3679,38 +3718,38 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, -/* block 198 */ +/* block 200 */ 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, 601,601,601,601,601,601,601,601,601,120,120,120,120,120,120,120, -899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,899, -899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,120, -900,900,900,900,900,900,900,900,900,900,120,120,120,120,901,901, +912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, +912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,120, +913,913,913,913,913,913,913,913,913,913,120,120,120,120,914,914, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 199 */ +/* block 201 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,120,120, -903,903,903,903,903,904,120,120,120,120,120,120,120,120,120,120, +915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, +915,915,915,915,915,915,915,915,915,915,915,915,915,915,120,120, +916,916,916,916,916,917,120,120,120,120,120,120,120,120,120,120, -/* block 200 */ -905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, -905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, -905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, -906,906,906,906,906,906,906,907,907,907,907,907,908,908,908,908, -909,909,909,909,907,908,120,120,120,120,120,120,120,120,120,120, -910,910,910,910,910,910,910,910,910,910,120,911,911,911,911,911, -911,911,120,905,905,905,905,905,905,905,905,905,905,905,905,905, -905,905,905,905,905,905,905,905,120,120,120,120,120,905,905,905, +/* block 202 */ +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +919,919,919,919,919,919,919,920,920,920,920,920,921,921,921,921, +922,922,922,922,920,921,120,120,120,120,120,120,120,120,120,120, +923,923,923,923,923,923,923,923,923,923,120,924,924,924,924,924, +924,924,120,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,120,120,120,120,120,918,918,918, -/* block 201 */ -905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +/* block 203 */ +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -3719,19 +3758,19 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 202 */ +/* block 204 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, -913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, +925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,925, +925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,925, +926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,926, +926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,926, -/* block 203 */ -914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914, -914,914,914,914,914,914,914,915,915,915,915,120,120,120,120,120, +/* block 205 */ +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +927,927,927,927,927,927,927,928,928,928,928,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -3739,57 +3778,77 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 204 */ -916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, -916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, -916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, -916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, -916,916,916,916,916,916,916,916,916,916,916,120,120,120,120,917, -916,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +/* block 206 */ +929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, +929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, +929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, +929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, +929,929,929,929,929,929,929,929,929,929,929,120,120,120,120,930, +929,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931, +931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931, +931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931, -/* block 205 */ -918,918,918,918,918,918,918,918,120,120,120,120,120,120,120,917, -917,917,917,919,919,919,919,919,919,919,919,919,919,919,919,919, -120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +/* block 207 */ +931,931,931,931,931,931,931,931,120,120,120,120,120,120,120,930, +930,930,930,932,932,932,932,932,932,932,932,932,932,932,932,932, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -920,921, 5,111,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, - -/* block 206 */ -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, - -/* block 207 */ -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,120,120,120,120,120,120,120,120, +933,934, 5,111,935,120,120,120,120,120,120,120,120,120,120,120, +936,936,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 208 */ -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, -922,922,922,120,120,120,120,120,120,120,120,120,120,120,120,120, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, /* block 209 */ +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937, +937,937,937,937,937,937,937,937,120,120,120,120,120,120,120,120, + +/* block 210 */ +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, + +/* block 211 */ +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 212 */ +937,937,937,937,937,937,937,937,937,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 213 */ 578,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, @@ -3799,7 +3858,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, -/* block 210 */ +/* block 214 */ 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, @@ -3809,7 +3868,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, -/* block 211 */ +/* block 215 */ 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, 573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -3817,49 +3876,49 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 573,573,573,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,578,578,578,578,120,120,120,120,120,120,120,120, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, -/* block 212 */ -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +/* block 216 */ +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, -/* block 213 */ -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,120,120,120,120, +/* block 217 */ +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939, +939,939,939,939,939,939,939,939,939,939,939,939,120,120,120,120, -/* block 214 */ -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,120,120,120,120,120, -924,924,924,924,924,924,924,924,924,924,924,924,924,120,120,120, +/* block 218 */ +940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940, +940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940, +940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940, +940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940, +940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940, +940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940, +940,940,940,940,940,940,940,940,940,940,940,120,120,120,120,120, +940,940,940,940,940,940,940,940,940,940,940,940,940,120,120,120, -/* block 215 */ -924,924,924,924,924,924,924,924,924,120,120,120,120,120,120,120, -924,924,924,924,924,924,924,924,924,924,120,120,925,926,926,927, -928,928,928,928,120,120,120,120,120,120,120,120,120,120,120,120, +/* block 219 */ +940,940,940,940,940,940,940,940,940,120,120,120,120,120,120,120, +940,940,940,940,940,940,940,940,940,940,120,120,941,942,942,943, +944,944,944,944,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 216 */ +/* block 220 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -3869,17 +3928,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,120, -/* block 217 */ +/* block 221 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20,929,930,113,113,113, 20, 20, 20,930,929,929, -929,929,929, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113, + 20, 20, 20, 20, 20,945,946,113,113,113, 20, 20, 20,946,945,945, +945,945,945, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113, -/* block 218 */ +/* block 222 */ 113,113,113, 20, 20,113,113,113,113,113,113,113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,113,113,113, 20, 20, @@ -3889,17 +3948,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 219 */ -684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, -684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, -684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, -684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, -684,684,931,931,931,684,120,120,120,120,120,120,120,120,120,120, +/* block 223 */ +685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685, +685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685, +685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685, +685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685, +685,685,947,947,947,685,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 220 */ +/* block 224 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -3909,7 +3968,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 221 */ +/* block 225 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -3919,7 +3978,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582, 582,582, 25, 25, 25, 25, 25, 25, 25,120,120,120,120,120,120,120, -/* block 222 */ +/* block 226 */ 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, @@ -3929,7 +3988,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -/* block 223 */ +/* block 227 */ 513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,513,120,513,513, 120,120,513,120,120,513,513,120,120,513,513,513,513,120,513,513, @@ -3939,7 +3998,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, -/* block 224 */ +/* block 228 */ 514,514,514,514,513,513,120,513,513,513,513,120,120,513,513,513, 513,513,513,513,513,120,513,513,513,513,513,513,513,120,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, @@ -3949,7 +4008,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 514,514,514,514,514,514,514,514,514,514,514,514,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -/* block 225 */ +/* block 229 */ 513,513,513,513,513,513,514,514,514,514,514,514,514,514,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, @@ -3959,7 +4018,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 513,513,513,513,513,513,513,513,513,513,513,513,513,513,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, -/* block 226 */ +/* block 230 */ 514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514, @@ -3969,7 +4028,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -/* block 227 */ +/* block 231 */ 513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 514,514,514,514,514,514,120,120,513,513,513,513,513,513,513,513, @@ -3979,7 +4038,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 514,514,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,513, 9,514,514,514,514, -/* block 228 */ +/* block 232 */ 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 514,514,514,514,514, 9,514,514,514,514,514,514,513,513,513,513, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, @@ -3989,7 +4048,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 9, 514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, -/* block 229 */ +/* block 233 */ 514,514,514,514,514,514,514,514,514, 9,514,514,514,514,514,514, 513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 513,513,513,513,513,513,513,513,513, 9,514,514,514,514,514,514, @@ -3999,97 +4058,97 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -/* block 230 */ -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, -932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +/* block 234 */ +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, -/* block 231 */ -933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, -933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, -933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, -933,933,933,933,933,933,933,932,932,932,932,933,933,933,933,933, -933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, -933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, -933,933,933,933,933,933,933,933,933,933,933,933,933,932,932,932, -932,932,932,932,932,933,932,932,932,932,932,932,932,932,932,932, +/* block 235 */ +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,948,948,948,948,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,948,948,948, +948,948,948,948,948,949,948,948,948,948,948,948,948,948,948,948, -/* block 232 */ -932,932,932,932,933,932,932,934,934,934,934,934,120,120,120,120, -120,120,120,120,120,120,120,120,120,120,120,933,933,933,933,933, -120,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +/* block 236 */ +948,948,948,948,949,948,948,950,950,950,950,950,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,949,949,949,949,949, +120,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 233 */ -935,935,935,935,935,935,935,120,935,935,935,935,935,935,935,935, -935,935,935,935,935,935,935,935,935,120,120,935,935,935,935,935, -935,935,120,935,935,120,935,935,935,935,935,120,120,120,120,120, +/* block 237 */ +951,951,951,951,951,951,951,120,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,120,120,951,951,951,951,951, +951,951,120,951,951,120,951,951,951,951,951,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 234 */ -936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936, -936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936, -936,936,936,936,936,936,936,936,936,936,936,936,936,120,120,120, -937,937,937,937,937,937,937,938,938,938,938,938,938,938,120,120, -939,939,939,939,939,939,939,939,939,939,120,120,120,120,936,940, +/* block 238 */ +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,120,120,120, +953,953,953,953,953,953,953,954,954,954,954,954,954,954,120,120, +955,955,955,955,955,955,955,955,955,955,120,120,120,120,952,956, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 235 */ +/* block 239 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941, -941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941, -941,941,941,941,941,941,941,941,941,941,941,941,942,942,942,942, -943,943,943,943,943,943,943,943,943,943,120,120,120,120,120,944, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +957,957,957,957,957,957,957,957,957,957,957,957,958,958,958,958, +959,959,959,959,959,959,959,959,959,959,120,120,120,120,120,960, -/* block 236 */ -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +/* block 240 */ +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -/* block 237 */ -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,120,120,946,946,946,946,946,946,946,946,946, -947,947,947,947,947,947,947,120,120,120,120,120,120,120,120,120, +/* block 241 */ +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,120,120,962,962,962,962,962,962,962,962,962, +963,963,963,963,963,963,963,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 238 */ -948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, -948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, -948,948,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,950,950,950,950,950,950,950,951,120,120,120,120, -952,952,952,952,952,952,952,952,952,952,120,120,120,120,953,953, +/* block 242 */ +964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, +964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, +964,964,965,965,965,965,965,965,965,965,965,965,965,965,965,965, +965,965,965,965,965,965,965,965,965,965,965,965,965,965,965,965, +965,965,965,965,966,966,966,966,966,966,966,967,120,120,120,120, +968,968,968,968,968,968,968,968,968,968,120,120,120,120,969,969, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 239 */ +/* block 243 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -4099,7 +4158,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -/* block 240 */ +/* block 244 */ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25, @@ -4109,7 +4168,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 241 */ +/* block 245 */ 120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, @@ -4119,87 +4178,87 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 242 */ -225,225,225,225,120,225,225,225,225,225,225,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, -120,225,225,120,225,120,120,225,120,225,225,225,225,225,225,225, -225,225,225,120,225,225,225,225,120,225,120,225,120,120,120,120, -120,120,225,120,120,120,120,225,120,225,120,225,120,225,225,225, -120,225,225,120,225,120,120,225,120,225,120,225,120,225,120,225, -120,225,225,120,225,120,120,225,225,225,225,120,225,225,225,225, -225,225,225,120,225,225,225,225,120,225,225,225,225,120,225,120, +/* block 246 */ +224,224,224,224,120,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +120,224,224,120,224,120,120,224,120,224,224,224,224,224,224,224, +224,224,224,120,224,224,224,224,120,224,120,224,120,120,120,120, +120,120,224,120,120,120,120,224,120,224,120,224,120,224,224,224, +120,224,224,120,224,120,120,224,120,224,120,224,120,224,120,224, +120,224,224,120,224,120,120,224,224,224,224,120,224,224,224,224, +224,224,224,120,224,224,224,224,120,224,224,224,224,120,224,120, -/* block 243 */ -225,225,225,225,225,225,225,225,225,225,120,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120, -120,225,225,225,120,225,225,225,225,225,120,225,225,225,225,225, -225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120, +/* block 247 */ +224,224,224,224,224,224,224,224,224,224,120,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,120,120,120,120, +120,224,224,224,120,224,224,224,224,224,120,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -218,218,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +217,217,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 244 */ +/* block 248 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 245 */ +/* block 249 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954, -954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970, +970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970, -/* block 246 */ - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,954,954,954, +/* block 250 */ + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,954,954,954, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, -/* block 247 */ +/* block 251 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,955,955,955,955,955,955,955,955,955,955, -955,955,955,955,955,955,955,955,955,955,955,955,955,955,955,955, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,971,971,971,971,971,971,971,971,971,971, +971,971,971,971,971,971,971,971,971,971,971,971,971,971,971,971, -/* block 248 */ -956, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954, +/* block 252 */ +972, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, - 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,954,954,954,954, - 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954, -584,584,954,954,954,954,954,954,954,954,954,954,954,954,954,954, - 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, + 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,970,970,970,970, + 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970, +584,584,970,970,970,970,970,970,970,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, -/* block 249 */ -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +/* block 253 */ +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, -/* block 250 */ +/* block 254 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4209,7 +4268,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 251 */ +/* block 255 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4217,9 +4276,9 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,957,957,957,957,957, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,973,973,973,973,973, -/* block 252 */ +/* block 256 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4229,7 +4288,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 253 */ +/* block 257 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4239,17 +4298,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -/* block 254 */ +/* block 258 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970, -/* block 255 */ +/* block 259 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -4257,99 +4316,109 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20,954,954,954,954,954,954,954,954,954,954,954,954, + 20, 20, 20, 20,970,970,970,970,970,970,970,970,970,970,970,970, -/* block 256 */ +/* block 260 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 21, 21, 21, 21,954,954,954,954,954,954,954, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, + 20, 20, 20, 20, 20, 21, 21, 21, 21,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, -/* block 257 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954, +/* block 261 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954, + 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,970, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -/* block 258 */ - 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954, +/* block 262 */ + 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,970, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970, + 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, -/* block 259 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954, 21, 21, 21, +/* block 263 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21,954, 21, 21, 21, 21,954,954,954, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21,970, 21, 21, 21, 21, 21, 21, -/* block 260 */ +/* block 264 */ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21,954,954, 21, 21, 21, 21, 21, 21,954,954,954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 261 */ +/* block 265 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954, - 21, 21, 21, 21,954,954,954,954, 21, 21, 21,954,954,954,954,954, + 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970, + 21, 21, 21, 21, 21,970,970,970, 21, 21, 21,970,970,970,970,970, -/* block 262 */ - 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954, - 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +/* block 266 */ + 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970, + 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970, + 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, -/* block 263 */ -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,120,120, +/* block 267 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,120,120,120,120,120,120, -/* block 264 */ +/* block 268 */ +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970, +970,970,970,970,970,970,970,970,970,970,970,970,970,970,120,120, + +/* block 269 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -586,586,586,586,586,586,586,120,120,120,120,120,120,120,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 265 */ +/* block 270 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, @@ -4359,7 +4428,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -/* block 266 */ +/* block 271 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, @@ -4369,7 +4438,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -/* block 267 */ +/* block 272 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -4379,7 +4448,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -/* block 268 */ +/* block 273 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, @@ -4389,7 +4458,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 586,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 269 */ +/* block 274 */ 586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, 586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, @@ -4399,17 +4468,27 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 270 */ +/* block 275 */ +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 276 */ 511, 24,511,511,511,511,511,511,511,511,511,511,511,511,511,511, 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, - -/* block 271 */ +974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974, +974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974, +974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974, +974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974, +974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974, +974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974, + +/* block 277 */ 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, @@ -4419,7 +4498,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, -/* block 272 */ +/* block 278 */ 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, @@ -4429,7 +4508,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, -/* block 273 */ +/* block 279 */ 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, @@ -4439,15 +4518,15 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, -/* block 274 */ -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,120,120, +/* block 280 */ +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,120,120, }; diff --git a/thirdparty/pcre2/src/pcre2_ucp.h b/thirdparty/pcre2/src/pcre2_ucp.h index 84b22fb064..9538062c71 100644 --- a/thirdparty/pcre2/src/pcre2_ucp.h +++ b/thirdparty/pcre2/src/pcre2_ucp.h @@ -286,7 +286,12 @@ enum { ucp_Elymaic, ucp_Nandinagari, ucp_Nyiakeng_Puachue_Hmong, - ucp_Wancho + ucp_Wancho, + /* New for Unicode 13.0.0 */ + ucp_Chorasmian, + ucp_Dives_Akuru, + ucp_Khitan_Small_Script, + ucp_Yezidi }; #endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */ diff --git a/thirdparty/pcre2/src/pcre2_valid_utf.c b/thirdparty/pcre2/src/pcre2_valid_utf.c index 96e8bff993..e47ea78f16 100644 --- a/thirdparty/pcre2/src/pcre2_valid_utf.c +++ b/thirdparty/pcre2/src/pcre2_valid_utf.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -347,7 +347,7 @@ for (p = string; length > 0; p++) length--; if ((*p & 0xfc00) != 0xdc00) { - *erroroffset = p - string; + *erroroffset = p - string - 1; return PCRE2_ERROR_UTF16_ERR2; } } diff --git a/thirdparty/pcre2/src/sljit/sljitConfig.h b/thirdparty/pcre2/src/sljit/sljitConfig.h index d54b5e6f54..1c821d287d 100644 --- a/thirdparty/pcre2/src/sljit/sljitConfig.h +++ b/thirdparty/pcre2/src/sljit/sljitConfig.h @@ -24,15 +24,19 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _SLJIT_CONFIG_H_ -#define _SLJIT_CONFIG_H_ +#ifndef SLJIT_CONFIG_H_ +#define SLJIT_CONFIG_H_ -/* --------------------------------------------------------------------- */ -/* Custom defines */ -/* --------------------------------------------------------------------- */ +#ifdef __cplusplus +extern "C" { +#endif -/* Put your custom defines here. This empty section will never change - which helps maintaining patches (with diff / patch utilities). */ +/* + This file contains the basic configuration options for the SLJIT compiler + and their default values. These options can be overridden in the + sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a + non-zero value. +*/ /* --------------------------------------------------------------------- */ /* Architecture */ @@ -50,7 +54,7 @@ /* #define SLJIT_CONFIG_MIPS_32 1 */ /* #define SLJIT_CONFIG_MIPS_64 1 */ /* #define SLJIT_CONFIG_SPARC_32 1 */ -/* #define SLJIT_CONFIG_TILEGX 1 */ +/* #define SLJIT_CONFIG_S390X 1 */ /* #define SLJIT_CONFIG_AUTO 1 */ /* #define SLJIT_CONFIG_UNSUPPORTED 1 */ @@ -59,18 +63,19 @@ /* Utilities */ /* --------------------------------------------------------------------- */ -/* Useful for thread-safe compiling of global functions. */ -#ifndef SLJIT_UTIL_GLOBAL_LOCK -/* Enabled by default */ -#define SLJIT_UTIL_GLOBAL_LOCK 1 -#endif - -/* Implements a stack like data structure (by using mmap / VirtualAlloc). */ +/* Implements a stack like data structure (by using mmap / VirtualAlloc */ +/* or a custom allocator). */ #ifndef SLJIT_UTIL_STACK /* Enabled by default */ #define SLJIT_UTIL_STACK 1 #endif +/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */ +#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION +/* Disabled by default */ +#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0 +#endif + /* Single threaded application. Does not require any locks. */ #ifndef SLJIT_SINGLE_THREADED /* Disabled by default. */ @@ -97,15 +102,31 @@ /* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an allocator which does not set writable and executable - permission flags at the same time. The trade-of is increased - memory consumption and disabled dynamic code modifications. */ + permission flags at the same time. + Instead, it creates a shared memory segment (usually backed by a file) + and maps it twice, with different permissions, depending on the use + case. + The trade-off is increased use of virtual memory, incompatibility with + fork(), and some possible additional security risks by the use of + publicly accessible files for the generated code. */ #ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR /* Disabled by default. */ #define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0 #endif +/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an + allocator which does not set writable and executable permission + flags at the same time. + Instead, it creates a new independent map on each invocation and + switches permissions at the underlying pages as needed. + The trade-off is increased memory use and degraded performance. */ +#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR +/* Disabled by default. */ +#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0 #endif +#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */ + /* Force cdecl calling convention even if a better calling convention (e.g. fastcall) is supported by the C compiler. If this option is disabled (this is the default), functions @@ -144,4 +165,8 @@ /* For further configurations, see the beginning of sljitConfigInternal.h */ +#ifdef __cplusplus +} /* extern "C" */ #endif + +#endif /* SLJIT_CONFIG_H_ */ diff --git a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h index acba9da4be..eb1132db30 100644 --- a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h +++ b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h @@ -24,8 +24,22 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _SLJIT_CONFIG_INTERNAL_H_ -#define _SLJIT_CONFIG_INTERNAL_H_ +#ifndef SLJIT_CONFIG_INTERNAL_H_ +#define SLJIT_CONFIG_INTERNAL_H_ + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE))) +#include <stdio.h> +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG \ + && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS))) +#include <stdlib.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* SLJIT defines the following architecture dependent types and macros: @@ -67,30 +81,13 @@ Other macros: SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT - SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) + SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper) */ /*****************/ /* Sanity check. */ /*****************/ -#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ - || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ - || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ - || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) -#error "An architecture must be selected" -#endif - #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ @@ -99,15 +96,36 @@ + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 #error "Multiple architectures are selected" #endif +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ + && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + && !(defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \ + && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) +#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO +#error "An architecture must be selected" +#else /* SLJIT_CONFIG_AUTO */ +#define SLJIT_CONFIG_AUTO 1 +#endif /* !SLJIT_CONFIG_AUTO */ +#endif /* !SLJIT_CONFIG */ + /********************************************************/ /* Automatic CPU detection (requires compiler support). */ /********************************************************/ @@ -140,8 +158,6 @@ #define SLJIT_CONFIG_MIPS_64 1 #elif defined(__sparc__) || defined(__sparc) #define SLJIT_CONFIG_SPARC_32 1 -#elif defined(__tilegx__) -#define SLJIT_CONFIG_TILEGX 1 #else /* Unsupported architecture */ #define SLJIT_CONFIG_UNSUPPORTED 1 @@ -191,6 +207,22 @@ #define SLJIT_CONFIG_SPARC 1 #endif +/***********************************************************/ +/* Intel Control-flow Enforcement Technology (CET) spport. */ +/***********************************************************/ + +#ifdef SLJIT_CONFIG_X86 + +#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) +#define SLJIT_CONFIG_X86_CET 1 +#endif + +#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__) +#include <x86intrin.h> +#endif + +#endif /* SLJIT_CONFIG_X86 */ + /**********************************/ /* External function definitions. */ /**********************************/ @@ -265,6 +297,7 @@ /* Type of public API functions. */ /*********************************/ +#ifndef SLJIT_API_FUNC_ATTRIBUTE #if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) /* Static ABI functions. For all-in-one programs. */ @@ -278,6 +311,7 @@ #else #define SLJIT_API_FUNC_ATTRIBUTE #endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */ +#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */ /****************************/ /* Instruction cache flush. */ @@ -287,7 +321,7 @@ #if __has_builtin(__builtin___clear_cache) #define SLJIT_CACHE_FLUSH(from, to) \ - __builtin___clear_cache((char*)from, (char*)to) + __builtin___clear_cache((char*)(from), (char*)(to)) #endif /* __has_builtin(__builtin___clear_cache) */ #endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */ @@ -318,7 +352,7 @@ #elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) #define SLJIT_CACHE_FLUSH(from, to) \ - __builtin___clear_cache((char*)from, (char*)to) + __builtin___clear_cache((char*)(from), (char*)(to)) #elif defined __ANDROID__ @@ -377,7 +411,7 @@ typedef long int sljit_sw; && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) #define SLJIT_32BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 2 typedef unsigned int sljit_uw; @@ -419,10 +453,14 @@ typedef double sljit_f64; #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) #define SLJIT_W(w) (w##l) #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#ifdef _WIN64 #define SLJIT_W(w) (w##ll) -#else +#else /* !windows */ +#define SLJIT_W(w) (w##l) +#endif /* windows */ +#else /* 32 bit */ #define SLJIT_W(w) (w) -#endif +#endif /* unknown */ #endif /* !SLJIT_W */ @@ -451,7 +489,27 @@ typedef double sljit_f64; #define SLJIT_BIG_ENDIAN 1 #endif -#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#ifndef SLJIT_MIPS_REV + +/* Auto detecting mips revision. */ +#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6) +#define SLJIT_MIPS_REV 6 +#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \ + || (defined __clang__ && defined _MIPS_ARCH_OCTEON) \ + || (defined __clang__ && defined _MIPS_ARCH_P5600) +/* clang either forgets to define (clang-7) __mips_isa_rev at all + * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+) + * and -march=p5600 (MIPS32 R5). + * It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5 + * (should be set to N exactly) so we cannot rely on this too. + */ +#define SLJIT_MIPS_REV 1 +#endif + +#endif /* !SLJIT_MIPS_REV */ + +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) #define SLJIT_BIG_ENDIAN 1 @@ -478,7 +536,8 @@ typedef double sljit_f64; || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) #define SLJIT_UNALIGNED 1 #endif @@ -496,17 +555,19 @@ typedef double sljit_f64; #ifndef SLJIT_FUNC -#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) +#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) \ + || !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -/* Force cdecl. */ #define SLJIT_FUNC -#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - -#if defined(__GNUC__) && !defined(__APPLE__) +#elif defined(__GNUC__) && !defined(__APPLE__) +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) #define SLJIT_FUNC __attribute__ ((fastcall)) #define SLJIT_X86_32_FASTCALL 1 +#else +#define SLJIT_FUNC +#endif /* gcc >= 3.4 */ #elif defined(_MSC_VER) @@ -520,16 +581,10 @@ typedef double sljit_f64; #else /* Unknown compiler. */ -/* The cdecl attribute is the default. */ -#define SLJIT_FUNC - -#endif - -#else /* Non x86-32 architectures. */ - +/* The cdecl calling convention is usually the x86 default. */ #define SLJIT_FUNC -#endif /* SLJIT_CONFIG_X86_32 */ +#endif /* SLJIT_USE_CDECL_CALLING_CONVENTION */ #endif /* !SLJIT_FUNC */ @@ -560,8 +615,16 @@ determine the next executed instruction after return. */ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); -#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) -#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) +#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size) +#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr) + +#ifndef SLJIT_MALLOC_EXEC +#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data)) +#endif /* SLJIT_MALLOC_EXEC */ + +#ifndef SLJIT_FREE_EXEC +#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data)) +#endif /* SLJIT_FREE_EXEC */ #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); @@ -570,7 +633,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_EXEC_OFFSET(ptr) 0 #endif -#endif +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ /**********************************************/ /* Registers and locals offset determination. */ @@ -646,11 +709,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw)) #endif -#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) +#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) -#define SLJIT_NUMBER_OF_REGISTERS 10 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5 -#define SLJIT_LOCALS_OFFSET_BASE 0 +/* + * https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME + * + * 160 + * .. FR6 + * .. FR4 + * .. FR2 + * 128 FR0 + * 120 R15 (used for SP) + * 112 R14 + * 104 R13 + * 96 R12 + * .. + * 48 R6 + * .. + * 16 R2 + * 8 RESERVED + * 0 SP + */ +#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160 + +#define SLJIT_NUMBER_OF_REGISTERS 12 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE #elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) @@ -679,24 +763,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); /* Debug and verbose related macros. */ /*************************************/ -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -#include <stdio.h> -#endif - #if (defined SLJIT_DEBUG && SLJIT_DEBUG) #if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) /* SLJIT_HALT_PROCESS must halt the process. */ #ifndef SLJIT_HALT_PROCESS -#include <stdlib.h> - #define SLJIT_HALT_PROCESS() \ abort(); #endif /* !SLJIT_HALT_PROCESS */ -#include <stdio.h> - #endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */ /* Feel free to redefine these two macros. */ @@ -742,4 +818,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #endif /* !SLJIT_COMPILE_ASSERT */ +#ifdef __cplusplus +} /* extern "C" */ #endif + +#endif /* SLJIT_CONFIG_INTERNAL_H_ */ diff --git a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c index 92ddb94914..61a32f23e9 100644 --- a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c +++ b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c @@ -72,9 +72,8 @@ alloc_chunk / free_chunk : * allocate executable system memory chunks * the size is always divisible by CHUNK_SIZE - allocator_grab_lock / allocator_release_lock : - * make the allocator thread safe - * can be empty if the OS (or the application) does not support threading + SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK : + * provided as part of sljitUtils * only the allocator requires this lock, sljit is fully thread safe as it only uses local variables */ @@ -95,6 +94,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) #else #ifdef __APPLE__ +#ifdef MAP_ANON /* Configures TARGET_OS_OSX when appropriate */ #include <TargetConditionals.h> @@ -104,17 +104,23 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) #ifdef MAP_JIT +/* + On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a + version where it's OK to have more than one JIT block. + On non-macOS systems, returns MAP_JIT if it is defined. +*/ static SLJIT_INLINE int get_map_jit_flag() { #if TARGET_OS_OSX - /* On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a version - of macOS where it's OK to have more than one JIT block. On non-macOS systems, returns - MAP_JIT if it is defined. */ + sljit_sw page_size = get_page_alignment() + 1; + void *ptr; static int map_jit_flag = -1; - /* The following code is thread safe because multiple initialization - sets map_jit_flag to the same value and the code has no side-effects. - Changing the kernel version witout system restart is (very) unlikely. */ + /* + The following code is thread safe because multiple initialization + sets map_jit_flag to the same value and the code has no side-effects. + Changing the kernel version witout system restart is (very) unlikely. + */ if (map_jit_flag == -1) { struct utsname name; @@ -123,13 +129,14 @@ static SLJIT_INLINE int get_map_jit_flag() /* Kernel version for 10.14.0 (Mojave) */ if (atoi(name.release) >= 18) { - /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */ - void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + /* Only use MAP_JIT if a hardened runtime is used */ + + ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); if (ptr == MAP_FAILED) { map_jit_flag = MAP_JIT; } else { - munmap(ptr, getpagesize()); + munmap(ptr, page_size); } } } @@ -141,7 +148,7 @@ static SLJIT_INLINE int get_map_jit_flag() } #endif /* MAP_JIT */ - +#endif /* MAP_ANON */ #endif /* __APPLE__ */ static SLJIT_INLINE void* alloc_chunk(sljit_uw size) @@ -159,10 +166,9 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size) retval = mmap(NULL, size, prot, flags, -1, 0); #else /* !MAP_ANON */ - if (dev_zero < 0) { - if (open_dev_zero()) - return NULL; - } + if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) + return NULL; + retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0); #endif /* MAP_ANON */ @@ -246,7 +252,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) struct free_block *free_block; sljit_uw chunk_size; - allocator_grab_lock(); + SLJIT_ALLOCATOR_LOCK(); if (size < (64 - sizeof(struct block_header))) size = (64 - sizeof(struct block_header)); size = ALIGN_SIZE(size); @@ -270,7 +276,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) } allocated_size += size; header->size = size; - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); return MEM_START(header); } free_block = free_block->next; @@ -279,7 +285,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK; header = (struct block_header*)alloc_chunk(chunk_size); if (!header) { - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); return NULL; } @@ -306,7 +312,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) } next_header->size = 1; next_header->prev_size = chunk_size; - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); return MEM_START(header); } @@ -315,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) struct block_header *header; struct free_block* free_block; - allocator_grab_lock(); + SLJIT_ALLOCATOR_LOCK(); header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); allocated_size -= header->size; @@ -352,7 +358,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) } } - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); } SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) @@ -360,7 +366,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) struct free_block* free_block; struct free_block* next_free_block; - allocator_grab_lock(); + SLJIT_ALLOCATOR_LOCK(); free_block = free_blocks; while (free_block) { @@ -375,5 +381,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) } SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); } diff --git a/thirdparty/pcre2/src/sljit/sljitLir.c b/thirdparty/pcre2/src/sljit/sljitLir.c index 9bab0c3ec6..d817c90b3a 100644 --- a/thirdparty/pcre2/src/sljit/sljitLir.c +++ b/thirdparty/pcre2/src/sljit/sljitLir.c @@ -28,7 +28,6 @@ #ifdef _WIN32 -/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */ #include <windows.h> #endif /* _WIN32 */ @@ -223,14 +222,6 @@ # define FCSR_FCC 33 #endif -#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) -# define IS_JAL 0x04 -# define IS_COND 0x08 - -# define PATCH_B 0x10 -# define PATCH_J 0x20 -#endif - #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) # define IS_MOVABLE 0x04 # define IS_COND 0x08 @@ -274,6 +265,8 @@ #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) #include "sljitProtExecAllocator.c" +#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) +#include "sljitWXExecAllocator.c" #else #include "sljitExecAllocator.c" #endif @@ -286,6 +279,10 @@ #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr)) #endif +#ifndef SLJIT_UPDATE_WX_FLAGS +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) +#endif + /* Argument checking features. */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -366,7 +363,7 @@ static sljit_s32 compiler_initialized = 0; static void init_compiler(void); #endif -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data) { struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data); if (!compiler) @@ -393,6 +390,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo compiler->error = SLJIT_SUCCESS; compiler->allocator_data = allocator_data; + compiler->exec_allocator_data = exec_allocator_data; compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data); compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data); @@ -485,22 +483,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi } #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data) { + SLJIT_UNUSED_ARG(exec_allocator_data); + /* Remove thumb mode flag. */ - SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); + SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1), exec_allocator_data); } #elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data) { + SLJIT_UNUSED_ARG(exec_allocator_data); + /* Resolve indirection. */ code = (void*)(*(sljit_uw*)code); - SLJIT_FREE_EXEC(code); + SLJIT_FREE_EXEC(code, exec_allocator_data); } #else -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data) { - SLJIT_FREE_EXEC(code); + SLJIT_UNUSED_ARG(exec_allocator_data); + + SLJIT_FREE_EXEC(code, exec_allocator_data); } #endif @@ -627,7 +631,10 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types) return arg_count; } -#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +/* Only used in RISC architectures where the instruction size is constant */ +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump, struct sljit_const *const_, struct sljit_put_label *put_label) @@ -649,7 +656,7 @@ static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct return result; } -#endif /* !SLJIT_CONFIG_X86 */ +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */ static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, @@ -926,7 +933,8 @@ static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, s static const char* op0_names[] = { (char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw", - (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s" + (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s", + (char*)"endbr", (char*)"skip_frames_before_return" }; static const char* op1_names[] = { @@ -943,6 +951,12 @@ static const char* op2_names[] = { (char*)"shl", (char*)"lshr", (char*)"ashr", }; +static const char* op_src_names[] = { + (char*)"fast_return", (char*)"skip_frames_before_fast_return", + (char*)"prefetch_l1", (char*)"prefetch_l2", + (char*)"prefetch_l3", (char*)"prefetch_once", +}; + static const char* fop1_names[] = { (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg", @@ -1152,37 +1166,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_c CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_SRC(src, srcw); - CHECK_ARGUMENT(src != SLJIT_IMM); - compiler->last_flags = 0; -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fast_return "); - sljit_verbose_param(compiler, src, srcw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW) - || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)); - CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2); - if (op >= SLJIT_LMUL_UW) + || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW) + || (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN)); + CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2); + if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN) compiler->last_flags = 0; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); - if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) { + if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) { fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w"); } fprintf(compiler->verbose, "\n"); @@ -1224,7 +1222,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler break; } - FUNCTION_CHECK_DST(dst, dstw, 1); + FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op)); FUNCTION_CHECK_SRC(src, srcw); if (GET_OPCODE(op) >= SLJIT_NOT) { @@ -1304,7 +1302,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler break; } - FUNCTION_CHECK_DST(dst, dstw, 1); + FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op)); FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z)); @@ -1325,6 +1323,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler CHECK_RETURN_OK; } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE); + FUNCTION_CHECK_SRC(src, srcw); + + if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) + { + CHECK_ARGUMENT(src != SLJIT_IMM); + compiler->last_flags = 0; + } + else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) + { + CHECK_ARGUMENT(src & SLJIT_MEM); + } +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s ", op_src_names[op - SLJIT_OP_SRC_BASE]); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg) { SLJIT_UNUSED_ARG(reg); @@ -1360,6 +1385,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0) || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0)); +#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + CHECK_ARGUMENT(size == 2 || size == 4 || size == 6); #else CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0); #endif @@ -2016,7 +2043,7 @@ static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *comp #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ - || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)) + || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)) static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, @@ -2093,8 +2120,8 @@ static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *com # include "sljitNativeMIPS_common.c" #elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC) # include "sljitNativeSPARC_common.c" -#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) -# include "sljitNativeTILEGX_64.c" +#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) +# include "sljitNativeS390X.c" #endif #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) @@ -2125,7 +2152,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #endif if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { - /* Immediate is prefered as second argument by most architectures. */ + /* Immediate is preferred as second argument by most architectures. */ switch (condition) { case SLJIT_LESS: condition = SLJIT_GREATER; @@ -2274,9 +2301,10 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) return "unsupported"; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data) { SLJIT_UNUSED_ARG(allocator_data); + SLJIT_UNUSED_ARG(exec_allocator_data); SLJIT_UNREACHABLE(); return NULL; } @@ -2324,9 +2352,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return 0; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data) { SLJIT_UNUSED_ARG(code); + SLJIT_UNUSED_ARG(exec_allocator_data); SLJIT_UNREACHABLE(); } @@ -2381,15 +2410,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { SLJIT_UNUSED_ARG(compiler); @@ -2429,6 +2449,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return SLJIT_ERR_UNSUPPORTED; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_UNREACHABLE(); + return SLJIT_ERR_UNSUPPORTED; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { SLJIT_UNREACHABLE(); @@ -2549,6 +2580,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw SLJIT_UNREACHABLE(); } +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label) +{ + SLJIT_UNUSED_ARG(put_label); + SLJIT_UNUSED_ARG(label); + SLJIT_UNREACHABLE(); +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); diff --git a/thirdparty/pcre2/src/sljit/sljitLir.h b/thirdparty/pcre2/src/sljit/sljitLir.h index 836d25cf71..93d2804675 100644 --- a/thirdparty/pcre2/src/sljit/sljitLir.h +++ b/thirdparty/pcre2/src/sljit/sljitLir.h @@ -24,8 +24,8 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _SLJIT_LIR_H_ -#define _SLJIT_LIR_H_ +#ifndef SLJIT_LIR_H_ +#define SLJIT_LIR_H_ /* ------------------------------------------------------------------------ @@ -70,9 +70,11 @@ - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code" */ -#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG) +#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE) +#include "sljitConfigPre.h" +#endif /* SLJIT_HAVE_CONFIG_PRE */ + #include "sljitConfig.h" -#endif /* The following header file defines useful macros for fine tuning sljit based code generators. They are listed in the beginning @@ -80,6 +82,14 @@ of sljitConfigInternal.h */ #include "sljitConfigInternal.h" +#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST) +#include "sljitConfigPost.h" +#endif /* SLJIT_HAVE_CONFIG_POST */ + +#ifdef __cplusplus +extern "C" { +#endif + /* --------------------------------------------------------------------- */ /* Error codes */ /* --------------------------------------------------------------------- */ @@ -154,10 +164,10 @@ of sljitConfigInternal.h */ */ /* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1 - or sljit_emit_op2 operations the result is discarded. If no status - flags are set, no instructions are emitted for these operations. Data - prefetch is a special exception, see SLJIT_MOV operation. Other SLJIT - operations do not support SLJIT_UNUSED as a destination operand. */ + or sljit_emit_op2 operations the result is discarded. Some status + flags must be set when the destination is SLJIT_UNUSED, because the + operation would have no effect otherwise. Other SLJIT operations do + not support SLJIT_UNUSED as a destination operand. */ #define SLJIT_UNUSED 0 /* Scratch registers. */ @@ -381,6 +391,7 @@ struct sljit_compiler { struct sljit_put_label *last_put_label; void *allocator_data; + void *exec_allocator_data; struct sljit_memory_fragment *buf; struct sljit_memory_fragment *abuf; @@ -447,9 +458,9 @@ struct sljit_compiler { sljit_sw cache_argw; #endif -#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) - sljit_s32 cache_arg; - sljit_sw cache_argw; +#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + /* Need to allocate register save area to make calls. */ + sljit_s32 have_save_area; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -481,10 +492,12 @@ struct sljit_compiler { custom memory managers. This pointer is passed to SLJIT_MALLOC and SLJIT_FREE macros. Most allocators (including the default one) ignores this value, and it is recommended to pass NULL - as a dummy value for allocator_data. + as a dummy value for allocator_data. The exec_allocator_data + has the same purpose but this one is passed to SLJIT_MALLOC_EXEC / + SLJIT_MALLOC_FREE functions. Returns NULL if failed. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data); /* Frees everything except the compiled machine code. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); @@ -531,7 +544,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* Free executable code. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data); /* When the protected executable allocator is used the JIT code is mapped @@ -567,10 +580,14 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler #define SLJIT_HAS_FPU 0 /* [Limitation] Some registers are virtual registers. */ #define SLJIT_HAS_VIRTUAL_REGISTERS 1 +/* [Emulated] Has zero register (setting a memory location to zero is efficient). */ +#define SLJIT_HAS_ZERO_REGISTER 2 /* [Emulated] Count leading zero is supported. */ -#define SLJIT_HAS_CLZ 2 +#define SLJIT_HAS_CLZ 3 /* [Emulated] Conditional move is supported. */ -#define SLJIT_HAS_CMOV 3 +#define SLJIT_HAS_CMOV 4 +/* [Emulated] Conditional move is supported. */ +#define SLJIT_HAS_PREFETCH 5 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* [Not emulated] SSE2 support is available on x86. */ @@ -658,10 +675,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp sljit_s32 src, sljit_sw srcw); /* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL). - Both sljit_emit_fast_enter and sljit_emit_fast_return functions preserve the + Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations preserve the values of all registers and stack frame. The return address is stored in the dst argument of sljit_emit_fast_enter, and this return address can be passed - to sljit_emit_fast_return to continue the execution after the fast call. + to SLJIT_FAST_RETURN to continue the execution after the fast call. Fast calls are cheap operations (usually only a single call instruction is emitted) but they do not preserve any registers. However the callee function @@ -669,16 +686,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp efficiently exploited by various optimizations. Registers can be saved manually by the callee function if needed. - Although returning to different address by sljit_emit_fast_return is possible, + Although returning to different address by SLJIT_FAST_RETURN is possible, this address usually cannot be predicted by the return address predictor of - modern CPUs which may reduce performance. Furthermore using sljit_emit_ijump - to return is also inefficient since return address prediction is usually - triggered by a specific form of ijump. + modern CPUs which may reduce performance. Furthermore certain security + enhancement technologies such as Intel Control-flow Enforcement Technology + (CET) may disallow returning to a different address. Flags: - (does not modify flags). */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw); /* Source and destination operands for arithmetical instructions @@ -692,7 +708,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler */ /* - IMPORATNT NOTE: memory access MUST be naturally aligned except + IMPORTANT NOTE: memory access MUST be naturally aligned unless SLJIT_UNALIGNED macro is defined and its value is 1. length | alignment @@ -734,6 +750,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler mips: [reg+imm], -65536 <= imm <= 65535 sparc: [reg+imm], -4096 <= imm <= 4095 [reg+reg] is supported + s390x: [reg+imm], -2^19 <= imm < 2^19 + [reg+reg] is supported + Write-back is not supported */ /* Macros for specifying operand types. */ @@ -887,6 +906,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler the behaviour is undefined. */ #define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7) #define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP) +/* Flags: - (does not modify flags) + ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64 + when Intel Control-flow Enforcement Technology (CET) is enabled. + No instruction for other architectures. */ +#define SLJIT_ENDBR (SLJIT_OP0_BASE + 8) +/* Flags: - (may destroy flags) + Skip stack frames before return. */ +#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op); @@ -904,15 +931,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile U32 - unsigned int (32 bit) data transfer S32 - signed int (32 bit) data transfer P - pointer (sljit_p) data transfer - - If the destination of a MOV instruction is SLJIT_UNUSED and the source - operand is a memory address the compiler emits a prefetch instruction - if this instruction is supported by the current CPU. Higher data sizes - bring the data closer to the core: a MOV with word size loads the data - into a higher level cache than a byte size. Otherwise the type does not - affect the prefetch instruction. Furthermore a prefetch instruction - never fails, so it can be used to prefetch a data from an address and - check whether that address is NULL afterwards. */ /* Flags: - (does not modify flags) */ @@ -1017,8 +1035,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w); +/* Starting index of opcodes for sljit_emit_op2. */ +#define SLJIT_OP_SRC_BASE 128 + +/* Note: src cannot be an immedate value + Flags: - (does not modify flags) */ +#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_BASE + 0) +/* Skip stack frames before fast return. + Note: src cannot be an immedate value + Flags: may destroy flags. */ +#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_BASE + 1) +/* Prefetch value into the level 1 data cache + Note: if the target CPU does not support data prefetch, + no instructions are emitted. + Note: this instruction never fails, even if the memory address is invalid. + Flags: - (does not modify flags) */ +#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_BASE + 2) +/* Prefetch value into the level 2 data cache + Note: same as SLJIT_PREFETCH_L1 if the target CPU + does not support this instruction form. + Note: this instruction never fails, even if the memory address is invalid. + Flags: - (does not modify flags) */ +#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_BASE + 3) +/* Prefetch value into the level 3 data cache + Note: same as SLJIT_PREFETCH_L2 if the target CPU + does not support this instruction form. + Note: this instruction never fails, even if the memory address is invalid. + Flags: - (does not modify flags) */ +#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_BASE + 4) +/* Prefetch a value which is only used once (and can be discarded afterwards) + Note: same as SLJIT_PREFETCH_L1 if the target CPU + does not support this instruction form. + Note: this instruction never fails, even if the memory address is invalid. + Flags: - (does not modify flags) */ +#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_BASE + 5) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw); + /* Starting index of opcodes for sljit_emit_fop1. */ -#define SLJIT_FOP1_BASE 128 +#define SLJIT_FOP1_BASE 160 /* Flags: - (does not modify flags) */ #define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0) @@ -1057,7 +1113,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_fop2. */ -#define SLJIT_FOP2_BASE 160 +#define SLJIT_FOP2_BASE 192 /* Flags: - (does not modify flags) */ #define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0) @@ -1161,7 +1217,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi /* Unconditional jump types. */ #define SLJIT_JUMP 24 - /* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */ + /* Fast calling method. See sljit_emit_fast_enter / SLJIT_FAST_RETURN. */ #define SLJIT_FAST_CALL 25 /* Called function must be declared with the SLJIT_FUNC attribute. */ #define SLJIT_CALL 26 @@ -1361,12 +1417,6 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void); /* Portable helper function to get an offset of a member. */ #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) -/* This global lock is useful to compile common functions. */ -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void); -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void); -#endif - #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) /* The sljit_stack structure and its manipulation functions provides @@ -1490,4 +1540,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags); -#endif /* _SLJIT_LIR_H_ */ +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SLJIT_LIR_H_ */ diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c index 71f7bcdadb..ae8479f031 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c @@ -467,18 +467,28 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC); sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2); + SLJIT_UNUSED_ARG(executable_offset); + if (diff <= 0x7fffff && diff >= -0x800000) { /* Turn to branch. */ if (!bl) { + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0); + } inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0); + } inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff); inst[1] = NOP; if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } @@ -491,28 +501,52 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut ptr = inst + 1; if (*inst != mov_pc) { + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0); + } inst[0] = mov_pc; if (!bl) { if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[1] = BLX | RM(TMP_REG1); if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } } + + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0); + } + *ptr = new_addr; + + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); + } } #else sljit_uw *inst = (sljit_uw*)jump_ptr; + + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); + + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0); + } + inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff); inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff); + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } @@ -529,10 +563,18 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off sljit_uw ldr_literal = ptr[1]; sljit_uw src2; + SLJIT_UNUSED_ARG(executable_offset); + src2 = get_imm(new_constant); if (src2) { + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0); + } + *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } @@ -541,8 +583,14 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off src2 = get_imm(~new_constant); if (src2) { + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0); + } + *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } @@ -555,19 +603,44 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off ptr = inst + 1; if (*inst != ldr_literal) { + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0); + } + *inst = ldr_literal; + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } + + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0); + } + *ptr = new_constant; + + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); + } #else sljit_uw *inst = (sljit_uw*)addr; + + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); + + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0); + } + inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff); inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff); + if (flush_cache) { + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } @@ -612,7 +685,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #else size = compiler->size; #endif - code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw)); + code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -653,7 +726,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } else { if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { - SLJIT_FREE_EXEC(code); + SLJIT_FREE_EXEC(code, compiler->exec_allocator_data); compiler->error = SLJIT_ERR_ALLOC_FAILED; return NULL; } @@ -666,6 +739,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; + + next_addr = compute_next_addr(label, jump, const_, put_label); } } } @@ -754,7 +829,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil cpool_current_index = 0; while (buf_ptr < buf_end) { if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { - SLJIT_FREE_EXEC(code); + SLJIT_FREE_EXEC(code, compiler->exec_allocator_data); compiler->error = SLJIT_ERR_ALLOC_FAILED; return NULL; } @@ -854,6 +929,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); return code; } @@ -870,6 +946,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CMOV: +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + case SLJIT_HAS_PREFETCH: +#endif return 1; default: @@ -1676,6 +1755,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); } return SLJIT_SUCCESS; + case SLJIT_ENDBR: + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; } return SLJIT_SUCCESS; @@ -1690,14 +1772,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) { -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) - return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1); -#endif - return SLJIT_SUCCESS; - } - switch (GET_OPCODE(op)) { case SLJIT_MOV: case SLJIT_MOV_U32: @@ -1779,6 +1853,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src))); + else + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1)); + + return push_inst(compiler, BX | RM(TMP_REG2)); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + return SLJIT_SUCCESS; + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + SLJIT_ASSERT(src & SLJIT_MEM); + return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1); +#else /* !SLJIT_CONFIG_ARM_V7 */ + return SLJIT_SUCCESS; +#endif /* SLJIT_CONFIG_ARM_V7 */ + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -2041,22 +2149,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - SLJIT_ASSERT(reg_map[TMP_REG2] == 14); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src))); - else - FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1)); - - return push_inst(compiler, BX | RM(TMP_REG2)); -} - /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ @@ -2615,11 +2707,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile } else { if (is_type1_transfer) { - if (memw > 4095 && memw < -4095) + if (memw > 4095 || memw < -4095) return SLJIT_ERR_UNSUPPORTED; } else { - if (memw > 255 && memw < -255) + if (memw > 255 || memw < -255) return SLJIT_ERR_UNSUPPORTED; } } diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c index e15b3451e8..52267e7df7 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c @@ -151,16 +151,6 @@ static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21)); } -static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) -{ - sljit_s32 dst = inst[0] & 0x1f; - SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); - inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); - inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); - inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21); - inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); -} - static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; @@ -253,7 +243,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil CHECK_PTR(check_sljit_generate_code(compiler)); reverse_buf(compiler); - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -380,6 +370,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); return code; } @@ -396,6 +387,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CMOV: + case SLJIT_HAS_PREFETCH: return 1; default: @@ -1154,6 +1146,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile case SLJIT_DIV_UW: case SLJIT_DIV_SW: return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); + case SLJIT_ENDBR: + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; } return SLJIT_SUCCESS; @@ -1171,23 +1166,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) { - if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) { - SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4); - - if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8) - dst = 5; - else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16) - dst = 3; - else - dst = 1; - - /* Signed word sized load is the prefetch instruction. */ - return emit_op_mem(compiler, WORD_SIZE | SIGNED, dst, src, srcw, TMP_REG1); - } - return SLJIT_SUCCESS; - } - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; op = GET_OPCODE(op); @@ -1327,6 +1305,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); + else + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1)); + + return push_inst(compiler, RET | RN(TMP_LR)); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + return SLJIT_SUCCESS; + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: + SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4); + + /* The reg_map[op] should provide the appropriate constant. */ + if (op == SLJIT_PREFETCH_L1) + op = 1; + else if (op == SLJIT_PREFETCH_L2) + op = 3; + else if (op == SLJIT_PREFETCH_L3) + op = 5; + else + op = 2; + + /* Signed word sized load is the prefetch instruction. */ + return emit_op_mem(compiler, WORD_SIZE | SIGNED, op, src, srcw, TMP_REG1); + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -1578,20 +1596,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); - else - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1)); - - return push_inst(compiler, RET | RN(TMP_LR)); -} - /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ @@ -1865,7 +1869,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile CHECK_ERROR(); CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw)); - if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256)) + if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256)) return SLJIT_ERR_UNSUPPORTED; if (type & SLJIT_MEM_SUPP) @@ -1915,7 +1919,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil CHECK_ERROR(); CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw)); - if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256)) + if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256)) return SLJIT_ERR_UNSUPPORTED; if (type & SLJIT_MEM_SUPP) @@ -2021,15 +2025,24 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins* inst = (sljit_ins*)addr; - modify_imm64_const(inst, new_target); + sljit_s32 dst; + SLJIT_UNUSED_ARG(executable_offset); + + SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0); + + dst = inst[0] & 0x1f; + SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); + inst[0] = MOVZ | dst | ((new_target & 0xffff) << 5); + inst[1] = MOVK | dst | (((new_target >> 16) & 0xffff) << 5) | (1 << 21); + inst[2] = MOVK | dst | (((new_target >> 32) & 0xffff) << 5) | (2 << 21); + inst[3] = MOVK | dst | ((new_target >> 48) << 5) | (3 << 21); + + SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 4); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins* inst = (sljit_ins*)addr; - modify_imm64_const(inst, new_constant); - inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 4); + sljit_set_jump_addr(addr, new_constant, executable_offset); } diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c index cdfe4a4d24..4624882f42 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c @@ -377,7 +377,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil CHECK_PTR(check_sljit_generate_code(compiler)); reverse_buf(compiler); - code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16)); + code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -463,6 +463,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); + /* Set thumb mode flag. */ return (void*)((sljit_uw)code | 0x1); } @@ -480,6 +482,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CMOV: + case SLJIT_HAS_PREFETCH: return 1; default: @@ -607,7 +610,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s Although some clever things could be done here, "NOT IMM" does not worth the efforts. */ break; case SLJIT_ADD: - nimm = -imm; + nimm = -(sljit_sw)imm; if (IS_2_LO_REGS(reg, dst)) { if (imm <= 0x7) return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); @@ -629,7 +632,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s nimm = get_imm(imm); if (nimm != INVALID_IMM) return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); - nimm = get_imm(-imm); + nimm = get_imm(-(sljit_sw)imm); if (nimm != INVALID_IMM) return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); break; @@ -654,11 +657,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s nimm = get_imm(imm); if (nimm != INVALID_IMM) return push_inst32(compiler, CMPI_W | RN4(reg) | nimm); - nimm = get_imm(-imm); + nimm = get_imm(-(sljit_sw)imm); if (nimm != INVALID_IMM) return push_inst32(compiler, CMNI_W | RN4(reg) | nimm); } - nimm = -imm; + nimm = -(sljit_sw)imm; if (IS_2_LO_REGS(reg, dst)) { if (imm <= 0x7) return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); @@ -680,7 +683,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s nimm = get_imm(imm); if (nimm != INVALID_IMM) return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); - nimm = get_imm(-imm); + nimm = get_imm(-(sljit_sw)imm); if (nimm != INVALID_IMM) return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); break; @@ -1328,6 +1331,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile } return SLJIT_SUCCESS; #endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */ + case SLJIT_ENDBR: + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; } return SLJIT_SUCCESS; @@ -1345,13 +1351,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) { - /* Since TMP_PC has index 15, IS_2_LO_REGS and IS_3_LO_REGS checks always fail. */ - if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) - return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1); - return SLJIT_SUCCESS; - } - dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; op = GET_OPCODE(op); @@ -1475,6 +1474,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG2); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + + if (FAST_IS_REG(src)) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src))); + else + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2)); + + return push_inst16(compiler, BX | RN3(TMP_REG2)); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + return SLJIT_SUCCESS; + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: + return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1); + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -1728,22 +1756,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - SLJIT_ASSERT(reg_map[TMP_REG2] == 14); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src))); - else - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2)); - - return push_inst16(compiler, BX | RN3(TMP_REG2)); -} - /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ @@ -2264,7 +2276,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile CHECK_ERROR(); CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw)); - if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255)) + if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255)) return SLJIT_ERR_UNSUPPORTED; if (type & SLJIT_MEM_SUPP) @@ -2356,15 +2368,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_u16 *inst = (sljit_u16*)addr; + SLJIT_UNUSED_ARG(executable_offset); + + SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0); modify_imm32_const(inst, new_target); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1); inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 4); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_u16 *inst = (sljit_u16*)addr; - modify_imm32_const(inst, new_constant); - inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 4); + sljit_set_jump_addr(addr, new_constant, executable_offset); } diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c index 16dec052fe..f887ee1311 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -86,12 +86,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_S8) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#else +#else /* SLJIT_MIPS_REV < 1 */ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ } return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); } @@ -105,12 +105,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { if (op == SLJIT_MOV_S16) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#else +#else /* SLJIT_MIPS_REV < 1 */ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ } return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); } @@ -129,12 +129,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) if (op & SLJIT_SET_Z) FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); if (!(flags & UNUSED_DEST)) FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); -#else +#else /* SLJIT_MIPS_REV < 1 */ if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); @@ -149,7 +149,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst))); FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ return SLJIT_SUCCESS; case SLJIT_ADD: @@ -368,21 +368,22 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(!(flags & SRC2_IMM)); if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); -#else /* !SLJIT_MIPS_R1 && !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 1 */ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); -#endif /* SLJIT_MIPS_R1 || SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 1 */ } -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) FAIL_IF(push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst))); FAIL_IF(push_inst(compiler, MUH | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG)); return push_inst(compiler, SUBU | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG); @@ -424,23 +425,20 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0); SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI); inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins *)addr; - - SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI); - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); - inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 2); + sljit_set_jump_addr(addr, new_constant, executable_offset); } static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr) diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c index a6a2bcc0c9..5ab9b7d06b 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c @@ -220,12 +220,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) if (op & SLJIT_SET_Z) FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); if (!(flags & UNUSED_DEST)) FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst))); -#else +#else /* SLJIT_MIPS_REV < 1 */ if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); @@ -240,7 +240,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ return SLJIT_SUCCESS; case SLJIT_ADD: @@ -459,26 +459,27 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(!(flags & SRC2_IMM)); if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) { -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)); -#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) if (op & SLJIT_I32_OP) return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); -#else /* !SLJIT_MIPS_R6 && !SLJIT_MIPS_R1 */ +#else /* SLJIT_MIPS_REV < 1 */ FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ } -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst))); FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG)); return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG); @@ -524,25 +525,21 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0); inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff); inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff); inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 6); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins *)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); - inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 6); + sljit_set_jump_addr(addr, new_constant, executable_offset); } static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr) diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c index 7d1d087496..ecf4dac4c8 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -25,15 +25,16 @@ */ /* Latest MIPS architecture. */ -/* Automatically detect SLJIT_MIPS_R1 */ -#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6) -#define SLJIT_MIPS_R6 1 +#ifndef __mips_hard_float +/* Disable automatic detection, covers both -msoft-float and -mno-float */ +#undef SLJIT_IS_FPU_AVAILABLE +#define SLJIT_IS_FPU_AVAILABLE 0 #endif SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) return "MIPS32-R6" SLJIT_CPUINFO; @@ -41,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) return "MIPS64-R6" SLJIT_CPUINFO; #endif /* SLJIT_CONFIG_MIPS_32 */ -#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) return "MIPS32-R1" SLJIT_CPUINFO; @@ -49,9 +50,9 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) return "MIPS64-R1" SLJIT_CPUINFO; #endif /* SLJIT_CONFIG_MIPS_32 */ -#else /* SLJIT_MIPS_R1 */ +#else /* SLJIT_MIPS_REV < 1 */ return "MIPS III" SLJIT_CPUINFO; -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ } /* Length of an instruction word @@ -117,11 +118,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define FR(dr) (freg_map[dr]) #define HI(opcode) ((opcode) << 26) #define LO(opcode) (opcode) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) /* CMP.cond.fmt */ /* S = (20 << 21) D = (21 << 21) */ #define CMP_FMT_S (20 << 21) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ /* S = (16 << 21) D = (17 << 21) */ #define FMT_S (16 << 21) #define FMT_D (17 << 21) @@ -134,13 +135,13 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define ANDI (HI(12)) #define B (HI(4)) #define BAL (HI(1) | (17 << 16)) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3)) #define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3)) -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define BC1F (HI(17) | (8 << 21)) #define BC1T (HI(17) | (8 << 21) | (1 << 16)) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ #define BEQ (HI(4)) #define BGEZ (HI(1) | (1 << 16)) #define BGTZ (HI(7)) @@ -149,23 +150,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define BNE (HI(5)) #define BREAK (HI(0) | LO(13)) #define CFC1 (HI(17) | (2 << 21)) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3)) #define C_ULE_S (HI(17) | CMP_FMT_S | LO(7)) #define C_ULT_S (HI(17) | CMP_FMT_S | LO(5)) #define C_UN_S (HI(17) | CMP_FMT_S | LO(1)) #define C_FD (FD(TMP_FREG3)) -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define C_UEQ_S (HI(17) | FMT_S | LO(51)) #define C_ULE_S (HI(17) | FMT_S | LO(55)) #define C_ULT_S (HI(17) | FMT_S | LO(53)) #define C_UN_S (HI(17) | FMT_S | LO(49)) #define C_FD (0) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ #define CVT_S_S (HI(17) | FMT_S | LO(32)) #define DADDIU (HI(25)) #define DADDU (HI(0) | LO(45)) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define DDIV (HI(0) | (2 << 6) | LO(30)) #define DDIVU (HI(0) | (2 << 6) | LO(31)) #define DMOD (HI(0) | (3 << 6) | LO(30)) @@ -176,14 +177,14 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define DMUHU (HI(0) | (3 << 6) | LO(29)) #define DMUL (HI(0) | (2 << 6) | LO(28)) #define DMULU (HI(0) | (2 << 6) | LO(29)) -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define DDIV (HI(0) | LO(30)) #define DDIVU (HI(0) | LO(31)) #define DIV (HI(0) | LO(26)) #define DIVU (HI(0) | LO(27)) #define DMULT (HI(0) | LO(28)) #define DMULTU (HI(0) | LO(29)) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ #define DIV_S (HI(17) | FMT_S | LO(3)) #define DSLL (HI(0) | LO(56)) #define DSLL32 (HI(0) | LO(60)) @@ -198,33 +199,33 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define J (HI(2)) #define JAL (HI(3)) #define JALR (HI(0) | LO(9)) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define JR (HI(0) | LO(9)) -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define JR (HI(0) | LO(8)) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ #define LD (HI(55)) #define LUI (HI(15)) #define LW (HI(35)) #define MFC1 (HI(17)) -#if !(defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) -#define MFHI (HI(0) | LO(16)) -#define MFLO (HI(0) | LO(18)) -#else /* SLJIT_MIPS_R6 */ +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define MOD (HI(0) | (3 << 6) | LO(26)) #define MODU (HI(0) | (3 << 6) | LO(27)) -#endif /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ +#define MFHI (HI(0) | LO(16)) +#define MFLO (HI(0) | LO(18)) +#endif /* SLJIT_MIPS_REV >= 6 */ #define MOV_S (HI(17) | FMT_S | LO(6)) #define MTC1 (HI(17) | (4 << 21)) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define MUH (HI(0) | (3 << 6) | LO(24)) #define MUHU (HI(0) | (3 << 6) | LO(25)) #define MUL (HI(0) | (2 << 6) | LO(24)) #define MULU (HI(0) | (2 << 6) | LO(25)) -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define MULT (HI(0) | LO(24)) #define MULTU (HI(0) | LO(25)) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ #define MUL_S (HI(17) | FMT_S | LO(2)) #define NEG_S (HI(17) | FMT_S | LO(7)) #define NOP (HI(0) | LO(0)) @@ -251,23 +252,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define XOR (HI(0) | LO(38)) #define XORI (HI(14)) -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) #define CLZ (HI(28) | LO(32)) -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define DCLZ (LO(18)) -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define DCLZ (HI(28) | LO(36)) #define MOVF (HI(0) | (0 << 16) | LO(1)) #define MOVN (HI(0) | LO(11)) #define MOVT (HI(0) | (1 << 16) | LO(1)) #define MOVZ (HI(0) | LO(10)) #define MUL (HI(28) | LO(2)) -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ #define PREF (HI(51)) #define PREFX (HI(19) | LO(15)) #define SEB (HI(31) | (16 << 6) | LO(32)) #define SEH (HI(31) | (24 << 6) | LO(32)) -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define ADDU_W ADDU @@ -289,9 +290,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { Useful for reordering instructions in the delay slot. */ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) { + sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); - sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr = ins; compiler->size++; @@ -303,10 +304,10 @@ static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags) { if (flags & IS_BIT26_COND) return (1 << 26); -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) if (flags & IS_BIT23_COND) return (1 << 23); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ return (1 << 16); } @@ -519,7 +520,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil CHECK_PTR(check_sljit_generate_code(compiler)); reverse_buf(compiler); - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -666,6 +667,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* GCC workaround for invalid code generation with -O2. */ sljit_cache_flush(code, code_ptr); #endif + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); return code; } @@ -678,17 +680,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; #elif defined(__GNUC__) - asm ("cfc1 %0, $0" : "=r"(fir)); + __asm__ ("cfc1 %0, $0" : "=r"(fir)); return (fir >> 22) & 0x1; #else #error "FIR check is not implemented for this architecture" #endif + case SLJIT_HAS_ZERO_REGISTER: + return 1; -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) case SLJIT_HAS_CLZ: case SLJIT_HAS_CMOV: + case SLJIT_HAS_PREFETCH: return 1; -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ default: return fir; @@ -1230,7 +1235,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, NOP, UNMOVABLE_INS); case SLJIT_LMUL_UW: case SLJIT_LMUL_SW: -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3))); FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1))); @@ -1240,7 +1245,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #endif /* SLJIT_CONFIG_MIPS_64 */ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0))); return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1)); -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #else /* !SLJIT_CONFIG_MIPS_64 */ @@ -1248,13 +1253,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #endif /* SLJIT_CONFIG_MIPS_64 */ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ case SLJIT_DIVMOD_UW: case SLJIT_DIVMOD_SW: case SLJIT_DIV_UW: case SLJIT_DIV_SW: SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if (int_op) { FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3))); @@ -1270,11 +1275,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #endif /* SLJIT_CONFIG_MIPS_64 */ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0))); return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1)); -#else /* !SLJIT_MIPS_R6 */ -#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#else /* SLJIT_MIPS_REV < 6 */ +#if !(defined SLJIT_MIPS_REV) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif /* !SLJIT_MIPS_R1 */ +#endif /* !SLJIT_MIPS_REV */ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if (int_op) FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); @@ -1285,13 +1290,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #endif /* SLJIT_CONFIG_MIPS_64 */ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ + case SLJIT_ENDBR: + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; } return SLJIT_SUCCESS; } -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { @@ -1312,7 +1320,7 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS); } -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, @@ -1329,14 +1337,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) - return emit_prefetch(compiler, src, srcw); -#endif - return SLJIT_SUCCESS; - } - #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT) flags |= INT_DATA | SIGNED_DATA; @@ -1463,6 +1463,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile #endif } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); + else + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); + + FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); + return push_inst(compiler, NOP, UNMOVABLE_INS); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + return SLJIT_SUCCESS; + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) + return emit_prefetch(compiler, src, srcw); +#else /* SLJIT_MIPS_REV < 1 */ + return SLJIT_SUCCESS; +#endif /* SLJIT_MIPS_REV >= 1 */ + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -1732,25 +1764,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * ADJUST_LOCAL_OFFSET(dst, dstw); if (FAST_IS_REG(dst)) - return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); + return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS); /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); - else - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); - - FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); - return push_inst(compiler, NOP, UNMOVABLE_INS); + FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw)); + compiler->delay_slot = UNMOVABLE_INS; + return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ @@ -1790,7 +1809,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi flags = IS_BIT26_COND; \ delay_check = src; -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define BR_T() \ inst = BC1NEZ; \ @@ -1801,7 +1820,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi flags = IS_BIT23_COND; \ delay_check = FCSR_FCC; -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ #define BR_T() \ inst = BC1T | JUMP_LENGTH; \ @@ -1812,7 +1831,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { @@ -2123,11 +2142,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co case SLJIT_GREATER_EQUAL_F64: case SLJIT_UNORDERED_F64: case SLJIT_ORDERED_F64: -#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar)); -#else /* !SLJIT_MIPS_R6 */ +#else /* SLJIT_MIPS_REV < 6 */ FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar)); -#endif /* SLJIT_MIPS_R6 */ +#endif /* SLJIT_MIPS_REV >= 6 */ FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar)); FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar)); src_ar = dst_ar; @@ -2167,14 +2186,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil sljit_s32 dst_reg, sljit_s32 src, sljit_sw srcw) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) sljit_ins ins; -#endif +#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */ CHECK_ERROR(); CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) @@ -2231,9 +2250,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg)); -#else +#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */ return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); -#endif +#endif /* SLJIT_MIPS_REV >= 1 */ } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c index 3ce741153f..7d9ec5338f 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c @@ -258,21 +258,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0); SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI); inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins *)addr; - - SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI); - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); - inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 2); + sljit_set_jump_addr(addr, new_constant, executable_offset); } diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c index 3b73021cc8..92147d2a5d 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c @@ -477,23 +477,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins*)addr; + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0); inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff); inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff); inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 5); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; - - inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); - inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); - inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 5); + sljit_set_jump_addr(addr, new_constant, executable_offset); } diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c index e827514315..d84562ce09 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c @@ -404,7 +404,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); #endif #endif - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -607,6 +607,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) return code_ptr; @@ -626,7 +627,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return 1; #endif + /* A saved register is set to a zero value. */ + case SLJIT_HAS_ZERO_REGISTER: case SLJIT_HAS_CLZ: + case SLJIT_HAS_PREFETCH: return 1; default: @@ -1158,6 +1162,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #else return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #endif + case SLJIT_ENDBR: + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; } return SLJIT_SUCCESS; @@ -1203,13 +1210,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) { - if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) - return emit_prefetch(compiler, src, srcw); - - return SLJIT_SUCCESS; - } - op = GET_OPCODE(op); if ((src & SLJIT_IMM) && srcw == 0) src = TMP_ZERO; @@ -1536,6 +1536,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, MTLR | S(src))); + else { + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); + } + + return push_inst(compiler, BLR); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + return SLJIT_SUCCESS; + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: + return emit_prefetch(compiler, src, srcw); + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -1854,22 +1883,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, MTLR | S(src))); - else { - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); - } - - return push_inst(compiler, BLR); -} - /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ diff --git a/thirdparty/pcre2/src/sljit/sljitNativeS390X.c b/thirdparty/pcre2/src/sljit/sljitNativeS390X.c new file mode 100644 index 0000000000..a8b65112d4 --- /dev/null +++ b/thirdparty/pcre2/src/sljit/sljitNativeS390X.c @@ -0,0 +1,2812 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/auxv.h> + +#ifdef __ARCH__ +#define ENABLE_STATIC_FACILITY_DETECTION 1 +#else +#define ENABLE_STATIC_FACILITY_DETECTION 0 +#endif +#define ENABLE_DYNAMIC_FACILITY_DETECTION 1 + +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) +{ + return "s390x" SLJIT_CPUINFO; +} + +/* Instructions. */ +typedef sljit_uw sljit_ins; + +/* Instruction tags (most significant halfword). */ +const sljit_ins sljit_ins_const = (sljit_ins)1 << 48; + +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = { + 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1 +}; + +/* there are also a[2-15] available, but they are slower to access and + * their use is limited as mundaym explained: + * https://github.com/zherczeg/sljit/pull/91#discussion_r486895689 + */ + +/* General Purpose Registers [0-15]. */ +typedef sljit_uw sljit_gpr; + +/* + * WARNING + * the following code is non standard and should be improved for + * consistency, but doesn't use SLJIT_NUMBER_OF_REGISTERS based + * registers because r0 and r1 are the ABI recommended volatiles. + * there is a gpr() function that maps sljit to physical register numbers + * that should be used instead of the usual index into reg_map[] and + * will be retired ASAP (TODO: carenas) + */ + +const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */ +const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */ +const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */ +const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */ +const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */ +const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */ +const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */ +const sljit_gpr r7 = 7; /* reg_map[6] */ +const sljit_gpr r8 = 8; /* reg_map[7] */ +const sljit_gpr r9 = 9; /* reg_map[8] */ +const sljit_gpr r10 = 10; /* reg_map[9] */ +const sljit_gpr r11 = 11; /* reg_map[10] */ +const sljit_gpr r12 = 12; /* reg_map[11]: GOT */ +const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */ +const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */ +const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */ + +/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */ +/* TODO(carenas): r12 might conflict in PIC code, reserve? */ +/* TODO(carenas): r13 is usually pointed to "pool" per ABI, using a tmp + * like we do know might be faster though, reserve? + */ + +/* TODO(carenas): should be named TMP_REG[1-2] for consistency */ +#define tmp0 r0 +#define tmp1 r1 + +/* TODO(carenas): flags should move to a different register so that + * link register doesn't need to change + */ + +/* Link registers. The normal link register is r14, but since + we use that for flags we need to use r0 instead to do fast + calls so that flags are preserved. */ +const sljit_gpr link_r = 14; /* r14 */ +const sljit_gpr fast_link_r = 0; /* r0 */ + +/* Flag register layout: + + 0 32 33 34 36 64 + +---------------+---+---+-------+-------+ + | ZERO | 0 | 0 | C C |///////| + +---------------+---+---+-------+-------+ +*/ +const sljit_gpr flag_r = 14; /* r14 */ + +struct sljit_s390x_const { + struct sljit_const const_; /* must be first */ + sljit_sw init_value; /* required to build literal pool */ +}; + +/* Convert SLJIT register to hardware register. */ +static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r) +{ + SLJIT_ASSERT(r != SLJIT_UNUSED); + SLJIT_ASSERT(r < (sljit_s32)(sizeof(reg_map) / sizeof(reg_map[0]))); + return reg_map[r]; +} + +/* Size of instruction in bytes. Tags must already be cleared. */ +static SLJIT_INLINE sljit_uw sizeof_ins(sljit_ins ins) +{ + /* keep faulting instructions */ + if (ins == 0) + return 2; + + if ((ins & 0x00000000ffffL) == ins) + return 2; + if ((ins & 0x0000ffffffffL) == ins) + return 4; + if ((ins & 0xffffffffffffL) == ins) + return 6; + + SLJIT_UNREACHABLE(); + return (sljit_uw)-1; +} + +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) +{ + sljit_ins *ibuf = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ibuf); + *ibuf = ins; + compiler->size++; + return SLJIT_SUCCESS; +} + +static sljit_s32 encode_inst(void **ptr, sljit_ins ins) +{ + sljit_u16 *ibuf = (sljit_u16 *)*ptr; + sljit_uw size = sizeof_ins(ins); + + SLJIT_ASSERT((size & 6) == size); + switch (size) { + case 6: + *ibuf++ = (sljit_u16)(ins >> 32); + /* fallthrough */ + case 4: + *ibuf++ = (sljit_u16)(ins >> 16); + /* fallthrough */ + case 2: + *ibuf++ = (sljit_u16)(ins); + } + *ptr = (void*)ibuf; + return SLJIT_SUCCESS; +} + +/* Map the given type to a 4-bit condition code mask. */ +static SLJIT_INLINE sljit_u8 get_cc(sljit_s32 type) { + const sljit_u8 eq = 1 << 3; /* equal {,to zero} */ + const sljit_u8 lt = 1 << 2; /* less than {,zero} */ + const sljit_u8 gt = 1 << 1; /* greater than {,zero} */ + const sljit_u8 ov = 1 << 0; /* {overflow,NaN} */ + + switch (type) { + case SLJIT_EQUAL: + case SLJIT_EQUAL_F64: + return eq; + + case SLJIT_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: + return ~eq; + + case SLJIT_LESS: + case SLJIT_SIG_LESS: + case SLJIT_LESS_F64: + return lt; + + case SLJIT_LESS_EQUAL: + case SLJIT_SIG_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: + return (lt | eq); + + case SLJIT_GREATER: + case SLJIT_SIG_GREATER: + case SLJIT_GREATER_F64: + return gt; + + case SLJIT_GREATER_EQUAL: + case SLJIT_SIG_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: + return (gt | eq); + + case SLJIT_OVERFLOW: + case SLJIT_MUL_OVERFLOW: + case SLJIT_UNORDERED_F64: + return ov; + + case SLJIT_NOT_OVERFLOW: + case SLJIT_MUL_NOT_OVERFLOW: + case SLJIT_ORDERED_F64: + return ~ov; + } + + SLJIT_UNREACHABLE(); + return (sljit_u8)-1; +} + +/* Facility to bit index mappings. + Note: some facilities share the same bit index. */ +typedef sljit_uw facility_bit; +#define STORE_FACILITY_LIST_EXTENDED_FACILITY 7 +#define FAST_LONG_DISPLACEMENT_FACILITY 19 +#define EXTENDED_IMMEDIATE_FACILITY 21 +#define GENERAL_INSTRUCTION_EXTENSION_FACILITY 34 +#define DISTINCT_OPERAND_FACILITY 45 +#define HIGH_WORD_FACILITY 45 +#define POPULATION_COUNT_FACILITY 45 +#define LOAD_STORE_ON_CONDITION_1_FACILITY 45 +#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY 49 +#define LOAD_STORE_ON_CONDITION_2_FACILITY 53 +#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY 58 +#define VECTOR_FACILITY 129 +#define VECTOR_ENHANCEMENTS_1_FACILITY 135 + +/* Report whether a facility is known to be present due to the compiler + settings. This function should always be compiled to a constant + value given a constant argument. */ +static SLJIT_INLINE int have_facility_static(facility_bit x) +{ +#if ENABLE_STATIC_FACILITY_DETECTION + switch (x) { + case FAST_LONG_DISPLACEMENT_FACILITY: + return (__ARCH__ >= 6 /* z990 */); + case EXTENDED_IMMEDIATE_FACILITY: + case STORE_FACILITY_LIST_EXTENDED_FACILITY: + return (__ARCH__ >= 7 /* z9-109 */); + case GENERAL_INSTRUCTION_EXTENSION_FACILITY: + return (__ARCH__ >= 8 /* z10 */); + case DISTINCT_OPERAND_FACILITY: + return (__ARCH__ >= 9 /* z196 */); + case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY: + return (__ARCH__ >= 10 /* zEC12 */); + case LOAD_STORE_ON_CONDITION_2_FACILITY: + case VECTOR_FACILITY: + return (__ARCH__ >= 11 /* z13 */); + case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY: + case VECTOR_ENHANCEMENTS_1_FACILITY: + return (__ARCH__ >= 12 /* z14 */); + default: + SLJIT_UNREACHABLE(); + } +#endif + return 0; +} + +static SLJIT_INLINE unsigned long get_hwcap() +{ + static unsigned long hwcap = 0; + if (SLJIT_UNLIKELY(!hwcap)) { + hwcap = getauxval(AT_HWCAP); + SLJIT_ASSERT(hwcap != 0); + } + return hwcap; +} + +static SLJIT_INLINE int have_stfle() +{ + if (have_facility_static(STORE_FACILITY_LIST_EXTENDED_FACILITY)) + return 1; + + return (get_hwcap() & HWCAP_S390_STFLE); +} + +/* Report whether the given facility is available. This function always + performs a runtime check. */ +static int have_facility_dynamic(facility_bit x) +{ +#if ENABLE_DYNAMIC_FACILITY_DETECTION + static struct { + sljit_uw bits[4]; + } cpu_features; + size_t size = sizeof(cpu_features); + const sljit_uw word_index = x >> 6; + const sljit_uw bit_index = ((1UL << 63) >> (x & 63)); + + SLJIT_ASSERT(x < size * 8); + if (SLJIT_UNLIKELY(!have_stfle())) + return 0; + + if (SLJIT_UNLIKELY(cpu_features.bits[0] == 0)) { + __asm__ __volatile__ ( + "lgr %%r0, %0;" + "stfle 0(%1);" + /* outputs */: + /* inputs */: "d" ((size / 8) - 1), "a" (&cpu_features) + /* clobbers */: "r0", "cc", "memory" + ); + SLJIT_ASSERT(cpu_features.bits[0] != 0); + } + return (cpu_features.bits[word_index] & bit_index) != 0; +#else + return 0; +#endif +} + +#define HAVE_FACILITY(name, bit) \ +static SLJIT_INLINE int name() \ +{ \ + static int have = -1; \ + /* Static check first. May allow the function to be optimized away. */ \ + if (have_facility_static(bit)) \ + have = 1; \ + else if (SLJIT_UNLIKELY(have < 0)) \ + have = have_facility_dynamic(bit) ? 1 : 0; \ +\ + return have; \ +} + +HAVE_FACILITY(have_eimm, EXTENDED_IMMEDIATE_FACILITY) +HAVE_FACILITY(have_ldisp, FAST_LONG_DISPLACEMENT_FACILITY) +HAVE_FACILITY(have_genext, GENERAL_INSTRUCTION_EXTENSION_FACILITY) +HAVE_FACILITY(have_lscond1, LOAD_STORE_ON_CONDITION_1_FACILITY) +HAVE_FACILITY(have_lscond2, LOAD_STORE_ON_CONDITION_2_FACILITY) +HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY) +#undef HAVE_FACILITY + +#define is_u12(d) (0 <= (d) && (d) <= 0x00000fffL) +#define is_u32(d) (0 <= (d) && (d) <= 0xffffffffL) + +#define CHECK_SIGNED(v, bitlen) \ + ((v) == (((v) << (sizeof(v) * 8 - bitlen)) >> (sizeof(v) * 8 - bitlen))) + +#define is_s16(d) CHECK_SIGNED((d), 16) +#define is_s20(d) CHECK_SIGNED((d), 20) +#define is_s32(d) CHECK_SIGNED((d), 32) + +static SLJIT_INLINE sljit_uw disp_s20(sljit_s32 d) +{ + sljit_uw dh = (d >> 12) & 0xff; + sljit_uw dl = (d << 8) & 0xfff00; + + SLJIT_ASSERT(is_s20(d)); + return dh | dl; +} + +/* TODO(carenas): variadic macro is not strictly needed */ +#define SLJIT_S390X_INSTRUCTION(op, ...) \ +static SLJIT_INLINE sljit_ins op(__VA_ARGS__) + +/* RR form instructions. */ +#define SLJIT_S390X_RR(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \ +{ \ + return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \ +} + +/* ADD */ +SLJIT_S390X_RR(ar, 0x1a00) + +/* ADD LOGICAL */ +SLJIT_S390X_RR(alr, 0x1e00) + +/* AND */ +SLJIT_S390X_RR(nr, 0x1400) + +/* BRANCH AND SAVE */ +SLJIT_S390X_RR(basr, 0x0d00) + +/* BRANCH ON CONDITION */ +SLJIT_S390X_RR(bcr, 0x0700) /* TODO(mundaym): type for mask? */ + +/* COMPARE */ +SLJIT_S390X_RR(cr, 0x1900) + +/* COMPARE LOGICAL */ +SLJIT_S390X_RR(clr, 0x1500) + +/* DIVIDE */ +SLJIT_S390X_RR(dr, 0x1d00) + +/* EXCLUSIVE OR */ +SLJIT_S390X_RR(xr, 0x1700) + +/* LOAD */ +SLJIT_S390X_RR(lr, 0x1800) + +/* LOAD COMPLEMENT */ +SLJIT_S390X_RR(lcr, 0x1300) + +/* OR */ +SLJIT_S390X_RR(or, 0x1600) + +/* SUBTRACT */ +SLJIT_S390X_RR(sr, 0x1b00) + +/* SUBTRACT LOGICAL */ +SLJIT_S390X_RR(slr, 0x1f00) + +#undef SLJIT_S390X_RR + +/* RRE form instructions */ +#define SLJIT_S390X_RRE(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \ +{ \ + return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \ +} + +/* ADD */ +SLJIT_S390X_RRE(agr, 0xb9080000) + +/* ADD LOGICAL */ +SLJIT_S390X_RRE(algr, 0xb90a0000) + +/* ADD LOGICAL WITH CARRY */ +SLJIT_S390X_RRE(alcr, 0xb9980000) +SLJIT_S390X_RRE(alcgr, 0xb9880000) + +/* AND */ +SLJIT_S390X_RRE(ngr, 0xb9800000) + +/* COMPARE */ +SLJIT_S390X_RRE(cgr, 0xb9200000) + +/* COMPARE LOGICAL */ +SLJIT_S390X_RRE(clgr, 0xb9210000) + +/* DIVIDE LOGICAL */ +SLJIT_S390X_RRE(dlr, 0xb9970000) +SLJIT_S390X_RRE(dlgr, 0xb9870000) + +/* DIVIDE SINGLE */ +SLJIT_S390X_RRE(dsgr, 0xb90d0000) + +/* EXCLUSIVE OR */ +SLJIT_S390X_RRE(xgr, 0xb9820000) + +/* LOAD */ +SLJIT_S390X_RRE(lgr, 0xb9040000) +SLJIT_S390X_RRE(lgfr, 0xb9140000) + +/* LOAD BYTE */ +SLJIT_S390X_RRE(lbr, 0xb9260000) +SLJIT_S390X_RRE(lgbr, 0xb9060000) + +/* LOAD COMPLEMENT */ +SLJIT_S390X_RRE(lcgr, 0xb9030000) + +/* LOAD HALFWORD */ +SLJIT_S390X_RRE(lhr, 0xb9270000) +SLJIT_S390X_RRE(lghr, 0xb9070000) + +/* LOAD LOGICAL */ +SLJIT_S390X_RRE(llgfr, 0xb9160000) + +/* LOAD LOGICAL CHARACTER */ +SLJIT_S390X_RRE(llcr, 0xb9940000) +SLJIT_S390X_RRE(llgcr, 0xb9840000) + +/* LOAD LOGICAL HALFWORD */ +SLJIT_S390X_RRE(llhr, 0xb9950000) +SLJIT_S390X_RRE(llghr, 0xb9850000) + +/* MULTIPLY LOGICAL */ +SLJIT_S390X_RRE(mlgr, 0xb9860000) + +/* MULTIPLY SINGLE */ +SLJIT_S390X_RRE(msr, 0xb2520000) +SLJIT_S390X_RRE(msgr, 0xb90c0000) +SLJIT_S390X_RRE(msgfr, 0xb91c0000) + +/* OR */ +SLJIT_S390X_RRE(ogr, 0xb9810000) + +/* SUBTRACT */ +SLJIT_S390X_RRE(sgr, 0xb9090000) + +/* SUBTRACT LOGICAL */ +SLJIT_S390X_RRE(slgr, 0xb90b0000) + +/* SUBTRACT LOGICAL WITH BORROW */ +SLJIT_S390X_RRE(slbr, 0xb9990000) +SLJIT_S390X_RRE(slbgr, 0xb9890000) + +#undef SLJIT_S390X_RRE + +/* RI-a form instructions */ +#define SLJIT_S390X_RIA(name, pattern, imm_type) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \ +{ \ + return (pattern) | ((reg & 0xf) << 20) | (imm & 0xffff); \ +} + +/* ADD HALFWORD IMMEDIATE */ +SLJIT_S390X_RIA(ahi, 0xa70a0000, sljit_s16) +SLJIT_S390X_RIA(aghi, 0xa70b0000, sljit_s16) + +/* COMPARE HALFWORD IMMEDIATE */ +SLJIT_S390X_RIA(chi, 0xa70e0000, sljit_s16) +SLJIT_S390X_RIA(cghi, 0xa70f0000, sljit_s16) + +/* LOAD HALFWORD IMMEDIATE */ +SLJIT_S390X_RIA(lhi, 0xa7080000, sljit_s16) +SLJIT_S390X_RIA(lghi, 0xa7090000, sljit_s16) + +/* LOAD LOGICAL IMMEDIATE */ +SLJIT_S390X_RIA(llihh, 0xa50c0000, sljit_u16) +SLJIT_S390X_RIA(llihl, 0xa50d0000, sljit_u16) +SLJIT_S390X_RIA(llilh, 0xa50e0000, sljit_u16) +SLJIT_S390X_RIA(llill, 0xa50f0000, sljit_u16) + +/* MULTIPLY HALFWORD IMMEDIATE */ +SLJIT_S390X_RIA(mhi, 0xa70c0000, sljit_s16) +SLJIT_S390X_RIA(mghi, 0xa70d0000, sljit_s16) + +/* OR IMMEDIATE */ +SLJIT_S390X_RIA(oilh, 0xa50a0000, sljit_u16) + +/* TEST UNDER MASK */ +SLJIT_S390X_RIA(tmlh, 0xa7000000, sljit_u16) + +#undef SLJIT_S390X_RIA + +/* RIL-a form instructions (requires extended immediate facility) */ +#define SLJIT_S390X_RILA(name, pattern, imm_type) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \ +{ \ + SLJIT_ASSERT(have_eimm()); \ + return (pattern) | ((sljit_ins)(reg & 0xf) << 36) | (imm & 0xffffffff); \ +} + +/* ADD IMMEDIATE */ +SLJIT_S390X_RILA(afi, 0xc20900000000, sljit_s32) +SLJIT_S390X_RILA(agfi, 0xc20800000000, sljit_s32) + +/* ADD IMMEDIATE HIGH */ +SLJIT_S390X_RILA(aih, 0xcc0800000000, sljit_s32) /* TODO(mundaym): high-word facility? */ + +/* ADD LOGICAL IMMEDIATE */ +SLJIT_S390X_RILA(alfi, 0xc20b00000000, sljit_u32) +SLJIT_S390X_RILA(algfi, 0xc20a00000000, sljit_u32) + +/* AND IMMEDIATE */ +SLJIT_S390X_RILA(nihf, 0xc00a00000000, sljit_u32) +SLJIT_S390X_RILA(nilf, 0xc00b00000000, sljit_u32) + +/* COMPARE IMMEDIATE */ +SLJIT_S390X_RILA(cfi, 0xc20d00000000, sljit_s32) +SLJIT_S390X_RILA(cgfi, 0xc20c00000000, sljit_s32) + +/* COMPARE IMMEDIATE HIGH */ +SLJIT_S390X_RILA(cih, 0xcc0d00000000, sljit_s32) /* TODO(mundaym): high-word facility? */ + +/* COMPARE LOGICAL IMMEDIATE */ +SLJIT_S390X_RILA(clfi, 0xc20f00000000, sljit_u32) +SLJIT_S390X_RILA(clgfi, 0xc20e00000000, sljit_u32) + +/* EXCLUSIVE OR IMMEDIATE */ +SLJIT_S390X_RILA(xilf, 0xc00700000000, sljit_u32) + +/* INSERT IMMEDIATE */ +SLJIT_S390X_RILA(iihf, 0xc00800000000, sljit_u32) +SLJIT_S390X_RILA(iilf, 0xc00900000000, sljit_u32) + +/* LOAD IMMEDIATE */ +SLJIT_S390X_RILA(lgfi, 0xc00100000000, sljit_s32) + +/* LOAD LOGICAL IMMEDIATE */ +SLJIT_S390X_RILA(llihf, 0xc00e00000000, sljit_u32) +SLJIT_S390X_RILA(llilf, 0xc00f00000000, sljit_u32) + +/* OR IMMEDIATE */ +SLJIT_S390X_RILA(oilf, 0xc00d00000000, sljit_u32) + +#undef SLJIT_S390X_RILA + +/* RX-a form instructions */ +#define SLJIT_S390X_RXA(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_u16 d, sljit_gpr x, sljit_gpr b) \ +{ \ + sljit_ins ri, xi, bi, di; \ +\ + SLJIT_ASSERT((d & 0xfff) == d); \ + ri = (sljit_ins)(r & 0xf) << 20; \ + xi = (sljit_ins)(x & 0xf) << 16; \ + bi = (sljit_ins)(b & 0xf) << 12; \ + di = (sljit_ins)(d & 0xfff); \ +\ + return (pattern) | ri | xi | bi | di; \ +} + +/* ADD */ +SLJIT_S390X_RXA(a, 0x5a000000) + +/* ADD LOGICAL */ +SLJIT_S390X_RXA(al, 0x5e000000) + +/* AND */ +SLJIT_S390X_RXA(n, 0x54000000) + +/* EXCLUSIVE OR */ +SLJIT_S390X_RXA(x, 0x57000000) + +/* LOAD */ +SLJIT_S390X_RXA(l, 0x58000000) + +/* LOAD ADDRESS */ +SLJIT_S390X_RXA(la, 0x41000000) + +/* LOAD HALFWORD */ +SLJIT_S390X_RXA(lh, 0x48000000) + +/* MULTIPLY SINGLE */ +SLJIT_S390X_RXA(ms, 0x71000000) + +/* OR */ +SLJIT_S390X_RXA(o, 0x56000000) + +/* STORE */ +SLJIT_S390X_RXA(st, 0x50000000) + +/* STORE CHARACTER */ +SLJIT_S390X_RXA(stc, 0x42000000) + +/* STORE HALFWORD */ +SLJIT_S390X_RXA(sth, 0x40000000) + +/* SUBTRACT */ +SLJIT_S390X_RXA(s, 0x5b000000) + +/* SUBTRACT LOGICAL */ +SLJIT_S390X_RXA(sl, 0x5f000000) + +#undef SLJIT_S390X_RXA + +/* RXY-a instructions */ +#define SLJIT_S390X_RXYA(name, pattern, cond) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \ +{ \ + sljit_ins ri, xi, bi, di; \ +\ + SLJIT_ASSERT(cond); \ + ri = (sljit_ins)(r & 0xf) << 36; \ + xi = (sljit_ins)(x & 0xf) << 32; \ + bi = (sljit_ins)(b & 0xf) << 28; \ + di = (sljit_ins)disp_s20(d) << 8; \ +\ + return (pattern) | ri | xi | bi | di; \ +} + +/* ADD */ +SLJIT_S390X_RXYA(ay, 0xe3000000005a, have_ldisp()) +SLJIT_S390X_RXYA(ag, 0xe30000000008, 1) + +/* ADD LOGICAL */ +SLJIT_S390X_RXYA(aly, 0xe3000000005e, have_ldisp()) +SLJIT_S390X_RXYA(alg, 0xe3000000000a, 1) + +/* ADD LOGICAL WITH CARRY */ +SLJIT_S390X_RXYA(alc, 0xe30000000098, 1) +SLJIT_S390X_RXYA(alcg, 0xe30000000088, 1) + +/* AND */ +SLJIT_S390X_RXYA(ny, 0xe30000000054, have_ldisp()) +SLJIT_S390X_RXYA(ng, 0xe30000000080, 1) + +/* EXCLUSIVE OR */ +SLJIT_S390X_RXYA(xy, 0xe30000000057, have_ldisp()) +SLJIT_S390X_RXYA(xg, 0xe30000000082, 1) + +/* LOAD */ +SLJIT_S390X_RXYA(ly, 0xe30000000058, have_ldisp()) +SLJIT_S390X_RXYA(lg, 0xe30000000004, 1) +SLJIT_S390X_RXYA(lgf, 0xe30000000014, 1) + +/* LOAD BYTE */ +SLJIT_S390X_RXYA(lb, 0xe30000000076, have_ldisp()) +SLJIT_S390X_RXYA(lgb, 0xe30000000077, have_ldisp()) + +/* LOAD HALFWORD */ +SLJIT_S390X_RXYA(lhy, 0xe30000000078, have_ldisp()) +SLJIT_S390X_RXYA(lgh, 0xe30000000015, 1) + +/* LOAD LOGICAL */ +SLJIT_S390X_RXYA(llgf, 0xe30000000016, 1) + +/* LOAD LOGICAL CHARACTER */ +SLJIT_S390X_RXYA(llc, 0xe30000000094, have_eimm()) +SLJIT_S390X_RXYA(llgc, 0xe30000000090, 1) + +/* LOAD LOGICAL HALFWORD */ +SLJIT_S390X_RXYA(llh, 0xe30000000095, have_eimm()) +SLJIT_S390X_RXYA(llgh, 0xe30000000091, 1) + +/* MULTIPLY SINGLE */ +SLJIT_S390X_RXYA(msy, 0xe30000000051, have_ldisp()) +SLJIT_S390X_RXYA(msg, 0xe3000000000c, 1) + +/* OR */ +SLJIT_S390X_RXYA(oy, 0xe30000000056, have_ldisp()) +SLJIT_S390X_RXYA(og, 0xe30000000081, 1) + +/* STORE */ +SLJIT_S390X_RXYA(sty, 0xe30000000050, have_ldisp()) +SLJIT_S390X_RXYA(stg, 0xe30000000024, 1) + +/* STORE CHARACTER */ +SLJIT_S390X_RXYA(stcy, 0xe30000000072, have_ldisp()) + +/* STORE HALFWORD */ +SLJIT_S390X_RXYA(sthy, 0xe30000000070, have_ldisp()) + +/* SUBTRACT */ +SLJIT_S390X_RXYA(sy, 0xe3000000005b, have_ldisp()) +SLJIT_S390X_RXYA(sg, 0xe30000000009, 1) + +/* SUBTRACT LOGICAL */ +SLJIT_S390X_RXYA(sly, 0xe3000000005f, have_ldisp()) +SLJIT_S390X_RXYA(slg, 0xe3000000000b, 1) + +/* SUBTRACT LOGICAL WITH BORROW */ +SLJIT_S390X_RXYA(slb, 0xe30000000099, 1) +SLJIT_S390X_RXYA(slbg, 0xe30000000089, 1) + +#undef SLJIT_S390X_RXYA + +/* RS-a instructions */ +#define SLJIT_S390X_RSA(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw d, sljit_gpr b) \ +{ \ + sljit_ins r1 = (sljit_ins)(reg & 0xf) << 20; \ + sljit_ins b2 = (sljit_ins)(b & 0xf) << 12; \ + sljit_ins d2 = (sljit_ins)(d & 0xfff); \ + return (pattern) | r1 | b2 | d2; \ +} + +/* SHIFT LEFT SINGLE LOGICAL */ +SLJIT_S390X_RSA(sll, 0x89000000) + +/* SHIFT RIGHT SINGLE */ +SLJIT_S390X_RSA(sra, 0x8a000000) + +/* SHIFT RIGHT SINGLE LOGICAL */ +SLJIT_S390X_RSA(srl, 0x88000000) + +#undef SLJIT_S390X_RSA + +/* RSY-a instructions */ +#define SLJIT_S390X_RSYA(name, pattern, cond) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_sw d, sljit_gpr b) \ +{ \ + sljit_ins r1, r3, b2, d2; \ +\ + SLJIT_ASSERT(cond); \ + r1 = (sljit_ins)(dst & 0xf) << 36; \ + r3 = (sljit_ins)(src & 0xf) << 32; \ + b2 = (sljit_ins)(b & 0xf) << 28; \ + d2 = (sljit_ins)disp_s20(d) << 8; \ +\ + return (pattern) | r1 | r3 | b2 | d2; \ +} + +/* LOAD MULTIPLE */ +SLJIT_S390X_RSYA(lmg, 0xeb0000000004, 1) + +/* SHIFT LEFT LOGICAL */ +SLJIT_S390X_RSYA(sllg, 0xeb000000000d, 1) + +/* SHIFT RIGHT SINGLE */ +SLJIT_S390X_RSYA(srag, 0xeb000000000a, 1) + +/* SHIFT RIGHT SINGLE LOGICAL */ +SLJIT_S390X_RSYA(srlg, 0xeb000000000c, 1) + +/* STORE MULTIPLE */ +SLJIT_S390X_RSYA(stmg, 0xeb0000000024, 1) + +#undef SLJIT_S390X_RSYA + +/* RIE-f instructions (require general-instructions-extension facility) */ +#define SLJIT_S390X_RIEF(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot) \ +{ \ + sljit_ins r1, r2, i3, i4, i5; \ +\ + SLJIT_ASSERT(have_genext()); \ + r1 = (sljit_ins)(dst & 0xf) << 36; \ + r2 = (sljit_ins)(src & 0xf) << 32; \ + i3 = (sljit_ins)start << 24; \ + i4 = (sljit_ins)end << 16; \ + i5 = (sljit_ins)rot << 8; \ +\ + return (pattern) | r1 | r2 | i3 | i4 | i5; \ +} + +/* ROTATE THEN AND SELECTED BITS */ +/* SLJIT_S390X_RIEF(rnsbg, 0xec0000000054) */ + +/* ROTATE THEN EXCLUSIVE OR SELECTED BITS */ +/* SLJIT_S390X_RIEF(rxsbg, 0xec0000000057) */ + +/* ROTATE THEN OR SELECTED BITS */ +SLJIT_S390X_RIEF(rosbg, 0xec0000000056) + +/* ROTATE THEN INSERT SELECTED BITS */ +/* SLJIT_S390X_RIEF(risbg, 0xec0000000055) */ +/* SLJIT_S390X_RIEF(risbgn, 0xec0000000059) */ + +/* ROTATE THEN INSERT SELECTED BITS HIGH */ +SLJIT_S390X_RIEF(risbhg, 0xec000000005d) + +/* ROTATE THEN INSERT SELECTED BITS LOW */ +/* SLJIT_S390X_RIEF(risblg, 0xec0000000051) */ + +#undef SLJIT_S390X_RIEF + +/* RRF-a instructions */ +#define SLJIT_S390X_RRFA(name, pattern, cond) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src1, sljit_gpr src2) \ +{ \ + sljit_ins r1, r2, r3; \ +\ + SLJIT_ASSERT(cond); \ + r1 = (sljit_ins)(dst & 0xf) << 4; \ + r2 = (sljit_ins)(src1 & 0xf); \ + r3 = (sljit_ins)(src2 & 0xf) << 12; \ +\ + return (pattern) | r3 | r1 | r2; \ +} + +/* MULTIPLY */ +SLJIT_S390X_RRFA(msrkc, 0xb9fd0000, have_misc2()) +SLJIT_S390X_RRFA(msgrkc, 0xb9ed0000, have_misc2()) + +#undef SLJIT_S390X_RRFA + +/* RRF-c instructions (require load/store-on-condition 1 facility) */ +#define SLJIT_S390X_RRFC(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_uw mask) \ +{ \ + sljit_ins r1, r2, m3; \ +\ + SLJIT_ASSERT(have_lscond1()); \ + r1 = (sljit_ins)(dst & 0xf) << 4; \ + r2 = (sljit_ins)(src & 0xf); \ + m3 = (sljit_ins)(mask & 0xf) << 12; \ +\ + return (pattern) | m3 | r1 | r2; \ +} + +/* LOAD HALFWORD IMMEDIATE ON CONDITION */ +SLJIT_S390X_RRFC(locr, 0xb9f20000) +SLJIT_S390X_RRFC(locgr, 0xb9e20000) + +#undef SLJIT_S390X_RRFC + +/* RIE-g instructions (require load/store-on-condition 2 facility) */ +#define SLJIT_S390X_RIEG(name, pattern) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw imm, sljit_uw mask) \ +{ \ + sljit_ins r1, m3, i2; \ +\ + SLJIT_ASSERT(have_lscond2()); \ + r1 = (sljit_ins)(reg & 0xf) << 36; \ + m3 = (sljit_ins)(mask & 0xf) << 32; \ + i2 = (sljit_ins)(imm & 0xffffL) << 16; \ +\ + return (pattern) | r1 | m3 | i2; \ +} + +/* LOAD HALFWORD IMMEDIATE ON CONDITION */ +SLJIT_S390X_RIEG(lochi, 0xec0000000042) +SLJIT_S390X_RIEG(locghi, 0xec0000000046) + +#undef SLJIT_S390X_RIEG + +#define SLJIT_S390X_RILB(name, pattern, cond) \ +SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw ri) \ +{ \ + sljit_ins r1, ri2; \ +\ + SLJIT_ASSERT(cond); \ + r1 = (sljit_ins)(reg & 0xf) << 36; \ + ri2 = (sljit_ins)(ri & 0xffffffff); \ +\ + return (pattern) | r1 | ri2; \ +} + +/* BRANCH RELATIVE AND SAVE LONG */ +SLJIT_S390X_RILB(brasl, 0xc00500000000, 1) + +/* LOAD ADDRESS RELATIVE LONG */ +SLJIT_S390X_RILB(larl, 0xc00000000000, 1) + +/* LOAD RELATIVE LONG */ +SLJIT_S390X_RILB(lgrl, 0xc40800000000, have_genext()) + +#undef SLJIT_S390X_RILB + +SLJIT_S390X_INSTRUCTION(br, sljit_gpr target) +{ + return 0x07f0 | target; +} + +SLJIT_S390X_INSTRUCTION(brcl, sljit_uw mask, sljit_sw target) +{ + sljit_ins m1 = (sljit_ins)(mask & 0xf) << 36; + sljit_ins ri2 = (sljit_ins)target & 0xffffffff; + return 0xc00400000000L | m1 | ri2; +} + +SLJIT_S390X_INSTRUCTION(flogr, sljit_gpr dst, sljit_gpr src) +{ + sljit_ins r1 = ((sljit_ins)dst & 0xf) << 8; + sljit_ins r2 = ((sljit_ins)src & 0xf); + SLJIT_ASSERT(have_eimm()); + return 0xb9830000 | r1 | r2; +} + +/* INSERT PROGRAM MASK */ +SLJIT_S390X_INSTRUCTION(ipm, sljit_gpr dst) +{ + return 0xb2220000 | ((sljit_ins)(dst & 0xf) << 4); +} + +/* ROTATE THEN INSERT SELECTED BITS HIGH (ZERO) */ +SLJIT_S390X_INSTRUCTION(risbhgz, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot) +{ + return risbhg(dst, src, start, 0x8 | end, rot); +} + +#undef SLJIT_S390X_INSTRUCTION + +/* load condition code as needed to match type */ +static sljit_s32 push_load_cc(struct sljit_compiler *compiler, sljit_s32 type) +{ + type &= ~SLJIT_I32_OP; + switch (type) { + case SLJIT_ZERO: + case SLJIT_NOT_ZERO: + return push_inst(compiler, cih(flag_r, 0)); + break; + default: + return push_inst(compiler, tmlh(flag_r, 0x3000)); + break; + } + return SLJIT_SUCCESS; +} + +static sljit_s32 push_store_zero_flag(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr source) +{ + /* insert low 32-bits into high 32-bits of flag register */ + FAIL_IF(push_inst(compiler, risbhgz(flag_r, source, 0, 31, 32))); + if (!(op & SLJIT_I32_OP)) { + /* OR high 32-bits with high 32-bits of flag register */ + return push_inst(compiler, rosbg(flag_r, source, 0, 31, 0)); + } + return SLJIT_SUCCESS; +} + +/* load 64-bit immediate into register without clobbering flags */ +static sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr target, sljit_sw v) +{ + /* 4 byte instructions */ + if (is_s16(v)) + return push_inst(compiler, lghi(target, (sljit_s16)v)); + + if ((sljit_uw)v == (v & 0x000000000000ffffU)) + return push_inst(compiler, llill(target, (sljit_u16)v)); + + if ((sljit_uw)v == (v & 0x00000000ffff0000U)) + return push_inst(compiler, llilh(target, (sljit_u16)(v >> 16))); + + if ((sljit_uw)v == (v & 0x0000ffff00000000U)) + return push_inst(compiler, llihl(target, (sljit_u16)(v >> 32))); + + if ((sljit_uw)v == (v & 0xffff000000000000U)) + return push_inst(compiler, llihh(target, (sljit_u16)(v >> 48))); + + /* 6 byte instructions (requires extended immediate facility) */ + if (have_eimm()) { + if (is_s32(v)) + return push_inst(compiler, lgfi(target, (sljit_s32)v)); + + if ((sljit_uw)v == (v & 0x00000000ffffffffU)) + return push_inst(compiler, llilf(target, (sljit_u32)v)); + + if ((sljit_uw)v == (v & 0xffffffff00000000U)) + return push_inst(compiler, llihf(target, (sljit_u32)(v >> 32))); + + FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v))); + return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32))); + } + /* TODO(mundaym): instruction sequences that don't use extended immediates */ + abort(); +} + +struct addr { + sljit_gpr base; + sljit_gpr index; + sljit_sw offset; +}; + +/* transform memory operand into D(X,B) form with a signed 20-bit offset */ +static sljit_s32 make_addr_bxy(struct sljit_compiler *compiler, + struct addr *addr, sljit_s32 mem, sljit_sw off, + sljit_gpr tmp /* clobbered, must not be r0 */) +{ + sljit_gpr base = r0; + sljit_gpr index = r0; + + SLJIT_ASSERT(tmp != r0); + if (mem & REG_MASK) + base = gpr(mem & REG_MASK); + + if (mem & OFFS_REG_MASK) { + index = gpr(OFFS_REG(mem)); + if (off != 0) { + /* shift and put the result into tmp */ + SLJIT_ASSERT(0 <= off && off < 64); + FAIL_IF(push_inst(compiler, sllg(tmp, index, off, 0))); + index = tmp; + off = 0; /* clear offset */ + } + } + else if (!is_s20(off)) { + FAIL_IF(push_load_imm_inst(compiler, tmp, off)); + index = tmp; + off = 0; /* clear offset */ + } + addr->base = base; + addr->index = index; + addr->offset = off; + return SLJIT_SUCCESS; +} + +/* transform memory operand into D(X,B) form with an unsigned 12-bit offset */ +static sljit_s32 make_addr_bx(struct sljit_compiler *compiler, + struct addr *addr, sljit_s32 mem, sljit_sw off, + sljit_gpr tmp /* clobbered, must not be r0 */) +{ + sljit_gpr base = r0; + sljit_gpr index = r0; + + SLJIT_ASSERT(tmp != r0); + if (mem & REG_MASK) + base = gpr(mem & REG_MASK); + + if (mem & OFFS_REG_MASK) { + index = gpr(OFFS_REG(mem)); + if (off != 0) { + /* shift and put the result into tmp */ + SLJIT_ASSERT(0 <= off && off < 64); + FAIL_IF(push_inst(compiler, sllg(tmp, index, off, 0))); + index = tmp; + off = 0; /* clear offset */ + } + } + else if (!is_u12(off)) { + FAIL_IF(push_load_imm_inst(compiler, tmp, off)); + index = tmp; + off = 0; /* clear offset */ + } + addr->base = base; + addr->index = index; + addr->offset = off; + return SLJIT_SUCCESS; +} + +#define EVAL(op, r, addr) op(r, addr.offset, addr.index, addr.base) +#define WHEN(cond, r, i1, i2, addr) \ + (cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr) + +static sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst, + sljit_s32 src, sljit_sw srcw, + sljit_gpr tmp /* clobbered */, sljit_s32 is_32bit) +{ + struct addr addr; + sljit_ins ins; + + SLJIT_ASSERT(src & SLJIT_MEM); + if (have_ldisp() || !is_32bit) + FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp)); + else + FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp)); + + if (is_32bit) + ins = WHEN(is_u12(addr.offset), dst, l, ly, addr); + else + ins = lg(dst, addr.offset, addr.index, addr.base); + + return push_inst(compiler, ins); +} + +static sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src, + sljit_s32 dst, sljit_sw dstw, + sljit_gpr tmp /* clobbered */, sljit_s32 is_32bit) +{ + struct addr addr; + sljit_ins ins; + + SLJIT_ASSERT(dst & SLJIT_MEM); + if (have_ldisp() || !is_32bit) + FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp)); + else + FAIL_IF(make_addr_bx(compiler, &addr, dst, dstw, tmp)); + + if (is_32bit) + ins = WHEN(is_u12(addr.offset), src, st, sty, addr); + else + ins = stg(src, addr.offset, addr.index, addr.base); + + return push_inst(compiler, ins); +} + +#undef WHEN + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_s390x_const *const_; + struct sljit_put_label *put_label; + sljit_sw executable_offset; + sljit_uw ins_size = 0; /* instructions */ + sljit_uw pool_size = 0; /* literal pool */ + sljit_uw pad_size; + sljit_uw i, j = 0; + struct sljit_memory_fragment *buf; + void *code, *code_ptr; + sljit_uw *pool, *pool_ptr; + + sljit_uw source; + sljit_sw offset; /* TODO(carenas): only need 32 bit */ + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_generate_code(compiler)); + reverse_buf(compiler); + + /* branch handling */ + label = compiler->labels; + jump = compiler->jumps; + put_label = compiler->put_labels; + + /* TODO(carenas): compiler->executable_size could be calculated + * before to avoid the following loop (except for + * pool_size) + */ + /* calculate the size of the code */ + for (buf = compiler->buf; buf != NULL; buf = buf->next) { + sljit_uw len = buf->used_size / sizeof(sljit_ins); + sljit_ins *ibuf = (sljit_ins *)buf->memory; + for (i = 0; i < len; ++i, ++j) { + sljit_ins ins = ibuf[i]; + + /* TODO(carenas): instruction tag vs size/addr == j + * using instruction tags for const is creative + * but unlike all other architectures, and is not + * done consistently for all other objects. + * This might need reviewing later. + */ + if (ins & sljit_ins_const) { + pool_size += sizeof(*pool); + ins &= ~sljit_ins_const; + } + if (label && label->size == j) { + label->size = ins_size; + label = label->next; + } + if (jump && jump->addr == j) { + if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) { + /* encoded: */ + /* brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */ + /* replace with: */ + /* lgrl %r1, <pool_addr> */ + /* bras %r14, %r1 (or bcr <mask>, %r1) */ + pool_size += sizeof(*pool); + ins_size += 2; + } + jump = jump->next; + } + if (put_label && put_label->addr == j) { + pool_size += sizeof(*pool); + put_label = put_label->next; + } + ins_size += sizeof_ins(ins); + } + } + + /* emit trailing label */ + if (label && label->size == j) { + label->size = ins_size; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!put_label); + + /* pad code size to 8 bytes so is accessible with half word offsets */ + /* the literal pool needs to be doubleword aligned */ + pad_size = ((ins_size + 7UL) & ~7UL) - ins_size; + SLJIT_ASSERT(pad_size < 8UL); + + /* allocate target buffer */ + code = SLJIT_MALLOC_EXEC(ins_size + pad_size + pool_size, + compiler->exec_allocator_data); + PTR_FAIL_WITH_EXEC_IF(code); + code_ptr = code; + executable_offset = SLJIT_EXEC_OFFSET(code); + + /* TODO(carenas): pool is optional, and the ABI recommends it to + * be created before the function code, instead of + * globally; if generated code is too big could + * need offsets bigger than 32bit words and asser() + */ + pool = (sljit_uw *)((sljit_uw)code + ins_size + pad_size); + pool_ptr = pool; + const_ = (struct sljit_s390x_const *)compiler->consts; + + /* update label addresses */ + label = compiler->labels; + while (label) { + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET( + (sljit_uw)code_ptr + label->size, executable_offset); + label = label->next; + } + + /* reset jumps */ + jump = compiler->jumps; + put_label = compiler->put_labels; + + /* emit the code */ + j = 0; + for (buf = compiler->buf; buf != NULL; buf = buf->next) { + sljit_uw len = buf->used_size / sizeof(sljit_ins); + sljit_ins *ibuf = (sljit_ins *)buf->memory; + for (i = 0; i < len; ++i, ++j) { + sljit_ins ins = ibuf[i]; + if (ins & sljit_ins_const) { + /* clear the const tag */ + ins &= ~sljit_ins_const; + + /* update instruction with relative address of constant */ + source = (sljit_uw)code_ptr; + offset = (sljit_uw)pool_ptr - source; + SLJIT_ASSERT(!(offset & 1)); + offset >>= 1; /* halfword (not byte) offset */ + SLJIT_ASSERT(is_s32(offset)); + ins |= (sljit_ins)offset & 0xffffffff; + + /* update address */ + const_->const_.addr = (sljit_uw)pool_ptr; + + /* store initial value into pool and update pool address */ + *(pool_ptr++) = const_->init_value; + + /* move to next constant */ + const_ = (struct sljit_s390x_const *)const_->const_.next; + } + if (jump && jump->addr == j) { + sljit_sw target = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) { + jump->addr = (sljit_uw)pool_ptr; + + /* load address into tmp1 */ + source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + offset = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source; + SLJIT_ASSERT(!(offset & 1)); + offset >>= 1; + SLJIT_ASSERT(is_s32(offset)); + encode_inst(&code_ptr, + lgrl(tmp1, offset & 0xffffffff)); + + /* store jump target into pool and update pool address */ + *(pool_ptr++) = target; + + /* branch to tmp1 */ + sljit_ins op = (ins >> 32) & 0xf; + sljit_ins arg = (ins >> 36) & 0xf; + switch (op) { + case 4: /* brcl -> bcr */ + ins = bcr(arg, tmp1); + break; + case 5: /* brasl -> basr */ + ins = basr(arg, tmp1); + break; + default: + abort(); + } + } + else { + jump->addr = (sljit_uw)code_ptr + 2; + source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + offset = target - source; + + /* offset must be halfword aligned */ + SLJIT_ASSERT(!(offset & 1)); + offset >>= 1; + SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */ + + /* patch jump target */ + ins |= (sljit_ins)offset & 0xffffffff; + } + jump = jump->next; + } + if (put_label && put_label->addr == j) { + source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; + + /* store target into pool */ + *pool_ptr = put_label->label->addr; + offset = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source; + pool_ptr++; + + SLJIT_ASSERT(!(offset & 1)); + offset >>= 1; + SLJIT_ASSERT(is_s32(offset)); + ins |= (sljit_ins)offset & 0xffffffff; + + put_label = put_label->next; + } + encode_inst(&code_ptr, ins); + } + } + SLJIT_ASSERT((sljit_u8 *)code + ins_size == code_ptr); + SLJIT_ASSERT((sljit_u8 *)pool + pool_size == (sljit_u8 *)pool_ptr); + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; + compiler->executable_size = ins_size; + code = SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + SLJIT_CACHE_FLUSH(code, code_ptr); + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); + return code; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) +{ + /* TODO(mundaym): implement all */ + switch (feature_type) { + case SLJIT_HAS_CLZ: + return have_eimm() ? 1 : 0; /* FLOGR instruction */ + case SLJIT_HAS_CMOV: + return have_lscond1() ? 1 : 0; + case SLJIT_HAS_FPU: + return 0; + } + return 0; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) +{ + sljit_s32 args = get_arg_count(arg_types); + sljit_sw frame_size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + + /* saved registers go in callee allocated save area */ + compiler->local_size = (local_size + 0xf) & ~0xf; + frame_size = compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE; + + FAIL_IF(push_inst(compiler, stmg(r6, r15, r6 * sizeof(sljit_sw), r15))); /* save registers TODO(MGM): optimize */ + if (frame_size != 0) { + if (is_s16(-frame_size)) + FAIL_IF(push_inst(compiler, aghi(r15, -((sljit_s16)frame_size)))); + else if (is_s32(-frame_size)) + FAIL_IF(push_inst(compiler, agfi(r15, -((sljit_s32)frame_size)))); + else { + FAIL_IF(push_load_imm_inst(compiler, tmp1, -frame_size)); + FAIL_IF(push_inst(compiler, la(r15, 0, tmp1, r15))); + } + } + + if (args >= 1) + FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S0), gpr(SLJIT_R0)))); + if (args >= 2) + FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S1), gpr(SLJIT_R1)))); + if (args >= 3) + FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S2), gpr(SLJIT_R2)))); + SLJIT_ASSERT(args < 4); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) +{ + CHECK_ERROR(); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + + /* TODO(mundaym): stack space for saved floating point registers */ + compiler->local_size = (local_size + 0xf) & ~0xf; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) +{ + sljit_sw size; + sljit_gpr end; + + CHECK_ERROR(); + CHECK(check_sljit_emit_return(compiler, op, src, srcw)); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + size = compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + (r6 * sizeof(sljit_sw)); + if (!is_s20(size)) { + FAIL_IF(push_load_imm_inst(compiler, tmp1, compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE)); + FAIL_IF(push_inst(compiler, la(r15, 0, tmp1, r15))); + size = r6 * sizeof(sljit_sw); + end = r14; /* r15 has been restored already */ + } + else + end = r15; + + FAIL_IF(push_inst(compiler, lmg(r6, end, size, r15))); /* restore registers TODO(MGM): optimize */ + FAIL_IF(push_inst(compiler, br(r14))); /* return */ + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) +{ + sljit_gpr arg0 = gpr(SLJIT_R0); + sljit_gpr arg1 = gpr(SLJIT_R1); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op0(compiler, op)); + + op = GET_OPCODE(op) | (op & SLJIT_I32_OP); + switch (op) { + case SLJIT_BREAKPOINT: + /* TODO(mundaym): insert real breakpoint? */ + case SLJIT_NOP: + return push_inst(compiler, 0x0700 /* 2-byte nop */); + case SLJIT_LMUL_UW: + FAIL_IF(push_inst(compiler, mlgr(arg0, arg0))); + break; + case SLJIT_LMUL_SW: + /* signed multiplication from: */ + /* Hacker's Delight, Second Edition: Chapter 8-3. */ + FAIL_IF(push_inst(compiler, srag(tmp0, arg0, 63, 0))); + FAIL_IF(push_inst(compiler, srag(tmp1, arg1, 63, 0))); + FAIL_IF(push_inst(compiler, ngr(tmp0, arg1))); + FAIL_IF(push_inst(compiler, ngr(tmp1, arg0))); + + /* unsigned multiplication */ + FAIL_IF(push_inst(compiler, mlgr(arg0, arg0))); + + FAIL_IF(push_inst(compiler, sgr(arg0, tmp0))); + FAIL_IF(push_inst(compiler, sgr(arg0, tmp1))); + break; + case SLJIT_DIV_U32: + case SLJIT_DIVMOD_U32: + FAIL_IF(push_inst(compiler, lhi(tmp0, 0))); + FAIL_IF(push_inst(compiler, lr(tmp1, arg0))); + FAIL_IF(push_inst(compiler, dlr(tmp0, arg1))); + FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */ + if (op == SLJIT_DIVMOD_U32) + return push_inst(compiler, lr(arg1, tmp0)); /* remainder */ + + return SLJIT_SUCCESS; + case SLJIT_DIV_S32: + case SLJIT_DIVMOD_S32: + FAIL_IF(push_inst(compiler, lhi(tmp0, 0))); + FAIL_IF(push_inst(compiler, lr(tmp1, arg0))); + FAIL_IF(push_inst(compiler, dr(tmp0, arg1))); + FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */ + if (op == SLJIT_DIVMOD_S32) + return push_inst(compiler, lr(arg1, tmp0)); /* remainder */ + + return SLJIT_SUCCESS; + case SLJIT_DIV_UW: + case SLJIT_DIVMOD_UW: + FAIL_IF(push_inst(compiler, lghi(tmp0, 0))); + FAIL_IF(push_inst(compiler, lgr(tmp1, arg0))); + FAIL_IF(push_inst(compiler, dlgr(tmp0, arg1))); + FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */ + if (op == SLJIT_DIVMOD_UW) + return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */ + + return SLJIT_SUCCESS; + case SLJIT_DIV_SW: + case SLJIT_DIVMOD_SW: + FAIL_IF(push_inst(compiler, lgr(tmp1, arg0))); + FAIL_IF(push_inst(compiler, dsgr(tmp0, arg1))); + FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */ + if (op == SLJIT_DIVMOD_SW) + return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */ + + return SLJIT_SUCCESS; + case SLJIT_ENDBR: + return SLJIT_SUCCESS; + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; + default: + SLJIT_UNREACHABLE(); + } + /* swap result registers */ + FAIL_IF(push_inst(compiler, lgr(tmp0, arg0))); + FAIL_IF(push_inst(compiler, lgr(arg0, arg1))); + return push_inst(compiler, lgr(arg1, tmp0)); +} + +/* LEVAL will be defined later with different parameters as needed */ +#define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins; + struct addr mem; + sljit_gpr dst_r; + sljit_gpr src_r; + sljit_s32 opcode = GET_OPCODE(op); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if ((dst == SLJIT_UNUSED) && !HAS_FLAGS(op)) { + /* TODO(carenas): implement prefetch? */ + return SLJIT_SUCCESS; + } + if (opcode >= SLJIT_MOV && opcode <= SLJIT_MOV_P) { + /* LOAD REGISTER */ + if (FAST_IS_REG(dst) && FAST_IS_REG(src)) { + dst_r = gpr(dst); + src_r = gpr(src); + switch (opcode | (op & SLJIT_I32_OP)) { + /* 32-bit */ + case SLJIT_MOV32_U8: + ins = llcr(dst_r, src_r); + break; + case SLJIT_MOV32_S8: + ins = lbr(dst_r, src_r); + break; + case SLJIT_MOV32_U16: + ins = llhr(dst_r, src_r); + break; + case SLJIT_MOV32_S16: + ins = lhr(dst_r, src_r); + break; + case SLJIT_MOV32: + ins = lr(dst_r, src_r); + break; + /* 64-bit */ + case SLJIT_MOV_U8: + ins = llgcr(dst_r, src_r); + break; + case SLJIT_MOV_S8: + ins = lgbr(dst_r, src_r); + break; + case SLJIT_MOV_U16: + ins = llghr(dst_r, src_r); + break; + case SLJIT_MOV_S16: + ins = lghr(dst_r, src_r); + break; + case SLJIT_MOV_U32: + ins = llgfr(dst_r, src_r); + break; + case SLJIT_MOV_S32: + ins = lgfr(dst_r, src_r); + break; + case SLJIT_MOV: + case SLJIT_MOV_P: + ins = lgr(dst_r, src_r); + break; + default: + ins = 0; + SLJIT_UNREACHABLE(); + } + FAIL_IF(push_inst(compiler, ins)); + if (HAS_FLAGS(op)) { + /* only handle zero flag */ + SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK)); + return push_store_zero_flag(compiler, op, dst_r); + } + return SLJIT_SUCCESS; + } + /* LOAD IMMEDIATE */ + if (FAST_IS_REG(dst) && (src & SLJIT_IMM)) { + switch (opcode) { + case SLJIT_MOV_U8: + srcw = (sljit_sw)((sljit_u8)(srcw)); + break; + case SLJIT_MOV_S8: + srcw = (sljit_sw)((sljit_s8)(srcw)); + break; + case SLJIT_MOV_U16: + srcw = (sljit_sw)((sljit_u16)(srcw)); + break; + case SLJIT_MOV_S16: + srcw = (sljit_sw)((sljit_s16)(srcw)); + break; + case SLJIT_MOV_U32: + srcw = (sljit_sw)((sljit_u32)(srcw)); + break; + case SLJIT_MOV_S32: + srcw = (sljit_sw)((sljit_s32)(srcw)); + break; + } + return push_load_imm_inst(compiler, gpr(dst), srcw); + } + /* LOAD */ + /* TODO(carenas): avoid reg being defined later */ + #define LEVAL(i) EVAL(i, reg, mem) + if (FAST_IS_REG(dst) && (src & SLJIT_MEM)) { + sljit_gpr reg = gpr(dst); + + FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1)); + /* TODO(carenas): convert all calls below to LEVAL */ + switch (opcode | (op & SLJIT_I32_OP)) { + case SLJIT_MOV32_U8: + ins = llc(reg, mem.offset, mem.index, mem.base); + break; + case SLJIT_MOV32_S8: + ins = lb(reg, mem.offset, mem.index, mem.base); + break; + case SLJIT_MOV32_U16: + ins = llh(reg, mem.offset, mem.index, mem.base); + break; + case SLJIT_MOV32_S16: + ins = WHEN2(is_u12(mem.offset), lh, lhy); + break; + case SLJIT_MOV32: + ins = WHEN2(is_u12(mem.offset), l, ly); + break; + case SLJIT_MOV_U8: + ins = LEVAL(llgc); + break; + case SLJIT_MOV_S8: + ins = lgb(reg, mem.offset, mem.index, mem.base); + break; + case SLJIT_MOV_U16: + ins = LEVAL(llgh); + break; + case SLJIT_MOV_S16: + ins = lgh(reg, mem.offset, mem.index, mem.base); + break; + case SLJIT_MOV_U32: + ins = LEVAL(llgf); + break; + case SLJIT_MOV_S32: + ins = lgf(reg, mem.offset, mem.index, mem.base); + break; + case SLJIT_MOV_P: + case SLJIT_MOV: + ins = lg(reg, mem.offset, mem.index, mem.base); + break; + default: + SLJIT_UNREACHABLE(); + } + FAIL_IF(push_inst(compiler, ins)); + if (HAS_FLAGS(op)) { + /* only handle zero flag */ + SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK)); + return push_store_zero_flag(compiler, op, reg); + } + return SLJIT_SUCCESS; + } + /* STORE and STORE IMMEDIATE */ + if ((dst & SLJIT_MEM) + && (FAST_IS_REG(src) || (src & SLJIT_IMM))) { + sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0; + if (src & SLJIT_IMM) { + /* TODO(mundaym): MOVE IMMEDIATE? */ + FAIL_IF(push_load_imm_inst(compiler, reg, srcw)); + } + struct addr mem; + FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); + switch (opcode) { + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: + return push_inst(compiler, + WHEN2(is_u12(mem.offset), stc, stcy)); + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: + return push_inst(compiler, + WHEN2(is_u12(mem.offset), sth, sthy)); + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: + return push_inst(compiler, + WHEN2(is_u12(mem.offset), st, sty)); + case SLJIT_MOV_P: + case SLJIT_MOV: + FAIL_IF(push_inst(compiler, LEVAL(stg))); + if (HAS_FLAGS(op)) { + /* only handle zero flag */ + SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK)); + return push_store_zero_flag(compiler, op, reg); + } + return SLJIT_SUCCESS; + default: + SLJIT_UNREACHABLE(); + } + } + #undef LEVAL + /* MOVE CHARACTERS */ + if ((dst & SLJIT_MEM) && (src & SLJIT_MEM)) { + struct addr mem; + FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1)); + switch (opcode) { + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: + FAIL_IF(push_inst(compiler, + EVAL(llgc, tmp0, mem))); + FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); + return push_inst(compiler, + EVAL(stcy, tmp0, mem)); + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: + FAIL_IF(push_inst(compiler, + EVAL(llgh, tmp0, mem))); + FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); + return push_inst(compiler, + EVAL(sthy, tmp0, mem)); + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: + FAIL_IF(push_inst(compiler, + EVAL(ly, tmp0, mem))); + FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); + return push_inst(compiler, + EVAL(sty, tmp0, mem)); + case SLJIT_MOV_P: + case SLJIT_MOV: + FAIL_IF(push_inst(compiler, + EVAL(lg, tmp0, mem))); + FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); + FAIL_IF(push_inst(compiler, + EVAL(stg, tmp0, mem))); + if (HAS_FLAGS(op)) { + /* only handle zero flag */ + SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK)); + return push_store_zero_flag(compiler, op, tmp0); + } + return SLJIT_SUCCESS; + default: + SLJIT_UNREACHABLE(); + } + } + SLJIT_UNREACHABLE(); + } + + SLJIT_ASSERT((src & SLJIT_IMM) == 0); /* no immediates */ + + dst_r = SLOW_IS_REG(dst) ? gpr(REG_MASK & dst) : tmp0; + src_r = FAST_IS_REG(src) ? gpr(REG_MASK & src) : tmp0; + if (src & SLJIT_MEM) + FAIL_IF(load_word(compiler, src_r, src, srcw, tmp1, src & SLJIT_I32_OP)); + + /* TODO(mundaym): optimize loads and stores */ + switch (opcode | (op & SLJIT_I32_OP)) { + case SLJIT_NOT: + /* emulate ~x with x^-1 */ + FAIL_IF(push_load_imm_inst(compiler, tmp1, -1)); + if (src_r != dst_r) + FAIL_IF(push_inst(compiler, lgr(dst_r, src_r))); + + FAIL_IF(push_inst(compiler, xgr(dst_r, tmp1))); + break; + case SLJIT_NOT32: + /* emulate ~x with x^-1 */ + if (have_eimm()) + FAIL_IF(push_inst(compiler, xilf(dst_r, -1))); + else { + FAIL_IF(push_load_imm_inst(compiler, tmp1, -1)); + if (src_r != dst_r) + FAIL_IF(push_inst(compiler, lr(dst_r, src_r))); + + FAIL_IF(push_inst(compiler, xr(dst_r, tmp1))); + } + break; + case SLJIT_NEG: + FAIL_IF(push_inst(compiler, lcgr(dst_r, src_r))); + break; + case SLJIT_NEG32: + FAIL_IF(push_inst(compiler, lcr(dst_r, src_r))); + break; + case SLJIT_CLZ: + if (have_eimm()) { + FAIL_IF(push_inst(compiler, flogr(tmp0, src_r))); /* clobbers tmp1 */ + if (dst_r != tmp0) + FAIL_IF(push_inst(compiler, lgr(dst_r, tmp0))); + } else { + abort(); /* TODO(mundaym): no eimm (?) */ + } + break; + case SLJIT_CLZ32: + if (have_eimm()) { + FAIL_IF(push_inst(compiler, sllg(tmp1, src_r, 32, 0))); + FAIL_IF(push_inst(compiler, iilf(tmp1, 0xffffffff))); + FAIL_IF(push_inst(compiler, flogr(tmp0, tmp1))); /* clobbers tmp1 */ + if (dst_r != tmp0) + FAIL_IF(push_inst(compiler, lr(dst_r, tmp0))); + } else { + abort(); /* TODO(mundaym): no eimm (?) */ + } + break; + default: + SLJIT_UNREACHABLE(); + } + + /* write condition code to emulated flag register */ + if (op & VARIABLE_FLAG_MASK) + FAIL_IF(push_inst(compiler, ipm(flag_r))); + + /* write zero flag to emulated flag register */ + if (op & SLJIT_SET_Z) + FAIL_IF(push_store_zero_flag(compiler, op, dst_r)); + + /* TODO(carenas): doesn't need FAIL_IF */ + if ((dst != SLJIT_UNUSED) && (dst & SLJIT_MEM)) + FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP)); + + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int is_commutative(sljit_s32 op) +{ + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + case SLJIT_ADDC: + case SLJIT_MUL: + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return 1; + } + return 0; +} + +static SLJIT_INLINE int is_shift(sljit_s32 op) { + sljit_s32 v = GET_OPCODE(op); + return (v == SLJIT_SHL || v == SLJIT_ASHR || v == SLJIT_LSHR) ? 1 : 0; +} + +static SLJIT_INLINE int sets_signed_flag(sljit_s32 op) +{ + switch (GET_FLAG_TYPE(op)) { + case SLJIT_OVERFLOW: + case SLJIT_NOT_OVERFLOW: + case SLJIT_SIG_LESS: + case SLJIT_SIG_LESS_EQUAL: + case SLJIT_SIG_GREATER: + case SLJIT_SIG_GREATER_EQUAL: + return 1; + } + return 0; +} + +/* Report whether we have an instruction for: + op dst src imm + where dst and src are separate registers. */ +static int have_op_3_imm(sljit_s32 op, sljit_sw imm) { + return 0; /* TODO(mundaym): implement */ +} + +/* Report whether we have an instruction for: + op reg imm + where reg is both a source and the destination. */ +static int have_op_2_imm(sljit_s32 op, sljit_sw imm) { + switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) { + case SLJIT_ADD32: + case SLJIT_ADD: + if (!HAS_FLAGS(op) || sets_signed_flag(op)) + return have_eimm() ? is_s32(imm) : is_s16(imm); + + return have_eimm() && is_u32(imm); + case SLJIT_MUL32: + case SLJIT_MUL: + /* TODO(mundaym): general extension check */ + /* for ms{,g}fi */ + if (op & VARIABLE_FLAG_MASK) + return 0; + + return have_genext() && is_s16(imm); + case SLJIT_OR32: + case SLJIT_XOR32: + case SLJIT_AND32: + /* only use if have extended immediate facility */ + /* this ensures flags are set correctly */ + return have_eimm(); + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + /* TODO(mundaym): make this more flexible */ + /* avoid using immediate variations, flags */ + /* won't be set correctly */ + return 0; + case SLJIT_ADDC32: + case SLJIT_ADDC: + /* no ADD LOGICAL WITH CARRY IMMEDIATE */ + return 0; + case SLJIT_SUB: + case SLJIT_SUB32: + case SLJIT_SUBC: + case SLJIT_SUBC32: + /* no SUBTRACT IMMEDIATE */ + /* TODO(mundaym): SUBTRACT LOGICAL IMMEDIATE */ + return 0; + } + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) + return SLJIT_SUCCESS; + + sljit_gpr dst_r = SLOW_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; + + if (is_commutative(op)) { + #define SWAP_ARGS \ + do { \ + sljit_s32 t = src1; \ + sljit_sw tw = src1w; \ + src1 = src2; \ + src1w = src2w; \ + src2 = t; \ + src2w = tw; \ + } while(0); + + /* prefer immediate in src2 */ + if (src1 & SLJIT_IMM) { + SWAP_ARGS + } + + /* prefer to have src1 use same register as dst */ + if (FAST_IS_REG(src2) && gpr(src2 & REG_MASK) == dst_r) { + SWAP_ARGS + } + + /* prefer memory argument in src2 */ + if (FAST_IS_REG(src2) && (src1 & SLJIT_MEM)) { + SWAP_ARGS + } + #undef SWAP_ARGS + } + + /* src1 must be in a register */ + sljit_gpr src1_r = FAST_IS_REG(src1) ? gpr(src1 & REG_MASK) : tmp0; + if (src1 & SLJIT_IMM) + FAIL_IF(push_load_imm_inst(compiler, src1_r, src1w)); + + if (src1 & SLJIT_MEM) + FAIL_IF(load_word(compiler, src1_r, src1, src1w, tmp1, op & SLJIT_I32_OP)); + + /* emit comparison before subtract */ + if (GET_OPCODE(op) == SLJIT_SUB && (op & VARIABLE_FLAG_MASK)) { + sljit_sw cmp = 0; + switch (GET_FLAG_TYPE(op)) { + case SLJIT_LESS: + case SLJIT_LESS_EQUAL: + case SLJIT_GREATER: + case SLJIT_GREATER_EQUAL: + cmp = 1; /* unsigned */ + break; + case SLJIT_EQUAL: + case SLJIT_SIG_LESS: + case SLJIT_SIG_LESS_EQUAL: + case SLJIT_SIG_GREATER: + case SLJIT_SIG_GREATER_EQUAL: + cmp = -1; /* signed */ + break; + } + if (cmp) { + /* clear flags - no need to generate now */ + op &= ~VARIABLE_FLAG_MASK; + sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1; + if (src2 & SLJIT_IMM) { + #define LEVAL(i) i(src1_r, src2w) + if (cmp > 0 && is_u32(src2w)) { + /* unsigned */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, clfi, clgfi))); + } + else if (cmp < 0 && is_s16(src2w)) { + /* signed */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, chi, cghi))); + } + else if (cmp < 0 && is_s32(src2w)) { + /* signed */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, cfi, cgfi))); + } + #undef LEVAL + #define LEVAL(i) i(src1_r, src2_r) + else { + FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w)); + if (cmp > 0) { + /* unsigned */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, clr, clgr))); + } + if (cmp < 0) { + /* signed */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, cr, cgr))); + } + } + } + else { + if (src2 & SLJIT_MEM) { + /* TODO(mundaym): comparisons with memory */ + /* load src2 into register */ + FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP)); + } + if (cmp > 0) { + /* unsigned */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, clr, clgr))); + } + if (cmp < 0) { + /* signed */ + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, cr, cgr))); + } + #undef LEVAL + } + FAIL_IF(push_inst(compiler, ipm(flag_r))); + } + } + + if (!HAS_FLAGS(op) && dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + /* need to specify signed or logical operation */ + int signed_flags = sets_signed_flag(op); + + if (is_shift(op)) { + /* handle shifts first, they have more constraints than other operations */ + sljit_sw d = 0; + sljit_gpr b = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : r0; + if (src2 & SLJIT_IMM) + d = src2w & ((op & SLJIT_I32_OP) ? 31 : 63); + + if (src2 & SLJIT_MEM) { + /* shift amount (b) cannot be in r0 (i.e. tmp0) */ + FAIL_IF(load_word(compiler, tmp1, src2, src2w, tmp1, op & SLJIT_I32_OP)); + b = tmp1; + } + /* src1 and dst share the same register in the base 32-bit ISA */ + /* TODO(mundaym): not needed when distinct-operand facility is available */ + int workaround_alias = op & SLJIT_I32_OP && src1_r != dst_r; + if (workaround_alias) { + /* put src1 into tmp0 so we can overwrite it */ + FAIL_IF(push_inst(compiler, lr(tmp0, src1_r))); + src1_r = tmp0; + } + switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) { + case SLJIT_SHL: + FAIL_IF(push_inst(compiler, sllg(dst_r, src1_r, d, b))); + break; + case SLJIT_SHL32: + FAIL_IF(push_inst(compiler, sll(src1_r, d, b))); + break; + case SLJIT_LSHR: + FAIL_IF(push_inst(compiler, srlg(dst_r, src1_r, d, b))); + break; + case SLJIT_LSHR32: + FAIL_IF(push_inst(compiler, srl(src1_r, d, b))); + break; + case SLJIT_ASHR: + FAIL_IF(push_inst(compiler, srag(dst_r, src1_r, d, b))); + break; + case SLJIT_ASHR32: + FAIL_IF(push_inst(compiler, sra(src1_r, d, b))); + break; + default: + SLJIT_UNREACHABLE(); + } + if (workaround_alias && dst_r != src1_r) + FAIL_IF(push_inst(compiler, lr(dst_r, src1_r))); + + } + else if ((GET_OPCODE(op) == SLJIT_MUL) && HAS_FLAGS(op)) { + /* multiply instructions do not generally set flags so we need to manually */ + /* detect overflow conditions */ + /* TODO(mundaym): 64-bit overflow */ + SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_MUL_OVERFLOW || + GET_FLAG_TYPE(op) == SLJIT_MUL_NOT_OVERFLOW); + sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1; + if (src2 & SLJIT_IMM) { + /* load src2 into register */ + FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w)); + } + if (src2 & SLJIT_MEM) { + /* load src2 into register */ + FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP)); + } + if (have_misc2()) { + #define LEVAL(i) i(dst_r, src1_r, src2_r) + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, msrkc, msgrkc))); + #undef LEVAL + } + else if (op & SLJIT_I32_OP) { + op &= ~VARIABLE_FLAG_MASK; + FAIL_IF(push_inst(compiler, lgfr(tmp0, src1_r))); + FAIL_IF(push_inst(compiler, msgfr(tmp0, src2_r))); + if (dst_r != tmp0) { + FAIL_IF(push_inst(compiler, lr(dst_r, tmp0))); + } + FAIL_IF(push_inst(compiler, aih(tmp0, 1))); + FAIL_IF(push_inst(compiler, nihf(tmp0, ~1U))); + FAIL_IF(push_inst(compiler, ipm(flag_r))); + FAIL_IF(push_inst(compiler, oilh(flag_r, 0x2000))); + } + else + return SLJIT_ERR_UNSUPPORTED; + + } + else if ((GET_OPCODE(op) == SLJIT_SUB) && (op & SLJIT_SET_Z) && !signed_flags) { + /* subtract logical instructions do not set the right flags unfortunately */ + /* instead, negate src2 and issue an add logical */ + /* TODO(mundaym): distinct operand facility where needed */ + if (src1_r != dst_r && src1_r != tmp0) { + #define LEVAL(i) i(tmp0, src1_r) + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, lr, lgr))); + src1_r = tmp0; + #undef LEVAL + } + sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1; + if (src2 & SLJIT_IMM) { + /* load src2 into register */ + FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w)); + } + if (src2 & SLJIT_MEM) { + /* load src2 into register */ + FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP)); + } + if (op & SLJIT_I32_OP) { + FAIL_IF(push_inst(compiler, lcr(tmp1, src2_r))); + FAIL_IF(push_inst(compiler, alr(src1_r, tmp1))); + if (src1_r != dst_r) + FAIL_IF(push_inst(compiler, lr(dst_r, src1_r))); + } + else { + FAIL_IF(push_inst(compiler, lcgr(tmp1, src2_r))); + FAIL_IF(push_inst(compiler, algr(src1_r, tmp1))); + if (src1_r != dst_r) + FAIL_IF(push_inst(compiler, lgr(dst_r, src1_r))); + } + } + else if ((src2 & SLJIT_IMM) && (src1_r == dst_r) && have_op_2_imm(op, src2w)) { + switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) { + #define LEVAL(i) i(dst_r, src2w) + case SLJIT_ADD: + if (!HAS_FLAGS(op) || signed_flags) { + FAIL_IF(push_inst(compiler, + WHEN2(is_s16(src2w), aghi, agfi))); + } + else + FAIL_IF(push_inst(compiler, LEVAL(algfi))); + + break; + case SLJIT_ADD32: + if (!HAS_FLAGS(op) || signed_flags) + FAIL_IF(push_inst(compiler, + WHEN2(is_s16(src2w), ahi, afi))); + else + FAIL_IF(push_inst(compiler, LEVAL(alfi))); + + break; + #undef LEVAL /* TODO(carenas): move down and refactor? */ + case SLJIT_MUL: + FAIL_IF(push_inst(compiler, mhi(dst_r, src2w))); + break; + case SLJIT_MUL32: + FAIL_IF(push_inst(compiler, mghi(dst_r, src2w))); + break; + case SLJIT_OR32: + FAIL_IF(push_inst(compiler, oilf(dst_r, src2w))); + break; + case SLJIT_XOR32: + FAIL_IF(push_inst(compiler, xilf(dst_r, src2w))); + break; + case SLJIT_AND32: + FAIL_IF(push_inst(compiler, nilf(dst_r, src2w))); + break; + default: + SLJIT_UNREACHABLE(); + } + } + else if ((src2 & SLJIT_IMM) && have_op_3_imm(op, src2w)) { + abort(); /* TODO(mundaym): implement */ + } + else if ((src2 & SLJIT_MEM) && (dst_r == src1_r)) { + /* most 32-bit instructions can only handle 12-bit immediate offsets */ + int need_u12 = !have_ldisp() && + (op & SLJIT_I32_OP) && + (GET_OPCODE(op) != SLJIT_ADDC) && + (GET_OPCODE(op) != SLJIT_SUBC); + struct addr mem; + if (need_u12) + FAIL_IF(make_addr_bx(compiler, &mem, src2, src2w, tmp1)); + else + FAIL_IF(make_addr_bxy(compiler, &mem, src2, src2w, tmp1)); + + int can_u12 = is_u12(mem.offset) ? 1 : 0; + sljit_ins ins = 0; + switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) { + /* 64-bit ops */ + #define LEVAL(i) EVAL(i, dst_r, mem) + case SLJIT_ADD: + ins = WHEN2(signed_flags, ag, alg); + break; + case SLJIT_SUB: + ins = WHEN2(signed_flags, sg, slg); + break; + case SLJIT_ADDC: + ins = LEVAL(alcg); + break; + case SLJIT_SUBC: + ins = LEVAL(slbg); + break; + case SLJIT_MUL: + ins = LEVAL(msg); + break; + case SLJIT_OR: + ins = LEVAL(og); + break; + case SLJIT_XOR: + ins = LEVAL(xg); + break; + case SLJIT_AND: + ins = LEVAL(ng); + break; + /* 32-bit ops */ + case SLJIT_ADD32: + if (signed_flags) + ins = WHEN2(can_u12, a, ay); + else + ins = WHEN2(can_u12, al, aly); + break; + case SLJIT_SUB32: + if (signed_flags) + ins = WHEN2(can_u12, s, sy); + else + ins = WHEN2(can_u12, sl, sly); + break; + case SLJIT_ADDC32: + ins = LEVAL(alc); + break; + case SLJIT_SUBC32: + ins = LEVAL(slb); + break; + case SLJIT_MUL32: + ins = WHEN2(can_u12, ms, msy); + break; + case SLJIT_OR32: + ins = WHEN2(can_u12, o, oy); + break; + case SLJIT_XOR32: + ins = WHEN2(can_u12, x, xy); + break; + case SLJIT_AND32: + ins = WHEN2(can_u12, n, ny); + break; + #undef LEVAL + default: + SLJIT_UNREACHABLE(); + } + FAIL_IF(push_inst(compiler, ins)); + } + else { + sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1; + if (src2 & SLJIT_IMM) { + /* load src2 into register */ + FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w)); + } + if (src2 & SLJIT_MEM) { + /* load src2 into register */ + FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP)); + } + /* TODO(mundaym): distinct operand facility where needed */ + #define LEVAL(i) i(tmp0, src1_r) + if (src1_r != dst_r && src1_r != tmp0) { + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, lr, lgr))); + src1_r = tmp0; + } + #undef LEVAL + sljit_ins ins = 0; + switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) { + #define LEVAL(i) i(src1_r, src2_r) + /* 64-bit ops */ + case SLJIT_ADD: + ins = WHEN2(signed_flags, agr, algr); + break; + case SLJIT_SUB: + ins = WHEN2(signed_flags, sgr, slgr); + break; + case SLJIT_ADDC: + ins = LEVAL(alcgr); + break; + case SLJIT_SUBC: + ins = LEVAL(slbgr); + break; + case SLJIT_MUL: + ins = LEVAL(msgr); + break; + case SLJIT_AND: + ins = LEVAL(ngr); + break; + case SLJIT_OR: + ins = LEVAL(ogr); + break; + case SLJIT_XOR: + ins = LEVAL(xgr); + break; + /* 32-bit ops */ + case SLJIT_ADD32: + ins = WHEN2(signed_flags, ar, alr); + break; + case SLJIT_SUB32: + ins = WHEN2(signed_flags, sr, slr); + break; + case SLJIT_ADDC32: + ins = LEVAL(alcr); + break; + case SLJIT_SUBC32: + ins = LEVAL(slbr); + break; + case SLJIT_MUL32: + ins = LEVAL(msr); + break; + case SLJIT_AND32: + ins = LEVAL(nr); + break; + case SLJIT_OR32: + ins = LEVAL(or); + break; + case SLJIT_XOR32: + ins = LEVAL(xr); + break; + #undef LEVAL + default: + SLJIT_UNREACHABLE(); + } + FAIL_IF(push_inst(compiler, ins)); + #define LEVAL(i) i(dst_r, src1_r) + if (src1_r != dst_r) + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, lr, lgr))); + #undef LEVAL + } + + /* write condition code to emulated flag register */ + if (op & VARIABLE_FLAG_MASK) + FAIL_IF(push_inst(compiler, ipm(flag_r))); + + /* write zero flag to emulated flag register */ + if (op & SLJIT_SET_Z) + FAIL_IF(push_store_zero_flag(compiler, op, dst_r)); + + /* finally write the result to memory if required */ + if (dst & SLJIT_MEM) { + SLJIT_ASSERT(dst_r != tmp1); + /* TODO(carenas): s/FAIL_IF/ return */ + FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src( + struct sljit_compiler *compiler, + sljit_s32 op, sljit_s32 src, sljit_sw srcw) +{ + sljit_gpr src_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + src_r = FAST_IS_REG(src) ? gpr(src) : tmp1; + if (src & SLJIT_MEM) + FAIL_IF(load_word(compiler, tmp1, src, srcw, tmp1, 0)); + + return push_inst(compiler, br(src_r)); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + /* TODO(carenas): implement? */ + return SLJIT_SUCCESS; + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: + /* TODO(carenas): implement */ + return SLJIT_SUCCESS; + default: + /* TODO(carenas): probably should not success by default */ + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +{ + CHECK_REG_INDEX(check_sljit_get_register_index(reg)); + return gpr(reg); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +{ + CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + abort(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) +{ + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); + + memcpy((sljit_u8 *)&ins + sizeof(ins) - size, instruction, size); + return push_inst(compiler, ins); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + abort(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ + CHECK_ERROR(); + abort(); +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (FAST_IS_REG(dst)) + return push_inst(compiler, lgr(gpr(dst), fast_link_r)); + + /* memory */ + return store_word(compiler, fast_link_r, dst, dstw, tmp1, 0); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_label(compiler)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) +{ + sljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(type & 0xff) : 0xf; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_jump(compiler, type)); + + /* reload condition code */ + if (mask != 0xf) + PTR_FAIL_IF(push_load_cc(compiler, type & 0xff)); + + /* record jump */ + struct sljit_jump *jump = (struct sljit_jump *) + ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + jump->addr = compiler->size; + + /* emit jump instruction */ + type &= 0xff; + if (type >= SLJIT_FAST_CALL) + PTR_FAIL_IF(push_inst(compiler, brasl(type == SLJIT_FAST_CALL ? fast_link_r : link_r, 0))); + else + PTR_FAIL_IF(push_inst(compiler, brcl(mask, 0))); + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 arg_types) +{ + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types)); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + + return sljit_emit_jump(compiler, type); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) +{ + sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp1; + + CHECK_ERROR(); + CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src & SLJIT_IMM) { + SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */ + FAIL_IF(push_load_imm_inst(compiler, src_r, srcw)); + } + else if (src & SLJIT_MEM) + FAIL_IF(load_word(compiler, src_r, src, srcw, tmp1, 0 /* 64-bit */)); + + /* emit jump instruction */ + if (type >= SLJIT_FAST_CALL) + return push_inst(compiler, basr(type == SLJIT_FAST_CALL ? fast_link_r : link_r, src_r)); + + return push_inst(compiler, br(src_r)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 arg_types, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw)); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->skip_checks = 1; +#endif + + return sljit_emit_ijump(compiler, type, src, srcw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 type) +{ + sljit_u8 mask = get_cc(type & 0xff); + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); + + sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; + sljit_gpr loc_r = tmp1; + switch (GET_OPCODE(op)) { + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + /* dst is also source operand */ + if (dst & SLJIT_MEM) + FAIL_IF(load_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP)); + + break; + case SLJIT_MOV: + case (SLJIT_MOV32 & ~SLJIT_I32_OP): + /* can write straight into destination */ + loc_r = dst_r; + break; + default: + SLJIT_UNREACHABLE(); + } + + if (mask != 0xf) + FAIL_IF(push_load_cc(compiler, type & 0xff)); + + /* TODO(mundaym): fold into cmov helper function? */ + #define LEVAL(i) i(loc_r, 1, mask) + if (have_lscond2()) { + FAIL_IF(push_load_imm_inst(compiler, loc_r, 0)); + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, lochi, locghi))); + } else { + /* TODO(mundaym): no load/store-on-condition 2 facility (ipm? branch-and-set?) */ + abort(); + } + #undef LEVAL + + /* apply bitwise op and set condition codes */ + switch (GET_OPCODE(op)) { + #define LEVAL(i) i(dst_r, loc_r) + case SLJIT_AND: + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, nr, ngr))); + break; + case SLJIT_OR: + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, or, ogr))); + break; + case SLJIT_XOR: + FAIL_IF(push_inst(compiler, + WHEN2(op & SLJIT_I32_OP, xr, xgr))); + break; + #undef LEVAL + } + + /* set zero flag if needed */ + if (op & SLJIT_SET_Z) + FAIL_IF(push_store_zero_flag(compiler, op, dst_r)); + + /* store result to memory if required */ + /* TODO(carenas): s/FAIL_IF/ return */ + if (dst & SLJIT_MEM) + FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP)); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_u8 mask = get_cc(type & 0xff); + sljit_gpr dst_r = gpr(dst_reg & ~SLJIT_I32_OP); + sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + + if (mask != 0xf) + FAIL_IF(push_load_cc(compiler, type & 0xff)); + + if (src & SLJIT_IMM) { + /* TODO(mundaym): fast path with lscond2 */ + FAIL_IF(push_load_imm_inst(compiler, src_r, srcw)); + } + + #define LEVAL(i) i(dst_r, src_r, mask) + if (have_lscond1()) + return push_inst(compiler, + WHEN2(dst_reg & SLJIT_I32_OP, locr, locgr)); + + #undef LEVAL + + /* TODO(mundaym): implement */ + return SLJIT_ERR_UNSUPPORTED; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +/* On s390x we build a literal pool to hold constants. This has two main + advantages: + + 1. we only need one instruction in the instruction stream (LGRL) + 2. we can store 64 bit addresses and use 32 bit offsets + + To retrofit the extra information needed to build the literal pool we + add a new sljit_s390x_const struct that contains the initial value but + can still be cast to a sljit_const. */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_s390x_const *const_; + sljit_gpr dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); + + const_ = (struct sljit_s390x_const*)ensure_abuf(compiler, + sizeof(struct sljit_s390x_const)); + PTR_FAIL_IF(!const_); + set_const((struct sljit_const*)const_, compiler); + const_->init_value = init_value; + + dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; + if (have_genext()) + PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | lgrl(dst_r, 0))); + else { + PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | larl(tmp1, 0))); + PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1))); + } + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, 0 /* always 64-bit */)); + + return (struct sljit_const*)const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) +{ + /* Update the constant pool. */ + sljit_uw *ptr = (sljit_uw *)addr; + SLJIT_UNUSED_ARG(executable_offset); + + SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0); + *ptr = new_target; + SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); + SLJIT_CACHE_FLUSH(ptr, ptr + 1); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) +{ + sljit_set_jump_addr(addr, new_constant, executable_offset); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label *sljit_emit_put_label( + struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_gpr dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); + + dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; + + if (have_genext()) + PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0))); + else { + PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0))); + PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1))); + } + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, 0)); + + return put_label; +} + +/* TODO(carenas): EVAL probably should move up or be refactored */ +#undef WHEN2 +#undef EVAL + +#undef tmp1 +#undef tmp0 + +/* TODO(carenas): undef other macros that spill like is_u12? */ diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c index 8079fad8df..e5167f02ba 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c @@ -266,21 +266,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_UNUSED_ARG(executable_offset); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0); SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000)); inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff); inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff); + SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins *)addr; - - SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000)); - inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff); - inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff); - inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); - SLJIT_CACHE_FLUSH(inst, inst + 2); + sljit_set_jump_addr(addr, new_constant, executable_offset); } diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c index bfa4ecede2..544d80d028 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c @@ -311,7 +311,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil CHECK_PTR(check_sljit_generate_code(compiler)); reverse_buf(compiler); - code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -437,6 +437,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); + SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); return code; } @@ -451,6 +452,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return 1; #endif + case SLJIT_HAS_ZERO_REGISTER: + return 1; + #if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64) case SLJIT_HAS_CMOV: return 1; @@ -872,6 +876,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #else #error "Implementation required" #endif + case SLJIT_ENDBR: + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return SLJIT_SUCCESS; } return SLJIT_SUCCESS; @@ -888,9 +895,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) - return SLJIT_SUCCESS; - op = GET_OPCODE(op); switch (op) { case SLJIT_MOV: @@ -971,6 +975,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (op) { + case SLJIT_FAST_RETURN: + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK))); + else + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw)); + + FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS)); + return push_inst(compiler, NOP, UNMOVABLE_INS); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -1215,25 +1246,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * ADJUST_LOCAL_OFFSET(dst, dstw); if (FAST_IS_REG(dst)) - return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst)); + return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), UNMOVABLE_INS); /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK))); - else - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw)); - - FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS)); - return push_inst(compiler, NOP, UNMOVABLE_INS); + FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw)); + compiler->delay_slot = UNMOVABLE_INS; + return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ diff --git a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c deleted file mode 100644 index dd82ebae6a..0000000000 --- a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c +++ /dev/null @@ -1,10159 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. - * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* This code is owned by Tilera Corporation, and distributed as part - of multiple projects. In sljit, the code is under BSD licence. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#define BFD_RELOC(x) R_##x - -/* Special registers. */ -#define TREG_LR 55 -#define TREG_SN 56 -#define TREG_ZERO 63 - -/* Canonical name of each register. */ -const char *const tilegx_register_names[] = -{ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", - "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", - "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr", - "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero" -}; - -enum -{ - R_NONE = 0, - R_TILEGX_NONE = 0, - R_TILEGX_64 = 1, - R_TILEGX_32 = 2, - R_TILEGX_16 = 3, - R_TILEGX_8 = 4, - R_TILEGX_64_PCREL = 5, - R_TILEGX_32_PCREL = 6, - R_TILEGX_16_PCREL = 7, - R_TILEGX_8_PCREL = 8, - R_TILEGX_HW0 = 9, - R_TILEGX_HW1 = 10, - R_TILEGX_HW2 = 11, - R_TILEGX_HW3 = 12, - R_TILEGX_HW0_LAST = 13, - R_TILEGX_HW1_LAST = 14, - R_TILEGX_HW2_LAST = 15, - R_TILEGX_COPY = 16, - R_TILEGX_GLOB_DAT = 17, - R_TILEGX_JMP_SLOT = 18, - R_TILEGX_RELATIVE = 19, - R_TILEGX_BROFF_X1 = 20, - R_TILEGX_JUMPOFF_X1 = 21, - R_TILEGX_JUMPOFF_X1_PLT = 22, - R_TILEGX_IMM8_X0 = 23, - R_TILEGX_IMM8_Y0 = 24, - R_TILEGX_IMM8_X1 = 25, - R_TILEGX_IMM8_Y1 = 26, - R_TILEGX_DEST_IMM8_X1 = 27, - R_TILEGX_MT_IMM14_X1 = 28, - R_TILEGX_MF_IMM14_X1 = 29, - R_TILEGX_MMSTART_X0 = 30, - R_TILEGX_MMEND_X0 = 31, - R_TILEGX_SHAMT_X0 = 32, - R_TILEGX_SHAMT_X1 = 33, - R_TILEGX_SHAMT_Y0 = 34, - R_TILEGX_SHAMT_Y1 = 35, - R_TILEGX_IMM16_X0_HW0 = 36, - R_TILEGX_IMM16_X1_HW0 = 37, - R_TILEGX_IMM16_X0_HW1 = 38, - R_TILEGX_IMM16_X1_HW1 = 39, - R_TILEGX_IMM16_X0_HW2 = 40, - R_TILEGX_IMM16_X1_HW2 = 41, - R_TILEGX_IMM16_X0_HW3 = 42, - R_TILEGX_IMM16_X1_HW3 = 43, - R_TILEGX_IMM16_X0_HW0_LAST = 44, - R_TILEGX_IMM16_X1_HW0_LAST = 45, - R_TILEGX_IMM16_X0_HW1_LAST = 46, - R_TILEGX_IMM16_X1_HW1_LAST = 47, - R_TILEGX_IMM16_X0_HW2_LAST = 48, - R_TILEGX_IMM16_X1_HW2_LAST = 49, - R_TILEGX_IMM16_X0_HW0_PCREL = 50, - R_TILEGX_IMM16_X1_HW0_PCREL = 51, - R_TILEGX_IMM16_X0_HW1_PCREL = 52, - R_TILEGX_IMM16_X1_HW1_PCREL = 53, - R_TILEGX_IMM16_X0_HW2_PCREL = 54, - R_TILEGX_IMM16_X1_HW2_PCREL = 55, - R_TILEGX_IMM16_X0_HW3_PCREL = 56, - R_TILEGX_IMM16_X1_HW3_PCREL = 57, - R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58, - R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59, - R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60, - R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61, - R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62, - R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63, - R_TILEGX_IMM16_X0_HW0_GOT = 64, - R_TILEGX_IMM16_X1_HW0_GOT = 65, - - R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66, - R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67, - R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68, - R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69, - R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70, - R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71, - - R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72, - R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73, - R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74, - R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75, - R_TILEGX_IMM16_X0_HW0_TLS_GD = 78, - R_TILEGX_IMM16_X1_HW0_TLS_GD = 79, - R_TILEGX_IMM16_X0_HW0_TLS_LE = 80, - R_TILEGX_IMM16_X1_HW0_TLS_LE = 81, - R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82, - R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83, - R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84, - R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85, - R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86, - R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87, - R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88, - R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89, - R_TILEGX_IMM16_X0_HW0_TLS_IE = 92, - R_TILEGX_IMM16_X1_HW0_TLS_IE = 93, - - R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94, - R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95, - R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96, - R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97, - R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98, - R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99, - - R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100, - R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101, - R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102, - R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103, - R_TILEGX_TLS_DTPMOD64 = 106, - R_TILEGX_TLS_DTPOFF64 = 107, - R_TILEGX_TLS_TPOFF64 = 108, - R_TILEGX_TLS_DTPMOD32 = 109, - R_TILEGX_TLS_DTPOFF32 = 110, - R_TILEGX_TLS_TPOFF32 = 111, - R_TILEGX_TLS_GD_CALL = 112, - R_TILEGX_IMM8_X0_TLS_GD_ADD = 113, - R_TILEGX_IMM8_X1_TLS_GD_ADD = 114, - R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115, - R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116, - R_TILEGX_TLS_IE_LOAD = 117, - R_TILEGX_IMM8_X0_TLS_ADD = 118, - R_TILEGX_IMM8_X1_TLS_ADD = 119, - R_TILEGX_IMM8_Y0_TLS_ADD = 120, - R_TILEGX_IMM8_Y1_TLS_ADD = 121, - R_TILEGX_GNU_VTINHERIT = 128, - R_TILEGX_GNU_VTENTRY = 129, - R_TILEGX_IRELATIVE = 130, - R_TILEGX_NUM = 131 -}; - -typedef enum -{ - TILEGX_PIPELINE_X0, - TILEGX_PIPELINE_X1, - TILEGX_PIPELINE_Y0, - TILEGX_PIPELINE_Y1, - TILEGX_PIPELINE_Y2, -} tilegx_pipeline; - -typedef unsigned long long tilegx_bundle_bits; - -/* These are the bits that determine if a bundle is in the X encoding. */ -#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62) - -enum -{ - /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */ - TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3, - - /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */ - TILEGX_NUM_PIPELINE_ENCODINGS = 5, - - /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */ - TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3, - - /* Instructions take this many bytes. */ - TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES, - - /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */ - TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3, - - /* Bundles should be aligned modulo this number of bytes. */ - TILEGX_BUNDLE_ALIGNMENT_IN_BYTES = - (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES), - - /* Number of registers (some are magic, such as network I/O). */ - TILEGX_NUM_REGISTERS = 64, -}; - -/* Make a few "tile_" variables to simplify common code between - architectures. */ - -typedef tilegx_bundle_bits tile_bundle_bits; -#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES -#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES -#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ - TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES - -/* 64-bit pattern for a { bpt ; nop } bundle. */ -#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL - -typedef enum -{ - TILEGX_OP_TYPE_REGISTER, - TILEGX_OP_TYPE_IMMEDIATE, - TILEGX_OP_TYPE_ADDRESS, - TILEGX_OP_TYPE_SPR -} tilegx_operand_type; - -struct tilegx_operand -{ - /* Is this operand a register, immediate or address? */ - tilegx_operand_type type; - - /* The default relocation type for this operand. */ - signed int default_reloc : 16; - - /* How many bits is this value? (used for range checking) */ - unsigned int num_bits : 5; - - /* Is the value signed? (used for range checking) */ - unsigned int is_signed : 1; - - /* Is this operand a source register? */ - unsigned int is_src_reg : 1; - - /* Is this operand written? (i.e. is it a destination register) */ - unsigned int is_dest_reg : 1; - - /* Is this operand PC-relative? */ - unsigned int is_pc_relative : 1; - - /* By how many bits do we right shift the value before inserting? */ - unsigned int rightshift : 2; - - /* Return the bits for this operand to be ORed into an existing bundle. */ - tilegx_bundle_bits (*insert) (int op); - - /* Extract this operand and return it. */ - unsigned int (*extract) (tilegx_bundle_bits bundle); -}; - -typedef enum -{ - TILEGX_OPC_BPT, - TILEGX_OPC_INFO, - TILEGX_OPC_INFOL, - TILEGX_OPC_LD4S_TLS, - TILEGX_OPC_LD_TLS, - TILEGX_OPC_MOVE, - TILEGX_OPC_MOVEI, - TILEGX_OPC_MOVELI, - TILEGX_OPC_PREFETCH, - TILEGX_OPC_PREFETCH_ADD_L1, - TILEGX_OPC_PREFETCH_ADD_L1_FAULT, - TILEGX_OPC_PREFETCH_ADD_L2, - TILEGX_OPC_PREFETCH_ADD_L2_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_L1, - TILEGX_OPC_PREFETCH_L1_FAULT, - TILEGX_OPC_PREFETCH_L2, - TILEGX_OPC_PREFETCH_L2_FAULT, - TILEGX_OPC_PREFETCH_L3, - TILEGX_OPC_PREFETCH_L3_FAULT, - TILEGX_OPC_RAISE, - TILEGX_OPC_ADD, - TILEGX_OPC_ADDI, - TILEGX_OPC_ADDLI, - TILEGX_OPC_ADDX, - TILEGX_OPC_ADDXI, - TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXSC, - TILEGX_OPC_AND, - TILEGX_OPC_ANDI, - TILEGX_OPC_BEQZ, - TILEGX_OPC_BEQZT, - TILEGX_OPC_BFEXTS, - TILEGX_OPC_BFEXTU, - TILEGX_OPC_BFINS, - TILEGX_OPC_BGEZ, - TILEGX_OPC_BGEZT, - TILEGX_OPC_BGTZ, - TILEGX_OPC_BGTZT, - TILEGX_OPC_BLBC, - TILEGX_OPC_BLBCT, - TILEGX_OPC_BLBS, - TILEGX_OPC_BLBST, - TILEGX_OPC_BLEZ, - TILEGX_OPC_BLEZT, - TILEGX_OPC_BLTZ, - TILEGX_OPC_BLTZT, - TILEGX_OPC_BNEZ, - TILEGX_OPC_BNEZT, - TILEGX_OPC_CLZ, - TILEGX_OPC_CMOVEQZ, - TILEGX_OPC_CMOVNEZ, - TILEGX_OPC_CMPEQ, - TILEGX_OPC_CMPEQI, - TILEGX_OPC_CMPEXCH, - TILEGX_OPC_CMPEXCH4, - TILEGX_OPC_CMPLES, - TILEGX_OPC_CMPLEU, - TILEGX_OPC_CMPLTS, - TILEGX_OPC_CMPLTSI, - TILEGX_OPC_CMPLTU, - TILEGX_OPC_CMPLTUI, - TILEGX_OPC_CMPNE, - TILEGX_OPC_CMUL, - TILEGX_OPC_CMULA, - TILEGX_OPC_CMULAF, - TILEGX_OPC_CMULF, - TILEGX_OPC_CMULFR, - TILEGX_OPC_CMULH, - TILEGX_OPC_CMULHR, - TILEGX_OPC_CRC32_32, - TILEGX_OPC_CRC32_8, - TILEGX_OPC_CTZ, - TILEGX_OPC_DBLALIGN, - TILEGX_OPC_DBLALIGN2, - TILEGX_OPC_DBLALIGN4, - TILEGX_OPC_DBLALIGN6, - TILEGX_OPC_DRAIN, - TILEGX_OPC_DTLBPR, - TILEGX_OPC_EXCH, - TILEGX_OPC_EXCH4, - TILEGX_OPC_FDOUBLE_ADD_FLAGS, - TILEGX_OPC_FDOUBLE_ADDSUB, - TILEGX_OPC_FDOUBLE_MUL_FLAGS, - TILEGX_OPC_FDOUBLE_PACK1, - TILEGX_OPC_FDOUBLE_PACK2, - TILEGX_OPC_FDOUBLE_SUB_FLAGS, - TILEGX_OPC_FDOUBLE_UNPACK_MAX, - TILEGX_OPC_FDOUBLE_UNPACK_MIN, - TILEGX_OPC_FETCHADD, - TILEGX_OPC_FETCHADD4, - TILEGX_OPC_FETCHADDGEZ, - TILEGX_OPC_FETCHADDGEZ4, - TILEGX_OPC_FETCHAND, - TILEGX_OPC_FETCHAND4, - TILEGX_OPC_FETCHOR, - TILEGX_OPC_FETCHOR4, - TILEGX_OPC_FINV, - TILEGX_OPC_FLUSH, - TILEGX_OPC_FLUSHWB, - TILEGX_OPC_FNOP, - TILEGX_OPC_FSINGLE_ADD1, - TILEGX_OPC_FSINGLE_ADDSUB2, - TILEGX_OPC_FSINGLE_MUL1, - TILEGX_OPC_FSINGLE_MUL2, - TILEGX_OPC_FSINGLE_PACK1, - TILEGX_OPC_FSINGLE_PACK2, - TILEGX_OPC_FSINGLE_SUB1, - TILEGX_OPC_ICOH, - TILEGX_OPC_ILL, - TILEGX_OPC_INV, - TILEGX_OPC_IRET, - TILEGX_OPC_J, - TILEGX_OPC_JAL, - TILEGX_OPC_JALR, - TILEGX_OPC_JALRP, - TILEGX_OPC_JR, - TILEGX_OPC_JRP, - TILEGX_OPC_LD, - TILEGX_OPC_LD1S, - TILEGX_OPC_LD1S_ADD, - TILEGX_OPC_LD1U, - TILEGX_OPC_LD1U_ADD, - TILEGX_OPC_LD2S, - TILEGX_OPC_LD2S_ADD, - TILEGX_OPC_LD2U, - TILEGX_OPC_LD2U_ADD, - TILEGX_OPC_LD4S, - TILEGX_OPC_LD4S_ADD, - TILEGX_OPC_LD4U, - TILEGX_OPC_LD4U_ADD, - TILEGX_OPC_LD_ADD, - TILEGX_OPC_LDNA, - TILEGX_OPC_LDNA_ADD, - TILEGX_OPC_LDNT, - TILEGX_OPC_LDNT1S, - TILEGX_OPC_LDNT1S_ADD, - TILEGX_OPC_LDNT1U, - TILEGX_OPC_LDNT1U_ADD, - TILEGX_OPC_LDNT2S, - TILEGX_OPC_LDNT2S_ADD, - TILEGX_OPC_LDNT2U, - TILEGX_OPC_LDNT2U_ADD, - TILEGX_OPC_LDNT4S, - TILEGX_OPC_LDNT4S_ADD, - TILEGX_OPC_LDNT4U, - TILEGX_OPC_LDNT4U_ADD, - TILEGX_OPC_LDNT_ADD, - TILEGX_OPC_LNK, - TILEGX_OPC_MF, - TILEGX_OPC_MFSPR, - TILEGX_OPC_MM, - TILEGX_OPC_MNZ, - TILEGX_OPC_MTSPR, - TILEGX_OPC_MUL_HS_HS, - TILEGX_OPC_MUL_HS_HU, - TILEGX_OPC_MUL_HS_LS, - TILEGX_OPC_MUL_HS_LU, - TILEGX_OPC_MUL_HU_HU, - TILEGX_OPC_MUL_HU_LS, - TILEGX_OPC_MUL_HU_LU, - TILEGX_OPC_MUL_LS_LS, - TILEGX_OPC_MUL_LS_LU, - TILEGX_OPC_MUL_LU_LU, - TILEGX_OPC_MULA_HS_HS, - TILEGX_OPC_MULA_HS_HU, - TILEGX_OPC_MULA_HS_LS, - TILEGX_OPC_MULA_HS_LU, - TILEGX_OPC_MULA_HU_HU, - TILEGX_OPC_MULA_HU_LS, - TILEGX_OPC_MULA_HU_LU, - TILEGX_OPC_MULA_LS_LS, - TILEGX_OPC_MULA_LS_LU, - TILEGX_OPC_MULA_LU_LU, - TILEGX_OPC_MULAX, - TILEGX_OPC_MULX, - TILEGX_OPC_MZ, - TILEGX_OPC_NAP, - TILEGX_OPC_NOP, - TILEGX_OPC_NOR, - TILEGX_OPC_OR, - TILEGX_OPC_ORI, - TILEGX_OPC_PCNT, - TILEGX_OPC_REVBITS, - TILEGX_OPC_REVBYTES, - TILEGX_OPC_ROTL, - TILEGX_OPC_ROTLI, - TILEGX_OPC_SHL, - TILEGX_OPC_SHL16INSLI, - TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADDX, - TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADDX, - TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADDX, - TILEGX_OPC_SHLI, - TILEGX_OPC_SHLX, - TILEGX_OPC_SHLXI, - TILEGX_OPC_SHRS, - TILEGX_OPC_SHRSI, - TILEGX_OPC_SHRU, - TILEGX_OPC_SHRUI, - TILEGX_OPC_SHRUX, - TILEGX_OPC_SHRUXI, - TILEGX_OPC_SHUFFLEBYTES, - TILEGX_OPC_ST, - TILEGX_OPC_ST1, - TILEGX_OPC_ST1_ADD, - TILEGX_OPC_ST2, - TILEGX_OPC_ST2_ADD, - TILEGX_OPC_ST4, - TILEGX_OPC_ST4_ADD, - TILEGX_OPC_ST_ADD, - TILEGX_OPC_STNT, - TILEGX_OPC_STNT1, - TILEGX_OPC_STNT1_ADD, - TILEGX_OPC_STNT2, - TILEGX_OPC_STNT2_ADD, - TILEGX_OPC_STNT4, - TILEGX_OPC_STNT4_ADD, - TILEGX_OPC_STNT_ADD, - TILEGX_OPC_SUB, - TILEGX_OPC_SUBX, - TILEGX_OPC_SUBXSC, - TILEGX_OPC_SWINT0, - TILEGX_OPC_SWINT1, - TILEGX_OPC_SWINT2, - TILEGX_OPC_SWINT3, - TILEGX_OPC_TBLIDXB0, - TILEGX_OPC_TBLIDXB1, - TILEGX_OPC_TBLIDXB2, - TILEGX_OPC_TBLIDXB3, - TILEGX_OPC_V1ADD, - TILEGX_OPC_V1ADDI, - TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADIFFU, - TILEGX_OPC_V1AVGU, - TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPEQI, - TILEGX_OPC_V1CMPLES, - TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTSI, - TILEGX_OPC_V1CMPLTU, - TILEGX_OPC_V1CMPLTUI, - TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1DDOTPU, - TILEGX_OPC_V1DDOTPUA, - TILEGX_OPC_V1DDOTPUS, - TILEGX_OPC_V1DDOTPUSA, - TILEGX_OPC_V1DOTP, - TILEGX_OPC_V1DOTPA, - TILEGX_OPC_V1DOTPU, - TILEGX_OPC_V1DOTPUA, - TILEGX_OPC_V1DOTPUS, - TILEGX_OPC_V1DOTPUSA, - TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_L, - TILEGX_OPC_V1MAXU, - TILEGX_OPC_V1MAXUI, - TILEGX_OPC_V1MINU, - TILEGX_OPC_V1MINUI, - TILEGX_OPC_V1MNZ, - TILEGX_OPC_V1MULTU, - TILEGX_OPC_V1MULU, - TILEGX_OPC_V1MULUS, - TILEGX_OPC_V1MZ, - TILEGX_OPC_V1SADAU, - TILEGX_OPC_V1SADU, - TILEGX_OPC_V1SHL, - TILEGX_OPC_V1SHLI, - TILEGX_OPC_V1SHRS, - TILEGX_OPC_V1SHRSI, - TILEGX_OPC_V1SHRU, - TILEGX_OPC_V1SHRUI, - TILEGX_OPC_V1SUB, - TILEGX_OPC_V1SUBUC, - TILEGX_OPC_V2ADD, - TILEGX_OPC_V2ADDI, - TILEGX_OPC_V2ADDSC, - TILEGX_OPC_V2ADIFFS, - TILEGX_OPC_V2AVGS, - TILEGX_OPC_V2CMPEQ, - TILEGX_OPC_V2CMPEQI, - TILEGX_OPC_V2CMPLES, - TILEGX_OPC_V2CMPLEU, - TILEGX_OPC_V2CMPLTS, - TILEGX_OPC_V2CMPLTSI, - TILEGX_OPC_V2CMPLTU, - TILEGX_OPC_V2CMPLTUI, - TILEGX_OPC_V2CMPNE, - TILEGX_OPC_V2DOTP, - TILEGX_OPC_V2DOTPA, - TILEGX_OPC_V2INT_H, - TILEGX_OPC_V2INT_L, - TILEGX_OPC_V2MAXS, - TILEGX_OPC_V2MAXSI, - TILEGX_OPC_V2MINS, - TILEGX_OPC_V2MINSI, - TILEGX_OPC_V2MNZ, - TILEGX_OPC_V2MULFSC, - TILEGX_OPC_V2MULS, - TILEGX_OPC_V2MULTS, - TILEGX_OPC_V2MZ, - TILEGX_OPC_V2PACKH, - TILEGX_OPC_V2PACKL, - TILEGX_OPC_V2PACKUC, - TILEGX_OPC_V2SADAS, - TILEGX_OPC_V2SADAU, - TILEGX_OPC_V2SADS, - TILEGX_OPC_V2SADU, - TILEGX_OPC_V2SHL, - TILEGX_OPC_V2SHLI, - TILEGX_OPC_V2SHLSC, - TILEGX_OPC_V2SHRS, - TILEGX_OPC_V2SHRSI, - TILEGX_OPC_V2SHRU, - TILEGX_OPC_V2SHRUI, - TILEGX_OPC_V2SUB, - TILEGX_OPC_V2SUBSC, - TILEGX_OPC_V4ADD, - TILEGX_OPC_V4ADDSC, - TILEGX_OPC_V4INT_H, - TILEGX_OPC_V4INT_L, - TILEGX_OPC_V4PACKSC, - TILEGX_OPC_V4SHL, - TILEGX_OPC_V4SHLSC, - TILEGX_OPC_V4SHRS, - TILEGX_OPC_V4SHRU, - TILEGX_OPC_V4SUB, - TILEGX_OPC_V4SUBSC, - TILEGX_OPC_WH64, - TILEGX_OPC_XOR, - TILEGX_OPC_XORI, - TILEGX_OPC_NONE -} tilegx_mnemonic; - -enum -{ - TILEGX_MAX_OPERANDS = 4 /* bfexts */ -}; - -struct tilegx_opcode -{ - /* The opcode mnemonic, e.g. "add" */ - const char *name; - - /* The enum value for this mnemonic. */ - tilegx_mnemonic mnemonic; - - /* A bit mask of which of the five pipes this instruction - is compatible with: - X0 0x01 - X1 0x02 - Y0 0x04 - Y1 0x08 - Y2 0x10 */ - unsigned char pipes; - - /* How many operands are there? */ - unsigned char num_operands; - - /* Which register does this write implicitly, or TREG_ZERO if none? */ - unsigned char implicitly_written_register; - - /* Can this be bundled with other instructions (almost always true). */ - unsigned char can_bundle; - - /* The description of the operands. Each of these is an - * index into the tilegx_operands[] table. */ - unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS]; - - /* A mask of which bits have predefined values for each pipeline. - * This is useful for disassembly. */ - tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS]; - - /* For each bit set in fixed_bit_masks, what the value is for this - * instruction. */ - tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS]; -}; - -/* Used for non-textual disassembly into structs. */ -struct tilegx_decoded_instruction -{ - const struct tilegx_opcode *opcode; - const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS]; - long long operand_values[TILEGX_MAX_OPERANDS]; -}; - -enum -{ - ADDI_IMM8_OPCODE_X0 = 1, - ADDI_IMM8_OPCODE_X1 = 1, - ADDI_OPCODE_Y0 = 0, - ADDI_OPCODE_Y1 = 1, - ADDLI_OPCODE_X0 = 1, - ADDLI_OPCODE_X1 = 0, - ADDXI_IMM8_OPCODE_X0 = 2, - ADDXI_IMM8_OPCODE_X1 = 2, - ADDXI_OPCODE_Y0 = 1, - ADDXI_OPCODE_Y1 = 2, - ADDXLI_OPCODE_X0 = 2, - ADDXLI_OPCODE_X1 = 1, - ADDXSC_RRR_0_OPCODE_X0 = 1, - ADDXSC_RRR_0_OPCODE_X1 = 1, - ADDX_RRR_0_OPCODE_X0 = 2, - ADDX_RRR_0_OPCODE_X1 = 2, - ADDX_RRR_0_OPCODE_Y0 = 0, - ADDX_SPECIAL_0_OPCODE_Y1 = 0, - ADD_RRR_0_OPCODE_X0 = 3, - ADD_RRR_0_OPCODE_X1 = 3, - ADD_RRR_0_OPCODE_Y0 = 1, - ADD_SPECIAL_0_OPCODE_Y1 = 1, - ANDI_IMM8_OPCODE_X0 = 3, - ANDI_IMM8_OPCODE_X1 = 3, - ANDI_OPCODE_Y0 = 2, - ANDI_OPCODE_Y1 = 3, - AND_RRR_0_OPCODE_X0 = 4, - AND_RRR_0_OPCODE_X1 = 4, - AND_RRR_5_OPCODE_Y0 = 0, - AND_RRR_5_OPCODE_Y1 = 0, - BEQZT_BRANCH_OPCODE_X1 = 16, - BEQZ_BRANCH_OPCODE_X1 = 17, - BFEXTS_BF_OPCODE_X0 = 4, - BFEXTU_BF_OPCODE_X0 = 5, - BFINS_BF_OPCODE_X0 = 6, - BF_OPCODE_X0 = 3, - BGEZT_BRANCH_OPCODE_X1 = 18, - BGEZ_BRANCH_OPCODE_X1 = 19, - BGTZT_BRANCH_OPCODE_X1 = 20, - BGTZ_BRANCH_OPCODE_X1 = 21, - BLBCT_BRANCH_OPCODE_X1 = 22, - BLBC_BRANCH_OPCODE_X1 = 23, - BLBST_BRANCH_OPCODE_X1 = 24, - BLBS_BRANCH_OPCODE_X1 = 25, - BLEZT_BRANCH_OPCODE_X1 = 26, - BLEZ_BRANCH_OPCODE_X1 = 27, - BLTZT_BRANCH_OPCODE_X1 = 28, - BLTZ_BRANCH_OPCODE_X1 = 29, - BNEZT_BRANCH_OPCODE_X1 = 30, - BNEZ_BRANCH_OPCODE_X1 = 31, - BRANCH_OPCODE_X1 = 2, - CMOVEQZ_RRR_0_OPCODE_X0 = 5, - CMOVEQZ_RRR_4_OPCODE_Y0 = 0, - CMOVNEZ_RRR_0_OPCODE_X0 = 6, - CMOVNEZ_RRR_4_OPCODE_Y0 = 1, - CMPEQI_IMM8_OPCODE_X0 = 4, - CMPEQI_IMM8_OPCODE_X1 = 4, - CMPEQI_OPCODE_Y0 = 3, - CMPEQI_OPCODE_Y1 = 4, - CMPEQ_RRR_0_OPCODE_X0 = 7, - CMPEQ_RRR_0_OPCODE_X1 = 5, - CMPEQ_RRR_3_OPCODE_Y0 = 0, - CMPEQ_RRR_3_OPCODE_Y1 = 2, - CMPEXCH4_RRR_0_OPCODE_X1 = 6, - CMPEXCH_RRR_0_OPCODE_X1 = 7, - CMPLES_RRR_0_OPCODE_X0 = 8, - CMPLES_RRR_0_OPCODE_X1 = 8, - CMPLES_RRR_2_OPCODE_Y0 = 0, - CMPLES_RRR_2_OPCODE_Y1 = 0, - CMPLEU_RRR_0_OPCODE_X0 = 9, - CMPLEU_RRR_0_OPCODE_X1 = 9, - CMPLEU_RRR_2_OPCODE_Y0 = 1, - CMPLEU_RRR_2_OPCODE_Y1 = 1, - CMPLTSI_IMM8_OPCODE_X0 = 5, - CMPLTSI_IMM8_OPCODE_X1 = 5, - CMPLTSI_OPCODE_Y0 = 4, - CMPLTSI_OPCODE_Y1 = 5, - CMPLTS_RRR_0_OPCODE_X0 = 10, - CMPLTS_RRR_0_OPCODE_X1 = 10, - CMPLTS_RRR_2_OPCODE_Y0 = 2, - CMPLTS_RRR_2_OPCODE_Y1 = 2, - CMPLTUI_IMM8_OPCODE_X0 = 6, - CMPLTUI_IMM8_OPCODE_X1 = 6, - CMPLTU_RRR_0_OPCODE_X0 = 11, - CMPLTU_RRR_0_OPCODE_X1 = 11, - CMPLTU_RRR_2_OPCODE_Y0 = 3, - CMPLTU_RRR_2_OPCODE_Y1 = 3, - CMPNE_RRR_0_OPCODE_X0 = 12, - CMPNE_RRR_0_OPCODE_X1 = 12, - CMPNE_RRR_3_OPCODE_Y0 = 1, - CMPNE_RRR_3_OPCODE_Y1 = 3, - CMULAF_RRR_0_OPCODE_X0 = 13, - CMULA_RRR_0_OPCODE_X0 = 14, - CMULFR_RRR_0_OPCODE_X0 = 15, - CMULF_RRR_0_OPCODE_X0 = 16, - CMULHR_RRR_0_OPCODE_X0 = 17, - CMULH_RRR_0_OPCODE_X0 = 18, - CMUL_RRR_0_OPCODE_X0 = 19, - CNTLZ_UNARY_OPCODE_X0 = 1, - CNTLZ_UNARY_OPCODE_Y0 = 1, - CNTTZ_UNARY_OPCODE_X0 = 2, - CNTTZ_UNARY_OPCODE_Y0 = 2, - CRC32_32_RRR_0_OPCODE_X0 = 20, - CRC32_8_RRR_0_OPCODE_X0 = 21, - DBLALIGN2_RRR_0_OPCODE_X0 = 22, - DBLALIGN2_RRR_0_OPCODE_X1 = 13, - DBLALIGN4_RRR_0_OPCODE_X0 = 23, - DBLALIGN4_RRR_0_OPCODE_X1 = 14, - DBLALIGN6_RRR_0_OPCODE_X0 = 24, - DBLALIGN6_RRR_0_OPCODE_X1 = 15, - DBLALIGN_RRR_0_OPCODE_X0 = 25, - DRAIN_UNARY_OPCODE_X1 = 1, - DTLBPR_UNARY_OPCODE_X1 = 2, - EXCH4_RRR_0_OPCODE_X1 = 16, - EXCH_RRR_0_OPCODE_X1 = 17, - FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26, - FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27, - FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28, - FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29, - FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30, - FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31, - FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32, - FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33, - FETCHADD4_RRR_0_OPCODE_X1 = 18, - FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19, - FETCHADDGEZ_RRR_0_OPCODE_X1 = 20, - FETCHADD_RRR_0_OPCODE_X1 = 21, - FETCHAND4_RRR_0_OPCODE_X1 = 22, - FETCHAND_RRR_0_OPCODE_X1 = 23, - FETCHOR4_RRR_0_OPCODE_X1 = 24, - FETCHOR_RRR_0_OPCODE_X1 = 25, - FINV_UNARY_OPCODE_X1 = 3, - FLUSHWB_UNARY_OPCODE_X1 = 4, - FLUSH_UNARY_OPCODE_X1 = 5, - FNOP_UNARY_OPCODE_X0 = 3, - FNOP_UNARY_OPCODE_X1 = 6, - FNOP_UNARY_OPCODE_Y0 = 3, - FNOP_UNARY_OPCODE_Y1 = 8, - FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34, - FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35, - FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36, - FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37, - FSINGLE_PACK1_UNARY_OPCODE_X0 = 4, - FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4, - FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38, - FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39, - ICOH_UNARY_OPCODE_X1 = 7, - ILL_UNARY_OPCODE_X1 = 8, - ILL_UNARY_OPCODE_Y1 = 9, - IMM8_OPCODE_X0 = 4, - IMM8_OPCODE_X1 = 3, - INV_UNARY_OPCODE_X1 = 9, - IRET_UNARY_OPCODE_X1 = 10, - JALRP_UNARY_OPCODE_X1 = 11, - JALRP_UNARY_OPCODE_Y1 = 10, - JALR_UNARY_OPCODE_X1 = 12, - JALR_UNARY_OPCODE_Y1 = 11, - JAL_JUMP_OPCODE_X1 = 0, - JRP_UNARY_OPCODE_X1 = 13, - JRP_UNARY_OPCODE_Y1 = 12, - JR_UNARY_OPCODE_X1 = 14, - JR_UNARY_OPCODE_Y1 = 13, - JUMP_OPCODE_X1 = 4, - J_JUMP_OPCODE_X1 = 1, - LD1S_ADD_IMM8_OPCODE_X1 = 7, - LD1S_OPCODE_Y2 = 0, - LD1S_UNARY_OPCODE_X1 = 15, - LD1U_ADD_IMM8_OPCODE_X1 = 8, - LD1U_OPCODE_Y2 = 1, - LD1U_UNARY_OPCODE_X1 = 16, - LD2S_ADD_IMM8_OPCODE_X1 = 9, - LD2S_OPCODE_Y2 = 2, - LD2S_UNARY_OPCODE_X1 = 17, - LD2U_ADD_IMM8_OPCODE_X1 = 10, - LD2U_OPCODE_Y2 = 3, - LD2U_UNARY_OPCODE_X1 = 18, - LD4S_ADD_IMM8_OPCODE_X1 = 11, - LD4S_OPCODE_Y2 = 1, - LD4S_UNARY_OPCODE_X1 = 19, - LD4U_ADD_IMM8_OPCODE_X1 = 12, - LD4U_OPCODE_Y2 = 2, - LD4U_UNARY_OPCODE_X1 = 20, - LDNA_UNARY_OPCODE_X1 = 21, - LDNT1S_ADD_IMM8_OPCODE_X1 = 13, - LDNT1S_UNARY_OPCODE_X1 = 22, - LDNT1U_ADD_IMM8_OPCODE_X1 = 14, - LDNT1U_UNARY_OPCODE_X1 = 23, - LDNT2S_ADD_IMM8_OPCODE_X1 = 15, - LDNT2S_UNARY_OPCODE_X1 = 24, - LDNT2U_ADD_IMM8_OPCODE_X1 = 16, - LDNT2U_UNARY_OPCODE_X1 = 25, - LDNT4S_ADD_IMM8_OPCODE_X1 = 17, - LDNT4S_UNARY_OPCODE_X1 = 26, - LDNT4U_ADD_IMM8_OPCODE_X1 = 18, - LDNT4U_UNARY_OPCODE_X1 = 27, - LDNT_ADD_IMM8_OPCODE_X1 = 19, - LDNT_UNARY_OPCODE_X1 = 28, - LD_ADD_IMM8_OPCODE_X1 = 20, - LD_OPCODE_Y2 = 3, - LD_UNARY_OPCODE_X1 = 29, - LNK_UNARY_OPCODE_X1 = 30, - LNK_UNARY_OPCODE_Y1 = 14, - LWNA_ADD_IMM8_OPCODE_X1 = 21, - MFSPR_IMM8_OPCODE_X1 = 22, - MF_UNARY_OPCODE_X1 = 31, - MM_BF_OPCODE_X0 = 7, - MNZ_RRR_0_OPCODE_X0 = 40, - MNZ_RRR_0_OPCODE_X1 = 26, - MNZ_RRR_4_OPCODE_Y0 = 2, - MNZ_RRR_4_OPCODE_Y1 = 2, - MODE_OPCODE_YA2 = 1, - MODE_OPCODE_YB2 = 2, - MODE_OPCODE_YC2 = 3, - MTSPR_IMM8_OPCODE_X1 = 23, - MULAX_RRR_0_OPCODE_X0 = 41, - MULAX_RRR_3_OPCODE_Y0 = 2, - MULA_HS_HS_RRR_0_OPCODE_X0 = 42, - MULA_HS_HS_RRR_9_OPCODE_Y0 = 0, - MULA_HS_HU_RRR_0_OPCODE_X0 = 43, - MULA_HS_LS_RRR_0_OPCODE_X0 = 44, - MULA_HS_LU_RRR_0_OPCODE_X0 = 45, - MULA_HU_HU_RRR_0_OPCODE_X0 = 46, - MULA_HU_HU_RRR_9_OPCODE_Y0 = 1, - MULA_HU_LS_RRR_0_OPCODE_X0 = 47, - MULA_HU_LU_RRR_0_OPCODE_X0 = 48, - MULA_LS_LS_RRR_0_OPCODE_X0 = 49, - MULA_LS_LS_RRR_9_OPCODE_Y0 = 2, - MULA_LS_LU_RRR_0_OPCODE_X0 = 50, - MULA_LU_LU_RRR_0_OPCODE_X0 = 51, - MULA_LU_LU_RRR_9_OPCODE_Y0 = 3, - MULX_RRR_0_OPCODE_X0 = 52, - MULX_RRR_3_OPCODE_Y0 = 3, - MUL_HS_HS_RRR_0_OPCODE_X0 = 53, - MUL_HS_HS_RRR_8_OPCODE_Y0 = 0, - MUL_HS_HU_RRR_0_OPCODE_X0 = 54, - MUL_HS_LS_RRR_0_OPCODE_X0 = 55, - MUL_HS_LU_RRR_0_OPCODE_X0 = 56, - MUL_HU_HU_RRR_0_OPCODE_X0 = 57, - MUL_HU_HU_RRR_8_OPCODE_Y0 = 1, - MUL_HU_LS_RRR_0_OPCODE_X0 = 58, - MUL_HU_LU_RRR_0_OPCODE_X0 = 59, - MUL_LS_LS_RRR_0_OPCODE_X0 = 60, - MUL_LS_LS_RRR_8_OPCODE_Y0 = 2, - MUL_LS_LU_RRR_0_OPCODE_X0 = 61, - MUL_LU_LU_RRR_0_OPCODE_X0 = 62, - MUL_LU_LU_RRR_8_OPCODE_Y0 = 3, - MZ_RRR_0_OPCODE_X0 = 63, - MZ_RRR_0_OPCODE_X1 = 27, - MZ_RRR_4_OPCODE_Y0 = 3, - MZ_RRR_4_OPCODE_Y1 = 3, - NAP_UNARY_OPCODE_X1 = 32, - NOP_UNARY_OPCODE_X0 = 5, - NOP_UNARY_OPCODE_X1 = 33, - NOP_UNARY_OPCODE_Y0 = 5, - NOP_UNARY_OPCODE_Y1 = 15, - NOR_RRR_0_OPCODE_X0 = 64, - NOR_RRR_0_OPCODE_X1 = 28, - NOR_RRR_5_OPCODE_Y0 = 1, - NOR_RRR_5_OPCODE_Y1 = 1, - ORI_IMM8_OPCODE_X0 = 7, - ORI_IMM8_OPCODE_X1 = 24, - OR_RRR_0_OPCODE_X0 = 65, - OR_RRR_0_OPCODE_X1 = 29, - OR_RRR_5_OPCODE_Y0 = 2, - OR_RRR_5_OPCODE_Y1 = 2, - PCNT_UNARY_OPCODE_X0 = 6, - PCNT_UNARY_OPCODE_Y0 = 6, - REVBITS_UNARY_OPCODE_X0 = 7, - REVBITS_UNARY_OPCODE_Y0 = 7, - REVBYTES_UNARY_OPCODE_X0 = 8, - REVBYTES_UNARY_OPCODE_Y0 = 8, - ROTLI_SHIFT_OPCODE_X0 = 1, - ROTLI_SHIFT_OPCODE_X1 = 1, - ROTLI_SHIFT_OPCODE_Y0 = 0, - ROTLI_SHIFT_OPCODE_Y1 = 0, - ROTL_RRR_0_OPCODE_X0 = 66, - ROTL_RRR_0_OPCODE_X1 = 30, - ROTL_RRR_6_OPCODE_Y0 = 0, - ROTL_RRR_6_OPCODE_Y1 = 0, - RRR_0_OPCODE_X0 = 5, - RRR_0_OPCODE_X1 = 5, - RRR_0_OPCODE_Y0 = 5, - RRR_0_OPCODE_Y1 = 6, - RRR_1_OPCODE_Y0 = 6, - RRR_1_OPCODE_Y1 = 7, - RRR_2_OPCODE_Y0 = 7, - RRR_2_OPCODE_Y1 = 8, - RRR_3_OPCODE_Y0 = 8, - RRR_3_OPCODE_Y1 = 9, - RRR_4_OPCODE_Y0 = 9, - RRR_4_OPCODE_Y1 = 10, - RRR_5_OPCODE_Y0 = 10, - RRR_5_OPCODE_Y1 = 11, - RRR_6_OPCODE_Y0 = 11, - RRR_6_OPCODE_Y1 = 12, - RRR_7_OPCODE_Y0 = 12, - RRR_7_OPCODE_Y1 = 13, - RRR_8_OPCODE_Y0 = 13, - RRR_9_OPCODE_Y0 = 14, - SHIFT_OPCODE_X0 = 6, - SHIFT_OPCODE_X1 = 6, - SHIFT_OPCODE_Y0 = 15, - SHIFT_OPCODE_Y1 = 14, - SHL16INSLI_OPCODE_X0 = 7, - SHL16INSLI_OPCODE_X1 = 7, - SHL1ADDX_RRR_0_OPCODE_X0 = 67, - SHL1ADDX_RRR_0_OPCODE_X1 = 31, - SHL1ADDX_RRR_7_OPCODE_Y0 = 1, - SHL1ADDX_RRR_7_OPCODE_Y1 = 1, - SHL1ADD_RRR_0_OPCODE_X0 = 68, - SHL1ADD_RRR_0_OPCODE_X1 = 32, - SHL1ADD_RRR_1_OPCODE_Y0 = 0, - SHL1ADD_RRR_1_OPCODE_Y1 = 0, - SHL2ADDX_RRR_0_OPCODE_X0 = 69, - SHL2ADDX_RRR_0_OPCODE_X1 = 33, - SHL2ADDX_RRR_7_OPCODE_Y0 = 2, - SHL2ADDX_RRR_7_OPCODE_Y1 = 2, - SHL2ADD_RRR_0_OPCODE_X0 = 70, - SHL2ADD_RRR_0_OPCODE_X1 = 34, - SHL2ADD_RRR_1_OPCODE_Y0 = 1, - SHL2ADD_RRR_1_OPCODE_Y1 = 1, - SHL3ADDX_RRR_0_OPCODE_X0 = 71, - SHL3ADDX_RRR_0_OPCODE_X1 = 35, - SHL3ADDX_RRR_7_OPCODE_Y0 = 3, - SHL3ADDX_RRR_7_OPCODE_Y1 = 3, - SHL3ADD_RRR_0_OPCODE_X0 = 72, - SHL3ADD_RRR_0_OPCODE_X1 = 36, - SHL3ADD_RRR_1_OPCODE_Y0 = 2, - SHL3ADD_RRR_1_OPCODE_Y1 = 2, - SHLI_SHIFT_OPCODE_X0 = 2, - SHLI_SHIFT_OPCODE_X1 = 2, - SHLI_SHIFT_OPCODE_Y0 = 1, - SHLI_SHIFT_OPCODE_Y1 = 1, - SHLXI_SHIFT_OPCODE_X0 = 3, - SHLXI_SHIFT_OPCODE_X1 = 3, - SHLX_RRR_0_OPCODE_X0 = 73, - SHLX_RRR_0_OPCODE_X1 = 37, - SHL_RRR_0_OPCODE_X0 = 74, - SHL_RRR_0_OPCODE_X1 = 38, - SHL_RRR_6_OPCODE_Y0 = 1, - SHL_RRR_6_OPCODE_Y1 = 1, - SHRSI_SHIFT_OPCODE_X0 = 4, - SHRSI_SHIFT_OPCODE_X1 = 4, - SHRSI_SHIFT_OPCODE_Y0 = 2, - SHRSI_SHIFT_OPCODE_Y1 = 2, - SHRS_RRR_0_OPCODE_X0 = 75, - SHRS_RRR_0_OPCODE_X1 = 39, - SHRS_RRR_6_OPCODE_Y0 = 2, - SHRS_RRR_6_OPCODE_Y1 = 2, - SHRUI_SHIFT_OPCODE_X0 = 5, - SHRUI_SHIFT_OPCODE_X1 = 5, - SHRUI_SHIFT_OPCODE_Y0 = 3, - SHRUI_SHIFT_OPCODE_Y1 = 3, - SHRUXI_SHIFT_OPCODE_X0 = 6, - SHRUXI_SHIFT_OPCODE_X1 = 6, - SHRUX_RRR_0_OPCODE_X0 = 76, - SHRUX_RRR_0_OPCODE_X1 = 40, - SHRU_RRR_0_OPCODE_X0 = 77, - SHRU_RRR_0_OPCODE_X1 = 41, - SHRU_RRR_6_OPCODE_Y0 = 3, - SHRU_RRR_6_OPCODE_Y1 = 3, - SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78, - ST1_ADD_IMM8_OPCODE_X1 = 25, - ST1_OPCODE_Y2 = 0, - ST1_RRR_0_OPCODE_X1 = 42, - ST2_ADD_IMM8_OPCODE_X1 = 26, - ST2_OPCODE_Y2 = 1, - ST2_RRR_0_OPCODE_X1 = 43, - ST4_ADD_IMM8_OPCODE_X1 = 27, - ST4_OPCODE_Y2 = 2, - ST4_RRR_0_OPCODE_X1 = 44, - STNT1_ADD_IMM8_OPCODE_X1 = 28, - STNT1_RRR_0_OPCODE_X1 = 45, - STNT2_ADD_IMM8_OPCODE_X1 = 29, - STNT2_RRR_0_OPCODE_X1 = 46, - STNT4_ADD_IMM8_OPCODE_X1 = 30, - STNT4_RRR_0_OPCODE_X1 = 47, - STNT_ADD_IMM8_OPCODE_X1 = 31, - STNT_RRR_0_OPCODE_X1 = 48, - ST_ADD_IMM8_OPCODE_X1 = 32, - ST_OPCODE_Y2 = 3, - ST_RRR_0_OPCODE_X1 = 49, - SUBXSC_RRR_0_OPCODE_X0 = 79, - SUBXSC_RRR_0_OPCODE_X1 = 50, - SUBX_RRR_0_OPCODE_X0 = 80, - SUBX_RRR_0_OPCODE_X1 = 51, - SUBX_RRR_0_OPCODE_Y0 = 2, - SUBX_RRR_0_OPCODE_Y1 = 2, - SUB_RRR_0_OPCODE_X0 = 81, - SUB_RRR_0_OPCODE_X1 = 52, - SUB_RRR_0_OPCODE_Y0 = 3, - SUB_RRR_0_OPCODE_Y1 = 3, - SWINT0_UNARY_OPCODE_X1 = 34, - SWINT1_UNARY_OPCODE_X1 = 35, - SWINT2_UNARY_OPCODE_X1 = 36, - SWINT3_UNARY_OPCODE_X1 = 37, - TBLIDXB0_UNARY_OPCODE_X0 = 9, - TBLIDXB0_UNARY_OPCODE_Y0 = 9, - TBLIDXB1_UNARY_OPCODE_X0 = 10, - TBLIDXB1_UNARY_OPCODE_Y0 = 10, - TBLIDXB2_UNARY_OPCODE_X0 = 11, - TBLIDXB2_UNARY_OPCODE_Y0 = 11, - TBLIDXB3_UNARY_OPCODE_X0 = 12, - TBLIDXB3_UNARY_OPCODE_Y0 = 12, - UNARY_RRR_0_OPCODE_X0 = 82, - UNARY_RRR_0_OPCODE_X1 = 53, - UNARY_RRR_1_OPCODE_Y0 = 3, - UNARY_RRR_1_OPCODE_Y1 = 3, - V1ADDI_IMM8_OPCODE_X0 = 8, - V1ADDI_IMM8_OPCODE_X1 = 33, - V1ADDUC_RRR_0_OPCODE_X0 = 83, - V1ADDUC_RRR_0_OPCODE_X1 = 54, - V1ADD_RRR_0_OPCODE_X0 = 84, - V1ADD_RRR_0_OPCODE_X1 = 55, - V1ADIFFU_RRR_0_OPCODE_X0 = 85, - V1AVGU_RRR_0_OPCODE_X0 = 86, - V1CMPEQI_IMM8_OPCODE_X0 = 9, - V1CMPEQI_IMM8_OPCODE_X1 = 34, - V1CMPEQ_RRR_0_OPCODE_X0 = 87, - V1CMPEQ_RRR_0_OPCODE_X1 = 56, - V1CMPLES_RRR_0_OPCODE_X0 = 88, - V1CMPLES_RRR_0_OPCODE_X1 = 57, - V1CMPLEU_RRR_0_OPCODE_X0 = 89, - V1CMPLEU_RRR_0_OPCODE_X1 = 58, - V1CMPLTSI_IMM8_OPCODE_X0 = 10, - V1CMPLTSI_IMM8_OPCODE_X1 = 35, - V1CMPLTS_RRR_0_OPCODE_X0 = 90, - V1CMPLTS_RRR_0_OPCODE_X1 = 59, - V1CMPLTUI_IMM8_OPCODE_X0 = 11, - V1CMPLTUI_IMM8_OPCODE_X1 = 36, - V1CMPLTU_RRR_0_OPCODE_X0 = 91, - V1CMPLTU_RRR_0_OPCODE_X1 = 60, - V1CMPNE_RRR_0_OPCODE_X0 = 92, - V1CMPNE_RRR_0_OPCODE_X1 = 61, - V1DDOTPUA_RRR_0_OPCODE_X0 = 161, - V1DDOTPUSA_RRR_0_OPCODE_X0 = 93, - V1DDOTPUS_RRR_0_OPCODE_X0 = 94, - V1DDOTPU_RRR_0_OPCODE_X0 = 162, - V1DOTPA_RRR_0_OPCODE_X0 = 95, - V1DOTPUA_RRR_0_OPCODE_X0 = 163, - V1DOTPUSA_RRR_0_OPCODE_X0 = 96, - V1DOTPUS_RRR_0_OPCODE_X0 = 97, - V1DOTPU_RRR_0_OPCODE_X0 = 164, - V1DOTP_RRR_0_OPCODE_X0 = 98, - V1INT_H_RRR_0_OPCODE_X0 = 99, - V1INT_H_RRR_0_OPCODE_X1 = 62, - V1INT_L_RRR_0_OPCODE_X0 = 100, - V1INT_L_RRR_0_OPCODE_X1 = 63, - V1MAXUI_IMM8_OPCODE_X0 = 12, - V1MAXUI_IMM8_OPCODE_X1 = 37, - V1MAXU_RRR_0_OPCODE_X0 = 101, - V1MAXU_RRR_0_OPCODE_X1 = 64, - V1MINUI_IMM8_OPCODE_X0 = 13, - V1MINUI_IMM8_OPCODE_X1 = 38, - V1MINU_RRR_0_OPCODE_X0 = 102, - V1MINU_RRR_0_OPCODE_X1 = 65, - V1MNZ_RRR_0_OPCODE_X0 = 103, - V1MNZ_RRR_0_OPCODE_X1 = 66, - V1MULTU_RRR_0_OPCODE_X0 = 104, - V1MULUS_RRR_0_OPCODE_X0 = 105, - V1MULU_RRR_0_OPCODE_X0 = 106, - V1MZ_RRR_0_OPCODE_X0 = 107, - V1MZ_RRR_0_OPCODE_X1 = 67, - V1SADAU_RRR_0_OPCODE_X0 = 108, - V1SADU_RRR_0_OPCODE_X0 = 109, - V1SHLI_SHIFT_OPCODE_X0 = 7, - V1SHLI_SHIFT_OPCODE_X1 = 7, - V1SHL_RRR_0_OPCODE_X0 = 110, - V1SHL_RRR_0_OPCODE_X1 = 68, - V1SHRSI_SHIFT_OPCODE_X0 = 8, - V1SHRSI_SHIFT_OPCODE_X1 = 8, - V1SHRS_RRR_0_OPCODE_X0 = 111, - V1SHRS_RRR_0_OPCODE_X1 = 69, - V1SHRUI_SHIFT_OPCODE_X0 = 9, - V1SHRUI_SHIFT_OPCODE_X1 = 9, - V1SHRU_RRR_0_OPCODE_X0 = 112, - V1SHRU_RRR_0_OPCODE_X1 = 70, - V1SUBUC_RRR_0_OPCODE_X0 = 113, - V1SUBUC_RRR_0_OPCODE_X1 = 71, - V1SUB_RRR_0_OPCODE_X0 = 114, - V1SUB_RRR_0_OPCODE_X1 = 72, - V2ADDI_IMM8_OPCODE_X0 = 14, - V2ADDI_IMM8_OPCODE_X1 = 39, - V2ADDSC_RRR_0_OPCODE_X0 = 115, - V2ADDSC_RRR_0_OPCODE_X1 = 73, - V2ADD_RRR_0_OPCODE_X0 = 116, - V2ADD_RRR_0_OPCODE_X1 = 74, - V2ADIFFS_RRR_0_OPCODE_X0 = 117, - V2AVGS_RRR_0_OPCODE_X0 = 118, - V2CMPEQI_IMM8_OPCODE_X0 = 15, - V2CMPEQI_IMM8_OPCODE_X1 = 40, - V2CMPEQ_RRR_0_OPCODE_X0 = 119, - V2CMPEQ_RRR_0_OPCODE_X1 = 75, - V2CMPLES_RRR_0_OPCODE_X0 = 120, - V2CMPLES_RRR_0_OPCODE_X1 = 76, - V2CMPLEU_RRR_0_OPCODE_X0 = 121, - V2CMPLEU_RRR_0_OPCODE_X1 = 77, - V2CMPLTSI_IMM8_OPCODE_X0 = 16, - V2CMPLTSI_IMM8_OPCODE_X1 = 41, - V2CMPLTS_RRR_0_OPCODE_X0 = 122, - V2CMPLTS_RRR_0_OPCODE_X1 = 78, - V2CMPLTUI_IMM8_OPCODE_X0 = 17, - V2CMPLTUI_IMM8_OPCODE_X1 = 42, - V2CMPLTU_RRR_0_OPCODE_X0 = 123, - V2CMPLTU_RRR_0_OPCODE_X1 = 79, - V2CMPNE_RRR_0_OPCODE_X0 = 124, - V2CMPNE_RRR_0_OPCODE_X1 = 80, - V2DOTPA_RRR_0_OPCODE_X0 = 125, - V2DOTP_RRR_0_OPCODE_X0 = 126, - V2INT_H_RRR_0_OPCODE_X0 = 127, - V2INT_H_RRR_0_OPCODE_X1 = 81, - V2INT_L_RRR_0_OPCODE_X0 = 128, - V2INT_L_RRR_0_OPCODE_X1 = 82, - V2MAXSI_IMM8_OPCODE_X0 = 18, - V2MAXSI_IMM8_OPCODE_X1 = 43, - V2MAXS_RRR_0_OPCODE_X0 = 129, - V2MAXS_RRR_0_OPCODE_X1 = 83, - V2MINSI_IMM8_OPCODE_X0 = 19, - V2MINSI_IMM8_OPCODE_X1 = 44, - V2MINS_RRR_0_OPCODE_X0 = 130, - V2MINS_RRR_0_OPCODE_X1 = 84, - V2MNZ_RRR_0_OPCODE_X0 = 131, - V2MNZ_RRR_0_OPCODE_X1 = 85, - V2MULFSC_RRR_0_OPCODE_X0 = 132, - V2MULS_RRR_0_OPCODE_X0 = 133, - V2MULTS_RRR_0_OPCODE_X0 = 134, - V2MZ_RRR_0_OPCODE_X0 = 135, - V2MZ_RRR_0_OPCODE_X1 = 86, - V2PACKH_RRR_0_OPCODE_X0 = 136, - V2PACKH_RRR_0_OPCODE_X1 = 87, - V2PACKL_RRR_0_OPCODE_X0 = 137, - V2PACKL_RRR_0_OPCODE_X1 = 88, - V2PACKUC_RRR_0_OPCODE_X0 = 138, - V2PACKUC_RRR_0_OPCODE_X1 = 89, - V2SADAS_RRR_0_OPCODE_X0 = 139, - V2SADAU_RRR_0_OPCODE_X0 = 140, - V2SADS_RRR_0_OPCODE_X0 = 141, - V2SADU_RRR_0_OPCODE_X0 = 142, - V2SHLI_SHIFT_OPCODE_X0 = 10, - V2SHLI_SHIFT_OPCODE_X1 = 10, - V2SHLSC_RRR_0_OPCODE_X0 = 143, - V2SHLSC_RRR_0_OPCODE_X1 = 90, - V2SHL_RRR_0_OPCODE_X0 = 144, - V2SHL_RRR_0_OPCODE_X1 = 91, - V2SHRSI_SHIFT_OPCODE_X0 = 11, - V2SHRSI_SHIFT_OPCODE_X1 = 11, - V2SHRS_RRR_0_OPCODE_X0 = 145, - V2SHRS_RRR_0_OPCODE_X1 = 92, - V2SHRUI_SHIFT_OPCODE_X0 = 12, - V2SHRUI_SHIFT_OPCODE_X1 = 12, - V2SHRU_RRR_0_OPCODE_X0 = 146, - V2SHRU_RRR_0_OPCODE_X1 = 93, - V2SUBSC_RRR_0_OPCODE_X0 = 147, - V2SUBSC_RRR_0_OPCODE_X1 = 94, - V2SUB_RRR_0_OPCODE_X0 = 148, - V2SUB_RRR_0_OPCODE_X1 = 95, - V4ADDSC_RRR_0_OPCODE_X0 = 149, - V4ADDSC_RRR_0_OPCODE_X1 = 96, - V4ADD_RRR_0_OPCODE_X0 = 150, - V4ADD_RRR_0_OPCODE_X1 = 97, - V4INT_H_RRR_0_OPCODE_X0 = 151, - V4INT_H_RRR_0_OPCODE_X1 = 98, - V4INT_L_RRR_0_OPCODE_X0 = 152, - V4INT_L_RRR_0_OPCODE_X1 = 99, - V4PACKSC_RRR_0_OPCODE_X0 = 153, - V4PACKSC_RRR_0_OPCODE_X1 = 100, - V4SHLSC_RRR_0_OPCODE_X0 = 154, - V4SHLSC_RRR_0_OPCODE_X1 = 101, - V4SHL_RRR_0_OPCODE_X0 = 155, - V4SHL_RRR_0_OPCODE_X1 = 102, - V4SHRS_RRR_0_OPCODE_X0 = 156, - V4SHRS_RRR_0_OPCODE_X1 = 103, - V4SHRU_RRR_0_OPCODE_X0 = 157, - V4SHRU_RRR_0_OPCODE_X1 = 104, - V4SUBSC_RRR_0_OPCODE_X0 = 158, - V4SUBSC_RRR_0_OPCODE_X1 = 105, - V4SUB_RRR_0_OPCODE_X0 = 159, - V4SUB_RRR_0_OPCODE_X1 = 106, - WH64_UNARY_OPCODE_X1 = 38, - XORI_IMM8_OPCODE_X0 = 20, - XORI_IMM8_OPCODE_X1 = 45, - XOR_RRR_0_OPCODE_X0 = 160, - XOR_RRR_0_OPCODE_X1 = 107, - XOR_RRR_5_OPCODE_Y0 = 3, - XOR_RRR_5_OPCODE_Y1 = 3 -}; - -static __inline unsigned int -get_BFEnd_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_BFOpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 24)) & 0xf); -} - -static __inline unsigned int -get_BFStart_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3f); -} - -static __inline unsigned int -get_BrOff_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x0000003f) | - (((unsigned int)(n >> 37)) & 0x0001ffc0); -} - -static __inline unsigned int -get_BrType_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 54)) & 0x1f); -} - -static __inline unsigned int -get_Dest_Imm8_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x0000003f) | - (((unsigned int)(n >> 43)) & 0x000000c0); -} - -static __inline unsigned int -get_Dest_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 0)) & 0x3f); -} - -static __inline unsigned int -get_Dest_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x3f); -} - -static __inline unsigned int -get_Dest_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 0)) & 0x3f); -} - -static __inline unsigned int -get_Dest_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x3f); -} - -static __inline unsigned int -get_Imm16_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0xffff); -} - -static __inline unsigned int -get_Imm16_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0xffff); -} - -static __inline unsigned int -get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 20)) & 0xff); -} - -static __inline unsigned int -get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 51)) & 0xff); -} - -static __inline unsigned int -get_Imm8_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0xff); -} - -static __inline unsigned int -get_Imm8_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0xff); -} - -static __inline unsigned int -get_Imm8_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0xff); -} - -static __inline unsigned int -get_Imm8_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0xff); -} - -static __inline unsigned int -get_JumpOff_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x7ffffff); -} - -static __inline unsigned int -get_JumpOpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 58)) & 0x1); -} - -static __inline unsigned int -get_MF_Imm14_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 37)) & 0x3fff); -} - -static __inline unsigned int -get_MT_Imm14_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 31)) & 0x0000003f) | - (((unsigned int)(n >> 37)) & 0x00003fc0); -} - -static __inline unsigned int -get_Mode(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 62)) & 0x3); -} - -static __inline unsigned int -get_Opcode_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 28)) & 0x7); -} - -static __inline unsigned int -get_Opcode_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 59)) & 0x7); -} - -static __inline unsigned int -get_Opcode_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 27)) & 0xf); -} - -static __inline unsigned int -get_Opcode_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 58)) & 0xf); -} - -static __inline unsigned int -get_Opcode_Y2(tilegx_bundle_bits n) -{ - return (((n >> 26)) & 0x00000001) | - (((unsigned int)(n >> 56)) & 0x00000002); -} - -static __inline unsigned int -get_RRROpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3ff); -} - -static __inline unsigned int -get_RRROpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3ff); -} - -static __inline unsigned int -get_RRROpcodeExtension_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3); -} - -static __inline unsigned int -get_RRROpcodeExtension_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3); -} - -static __inline unsigned int -get_ShAmt_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_ShAmt_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_ShAmt_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_ShAmt_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3ff); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3ff); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 18)) & 0x3); -} - -static __inline unsigned int -get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 49)) & 0x3); -} - -static __inline unsigned int -get_SrcA_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 6)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 37)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 6)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 37)) & 0x3f); -} - -static __inline unsigned int -get_SrcA_Y2(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 20)) & 0x3f); -} - -static __inline unsigned int -get_SrcBDest_Y2(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 51)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_SrcB_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num) -{ - const unsigned int n = (unsigned int)num; - return (((n >> 12)) & 0x3f); -} - -static __inline unsigned int -get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n) -{ - return (((unsigned int)(n >> 43)) & 0x3f); -} - -static __inline int -sign_extend(int n, int num_bits) -{ - int shift = (int)(sizeof(int) * 8 - num_bits); - return (n << shift) >> shift; -} - -static __inline tilegx_bundle_bits -create_BFEnd_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_BFOpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xf) << 24); -} - -static __inline tilegx_bundle_bits -create_BFStart_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 18); -} - -static __inline tilegx_bundle_bits -create_BrOff_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | - (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37); -} - -static __inline tilegx_bundle_bits -create_BrType_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x1f)) << 54); -} - -static __inline tilegx_bundle_bits -create_Dest_Imm8_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | - (((tilegx_bundle_bits)(n & 0x000000c0)) << 43); -} - -static __inline tilegx_bundle_bits -create_Dest_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 0); -} - -static __inline tilegx_bundle_bits -create_Dest_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 31); -} - -static __inline tilegx_bundle_bits -create_Dest_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 0); -} - -static __inline tilegx_bundle_bits -create_Dest_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 31); -} - -static __inline tilegx_bundle_bits -create_Imm16_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xffff) << 12); -} - -static __inline tilegx_bundle_bits -create_Imm16_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xffff)) << 43); -} - -static __inline tilegx_bundle_bits -create_Imm8OpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xff) << 20); -} - -static __inline tilegx_bundle_bits -create_Imm8OpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xff)) << 51); -} - -static __inline tilegx_bundle_bits -create_Imm8_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xff) << 12); -} - -static __inline tilegx_bundle_bits -create_Imm8_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xff)) << 43); -} - -static __inline tilegx_bundle_bits -create_Imm8_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xff) << 12); -} - -static __inline tilegx_bundle_bits -create_Imm8_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xff)) << 43); -} - -static __inline tilegx_bundle_bits -create_JumpOff_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31); -} - -static __inline tilegx_bundle_bits -create_JumpOpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x1)) << 58); -} - -static __inline tilegx_bundle_bits -create_MF_Imm14_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3fff)) << 37); -} - -static __inline tilegx_bundle_bits -create_MT_Imm14_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | - (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37); -} - -static __inline tilegx_bundle_bits -create_Mode(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3)) << 62); -} - -static __inline tilegx_bundle_bits -create_Opcode_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x7) << 28); -} - -static __inline tilegx_bundle_bits -create_Opcode_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x7)) << 59); -} - -static __inline tilegx_bundle_bits -create_Opcode_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0xf) << 27); -} - -static __inline tilegx_bundle_bits -create_Opcode_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0xf)) << 58); -} - -static __inline tilegx_bundle_bits -create_Opcode_Y2(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x00000001) << 26) | - (((tilegx_bundle_bits)(n & 0x00000002)) << 56); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3ff) << 18); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3) << 18); -} - -static __inline tilegx_bundle_bits -create_RRROpcodeExtension_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3)) << 49); -} - -static __inline tilegx_bundle_bits -create_ShAmt_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_ShAmt_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_ShAmt_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_ShAmt_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3ff) << 18); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3) << 18); -} - -static __inline tilegx_bundle_bits -create_ShiftOpcodeExtension_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3)) << 49); -} - -static __inline tilegx_bundle_bits -create_SrcA_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 6); -} - -static __inline tilegx_bundle_bits -create_SrcA_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 37); -} - -static __inline tilegx_bundle_bits -create_SrcA_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 6); -} - -static __inline tilegx_bundle_bits -create_SrcA_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 37); -} - -static __inline tilegx_bundle_bits -create_SrcA_Y2(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 20); -} - -static __inline tilegx_bundle_bits -create_SrcBDest_Y2(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 51); -} - -static __inline tilegx_bundle_bits -create_SrcB_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_SrcB_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_SrcB_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_SrcB_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_X0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_X1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_Y0(int num) -{ - const unsigned int n = (unsigned int)num; - return ((n & 0x3f) << 12); -} - -static __inline tilegx_bundle_bits -create_UnaryOpcodeExtension_Y1(int num) -{ - const unsigned int n = (unsigned int)num; - return (((tilegx_bundle_bits)(n & 0x3f)) << 43); -} - -const struct tilegx_opcode tilegx_opcodes[336] = -{ - { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffffffff80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a44ae00000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1, - { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00fffULL, - 0xfff807ff80000000ULL, - 0x0000000078000fffULL, - 0x3c0007ff80000000ULL, - 0ULL - }, - { - 0x0000000040300fffULL, - 0x181807ff80000000ULL, - 0x0000000010000fffULL, - 0x0c0007ff80000000ULL, - -1ULL - } -#endif - }, - { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1, - { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000fffULL, - 0xf80007ff80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000070000fffULL, - 0x380007ff80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1858000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18a0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1, - { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0xfffff80000000000ULL, - 0x00000000780ff000ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - 0x000000005107f000ULL, - 0x283bf80000000000ULL, - 0x00000000500bf000ULL, - 0x2c05f80000000000ULL, - -1ULL - } -#endif - }, - { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1, - { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00fc0ULL, - 0xfff807e000000000ULL, - 0x0000000078000fc0ULL, - 0x3c0007e000000000ULL, - 0ULL - }, - { - 0x0000000040100fc0ULL, - 0x180807e000000000ULL, - 0x0000000000000fc0ULL, - 0x040007e000000000ULL, - -1ULL - } -#endif - }, - { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1, - { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000fc0ULL, - 0xf80007e000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000010000fc0ULL, - 0x000007e000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a801f80000000ULL, - -1ULL, - -1ULL, - 0x41f8000004000000ULL - } -#endif - }, - { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1840001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1838001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1850001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1848001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1860001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8001f80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1858001f80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a801f80000000ULL, - -1ULL, - -1ULL, - 0x41f8000004000000ULL - } -#endif - }, - { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a781f80000000ULL, - -1ULL, - -1ULL, - 0x41f8000000000000ULL - } -#endif - }, - { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a901f80000000ULL, - -1ULL, - -1ULL, - 0x43f8000004000000ULL - } -#endif - }, - { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a881f80000000ULL, - -1ULL, - -1ULL, - 0x43f8000000000000ULL - } -#endif - }, - { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286aa01f80000000ULL, - -1ULL, - -1ULL, - 0x83f8000000000000ULL - } -#endif - }, - { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff81f80000000ULL, - 0ULL, - 0ULL, - 0xc3f8000004000000ULL - }, - { - -1ULL, - 0x286a981f80000000ULL, - -1ULL, - -1ULL, - 0x81f8000004000000ULL - } -#endif - }, - { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffffffff80000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a44ae80000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000500c0000ULL, - 0x2806000000000000ULL, - 0x0000000028040000ULL, - 0x1802000000000000ULL, - -1ULL - } -#endif - }, - { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040100000ULL, - 0x1808000000000000ULL, - 0ULL, - 0x0400000000000000ULL, - -1ULL - } -#endif - }, - { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000000ULL, - 0xf800000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000010000000ULL, - 0ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050080000ULL, - 0x2804000000000000ULL, - 0x0000000028000000ULL, - 0x1800000000000000ULL, - -1ULL - } -#endif - }, - { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040200000ULL, - 0x1810000000000000ULL, - 0x0000000008000000ULL, - 0x0800000000000000ULL, - -1ULL - } -#endif - }, - { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000000ULL, - 0xf800000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000020000000ULL, - 0x0800000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050040000ULL, - 0x2802000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050100000ULL, - 0x2808000000000000ULL, - 0x0000000050000000ULL, - 0x2c00000000000000ULL, - -1ULL - } -#endif - }, - { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040300000ULL, - 0x1818000000000000ULL, - 0x0000000010000000ULL, - 0x0c00000000000000ULL, - -1ULL - } -#endif - }, - { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1440000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1400000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1, - { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000034000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1, - { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000035000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1, - { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000036000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x14c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1480000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1540000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1500000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x15c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1580000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1640000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1600000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x16c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1680000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1740000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1700000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x17c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xffc0000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1780000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051481000ULL, - -1ULL, - 0x00000000300c1000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050140000ULL, - -1ULL, - 0x0000000048000000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050180000ULL, - -1ULL, - 0x0000000048040000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000501c0000ULL, - 0x280a000000000000ULL, - 0x0000000040000000ULL, - 0x2404000000000000ULL, - -1ULL - } -#endif - }, - { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040400000ULL, - 0x1820000000000000ULL, - 0x0000000018000000ULL, - 0x1000000000000000ULL, - -1ULL - } -#endif - }, - { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x280e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x280c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050200000ULL, - 0x2810000000000000ULL, - 0x0000000038000000ULL, - 0x2000000000000000ULL, - -1ULL - } -#endif - }, - { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050240000ULL, - 0x2812000000000000ULL, - 0x0000000038040000ULL, - 0x2002000000000000ULL, - -1ULL - } -#endif - }, - { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050280000ULL, - 0x2814000000000000ULL, - 0x0000000038080000ULL, - 0x2004000000000000ULL, - -1ULL - } -#endif - }, - { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0x0000000078000000ULL, - 0x3c00000000000000ULL, - 0ULL - }, - { - 0x0000000040500000ULL, - 0x1828000000000000ULL, - 0x0000000020000000ULL, - 0x1400000000000000ULL, - -1ULL - } -#endif - }, - { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000502c0000ULL, - 0x2816000000000000ULL, - 0x00000000380c0000ULL, - 0x2006000000000000ULL, - -1ULL - } -#endif - }, - { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040600000ULL, - 0x1830000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050300000ULL, - 0x2818000000000000ULL, - 0x0000000040040000ULL, - 0x2406000000000000ULL, - -1ULL - } -#endif - }, - { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000504c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050380000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050340000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050400000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000503c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050480000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050440000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050500000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050540000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051482000ULL, - -1ULL, - 0x00000000300c2000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050640000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050580000ULL, - 0x281a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000505c0000ULL, - 0x281c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050600000ULL, - 0x281e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a080000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a100000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2822000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2820000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000506c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050680000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050700000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050740000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050780000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000507c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050800000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050840000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x282a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2824000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2828000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2826000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x282e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x282c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2832000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2830000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a180000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a280000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a200000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1, - { { }, { }, { }, { }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0xfffff80000000000ULL, - 0x00000000780ff000ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - 0x0000000051483000ULL, - 0x286a300000000000ULL, - 0x00000000300c3000ULL, - 0x1c06400000000000ULL, - -1ULL - } -#endif - }, - { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050880000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000508c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050900000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050940000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051484000ULL, - -1ULL, - 0x00000000300c4000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050980000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000509c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a380000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a400000000000ULL, - -1ULL, - 0x1c06480000000000ULL, - -1ULL - } -#endif - }, - { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a480000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286a500000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfc00000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2400000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1, - { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfc00000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2000000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a600000000000ULL, - -1ULL, - 0x1c06580000000000ULL, - -1ULL - } -#endif - }, - { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a580000000000ULL, - -1ULL, - 0x1c06500000000000ULL, - -1ULL - } -#endif - }, - { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a700000000000ULL, - -1ULL, - 0x1c06680000000000ULL, - -1ULL - } -#endif - }, - { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286a680000000000ULL, - -1ULL, - 0x1c06600000000000ULL, - -1ULL - } -#endif - }, - { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286ae80000000000ULL, - -1ULL, - -1ULL, - 0x8200000004000000ULL - } -#endif - }, - { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a780000000000ULL, - -1ULL, - -1ULL, - 0x4000000000000000ULL - } -#endif - }, - { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1838000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a800000000000ULL, - -1ULL, - -1ULL, - 0x4000000004000000ULL - } -#endif - }, - { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1840000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a880000000000ULL, - -1ULL, - -1ULL, - 0x4200000000000000ULL - } -#endif - }, - { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1848000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a900000000000ULL, - -1ULL, - -1ULL, - 0x4200000004000000ULL - } -#endif - }, - { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1850000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286a980000000000ULL, - -1ULL, - -1ULL, - 0x8000000004000000ULL - } -#endif - }, - { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1858000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x286aa00000000000ULL, - -1ULL, - -1ULL, - 0x8200000000000000ULL - } -#endif - }, - { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1860000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18a0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286aa80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18a8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ae00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ab00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1868000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ab80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1870000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ac00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1878000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ac80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1880000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ad00000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1888000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286ad80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1890000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1898000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1, - { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - -1ULL, - 0x286af00000000000ULL, - -1ULL, - 0x1c06700000000000ULL, - -1ULL - } -#endif - }, - { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286af80000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18b0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1, - { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007f000000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000037000000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050a00000ULL, - 0x2834000000000000ULL, - 0x0000000048080000ULL, - 0x2804000000000000ULL, - -1ULL - } -#endif - }, - { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18b8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050d40000ULL, - -1ULL, - 0x0000000068000000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050d80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050dc0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050e00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050e40000ULL, - -1ULL, - 0x0000000068040000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050e80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050ec0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050f00000ULL, - -1ULL, - 0x0000000068080000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050f40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050f80000ULL, - -1ULL, - 0x00000000680c0000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050a80000ULL, - -1ULL, - 0x0000000070000000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050ac0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050b00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050b40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050b80000ULL, - -1ULL, - 0x0000000070040000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050bc0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050c00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050c40000ULL, - -1ULL, - 0x0000000070080000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050c80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050cc0000ULL, - -1ULL, - 0x00000000700c0000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050a40000ULL, - -1ULL, - 0x0000000040080000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0x00000000780c0000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000050d00000ULL, - -1ULL, - 0x00000000400c0000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000050fc0000ULL, - 0x2836000000000000ULL, - 0x00000000480c0000ULL, - 0x2806000000000000ULL, - -1ULL - } -#endif - }, - { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1, - { { }, { }, { }, { }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0xfffff80000000000ULL, - 0x00000000780ff000ULL, - 0x3c07f80000000000ULL, - 0ULL - }, - { - 0x0000000051485000ULL, - 0x286b080000000000ULL, - 0x00000000300c5000ULL, - 0x1c06780000000000ULL, - -1ULL - } -#endif - }, - { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051000000ULL, - 0x2838000000000000ULL, - 0x0000000050040000ULL, - 0x2c02000000000000ULL, - -1ULL - } -#endif - }, - { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051040000ULL, - 0x283a000000000000ULL, - 0x0000000050080000ULL, - 0x2c04000000000000ULL, - -1ULL - } -#endif - }, - { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040700000ULL, - 0x18c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051486000ULL, - -1ULL, - 0x00000000300c6000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051487000ULL, - -1ULL, - 0x00000000300c7000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1, - { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051488000ULL, - -1ULL, - 0x00000000300c8000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051080000ULL, - 0x283c000000000000ULL, - 0x0000000058000000ULL, - 0x3000000000000000ULL, - -1ULL - } -#endif - }, - { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060040000ULL, - 0x3002000000000000ULL, - 0x0000000078000000ULL, - 0x3800000000000000ULL, - -1ULL - } -#endif - }, - { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051280000ULL, - 0x284c000000000000ULL, - 0x0000000058040000ULL, - 0x3002000000000000ULL, - -1ULL - } -#endif - }, - { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc000000070000000ULL, - 0xf800000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000070000000ULL, - 0x3800000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051100000ULL, - 0x2840000000000000ULL, - 0x0000000030000000ULL, - 0x1c00000000000000ULL, - -1ULL - } -#endif - }, - { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000510c0000ULL, - 0x283e000000000000ULL, - 0x0000000060040000ULL, - 0x3402000000000000ULL, - -1ULL - } -#endif - }, - { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051180000ULL, - 0x2844000000000000ULL, - 0x0000000030040000ULL, - 0x1c02000000000000ULL, - -1ULL - } -#endif - }, - { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051140000ULL, - 0x2842000000000000ULL, - 0x0000000060080000ULL, - 0x3404000000000000ULL, - -1ULL - } -#endif - }, - { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051200000ULL, - 0x2848000000000000ULL, - 0x0000000030080000ULL, - 0x1c04000000000000ULL, - -1ULL - } -#endif - }, - { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000511c0000ULL, - 0x2846000000000000ULL, - 0x00000000600c0000ULL, - 0x3406000000000000ULL, - -1ULL - } -#endif - }, - { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060080000ULL, - 0x3004000000000000ULL, - 0x0000000078040000ULL, - 0x3802000000000000ULL, - -1ULL - } -#endif - }, - { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051240000ULL, - 0x284a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000600c0000ULL, - 0x3006000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x00000000512c0000ULL, - 0x284e000000000000ULL, - 0x0000000058080000ULL, - 0x3004000000000000ULL, - -1ULL - } -#endif - }, - { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060100000ULL, - 0x3008000000000000ULL, - 0x0000000078080000ULL, - 0x3804000000000000ULL, - -1ULL - } -#endif - }, - { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051340000ULL, - 0x2852000000000000ULL, - 0x00000000580c0000ULL, - 0x3006000000000000ULL, - -1ULL - } -#endif - }, - { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000060140000ULL, - 0x300a000000000000ULL, - 0x00000000780c0000ULL, - 0x3806000000000000ULL, - -1ULL - } -#endif - }, - { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051300000ULL, - 0x2850000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060180000ULL, - 0x300c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051380000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2862000000000000ULL, - -1ULL, - -1ULL, - 0xc200000004000000ULL - } -#endif - }, - { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2854000000000000ULL, - -1ULL, - -1ULL, - 0xc000000000000000ULL - } -#endif - }, - { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18c8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2856000000000000ULL, - -1ULL, - -1ULL, - 0xc000000004000000ULL - } -#endif - }, - { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18d0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0xc200000004000000ULL - }, - { - -1ULL, - 0x2858000000000000ULL, - -1ULL, - -1ULL, - 0xc200000000000000ULL - } -#endif - }, - { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18d8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x1900000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x2860000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x285a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18e0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x285c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18e8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1, - { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x285e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18f0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1, - { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x18f8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051440000ULL, - 0x2868000000000000ULL, - 0x00000000280c0000ULL, - 0x1806000000000000ULL, - -1ULL - } -#endif - }, - { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000051400000ULL, - 0x2866000000000000ULL, - 0x0000000028080000ULL, - 0x1804000000000000ULL, - -1ULL - } -#endif - }, - { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000513c0000ULL, - 0x2864000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b100000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b180000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b200000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0, - { { 0, }, { }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b280000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051489000ULL, - -1ULL, - 0x00000000300c9000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x000000005148a000ULL, - -1ULL, - 0x00000000300ca000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x000000005148b000ULL, - -1ULL, - 0x00000000300cb000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1, - { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffff000ULL, - 0ULL, - 0x00000000780ff000ULL, - 0ULL, - 0ULL - }, - { - 0x000000005148c000ULL, - -1ULL, - 0x00000000300cc000ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051500000ULL, - 0x286e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040800000ULL, - 0x1908000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000514c0000ULL, - 0x286c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051540000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051580000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000515c0000ULL, - 0x2870000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040900000ULL, - 0x1910000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051600000ULL, - 0x2872000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051640000ULL, - 0x2874000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051680000ULL, - 0x2876000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040a00000ULL, - 0x1918000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000516c0000ULL, - 0x2878000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040b00000ULL, - 0x1920000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051700000ULL, - 0x287a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052880000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052840000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051780000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051740000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051880000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000517c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052900000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000528c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051840000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051800000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000518c0000ULL, - 0x287c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051900000ULL, - 0x287e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051940000ULL, - 0x2880000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040c00000ULL, - 0x1928000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051980000ULL, - 0x2882000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040d00000ULL, - 0x1930000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000519c0000ULL, - 0x2884000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051a00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051a80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051a40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051ac0000ULL, - 0x2886000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051b00000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051b40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051b80000ULL, - 0x2888000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000601c0000ULL, - 0x300e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051bc0000ULL, - 0x288a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060200000ULL, - 0x3010000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051c00000ULL, - 0x288c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060240000ULL, - 0x3012000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051c80000ULL, - 0x2890000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051c40000ULL, - 0x288e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051d00000ULL, - 0x2894000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040e00000ULL, - 0x1938000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051cc0000ULL, - 0x2892000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051d40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051d80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051dc0000ULL, - 0x2896000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000040f00000ULL, - 0x1940000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051e00000ULL, - 0x2898000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051e40000ULL, - 0x289a000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051e80000ULL, - 0x289c000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041000000ULL, - 0x1948000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051ec0000ULL, - 0x289e000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041100000ULL, - 0x1950000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051f00000ULL, - 0x28a0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051f80000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051f40000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000051fc0000ULL, - 0x28a2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052000000ULL, - 0x28a4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052040000ULL, - 0x28a6000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041200000ULL, - 0x1958000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052080000ULL, - 0x28a8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041300000ULL, - 0x1960000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000520c0000ULL, - 0x28aa000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052100000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052140000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052180000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000521c0000ULL, - 0x28ac000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052200000ULL, - 0x28ae000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052240000ULL, - 0x28b0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052280000ULL, - 0x28b2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000522c0000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1, - { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052300000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052340000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052380000ULL, - -1ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052400000ULL, - 0x28b6000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060280000ULL, - 0x3014000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000523c0000ULL, - 0x28b4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052440000ULL, - 0x28b8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000602c0000ULL, - 0x3016000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052480000ULL, - 0x28ba000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000060300000ULL, - 0x3018000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052500000ULL, - 0x28be000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000524c0000ULL, - 0x28bc000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052580000ULL, - 0x28c2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052540000ULL, - 0x28c0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000525c0000ULL, - 0x28c4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052600000ULL, - 0x28c6000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052640000ULL, - 0x28c8000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000526c0000ULL, - 0x28cc000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052680000ULL, - 0x28ca000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052700000ULL, - 0x28ce000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052740000ULL, - 0x28d0000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x00000000527c0000ULL, - 0x28d4000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000052780000ULL, - 0x28d2000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1, - { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0ULL, - 0xfffff80000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - -1ULL, - 0x286b300000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1, - { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ffc0000ULL, - 0xfffe000000000000ULL, - 0x00000000780c0000ULL, - 0x3c06000000000000ULL, - 0ULL - }, - { - 0x0000000052800000ULL, - 0x28d6000000000000ULL, - 0x00000000500c0000ULL, - 0x2c06000000000000ULL, - -1ULL - } -#endif - }, - { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1, - { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, -#ifndef DISASM_ONLY - { - 0xc00000007ff00000ULL, - 0xfff8000000000000ULL, - 0ULL, - 0ULL, - 0ULL - }, - { - 0x0000000041400000ULL, - 0x1968000000000000ULL, - -1ULL, - -1ULL, - -1ULL - } -#endif - }, - { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } }, -#ifndef DISASM_ONLY - { 0, }, { 0, } -#endif - } -}; - -#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6)) -#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index)) - -static const unsigned short decode_X0_fsm[936] = -{ - BITFIELD(22, 9) /* index 0 */, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS, - TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU, - TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS, - TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM, - TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578), - CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671), - CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865), - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), - BITFIELD(6, 2) /* index 513 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), - BITFIELD(8, 2) /* index 518 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), - BITFIELD(10, 2) /* index 523 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, - BITFIELD(20, 2) /* index 528 */, - TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), - BITFIELD(6, 2) /* index 533 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), - BITFIELD(8, 2) /* index 538 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), - BITFIELD(10, 2) /* index 543 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(0, 2) /* index 548 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), - BITFIELD(2, 2) /* index 553 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), - BITFIELD(4, 2) /* index 558 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), - BITFIELD(6, 2) /* index 563 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), - BITFIELD(8, 2) /* index 568 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), - BITFIELD(10, 2) /* index 573 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(20, 2) /* index 578 */, - TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI, - BITFIELD(20, 2) /* index 583 */, - TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI, - TILEGX_OPC_V1CMPLTUI, - BITFIELD(20, 2) /* index 588 */, - TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI, - TILEGX_OPC_V2CMPEQI, - BITFIELD(20, 2) /* index 593 */, - TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI, - TILEGX_OPC_V2MINSI, - BITFIELD(20, 2) /* index 598 */, - TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(18, 4) /* index 603 */, - TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, - TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR, - BITFIELD(18, 4) /* index 620 */, - TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL, - TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2, - TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN, - TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS, - TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1, - TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS, - BITFIELD(18, 4) /* index 637 */, - TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN, - TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2, - TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2, - TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX, - TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS, - TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS, - BITFIELD(18, 4) /* index 654 */, - TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU, - TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS, - TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU, - TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU, - TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU, - TILEGX_OPC_MZ, - BITFIELD(18, 4) /* index 671 */, - TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, - TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES, - TILEGX_OPC_SUBXSC, - BITFIELD(12, 2) /* index 688 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693), - BITFIELD(14, 2) /* index 693 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698), - BITFIELD(16, 2) /* index 698 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(18, 4) /* index 703 */, - TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU, - TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA, - BITFIELD(12, 4) /* index 720 */, - TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757), - CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787), - CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 737 */, - TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 742 */, - TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 747 */, - TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 752 */, - TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 757 */, - TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 762 */, - TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 767 */, - TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 772 */, - TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 777 */, - TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 782 */, - TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 787 */, - TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(16, 2) /* index 792 */, - TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(18, 4) /* index 797 */, - TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP, - TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU, - TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS, - TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU, - TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, - BITFIELD(18, 4) /* index 814 */, - TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, - TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS, - TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, - TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE, - TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H, - BITFIELD(18, 4) /* index 831 */, - TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, - TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ, - TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, - TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS, - TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC, - BITFIELD(18, 4) /* index 848 */, - TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC, - TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, - TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, - TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, - TILEGX_OPC_V4SUB, - BITFIELD(18, 3) /* index 865 */, - CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 874 */, - TILEGX_OPC_XOR, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 877 */, - TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 880 */, - TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 883 */, - TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE, - BITFIELD(21, 1) /* index 886 */, - TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE, - BITFIELD(18, 4) /* index 889 */, - TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, - TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, - TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, - TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, - BITFIELD(0, 2) /* index 906 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(911), - BITFIELD(2, 2) /* index 911 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(916), - BITFIELD(4, 2) /* index 916 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(921), - BITFIELD(6, 2) /* index 921 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(926), - BITFIELD(8, 2) /* index 926 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(931), - BITFIELD(10, 2) /* index 931 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - TILEGX_OPC_INFOL, -}; - -static const unsigned short decode_X1_fsm[1266] = -{ - BITFIELD(53, 9) /* index 0 */, - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), - CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, - TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT, - TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT, - TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT, - TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT, - TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST, - TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT, - TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT, - TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT, - TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578), - CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758), - CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, - TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, - CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185), - CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), - CHILD(1236), - BITFIELD(37, 2) /* index 513 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), - BITFIELD(39, 2) /* index 518 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), - BITFIELD(41, 2) /* index 523 */, - TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, - BITFIELD(51, 2) /* index 528 */, - TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), - BITFIELD(37, 2) /* index 533 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), - BITFIELD(39, 2) /* index 538 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), - BITFIELD(41, 2) /* index 543 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(31, 2) /* index 548 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), - BITFIELD(33, 2) /* index 553 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), - BITFIELD(35, 2) /* index 558 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), - BITFIELD(37, 2) /* index 563 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), - BITFIELD(39, 2) /* index 568 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), - BITFIELD(41, 2) /* index 573 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(51, 2) /* index 578 */, - TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583), - BITFIELD(31, 2) /* index 583 */, - TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588), - BITFIELD(33, 2) /* index 588 */, - TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593), - BITFIELD(35, 2) /* index 593 */, - TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, - TILEGX_OPC_PREFETCH_ADD_L1_FAULT, - BITFIELD(51, 2) /* index 598 */, - CHILD(603), CHILD(618), CHILD(633), CHILD(648), - BITFIELD(31, 2) /* index 603 */, - TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608), - BITFIELD(33, 2) /* index 608 */, - TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613), - BITFIELD(35, 2) /* index 613 */, - TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, - TILEGX_OPC_PREFETCH_ADD_L1, - BITFIELD(31, 2) /* index 618 */, - TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623), - BITFIELD(33, 2) /* index 623 */, - TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628), - BITFIELD(35, 2) /* index 628 */, - TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, - TILEGX_OPC_PREFETCH_ADD_L2_FAULT, - BITFIELD(31, 2) /* index 633 */, - TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638), - BITFIELD(33, 2) /* index 638 */, - TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643), - BITFIELD(35, 2) /* index 643 */, - TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, - TILEGX_OPC_PREFETCH_ADD_L2, - BITFIELD(31, 2) /* index 648 */, - CHILD(653), CHILD(653), CHILD(653), CHILD(673), - BITFIELD(43, 2) /* index 653 */, - CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - BITFIELD(45, 2) /* index 658 */, - CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - BITFIELD(47, 2) /* index 663 */, - CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - BITFIELD(49, 2) /* index 668 */, - TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, - TILEGX_OPC_LD4S_ADD, - BITFIELD(33, 2) /* index 673 */, - CHILD(653), CHILD(653), CHILD(653), CHILD(678), - BITFIELD(35, 2) /* index 678 */, - CHILD(653), CHILD(653), CHILD(653), CHILD(683), - BITFIELD(43, 2) /* index 683 */, - CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(45, 2) /* index 688 */, - CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(47, 2) /* index 693 */, - CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(49, 2) /* index 698 */, - TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, - BITFIELD(51, 2) /* index 703 */, - CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD, - TILEGX_OPC_LDNT2S_ADD, - BITFIELD(31, 2) /* index 708 */, - TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713), - BITFIELD(33, 2) /* index 713 */, - TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718), - BITFIELD(35, 2) /* index 718 */, - TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, - TILEGX_OPC_PREFETCH_ADD_L3, - BITFIELD(51, 2) /* index 723 */, - TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD, - TILEGX_OPC_LDNT_ADD, - BITFIELD(51, 2) /* index 728 */, - CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR, - BITFIELD(43, 2) /* index 733 */, - CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(45, 2) /* index 738 */, - CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(47, 2) /* index 743 */, - CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(49, 2) /* index 748 */, - TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, - BITFIELD(51, 2) /* index 753 */, - TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD, - BITFIELD(51, 2) /* index 758 */, - TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD, - TILEGX_OPC_STNT_ADD, - BITFIELD(51, 2) /* index 763 */, - TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, - TILEGX_OPC_V1CMPLTSI, - BITFIELD(51, 2) /* index 768 */, - TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, - TILEGX_OPC_V2ADDI, - BITFIELD(51, 2) /* index 773 */, - TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, - TILEGX_OPC_V2MAXSI, - BITFIELD(51, 2) /* index 778 */, - TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(49, 4) /* index 783 */, - TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, - TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4, - TILEGX_OPC_DBLALIGN6, - BITFIELD(49, 4) /* index 800 */, - TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4, - TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD, - TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4, - TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR, - CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, - BITFIELD(43, 2) /* index 817 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822), - BITFIELD(45, 2) /* index 822 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827), - BITFIELD(47, 2) /* index 827 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(49, 4) /* index 832 */, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, - TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1, - TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2, - TILEGX_OPC_STNT4, - BITFIELD(46, 7) /* index 849 */, - TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, - TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, - TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, - TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC, - TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, - TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX, - TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, - TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, - TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, - TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987), - CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, - TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, - TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, - TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, - TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, - TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, - TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, - TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, - TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, - TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, - TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, - TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, - TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, - TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, - TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, - BITFIELD(43, 3) /* index 978 */, - TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV, - TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH, - BITFIELD(43, 3) /* index 987 */, - CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP, - TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051), - BITFIELD(31, 2) /* index 996 */, - CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(33, 2) /* index 1001 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006), - BITFIELD(35, 2) /* index 1006 */, - TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(37, 2) /* index 1011 */, - TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(39, 2) /* index 1016 */, - TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(41, 2) /* index 1021 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL, - BITFIELD(33, 2) /* index 1026 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031), - BITFIELD(35, 2) /* index 1031 */, - TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(37, 2) /* index 1036 */, - TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(39, 2) /* index 1041 */, - TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL, - BITFIELD(41, 2) /* index 1046 */, - TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL, - BITFIELD(31, 2) /* index 1051 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056), - BITFIELD(33, 2) /* index 1056 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061), - BITFIELD(35, 2) /* index 1061 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, - TILEGX_OPC_PREFETCH_L1_FAULT, - BITFIELD(43, 3) /* index 1066 */, - CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135), - TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U, - BITFIELD(31, 2) /* index 1075 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080), - BITFIELD(33, 2) /* index 1080 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085), - BITFIELD(35, 2) /* index 1085 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, - BITFIELD(31, 2) /* index 1090 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095), - BITFIELD(33, 2) /* index 1095 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100), - BITFIELD(35, 2) /* index 1100 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, - TILEGX_OPC_PREFETCH_L2_FAULT, - BITFIELD(31, 2) /* index 1105 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110), - BITFIELD(33, 2) /* index 1110 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115), - BITFIELD(35, 2) /* index 1115 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, - BITFIELD(31, 2) /* index 1120 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125), - BITFIELD(33, 2) /* index 1125 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130), - BITFIELD(35, 2) /* index 1130 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, - TILEGX_OPC_PREFETCH_L3_FAULT, - BITFIELD(31, 2) /* index 1135 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140), - BITFIELD(33, 2) /* index 1140 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145), - BITFIELD(35, 2) /* index 1145 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, - BITFIELD(43, 3) /* index 1150 */, - TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U, - TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF, - BITFIELD(43, 3) /* index 1159 */, - TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1, - TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE, - BITFIELD(49, 4) /* index 1168 */, - TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ, - TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, - TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ, - TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS, - TILEGX_OPC_V2CMPLTU, - BITFIELD(49, 4) /* index 1185 */, - TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L, - TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ, - TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, - TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, - TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB, - BITFIELD(49, 4) /* index 1202 */, - TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, - TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, - TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, - TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(49, 4) /* index 1219 */, - TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, - TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, - TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, - TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, - BITFIELD(31, 2) /* index 1236 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1241), - BITFIELD(33, 2) /* index 1241 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1246), - BITFIELD(35, 2) /* index 1246 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1251), - BITFIELD(37, 2) /* index 1251 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1256), - BITFIELD(39, 2) /* index 1256 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - CHILD(1261), - BITFIELD(41, 2) /* index 1261 */, - TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, - TILEGX_OPC_INFOL, -}; - -static const unsigned short decode_Y0_fsm[178] = -{ - BITFIELD(27, 4) /* index 0 */, - CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, - TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123), - CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168), - CHILD(173), - BITFIELD(6, 2) /* index 17 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), - BITFIELD(8, 2) /* index 22 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), - BITFIELD(10, 2) /* index 27 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(0, 2) /* index 32 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), - BITFIELD(2, 2) /* index 37 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), - BITFIELD(4, 2) /* index 42 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), - BITFIELD(6, 2) /* index 47 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), - BITFIELD(8, 2) /* index 52 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), - BITFIELD(10, 2) /* index 57 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(18, 2) /* index 62 */, - TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, - BITFIELD(15, 5) /* index 67 */, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100), - CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(12, 3) /* index 100 */, - TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP, - TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT, - TILEGX_OPC_REVBITS, - BITFIELD(12, 3) /* index 109 */, - TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1, - TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - TILEGX_OPC_NONE, - BITFIELD(18, 2) /* index 118 */, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - BITFIELD(18, 2) /* index 123 */, - TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX, - BITFIELD(18, 2) /* index 128 */, - TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, - BITFIELD(18, 2) /* index 133 */, - TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR, - BITFIELD(12, 2) /* index 138 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143), - BITFIELD(14, 2) /* index 143 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148), - BITFIELD(16, 2) /* index 148 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(18, 2) /* index 153 */, - TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, - BITFIELD(18, 2) /* index 158 */, - TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, - TILEGX_OPC_SHL3ADDX, - BITFIELD(18, 2) /* index 163 */, - TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS, - TILEGX_OPC_MUL_LU_LU, - BITFIELD(18, 2) /* index 168 */, - TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS, - TILEGX_OPC_MULA_LU_LU, - BITFIELD(18, 2) /* index 173 */, - TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, -}; - -static const unsigned short decode_Y1_fsm[167] = -{ - BITFIELD(58, 4) /* index 0 */, - TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, - TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122), - CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE, - BITFIELD(37, 2) /* index 17 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), - BITFIELD(39, 2) /* index 22 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), - BITFIELD(41, 2) /* index 27 */, - TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, - BITFIELD(31, 2) /* index 32 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), - BITFIELD(33, 2) /* index 37 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), - BITFIELD(35, 2) /* index 42 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), - BITFIELD(37, 2) /* index 47 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), - BITFIELD(39, 2) /* index 52 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), - BITFIELD(41, 2) /* index 57 */, - TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, - BITFIELD(49, 2) /* index 62 */, - TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, - BITFIELD(47, 4) /* index 67 */, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, - TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, - TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, - TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84), - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, - BITFIELD(43, 3) /* index 84 */, - CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108), - CHILD(111), CHILD(114), - BITFIELD(46, 1) /* index 93 */, - TILEGX_OPC_NONE, TILEGX_OPC_FNOP, - BITFIELD(46, 1) /* index 96 */, - TILEGX_OPC_NONE, TILEGX_OPC_ILL, - BITFIELD(46, 1) /* index 99 */, - TILEGX_OPC_NONE, TILEGX_OPC_JALRP, - BITFIELD(46, 1) /* index 102 */, - TILEGX_OPC_NONE, TILEGX_OPC_JALR, - BITFIELD(46, 1) /* index 105 */, - TILEGX_OPC_NONE, TILEGX_OPC_JRP, - BITFIELD(46, 1) /* index 108 */, - TILEGX_OPC_NONE, TILEGX_OPC_JR, - BITFIELD(46, 1) /* index 111 */, - TILEGX_OPC_NONE, TILEGX_OPC_LNK, - BITFIELD(46, 1) /* index 114 */, - TILEGX_OPC_NONE, TILEGX_OPC_NOP, - BITFIELD(49, 2) /* index 117 */, - TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, - BITFIELD(49, 2) /* index 122 */, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, - BITFIELD(49, 2) /* index 127 */, - TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, - BITFIELD(49, 2) /* index 132 */, - TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR, - BITFIELD(43, 2) /* index 137 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142), - BITFIELD(45, 2) /* index 142 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147), - BITFIELD(47, 2) /* index 147 */, - TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, - BITFIELD(49, 2) /* index 152 */, - TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, - BITFIELD(49, 2) /* index 157 */, - TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, - TILEGX_OPC_SHL3ADDX, - BITFIELD(49, 2) /* index 162 */, - TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, -}; - -static const unsigned short decode_Y2_fsm[118] = -{ - BITFIELD(62, 2) /* index 0 */, - TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109), - BITFIELD(55, 3) /* index 5 */, - CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40), - CHILD(43), - BITFIELD(26, 1) /* index 14 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1U, - BITFIELD(26, 1) /* index 17 */, - CHILD(20), CHILD(30), - BITFIELD(51, 2) /* index 20 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25), - BITFIELD(53, 2) /* index 25 */, - TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, - TILEGX_OPC_PREFETCH_L1_FAULT, - BITFIELD(51, 2) /* index 30 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35), - BITFIELD(53, 2) /* index 35 */, - TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, - BITFIELD(26, 1) /* index 40 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2U, - BITFIELD(26, 1) /* index 43 */, - CHILD(46), CHILD(56), - BITFIELD(51, 2) /* index 46 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51), - BITFIELD(53, 2) /* index 51 */, - TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, - TILEGX_OPC_PREFETCH_L2_FAULT, - BITFIELD(51, 2) /* index 56 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61), - BITFIELD(53, 2) /* index 61 */, - TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, - BITFIELD(56, 2) /* index 66 */, - CHILD(71), CHILD(74), CHILD(90), CHILD(93), - BITFIELD(26, 1) /* index 71 */, - TILEGX_OPC_NONE, TILEGX_OPC_LD4S, - BITFIELD(26, 1) /* index 74 */, - TILEGX_OPC_NONE, CHILD(77), - BITFIELD(51, 2) /* index 77 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82), - BITFIELD(53, 2) /* index 82 */, - TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87), - BITFIELD(55, 1) /* index 87 */, - TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT, - BITFIELD(26, 1) /* index 90 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD, - BITFIELD(26, 1) /* index 93 */, - CHILD(96), TILEGX_OPC_LD, - BITFIELD(51, 2) /* index 96 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101), - BITFIELD(53, 2) /* index 101 */, - TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106), - BITFIELD(55, 1) /* index 106 */, - TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, - BITFIELD(26, 1) /* index 109 */, - CHILD(112), CHILD(115), - BITFIELD(57, 1) /* index 112 */, - TILEGX_OPC_ST1, TILEGX_OPC_ST4, - BITFIELD(57, 1) /* index 115 */, - TILEGX_OPC_ST2, TILEGX_OPC_ST, -}; - -#undef BITFIELD -#undef CHILD - -const unsigned short * const -tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] = -{ - decode_X0_fsm, - decode_X1_fsm, - decode_Y0_fsm, - decode_Y1_fsm, - decode_Y2_fsm -}; - -const struct tilegx_operand tilegx_operands[35] = -{ - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0), - 8, 1, 0, 0, 0, 0, - create_Imm8_X0, get_Imm8_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1), - 8, 1, 0, 0, 0, 0, - create_Imm8_X1, get_Imm8_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0), - 8, 1, 0, 0, 0, 0, - create_Imm8_Y0, get_Imm8_Y0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1), - 8, 1, 0, 0, 0, 0, - create_Imm8_Y1, get_Imm8_Y1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST), - 16, 1, 0, 0, 0, 0, - create_Imm16_X0, get_Imm16_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST), - 16, 1, 0, 0, 0, 0, - create_Imm16_X1, get_Imm16_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_X1, get_Dest_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_X1, get_SrcA_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_X0, get_Dest_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_X0, get_SrcA_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_Y0, get_Dest_Y0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_Y0, get_SrcA_Y0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_Dest_Y1, get_Dest_Y1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_Y1, get_SrcA_Y1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcA_Y2, get_SrcA_Y2 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 1, 0, 0, - create_SrcA_X1, get_SrcA_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_X0, get_SrcB_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_X1, get_SrcB_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_Y0, get_SrcB_Y0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcB_Y1, get_SrcB_Y1 - }, - { - TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1), - 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, - create_BrOff_X1, get_BrOff_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0), - 6, 0, 0, 0, 0, 0, - create_BFStart_X0, get_BFStart_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0), - 6, 0, 0, 0, 0, 0, - create_BFEnd_X0, get_BFEnd_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 1, 0, 0, - create_Dest_X0, get_Dest_X0 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 1, 0, 0, - create_Dest_Y0, get_Dest_Y0 - }, - { - TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1), - 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, - create_JumpOff_X1, get_JumpOff_X1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 0, 1, 0, 0, - create_SrcBDest_Y2, get_SrcBDest_Y2 - }, - { - TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1), - 14, 0, 0, 0, 0, 0, - create_MF_Imm14_X1, get_MF_Imm14_X1 - }, - { - TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1), - 14, 0, 0, 0, 0, 0, - create_MT_Imm14_X1, get_MT_Imm14_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0), - 6, 0, 0, 0, 0, 0, - create_ShAmt_X0, get_ShAmt_X0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1), - 6, 0, 0, 0, 0, 0, - create_ShAmt_X1, get_ShAmt_X1 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0), - 6, 0, 0, 0, 0, 0, - create_ShAmt_Y0, get_ShAmt_Y0 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1), - 6, 0, 0, 0, 0, 0, - create_ShAmt_Y1, get_ShAmt_Y1 - }, - { - TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), - 6, 0, 1, 0, 0, 0, - create_SrcBDest_Y2, get_SrcBDest_Y2 - }, - { - TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1), - 8, 1, 0, 0, 0, 0, - create_Dest_Imm8_X1, get_Dest_Imm8_X1 - } -}; - -/* Given a set of bundle bits and a specific pipe, returns which - * instruction the bundle contains in that pipe. - */ -const struct tilegx_opcode * -find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe) -{ - const unsigned short *table = tilegx_bundle_decoder_fsms[pipe]; - int index = 0; - - while (1) - { - unsigned short bitspec = table[index]; - unsigned int bitfield = - ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6); - - unsigned short next = table[index + 1 + bitfield]; - if (next <= TILEGX_OPC_NONE) - return &tilegx_opcodes[next]; - - index = next - TILEGX_OPC_NONE; - } -} - -int -parse_insn_tilegx(tilegx_bundle_bits bits, - unsigned long long pc, - struct tilegx_decoded_instruction - decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]) -{ - int num_instructions = 0; - int pipe; - - int min_pipe, max_pipe; - if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0) - { - min_pipe = TILEGX_PIPELINE_X0; - max_pipe = TILEGX_PIPELINE_X1; - } - else - { - min_pipe = TILEGX_PIPELINE_Y0; - max_pipe = TILEGX_PIPELINE_Y2; - } - - /* For each pipe, find an instruction that fits. */ - for (pipe = min_pipe; pipe <= max_pipe; pipe++) - { - const struct tilegx_opcode *opc; - struct tilegx_decoded_instruction *d; - int i; - - d = &decoded[num_instructions++]; - opc = find_opcode (bits, (tilegx_pipeline)pipe); - d->opcode = opc; - - /* Decode each operand, sign extending, etc. as appropriate. */ - for (i = 0; i < opc->num_operands; i++) - { - const struct tilegx_operand *op = - &tilegx_operands[opc->operands[pipe][i]]; - int raw_opval = op->extract (bits); - long long opval; - - if (op->is_signed) - { - /* Sign-extend the operand. */ - int shift = (int)((sizeof(int) * 8) - op->num_bits); - raw_opval = (raw_opval << shift) >> shift; - } - - /* Adjust PC-relative scaled branch offsets. */ - if (op->type == TILEGX_OP_TYPE_ADDRESS) - opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc; - else - opval = raw_opval; - - /* Record the final value. */ - d->operands[i] = op; - d->operand_values[i] = opval; - } - } - - return num_instructions; -} - -struct tilegx_spr -{ - /* The number */ - int number; - - /* The name */ - const char *name; -}; - -static int -tilegx_spr_compare (const void *a_ptr, const void *b_ptr) -{ - const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr; - const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr; - return (a->number - b->number); -} - -const struct tilegx_spr tilegx_sprs[] = { - { 0, "MPL_MEM_ERROR_SET_0" }, - { 1, "MPL_MEM_ERROR_SET_1" }, - { 2, "MPL_MEM_ERROR_SET_2" }, - { 3, "MPL_MEM_ERROR_SET_3" }, - { 4, "MPL_MEM_ERROR" }, - { 5, "MEM_ERROR_CBOX_ADDR" }, - { 6, "MEM_ERROR_CBOX_STATUS" }, - { 7, "MEM_ERROR_ENABLE" }, - { 8, "MEM_ERROR_MBOX_ADDR" }, - { 9, "MEM_ERROR_MBOX_STATUS" }, - { 10, "SBOX_ERROR" }, - { 11, "XDN_DEMUX_ERROR" }, - { 256, "MPL_SINGLE_STEP_3_SET_0" }, - { 257, "MPL_SINGLE_STEP_3_SET_1" }, - { 258, "MPL_SINGLE_STEP_3_SET_2" }, - { 259, "MPL_SINGLE_STEP_3_SET_3" }, - { 260, "MPL_SINGLE_STEP_3" }, - { 261, "SINGLE_STEP_CONTROL_3" }, - { 512, "MPL_SINGLE_STEP_2_SET_0" }, - { 513, "MPL_SINGLE_STEP_2_SET_1" }, - { 514, "MPL_SINGLE_STEP_2_SET_2" }, - { 515, "MPL_SINGLE_STEP_2_SET_3" }, - { 516, "MPL_SINGLE_STEP_2" }, - { 517, "SINGLE_STEP_CONTROL_2" }, - { 768, "MPL_SINGLE_STEP_1_SET_0" }, - { 769, "MPL_SINGLE_STEP_1_SET_1" }, - { 770, "MPL_SINGLE_STEP_1_SET_2" }, - { 771, "MPL_SINGLE_STEP_1_SET_3" }, - { 772, "MPL_SINGLE_STEP_1" }, - { 773, "SINGLE_STEP_CONTROL_1" }, - { 1024, "MPL_SINGLE_STEP_0_SET_0" }, - { 1025, "MPL_SINGLE_STEP_0_SET_1" }, - { 1026, "MPL_SINGLE_STEP_0_SET_2" }, - { 1027, "MPL_SINGLE_STEP_0_SET_3" }, - { 1028, "MPL_SINGLE_STEP_0" }, - { 1029, "SINGLE_STEP_CONTROL_0" }, - { 1280, "MPL_IDN_COMPLETE_SET_0" }, - { 1281, "MPL_IDN_COMPLETE_SET_1" }, - { 1282, "MPL_IDN_COMPLETE_SET_2" }, - { 1283, "MPL_IDN_COMPLETE_SET_3" }, - { 1284, "MPL_IDN_COMPLETE" }, - { 1285, "IDN_COMPLETE_PENDING" }, - { 1536, "MPL_UDN_COMPLETE_SET_0" }, - { 1537, "MPL_UDN_COMPLETE_SET_1" }, - { 1538, "MPL_UDN_COMPLETE_SET_2" }, - { 1539, "MPL_UDN_COMPLETE_SET_3" }, - { 1540, "MPL_UDN_COMPLETE" }, - { 1541, "UDN_COMPLETE_PENDING" }, - { 1792, "MPL_ITLB_MISS_SET_0" }, - { 1793, "MPL_ITLB_MISS_SET_1" }, - { 1794, "MPL_ITLB_MISS_SET_2" }, - { 1795, "MPL_ITLB_MISS_SET_3" }, - { 1796, "MPL_ITLB_MISS" }, - { 1797, "ITLB_TSB_BASE_ADDR_0" }, - { 1798, "ITLB_TSB_BASE_ADDR_1" }, - { 1920, "ITLB_CURRENT_ATTR" }, - { 1921, "ITLB_CURRENT_PA" }, - { 1922, "ITLB_CURRENT_VA" }, - { 1923, "ITLB_INDEX" }, - { 1924, "ITLB_MATCH_0" }, - { 1925, "ITLB_PERF" }, - { 1926, "ITLB_PR" }, - { 1927, "ITLB_TSB_ADDR_0" }, - { 1928, "ITLB_TSB_ADDR_1" }, - { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" }, - { 1930, "ITLB_TSB_FILL_MATCH" }, - { 1931, "NUMBER_ITLB" }, - { 1932, "REPLACEMENT_ITLB" }, - { 1933, "WIRED_ITLB" }, - { 2048, "MPL_ILL_SET_0" }, - { 2049, "MPL_ILL_SET_1" }, - { 2050, "MPL_ILL_SET_2" }, - { 2051, "MPL_ILL_SET_3" }, - { 2052, "MPL_ILL" }, - { 2304, "MPL_GPV_SET_0" }, - { 2305, "MPL_GPV_SET_1" }, - { 2306, "MPL_GPV_SET_2" }, - { 2307, "MPL_GPV_SET_3" }, - { 2308, "MPL_GPV" }, - { 2309, "GPV_REASON" }, - { 2560, "MPL_IDN_ACCESS_SET_0" }, - { 2561, "MPL_IDN_ACCESS_SET_1" }, - { 2562, "MPL_IDN_ACCESS_SET_2" }, - { 2563, "MPL_IDN_ACCESS_SET_3" }, - { 2564, "MPL_IDN_ACCESS" }, - { 2565, "IDN_DEMUX_COUNT_0" }, - { 2566, "IDN_DEMUX_COUNT_1" }, - { 2567, "IDN_FLUSH_EGRESS" }, - { 2568, "IDN_PENDING" }, - { 2569, "IDN_ROUTE_ORDER" }, - { 2570, "IDN_SP_FIFO_CNT" }, - { 2688, "IDN_DATA_AVAIL" }, - { 2816, "MPL_UDN_ACCESS_SET_0" }, - { 2817, "MPL_UDN_ACCESS_SET_1" }, - { 2818, "MPL_UDN_ACCESS_SET_2" }, - { 2819, "MPL_UDN_ACCESS_SET_3" }, - { 2820, "MPL_UDN_ACCESS" }, - { 2821, "UDN_DEMUX_COUNT_0" }, - { 2822, "UDN_DEMUX_COUNT_1" }, - { 2823, "UDN_DEMUX_COUNT_2" }, - { 2824, "UDN_DEMUX_COUNT_3" }, - { 2825, "UDN_FLUSH_EGRESS" }, - { 2826, "UDN_PENDING" }, - { 2827, "UDN_ROUTE_ORDER" }, - { 2828, "UDN_SP_FIFO_CNT" }, - { 2944, "UDN_DATA_AVAIL" }, - { 3072, "MPL_SWINT_3_SET_0" }, - { 3073, "MPL_SWINT_3_SET_1" }, - { 3074, "MPL_SWINT_3_SET_2" }, - { 3075, "MPL_SWINT_3_SET_3" }, - { 3076, "MPL_SWINT_3" }, - { 3328, "MPL_SWINT_2_SET_0" }, - { 3329, "MPL_SWINT_2_SET_1" }, - { 3330, "MPL_SWINT_2_SET_2" }, - { 3331, "MPL_SWINT_2_SET_3" }, - { 3332, "MPL_SWINT_2" }, - { 3584, "MPL_SWINT_1_SET_0" }, - { 3585, "MPL_SWINT_1_SET_1" }, - { 3586, "MPL_SWINT_1_SET_2" }, - { 3587, "MPL_SWINT_1_SET_3" }, - { 3588, "MPL_SWINT_1" }, - { 3840, "MPL_SWINT_0_SET_0" }, - { 3841, "MPL_SWINT_0_SET_1" }, - { 3842, "MPL_SWINT_0_SET_2" }, - { 3843, "MPL_SWINT_0_SET_3" }, - { 3844, "MPL_SWINT_0" }, - { 4096, "MPL_ILL_TRANS_SET_0" }, - { 4097, "MPL_ILL_TRANS_SET_1" }, - { 4098, "MPL_ILL_TRANS_SET_2" }, - { 4099, "MPL_ILL_TRANS_SET_3" }, - { 4100, "MPL_ILL_TRANS" }, - { 4101, "ILL_TRANS_REASON" }, - { 4102, "ILL_VA_PC" }, - { 4352, "MPL_UNALIGN_DATA_SET_0" }, - { 4353, "MPL_UNALIGN_DATA_SET_1" }, - { 4354, "MPL_UNALIGN_DATA_SET_2" }, - { 4355, "MPL_UNALIGN_DATA_SET_3" }, - { 4356, "MPL_UNALIGN_DATA" }, - { 4608, "MPL_DTLB_MISS_SET_0" }, - { 4609, "MPL_DTLB_MISS_SET_1" }, - { 4610, "MPL_DTLB_MISS_SET_2" }, - { 4611, "MPL_DTLB_MISS_SET_3" }, - { 4612, "MPL_DTLB_MISS" }, - { 4613, "DTLB_TSB_BASE_ADDR_0" }, - { 4614, "DTLB_TSB_BASE_ADDR_1" }, - { 4736, "AAR" }, - { 4737, "CACHE_PINNED_WAYS" }, - { 4738, "DTLB_BAD_ADDR" }, - { 4739, "DTLB_BAD_ADDR_REASON" }, - { 4740, "DTLB_CURRENT_ATTR" }, - { 4741, "DTLB_CURRENT_PA" }, - { 4742, "DTLB_CURRENT_VA" }, - { 4743, "DTLB_INDEX" }, - { 4744, "DTLB_MATCH_0" }, - { 4745, "DTLB_PERF" }, - { 4746, "DTLB_TSB_ADDR_0" }, - { 4747, "DTLB_TSB_ADDR_1" }, - { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" }, - { 4749, "DTLB_TSB_FILL_MATCH" }, - { 4750, "NUMBER_DTLB" }, - { 4751, "REPLACEMENT_DTLB" }, - { 4752, "WIRED_DTLB" }, - { 4864, "MPL_DTLB_ACCESS_SET_0" }, - { 4865, "MPL_DTLB_ACCESS_SET_1" }, - { 4866, "MPL_DTLB_ACCESS_SET_2" }, - { 4867, "MPL_DTLB_ACCESS_SET_3" }, - { 4868, "MPL_DTLB_ACCESS" }, - { 5120, "MPL_IDN_FIREWALL_SET_0" }, - { 5121, "MPL_IDN_FIREWALL_SET_1" }, - { 5122, "MPL_IDN_FIREWALL_SET_2" }, - { 5123, "MPL_IDN_FIREWALL_SET_3" }, - { 5124, "MPL_IDN_FIREWALL" }, - { 5125, "IDN_DIRECTION_PROTECT" }, - { 5376, "MPL_UDN_FIREWALL_SET_0" }, - { 5377, "MPL_UDN_FIREWALL_SET_1" }, - { 5378, "MPL_UDN_FIREWALL_SET_2" }, - { 5379, "MPL_UDN_FIREWALL_SET_3" }, - { 5380, "MPL_UDN_FIREWALL" }, - { 5381, "UDN_DIRECTION_PROTECT" }, - { 5632, "MPL_TILE_TIMER_SET_0" }, - { 5633, "MPL_TILE_TIMER_SET_1" }, - { 5634, "MPL_TILE_TIMER_SET_2" }, - { 5635, "MPL_TILE_TIMER_SET_3" }, - { 5636, "MPL_TILE_TIMER" }, - { 5637, "TILE_TIMER_CONTROL" }, - { 5888, "MPL_AUX_TILE_TIMER_SET_0" }, - { 5889, "MPL_AUX_TILE_TIMER_SET_1" }, - { 5890, "MPL_AUX_TILE_TIMER_SET_2" }, - { 5891, "MPL_AUX_TILE_TIMER_SET_3" }, - { 5892, "MPL_AUX_TILE_TIMER" }, - { 5893, "AUX_TILE_TIMER_CONTROL" }, - { 6144, "MPL_IDN_TIMER_SET_0" }, - { 6145, "MPL_IDN_TIMER_SET_1" }, - { 6146, "MPL_IDN_TIMER_SET_2" }, - { 6147, "MPL_IDN_TIMER_SET_3" }, - { 6148, "MPL_IDN_TIMER" }, - { 6149, "IDN_DEADLOCK_COUNT" }, - { 6150, "IDN_DEADLOCK_TIMEOUT" }, - { 6400, "MPL_UDN_TIMER_SET_0" }, - { 6401, "MPL_UDN_TIMER_SET_1" }, - { 6402, "MPL_UDN_TIMER_SET_2" }, - { 6403, "MPL_UDN_TIMER_SET_3" }, - { 6404, "MPL_UDN_TIMER" }, - { 6405, "UDN_DEADLOCK_COUNT" }, - { 6406, "UDN_DEADLOCK_TIMEOUT" }, - { 6656, "MPL_IDN_AVAIL_SET_0" }, - { 6657, "MPL_IDN_AVAIL_SET_1" }, - { 6658, "MPL_IDN_AVAIL_SET_2" }, - { 6659, "MPL_IDN_AVAIL_SET_3" }, - { 6660, "MPL_IDN_AVAIL" }, - { 6661, "IDN_AVAIL_EN" }, - { 6912, "MPL_UDN_AVAIL_SET_0" }, - { 6913, "MPL_UDN_AVAIL_SET_1" }, - { 6914, "MPL_UDN_AVAIL_SET_2" }, - { 6915, "MPL_UDN_AVAIL_SET_3" }, - { 6916, "MPL_UDN_AVAIL" }, - { 6917, "UDN_AVAIL_EN" }, - { 7168, "MPL_IPI_3_SET_0" }, - { 7169, "MPL_IPI_3_SET_1" }, - { 7170, "MPL_IPI_3_SET_2" }, - { 7171, "MPL_IPI_3_SET_3" }, - { 7172, "MPL_IPI_3" }, - { 7173, "IPI_EVENT_3" }, - { 7174, "IPI_EVENT_RESET_3" }, - { 7175, "IPI_EVENT_SET_3" }, - { 7176, "IPI_MASK_3" }, - { 7177, "IPI_MASK_RESET_3" }, - { 7178, "IPI_MASK_SET_3" }, - { 7424, "MPL_IPI_2_SET_0" }, - { 7425, "MPL_IPI_2_SET_1" }, - { 7426, "MPL_IPI_2_SET_2" }, - { 7427, "MPL_IPI_2_SET_3" }, - { 7428, "MPL_IPI_2" }, - { 7429, "IPI_EVENT_2" }, - { 7430, "IPI_EVENT_RESET_2" }, - { 7431, "IPI_EVENT_SET_2" }, - { 7432, "IPI_MASK_2" }, - { 7433, "IPI_MASK_RESET_2" }, - { 7434, "IPI_MASK_SET_2" }, - { 7680, "MPL_IPI_1_SET_0" }, - { 7681, "MPL_IPI_1_SET_1" }, - { 7682, "MPL_IPI_1_SET_2" }, - { 7683, "MPL_IPI_1_SET_3" }, - { 7684, "MPL_IPI_1" }, - { 7685, "IPI_EVENT_1" }, - { 7686, "IPI_EVENT_RESET_1" }, - { 7687, "IPI_EVENT_SET_1" }, - { 7688, "IPI_MASK_1" }, - { 7689, "IPI_MASK_RESET_1" }, - { 7690, "IPI_MASK_SET_1" }, - { 7936, "MPL_IPI_0_SET_0" }, - { 7937, "MPL_IPI_0_SET_1" }, - { 7938, "MPL_IPI_0_SET_2" }, - { 7939, "MPL_IPI_0_SET_3" }, - { 7940, "MPL_IPI_0" }, - { 7941, "IPI_EVENT_0" }, - { 7942, "IPI_EVENT_RESET_0" }, - { 7943, "IPI_EVENT_SET_0" }, - { 7944, "IPI_MASK_0" }, - { 7945, "IPI_MASK_RESET_0" }, - { 7946, "IPI_MASK_SET_0" }, - { 8192, "MPL_PERF_COUNT_SET_0" }, - { 8193, "MPL_PERF_COUNT_SET_1" }, - { 8194, "MPL_PERF_COUNT_SET_2" }, - { 8195, "MPL_PERF_COUNT_SET_3" }, - { 8196, "MPL_PERF_COUNT" }, - { 8197, "PERF_COUNT_0" }, - { 8198, "PERF_COUNT_1" }, - { 8199, "PERF_COUNT_CTL" }, - { 8200, "PERF_COUNT_DN_CTL" }, - { 8201, "PERF_COUNT_STS" }, - { 8202, "WATCH_MASK" }, - { 8203, "WATCH_VAL" }, - { 8448, "MPL_AUX_PERF_COUNT_SET_0" }, - { 8449, "MPL_AUX_PERF_COUNT_SET_1" }, - { 8450, "MPL_AUX_PERF_COUNT_SET_2" }, - { 8451, "MPL_AUX_PERF_COUNT_SET_3" }, - { 8452, "MPL_AUX_PERF_COUNT" }, - { 8453, "AUX_PERF_COUNT_0" }, - { 8454, "AUX_PERF_COUNT_1" }, - { 8455, "AUX_PERF_COUNT_CTL" }, - { 8456, "AUX_PERF_COUNT_STS" }, - { 8704, "MPL_INTCTRL_3_SET_0" }, - { 8705, "MPL_INTCTRL_3_SET_1" }, - { 8706, "MPL_INTCTRL_3_SET_2" }, - { 8707, "MPL_INTCTRL_3_SET_3" }, - { 8708, "MPL_INTCTRL_3" }, - { 8709, "INTCTRL_3_STATUS" }, - { 8710, "INTERRUPT_MASK_3" }, - { 8711, "INTERRUPT_MASK_RESET_3" }, - { 8712, "INTERRUPT_MASK_SET_3" }, - { 8713, "INTERRUPT_VECTOR_BASE_3" }, - { 8714, "SINGLE_STEP_EN_0_3" }, - { 8715, "SINGLE_STEP_EN_1_3" }, - { 8716, "SINGLE_STEP_EN_2_3" }, - { 8717, "SINGLE_STEP_EN_3_3" }, - { 8832, "EX_CONTEXT_3_0" }, - { 8833, "EX_CONTEXT_3_1" }, - { 8834, "SYSTEM_SAVE_3_0" }, - { 8835, "SYSTEM_SAVE_3_1" }, - { 8836, "SYSTEM_SAVE_3_2" }, - { 8837, "SYSTEM_SAVE_3_3" }, - { 8960, "MPL_INTCTRL_2_SET_0" }, - { 8961, "MPL_INTCTRL_2_SET_1" }, - { 8962, "MPL_INTCTRL_2_SET_2" }, - { 8963, "MPL_INTCTRL_2_SET_3" }, - { 8964, "MPL_INTCTRL_2" }, - { 8965, "INTCTRL_2_STATUS" }, - { 8966, "INTERRUPT_MASK_2" }, - { 8967, "INTERRUPT_MASK_RESET_2" }, - { 8968, "INTERRUPT_MASK_SET_2" }, - { 8969, "INTERRUPT_VECTOR_BASE_2" }, - { 8970, "SINGLE_STEP_EN_0_2" }, - { 8971, "SINGLE_STEP_EN_1_2" }, - { 8972, "SINGLE_STEP_EN_2_2" }, - { 8973, "SINGLE_STEP_EN_3_2" }, - { 9088, "EX_CONTEXT_2_0" }, - { 9089, "EX_CONTEXT_2_1" }, - { 9090, "SYSTEM_SAVE_2_0" }, - { 9091, "SYSTEM_SAVE_2_1" }, - { 9092, "SYSTEM_SAVE_2_2" }, - { 9093, "SYSTEM_SAVE_2_3" }, - { 9216, "MPL_INTCTRL_1_SET_0" }, - { 9217, "MPL_INTCTRL_1_SET_1" }, - { 9218, "MPL_INTCTRL_1_SET_2" }, - { 9219, "MPL_INTCTRL_1_SET_3" }, - { 9220, "MPL_INTCTRL_1" }, - { 9221, "INTCTRL_1_STATUS" }, - { 9222, "INTERRUPT_MASK_1" }, - { 9223, "INTERRUPT_MASK_RESET_1" }, - { 9224, "INTERRUPT_MASK_SET_1" }, - { 9225, "INTERRUPT_VECTOR_BASE_1" }, - { 9226, "SINGLE_STEP_EN_0_1" }, - { 9227, "SINGLE_STEP_EN_1_1" }, - { 9228, "SINGLE_STEP_EN_2_1" }, - { 9229, "SINGLE_STEP_EN_3_1" }, - { 9344, "EX_CONTEXT_1_0" }, - { 9345, "EX_CONTEXT_1_1" }, - { 9346, "SYSTEM_SAVE_1_0" }, - { 9347, "SYSTEM_SAVE_1_1" }, - { 9348, "SYSTEM_SAVE_1_2" }, - { 9349, "SYSTEM_SAVE_1_3" }, - { 9472, "MPL_INTCTRL_0_SET_0" }, - { 9473, "MPL_INTCTRL_0_SET_1" }, - { 9474, "MPL_INTCTRL_0_SET_2" }, - { 9475, "MPL_INTCTRL_0_SET_3" }, - { 9476, "MPL_INTCTRL_0" }, - { 9477, "INTCTRL_0_STATUS" }, - { 9478, "INTERRUPT_MASK_0" }, - { 9479, "INTERRUPT_MASK_RESET_0" }, - { 9480, "INTERRUPT_MASK_SET_0" }, - { 9481, "INTERRUPT_VECTOR_BASE_0" }, - { 9482, "SINGLE_STEP_EN_0_0" }, - { 9483, "SINGLE_STEP_EN_1_0" }, - { 9484, "SINGLE_STEP_EN_2_0" }, - { 9485, "SINGLE_STEP_EN_3_0" }, - { 9600, "EX_CONTEXT_0_0" }, - { 9601, "EX_CONTEXT_0_1" }, - { 9602, "SYSTEM_SAVE_0_0" }, - { 9603, "SYSTEM_SAVE_0_1" }, - { 9604, "SYSTEM_SAVE_0_2" }, - { 9605, "SYSTEM_SAVE_0_3" }, - { 9728, "MPL_BOOT_ACCESS_SET_0" }, - { 9729, "MPL_BOOT_ACCESS_SET_1" }, - { 9730, "MPL_BOOT_ACCESS_SET_2" }, - { 9731, "MPL_BOOT_ACCESS_SET_3" }, - { 9732, "MPL_BOOT_ACCESS" }, - { 9733, "BIG_ENDIAN_CONFIG" }, - { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" }, - { 9735, "CACHE_INVALIDATION_MASK_0" }, - { 9736, "CACHE_INVALIDATION_MASK_1" }, - { 9737, "CACHE_INVALIDATION_MASK_2" }, - { 9738, "CBOX_CACHEASRAM_CONFIG" }, - { 9739, "CBOX_CACHE_CONFIG" }, - { 9740, "CBOX_HOME_MAP_ADDR" }, - { 9741, "CBOX_HOME_MAP_DATA" }, - { 9742, "CBOX_MMAP_0" }, - { 9743, "CBOX_MMAP_1" }, - { 9744, "CBOX_MMAP_2" }, - { 9745, "CBOX_MMAP_3" }, - { 9746, "CBOX_MSR" }, - { 9747, "DIAG_BCST_CTL" }, - { 9748, "DIAG_BCST_MASK" }, - { 9749, "DIAG_BCST_TRIGGER" }, - { 9750, "DIAG_MUX_CTL" }, - { 9751, "DIAG_TRACE_CTL" }, - { 9752, "DIAG_TRACE_DATA" }, - { 9753, "DIAG_TRACE_STS" }, - { 9754, "IDN_DEMUX_BUF_THRESH" }, - { 9755, "L1_I_PIN_WAY_0" }, - { 9756, "MEM_ROUTE_ORDER" }, - { 9757, "MEM_STRIPE_CONFIG" }, - { 9758, "PERF_COUNT_PLS" }, - { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" }, - { 9760, "QUIESCE_CTL" }, - { 9761, "RSHIM_COORD" }, - { 9762, "SBOX_CONFIG" }, - { 9763, "UDN_DEMUX_BUF_THRESH" }, - { 9764, "XDN_CORE_STARVATION_COUNT" }, - { 9765, "XDN_ROUND_ROBIN_ARB_CTL" }, - { 9856, "CYCLE_MODIFY" }, - { 9857, "I_AAR" }, - { 9984, "MPL_WORLD_ACCESS_SET_0" }, - { 9985, "MPL_WORLD_ACCESS_SET_1" }, - { 9986, "MPL_WORLD_ACCESS_SET_2" }, - { 9987, "MPL_WORLD_ACCESS_SET_3" }, - { 9988, "MPL_WORLD_ACCESS" }, - { 9989, "DONE" }, - { 9990, "DSTREAM_PF" }, - { 9991, "FAIL" }, - { 9992, "INTERRUPT_CRITICAL_SECTION" }, - { 9993, "PASS" }, - { 9994, "PSEUDO_RANDOM_NUMBER" }, - { 9995, "TILE_COORD" }, - { 9996, "TILE_RTF_HWM" }, - { 10112, "CMPEXCH_VALUE" }, - { 10113, "CYCLE" }, - { 10114, "EVENT_BEGIN" }, - { 10115, "EVENT_END" }, - { 10116, "PROC_STATUS" }, - { 10117, "SIM_CONTROL" }, - { 10118, "SIM_SOCKET" }, - { 10119, "STATUS_SATURATE" }, - { 10240, "MPL_I_ASID_SET_0" }, - { 10241, "MPL_I_ASID_SET_1" }, - { 10242, "MPL_I_ASID_SET_2" }, - { 10243, "MPL_I_ASID_SET_3" }, - { 10244, "MPL_I_ASID" }, - { 10245, "I_ASID" }, - { 10496, "MPL_D_ASID_SET_0" }, - { 10497, "MPL_D_ASID_SET_1" }, - { 10498, "MPL_D_ASID_SET_2" }, - { 10499, "MPL_D_ASID_SET_3" }, - { 10500, "MPL_D_ASID" }, - { 10501, "D_ASID" }, - { 10752, "MPL_DOUBLE_FAULT_SET_0" }, - { 10753, "MPL_DOUBLE_FAULT_SET_1" }, - { 10754, "MPL_DOUBLE_FAULT_SET_2" }, - { 10755, "MPL_DOUBLE_FAULT_SET_3" }, - { 10756, "MPL_DOUBLE_FAULT" }, - { 10757, "LAST_INTERRUPT_REASON" }, -}; - -const int tilegx_num_sprs = 441; - -const char * -get_tilegx_spr_name (int num) -{ - void *result; - struct tilegx_spr key; - - key.number = num; - result = bsearch((const void *) &key, (const void *) tilegx_sprs, - tilegx_num_sprs, sizeof (struct tilegx_spr), - tilegx_spr_compare); - - if (result == NULL) - { - return (NULL); - } - else - { - struct tilegx_spr *result_ptr = (struct tilegx_spr *) result; - return (result_ptr->name); - } -} - -int -print_insn_tilegx (unsigned char * memaddr) -{ - struct tilegx_decoded_instruction - decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; - unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES]; - int i, num_instructions, num_printed; - tilegx_mnemonic padding_mnemonic; - - memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES); - - /* Parse the instructions in the bundle. */ - num_instructions = - parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded); - - /* Print the instructions in the bundle. */ - printf("{ "); - num_printed = 0; - - /* Determine which nop opcode is used for padding and should be skipped. */ - padding_mnemonic = TILEGX_OPC_FNOP; - for (i = 0; i < num_instructions; i++) - { - if (!decoded[i].opcode->can_bundle) - { - /* Instructions that cannot be bundled are padded out with nops, - rather than fnops. Displaying them is always clutter. */ - padding_mnemonic = TILEGX_OPC_NOP; - break; - } - } - - for (i = 0; i < num_instructions; i++) - { - const struct tilegx_opcode *opcode = decoded[i].opcode; - const char *name; - int j; - - /* Do not print out fnops, unless everything is an fnop, in - which case we will print out just the last one. */ - if (opcode->mnemonic == padding_mnemonic - && (num_printed > 0 || i + 1 < num_instructions)) - continue; - - if (num_printed > 0) - printf(" ; "); - ++num_printed; - - name = opcode->name; - if (name == NULL) - name = "<invalid>"; - printf("%s", name); - - for (j = 0; j < opcode->num_operands; j++) - { - unsigned long long num; - const struct tilegx_operand *op; - const char *spr_name; - - if (j > 0) - printf (","); - printf (" "); - - num = decoded[i].operand_values[j]; - - op = decoded[i].operands[j]; - switch (op->type) - { - case TILEGX_OP_TYPE_REGISTER: - printf ("%s", tilegx_register_names[(int)num]); - break; - case TILEGX_OP_TYPE_SPR: - spr_name = get_tilegx_spr_name(num); - if (spr_name != NULL) - printf ("%s", spr_name); - else - printf ("%d", (int)num); - break; - case TILEGX_OP_TYPE_IMMEDIATE: - printf ("%d", (int)num); - break; - case TILEGX_OP_TYPE_ADDRESS: - printf ("0x%016llx", num); - break; - default: - abort (); - } - } - } - printf (" }\n"); - - return TILEGX_BUNDLE_SIZE_IN_BYTES; -} diff --git a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c deleted file mode 100644 index 003f43a790..0000000000 --- a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c +++ /dev/null @@ -1,2555 +0,0 @@ -/* - * Stack-less Just-In-Time compiler - * - * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. - * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* TileGX architecture. */ -/* Contributed by Tilera Corporation. */ -#include "sljitNativeTILEGX-encoder.c" - -#define SIMM_8BIT_MAX (0x7f) -#define SIMM_8BIT_MIN (-0x80) -#define SIMM_16BIT_MAX (0x7fff) -#define SIMM_16BIT_MIN (-0x8000) -#define SIMM_17BIT_MAX (0xffff) -#define SIMM_17BIT_MIN (-0x10000) -#define SIMM_32BIT_MAX (0x7fffffff) -#define SIMM_32BIT_MIN (-0x7fffffff - 1) -#define SIMM_48BIT_MAX (0x7fffffff0000L) -#define SIMM_48BIT_MIN (-0x800000000000L) -#define IMM16(imm) ((imm) & 0xffff) - -#define UIMM_16BIT_MAX (0xffff) - -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) -#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5) -#define PIC_ADDR_REG TMP_REG2 - -static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { - 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7 -}; - -#define SLJIT_LOCALS_REG_mapped 54 -#define TMP_REG1_mapped 5 -#define TMP_REG2_mapped 16 -#define TMP_REG3_mapped 6 -#define ADDR_TMP_mapped 7 - -/* Flags are keept in volatile registers. */ -#define EQUAL_FLAG 8 -/* And carry flag as well. */ -#define ULESS_FLAG 9 -#define UGREATER_FLAG 10 -#define LESS_FLAG 11 -#define GREATER_FLAG 12 -#define OVERFLOW_FLAG 13 - -#define ZERO 63 -#define RA 55 -#define TMP_EREG1 14 -#define TMP_EREG2 15 - -#define LOAD_DATA 0x01 -#define WORD_DATA 0x00 -#define BYTE_DATA 0x02 -#define HALF_DATA 0x04 -#define INT_DATA 0x06 -#define SIGNED_DATA 0x08 -#define DOUBLE_DATA 0x10 - -/* Separates integer and floating point registers */ -#define GPR_REG 0xf - -#define MEM_MASK 0x1f - -#define WRITE_BACK 0x00020 -#define ARG_TEST 0x00040 -#define ALT_KEEP_CACHE 0x00080 -#define CUMULATIVE_OP 0x00100 -#define LOGICAL_OP 0x00200 -#define IMM_OP 0x00400 -#define SRC2_IMM 0x00800 - -#define UNUSED_DEST 0x01000 -#define REG_DEST 0x02000 -#define REG1_SOURCE 0x04000 -#define REG2_SOURCE 0x08000 -#define SLOW_SRC1 0x10000 -#define SLOW_SRC2 0x20000 -#define SLOW_DEST 0x40000 - -/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. - */ -#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) - -SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void) -{ - return "TileGX" SLJIT_CPUINFO; -} - -/* Length of an instruction word */ -typedef sljit_uw sljit_ins; - -struct jit_instr { - const struct tilegx_opcode* opcode; - tilegx_pipeline pipe; - unsigned long input_registers; - unsigned long output_registers; - int operand_value[4]; - int line; -}; - -/* Opcode Helper Macros */ -#define TILEGX_X_MODE 0 - -#define X_MODE create_Mode(TILEGX_X_MODE) - -#define FNOP_X0 \ - create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ - create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) - -#define FNOP_X1 \ - create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1) - -#define NOP \ - create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1 - -#define ANOP_X0 \ - create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ - create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0) - -#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \ - create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0 - -#define ADD_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0 - -#define ADDI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0 - -#define SUB_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0 - -#define NOR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0 - -#define OR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0 - -#define AND_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0 - -#define XOR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0 - -#define CMOVNEZ_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1 - -#define CMOVEQZ_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1 - -#define ADDLI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0 - -#define V4INT_L_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0 - -#define BFEXTU_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ - create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1 - -#define BFEXTS_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ - create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1 - -#define SHL16INSLI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0 - -#define ST_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0 - -#define LD_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0 - -#define JR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0 - -#define JALR_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ - create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0 - -#define CLZ_X0 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ - create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ - create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1 - -#define CMPLTUI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0 - -#define CMPLTU_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0 - -#define CMPLTS_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0 - -#define XORI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0 - -#define ORI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0 - -#define ANDI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ - create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0 - -#define SHLI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ - create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0 - -#define SHL_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0 - -#define SHRSI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ - create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0 - -#define SHRS_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0 - -#define SHRUI_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ - create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0 - -#define SHRU_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ - create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0 - -#define BEQZ_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ - create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0 - -#define BNEZ_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ - create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0 - -#define J_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ - create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0 - -#define JAL_X1 \ - create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ - create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0 - -#define DEST_X0(x) create_Dest_X0(x) -#define SRCA_X0(x) create_SrcA_X0(x) -#define SRCB_X0(x) create_SrcB_X0(x) -#define DEST_X1(x) create_Dest_X1(x) -#define SRCA_X1(x) create_SrcA_X1(x) -#define SRCB_X1(x) create_SrcB_X1(x) -#define IMM16_X1(x) create_Imm16_X1(x) -#define IMM8_X1(x) create_Imm8_X1(x) -#define BFSTART_X0(x) create_BFStart_X0(x) -#define BFEND_X0(x) create_BFEnd_X0(x) -#define SHIFTIMM_X1(x) create_ShAmt_X1(x) -#define JOFF_X1(x) create_JumpOff_X1(x) -#define BOFF_X1(x) create_BrOff_X1(x) - -static const tilegx_mnemonic data_transfer_insts[16] = { - /* u w s */ TILEGX_OPC_ST /* st */, - /* u w l */ TILEGX_OPC_LD /* ld */, - /* u b s */ TILEGX_OPC_ST1 /* st1 */, - /* u b l */ TILEGX_OPC_LD1U /* ld1u */, - /* u h s */ TILEGX_OPC_ST2 /* st2 */, - /* u h l */ TILEGX_OPC_LD2U /* ld2u */, - /* u i s */ TILEGX_OPC_ST4 /* st4 */, - /* u i l */ TILEGX_OPC_LD4U /* ld4u */, - /* s w s */ TILEGX_OPC_ST /* st */, - /* s w l */ TILEGX_OPC_LD /* ld */, - /* s b s */ TILEGX_OPC_ST1 /* st1 */, - /* s b l */ TILEGX_OPC_LD1S /* ld1s */, - /* s h s */ TILEGX_OPC_ST2 /* st2 */, - /* s h l */ TILEGX_OPC_LD2S /* ld2s */, - /* s i s */ TILEGX_OPC_ST4 /* st4 */, - /* s i l */ TILEGX_OPC_LD4S /* ld4s */, -}; - -#ifdef TILEGX_JIT_DEBUG -static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) -{ - sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - printf("|%04d|S0|:\t\t", line); - print_insn_tilegx(ptr); - return SLJIT_SUCCESS; -} - -static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) -{ - sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - return SLJIT_SUCCESS; -} - -#define push_inst(a, b) push_inst_debug(a, b, __LINE__) -#else -static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) -{ - sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); - FAIL_IF(!ptr); - *ptr = ins; - compiler->size++; - return SLJIT_SUCCESS; -} -#endif - -#define BUNDLE_FORMAT_MASK(p0, p1, p2) \ - ((p0) | ((p1) << 8) | ((p2) << 16)) - -#define BUNDLE_FORMAT(p0, p1, p2) \ - { \ - { \ - (tilegx_pipeline)(p0), \ - (tilegx_pipeline)(p1), \ - (tilegx_pipeline)(p2) \ - }, \ - BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \ - } - -#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS - -#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1) - -#define PI(encoding) \ - push_inst(compiler, encoding) - -#define PB3(opcode, dst, srca, srcb) \ - push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__) - -#define PB2(opcode, dst, src) \ - push_2_buffer(compiler, opcode, dst, src, __LINE__) - -#define JR(reg) \ - push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__) - -#define ADD(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__) - -#define SUB(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__) - -#define MUL(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__) - -#define NOR(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__) - -#define OR(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__) - -#define XOR(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__) - -#define AND(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__) - -#define CLZ(dst, src) \ - push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__) - -#define SHLI(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__) - -#define SHRUI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__) - -#define XORI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__) - -#define ORI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__) - -#define CMPLTU(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__) - -#define CMPLTS(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__) - -#define CMPLTUI(dst, srca, imm) \ - push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__) - -#define CMOVNEZ(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__) - -#define CMOVEQZ(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__) - -#define ADDLI(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__) - -#define SHL16INSLI(dst, srca, srcb) \ - push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__) - -#define LD_ADD(dst, addr, adjust) \ - push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__) - -#define ST_ADD(src, addr, adjust) \ - push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__) - -#define LD(dst, addr) \ - push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__) - -#define BFEXTU(dst, src, start, end) \ - push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__) - -#define BFEXTS(dst, src, start, end) \ - push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__) - -#define ADD_SOLO(dest, srca, srcb) \ - push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb)) - -#define ADDI_SOLO(dest, srca, imm) \ - push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm)) - -#define ADDLI_SOLO(dest, srca, imm) \ - push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) - -#define SHL16INSLI_SOLO(dest, srca, imm) \ - push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) - -#define JALR_SOLO(reg) \ - push_inst(compiler, JALR_X1 | SRCA_X1(reg)) - -#define JR_SOLO(reg) \ - push_inst(compiler, JR_X1 | SRCA_X1(reg)) - -struct Format { - /* Mapping of bundle issue slot to assigned pipe. */ - tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; - - /* Mask of pipes used by this bundle. */ - unsigned int pipe_mask; -}; - -const struct Format formats[] = -{ - /* In Y format we must always have something in Y2, since it has - * no fnop, so this conveys that Y2 must always be used. */ - BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE), - - /* Y format has three instructions. */ - BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1), - BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0), - - /* X format has only two instructions. */ - BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE), - BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE) -}; - - -struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; -unsigned long inst_buf_index; - -tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode) -{ - /* FIXME: tile: we could pregenerate this. */ - int pipe; - for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++) - ; - return (tilegx_pipeline)(pipe); -} - -void insert_nop(tilegx_mnemonic opc, int line) -{ - const struct tilegx_opcode* opcode = NULL; - - memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]); - - opcode = &tilegx_opcodes[opc]; - inst_buf[0].opcode = opcode; - inst_buf[0].pipe = get_any_valid_pipe(opcode); - inst_buf[0].input_registers = 0; - inst_buf[0].output_registers = 0; - inst_buf[0].line = line; - ++inst_buf_index; -} - -const struct Format* compute_format() -{ - unsigned int compatible_pipes = BUNDLE_FORMAT_MASK( - inst_buf[0].opcode->pipes, - inst_buf[1].opcode->pipes, - (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE))); - - const struct Format* match = NULL; - const struct Format *b = NULL; - unsigned int i; - for (i = 0; i < sizeof formats / sizeof formats[0]; i++) { - b = &formats[i]; - if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) { - match = b; - break; - } - } - - return match; -} - -sljit_s32 assign_pipes() -{ - unsigned long output_registers = 0; - unsigned int i = 0; - - if (inst_buf_index == 1) { - tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle - ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP; - insert_nop(opc, __LINE__); - } - - const struct Format* match = compute_format(); - - if (match == NULL) - return -1; - - for (i = 0; i < inst_buf_index; i++) { - - if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0)) - return -1; - - if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0)) - return -1; - - /* Don't include Rzero in the match set, to avoid triggering - needlessly on 'prefetch' instrs. */ - - output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL; - - inst_buf[i].pipe = match->pipe[i]; - } - - /* If only 2 instrs, and in Y-mode, insert a nop. */ - if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) { - insert_nop(TILEGX_OPC_FNOP, __LINE__); - - /* Select the yet unassigned pipe. */ - tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0 - + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2) - - (inst_buf[1].pipe + inst_buf[2].pipe))); - - inst_buf[0].pipe = pipe; - } - - return 0; -} - -tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst) -{ - int i, val; - const struct tilegx_opcode* opcode = inst->opcode; - tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe]; - - const struct tilegx_operand* operand = NULL; - for (i = 0; i < opcode->num_operands; i++) { - operand = &tilegx_operands[opcode->operands[inst->pipe][i]]; - val = inst->operand_value[i]; - - bits |= operand->insert(val); - } - - return bits; -} - -static sljit_s32 update_buffer(struct sljit_compiler *compiler) -{ - int i; - int orig_index = inst_buf_index; - struct jit_instr inst0 = inst_buf[0]; - struct jit_instr inst1 = inst_buf[1]; - struct jit_instr inst2 = inst_buf[2]; - tilegx_bundle_bits bits = 0; - - /* If the bundle is valid as is, perform the encoding and return 1. */ - if (assign_pipes() == 0) { - for (i = 0; i < inst_buf_index; i++) { - bits |= get_bundle_bit(inst_buf + i); -#ifdef TILEGX_JIT_DEBUG - printf("|%04d", inst_buf[i].line); -#endif - } -#ifdef TILEGX_JIT_DEBUG - if (inst_buf_index == 3) - printf("|M0|:\t"); - else - printf("|M0|:\t\t"); - print_insn_tilegx(&bits); -#endif - - inst_buf_index = 0; - -#ifdef TILEGX_JIT_DEBUG - return push_inst_nodebug(compiler, bits); -#else - return push_inst(compiler, bits); -#endif - } - - /* If the bundle is invalid, split it in two. First encode the first two - (or possibly 1) instructions, and then the last, separately. Note that - assign_pipes may have re-ordered the instrs (by inserting no-ops in - lower slots) so we need to reset them. */ - - inst_buf_index = orig_index - 1; - inst_buf[0] = inst0; - inst_buf[1] = inst1; - inst_buf[2] = inst2; - if (assign_pipes() == 0) { - for (i = 0; i < inst_buf_index; i++) { - bits |= get_bundle_bit(inst_buf + i); -#ifdef TILEGX_JIT_DEBUG - printf("|%04d", inst_buf[i].line); -#endif - } - -#ifdef TILEGX_JIT_DEBUG - if (inst_buf_index == 3) - printf("|M1|:\t"); - else - printf("|M1|:\t\t"); - print_insn_tilegx(&bits); -#endif - - if ((orig_index - 1) == 2) { - inst_buf[0] = inst2; - inst_buf_index = 1; - } else if ((orig_index - 1) == 1) { - inst_buf[0] = inst1; - inst_buf_index = 1; - } else - SLJIT_UNREACHABLE(); - -#ifdef TILEGX_JIT_DEBUG - return push_inst_nodebug(compiler, bits); -#else - return push_inst(compiler, bits); -#endif - } else { - /* We had 3 instrs of which the first 2 can't live in the same bundle. - Split those two. Note that we don't try to then combine the second - and third instr into a single bundle. First instruction: */ - inst_buf_index = 1; - inst_buf[0] = inst0; - inst_buf[1] = inst1; - inst_buf[2] = inst2; - if (assign_pipes() == 0) { - for (i = 0; i < inst_buf_index; i++) { - bits |= get_bundle_bit(inst_buf + i); -#ifdef TILEGX_JIT_DEBUG - printf("|%04d", inst_buf[i].line); -#endif - } - -#ifdef TILEGX_JIT_DEBUG - if (inst_buf_index == 3) - printf("|M2|:\t"); - else - printf("|M2|:\t\t"); - print_insn_tilegx(&bits); -#endif - - inst_buf[0] = inst1; - inst_buf[1] = inst2; - inst_buf_index = orig_index - 1; -#ifdef TILEGX_JIT_DEBUG - return push_inst_nodebug(compiler, bits); -#else - return push_inst(compiler, bits); -#endif - } else - SLJIT_UNREACHABLE(); - } - - SLJIT_UNREACHABLE(); -} - -static sljit_s32 flush_buffer(struct sljit_compiler *compiler) -{ - while (inst_buf_index != 0) { - FAIL_IF(update_buffer(compiler)); - } - return SLJIT_SUCCESS; -} - -static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].operand_value[1] = op1; - inst_buf[inst_buf_index].operand_value[2] = op2; - inst_buf[inst_buf_index].operand_value[3] = op3; - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = 1L << op0; - inst_buf[inst_buf_index].line = line; - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].operand_value[1] = op1; - inst_buf[inst_buf_index].operand_value[2] = op2; - inst_buf[inst_buf_index].line = line; - - switch (opc) { - case TILEGX_OPC_ST_ADD: - inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - case TILEGX_OPC_LD_ADD: - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1); - break; - case TILEGX_OPC_ADD: - case TILEGX_OPC_AND: - case TILEGX_OPC_SUB: - case TILEGX_OPC_MULX: - case TILEGX_OPC_OR: - case TILEGX_OPC_XOR: - case TILEGX_OPC_NOR: - case TILEGX_OPC_SHL: - case TILEGX_OPC_SHRU: - case TILEGX_OPC_SHRS: - case TILEGX_OPC_CMPLTU: - case TILEGX_OPC_CMPLTS: - case TILEGX_OPC_CMOVEQZ: - case TILEGX_OPC_CMOVNEZ: - inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2); - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - case TILEGX_OPC_ADDLI: - case TILEGX_OPC_XORI: - case TILEGX_OPC_ORI: - case TILEGX_OPC_SHLI: - case TILEGX_OPC_SHRUI: - case TILEGX_OPC_SHRSI: - case TILEGX_OPC_SHL16INSLI: - case TILEGX_OPC_CMPLTUI: - case TILEGX_OPC_CMPLTSI: - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - default: - printf("unrecoginzed opc: %s\n", opcode->name); - SLJIT_UNREACHABLE(); - } - - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].operand_value[1] = op1; - inst_buf[inst_buf_index].line = line; - - switch (opc) { - case TILEGX_OPC_BEQZ: - case TILEGX_OPC_BNEZ: - inst_buf[inst_buf_index].input_registers = 1L << op0; - break; - case TILEGX_OPC_ST: - case TILEGX_OPC_ST1: - case TILEGX_OPC_ST2: - case TILEGX_OPC_ST4: - inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); - inst_buf[inst_buf_index].output_registers = 0; - break; - case TILEGX_OPC_CLZ: - case TILEGX_OPC_LD: - case TILEGX_OPC_LD1U: - case TILEGX_OPC_LD1S: - case TILEGX_OPC_LD2U: - case TILEGX_OPC_LD2S: - case TILEGX_OPC_LD4U: - case TILEGX_OPC_LD4S: - inst_buf[inst_buf_index].input_registers = 1L << op1; - inst_buf[inst_buf_index].output_registers = 1L << op0; - break; - default: - printf("unrecoginzed opc: %s\n", opcode->name); - SLJIT_UNREACHABLE(); - } - - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].input_registers = 0; - inst_buf[inst_buf_index].output_registers = 0; - inst_buf[inst_buf_index].line = line; - inst_buf_index++; - - return SLJIT_SUCCESS; -} - -static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) -{ - if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) - FAIL_IF(update_buffer(compiler)); - - const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; - inst_buf[inst_buf_index].opcode = opcode; - inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); - inst_buf[inst_buf_index].operand_value[0] = op0; - inst_buf[inst_buf_index].input_registers = 1L << op0; - inst_buf[inst_buf_index].output_registers = 0; - inst_buf[inst_buf_index].line = line; - inst_buf_index++; - - return flush_buffer(compiler); -} - -static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) -{ - sljit_sw diff; - sljit_uw target_addr; - sljit_ins *inst; - - if (jump->flags & SLJIT_REWRITABLE_JUMP) - return code_ptr; - - if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; - else { - SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); - } - - inst = (sljit_ins *)jump->addr; - if (jump->flags & IS_COND) - inst--; - - diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3; - if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) { - jump->flags |= PATCH_B; - - if (!(jump->flags & IS_COND)) { - if (jump->flags & IS_JAL) { - jump->flags &= ~(PATCH_B); - jump->flags |= PATCH_J; - inst[0] = JAL_X1; - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - } else { - inst[0] = BEQZ_X1 | SRCA_X1(ZERO); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - } - - return inst; - } - - inst[0] = inst[0] ^ (0x7L << 55); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - jump->addr -= sizeof(sljit_ins); - return inst; - } - - if (jump->flags & IS_COND) { - if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { - jump->flags |= PATCH_J; - inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2); - inst[1] = J_X1; - return inst + 1; - } - - return code_ptr; - } - - if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { - jump->flags |= PATCH_J; - - if (jump->flags & IS_JAL) { - inst[0] = JAL_X1; - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - - } else { - inst[0] = J_X1; - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(inst); -#endif - } - - return inst; - } - - return code_ptr; -} - -SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler) -{ - struct sljit_memory_fragment *buf; - sljit_ins *code; - sljit_ins *code_ptr; - sljit_ins *buf_ptr; - sljit_ins *buf_end; - sljit_uw word_count; - sljit_uw addr; - - struct sljit_label *label; - struct sljit_jump *jump; - struct sljit_const *const_; - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_generate_code(compiler)); - reverse_buf(compiler); - - code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); - PTR_FAIL_WITH_EXEC_IF(code); - buf = compiler->buf; - - code_ptr = code; - word_count = 0; - label = compiler->labels; - jump = compiler->jumps; - const_ = compiler->consts; - do { - buf_ptr = (sljit_ins *)buf->memory; - buf_end = buf_ptr + (buf->used_size >> 3); - do { - *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw) code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - if (jump && jump->addr == word_count) { - if (jump->flags & IS_JAL) - jump->addr = (sljit_uw)(code_ptr - 4); - else - jump->addr = (sljit_uw)(code_ptr - 3); - - code_ptr = detect_jump_type(jump, code_ptr, code); - jump = jump->next; - } - - if (const_ && const_->addr == word_count) { - /* Just recording the address. */ - const_->addr = (sljit_uw) code_ptr; - const_ = const_->next; - } - - code_ptr++; - word_count++; - } while (buf_ptr < buf_end); - - buf = buf->next; - } while (buf); - - if (label && label->size == word_count) { - label->addr = (sljit_uw) code_ptr; - label->size = code_ptr - code; - label = label->next; - } - - SLJIT_ASSERT(!label); - SLJIT_ASSERT(!jump); - SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); - - jump = compiler->jumps; - while (jump) { - do { - addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins *)jump->addr; - - if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - (jump->addr)) >> 3; - SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN); - buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(buf_ptr); -#endif - break; - } - - if (jump->flags & PATCH_J) { - SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)); - addr = (sljit_sw)(addr - (jump->addr)) >> 3; - buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr); - -#ifdef TILEGX_JIT_DEBUG - printf("[runtime relocate]%04d:\t", __LINE__); - print_insn_tilegx(buf_ptr); -#endif - break; - } - - SLJIT_ASSERT(!(jump->flags & IS_JAL)); - - /* Set the fields of immediate loads. */ - buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43); - buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43); - buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43); - } while (0); - - jump = jump->next; - } - - compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); - SLJIT_CACHE_FLUSH(code, code_ptr); - return code; -} - -static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) -{ - - if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN) - return ADDLI(dst_ar, ZERO, imm); - - if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) { - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); - } - - if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) { - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); - } - - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); -} - -static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush) -{ - /* Should *not* be optimized as load_immediate, as pcre relocation - mechanism will match this fixed 4-instruction pattern. */ - if (flush) { - FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32)); - FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI_SOLO(dst_ar, dst_ar, imm); - } - - FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); - FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); - return SHL16INSLI(dst_ar, dst_ar, imm); -} - -static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush) -{ - /* Should *not* be optimized as load_immediate, as pcre relocation - mechanism will match this fixed 4-instruction pattern. */ - if (flush) { - FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48)); - FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); - FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); - return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm); - } - - FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48)); - FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); - FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); - return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) -{ - sljit_ins base; - sljit_s32 i, tmp; - - CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - local_size = (local_size + 7) & ~7; - compiler->local_size = local_size; - - if (local_size <= SIMM_16BIT_MAX) { - /* Frequent case. */ - FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size)); - base = SLJIT_LOCALS_REG_mapped; - } else { - FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); - FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO)); - FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); - base = TMP_REG2_mapped; - local_size = 0; - } - - /* Save the return address. */ - FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); - FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8)); - - /* Save the S registers. */ - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8)); - } - - /* Save the R registers that need to be reserved. */ - for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8)); - } - - /* Move the arguments to S registers. */ - for (i = 0; i < args; i++) { - FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO)); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) -{ - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); - - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); - compiler->local_size = (local_size + 7) & ~7; - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) -{ - sljit_s32 local_size; - sljit_ins base; - sljit_s32 i, tmp; - sljit_s32 saveds; - - CHECK_ERROR(); - CHECK(check_sljit_emit_return(compiler, op, src, srcw)); - - FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - - local_size = compiler->local_size; - if (local_size <= SIMM_16BIT_MAX) - base = SLJIT_LOCALS_REG_mapped; - else { - FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); - FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); - base = TMP_REG1_mapped; - local_size = 0; - } - - /* Restore the return address. */ - FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); - FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8)); - - /* Restore the S registers. */ - saveds = compiler->saveds; - tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; - for (i = SLJIT_S0; i >= tmp; i--) { - FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8)); - } - - /* Restore the R registers that need to be reserved. */ - for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8)); - } - - if (compiler->local_size <= SIMM_16BIT_MAX) - FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size)); - else - FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO)); - - return JR(RA); -} - -/* reg_ar is an absoulute register! */ - -/* Can perform an operation using at most 1 instruction. */ -static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) -{ - SLJIT_ASSERT(arg & SLJIT_MEM); - - if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) - && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { - /* Works for both absoulte and relative addresses. */ - if (SLJIT_UNLIKELY(flags & ARG_TEST)) - return 1; - - FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw)); - - if (flags & LOAD_DATA) - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); - else - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); - - return -1; - } - - return 0; -} - -/* See getput_arg below. - Note: can_cache is called only for binary operators. Those - operators always uses word arguments without write back. */ -static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) -{ - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); - - /* Simple operation except for updates. */ - if (arg & OFFS_REG_MASK) { - argw &= 0x3; - next_argw &= 0x3; - if (argw && argw == next_argw - && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) - return 1; - return 0; - } - - if (arg == next_arg) { - if (((next_argw - argw) <= SIMM_16BIT_MAX - && (next_argw - argw) >= SIMM_16BIT_MIN)) - return 1; - - return 0; - } - - return 0; -} - -/* Emit the necessary instructions. See can_cache above. */ -static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) -{ - sljit_s32 tmp_ar, base; - - SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(next_arg & SLJIT_MEM)) { - next_arg = 0; - next_argw = 0; - } - - if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) - tmp_ar = reg_ar; - else - tmp_ar = TMP_REG1_mapped; - - base = arg & REG_MASK; - - if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - argw &= 0x3; - - if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) { - SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar); - FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); - reg_ar = TMP_REG1_mapped; - } - - /* Using the cache. */ - if (argw == compiler->cache_argw) { - if (!(flags & WRITE_BACK)) { - if (arg == compiler->cache_arg) { - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { - if (arg == next_arg && argw == (next_argw & 0x3)) { - compiler->cache_arg = arg; - compiler->cache_argw = argw; - FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped)); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped)); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); - else - return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); - } - } else { - if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { - FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); - else - return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); - } - } - } - - if (SLJIT_UNLIKELY(argw)) { - compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); - compiler->cache_argw = argw; - FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw)); - } - - if (!(flags & WRITE_BACK)) { - if (arg == next_arg && argw == (next_argw & 0x3)) { - compiler->cache_arg = arg; - compiler->cache_argw = argw; - FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); - tmp_ar = TMP_REG3_mapped; - } else - FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); - else - return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); - } - - FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); - else - return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); - } - - if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { - /* Update only applies if a base register exists. */ - if (reg_ar == reg_map[base]) { - SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar); - if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { - FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw)); - if (flags & LOAD_DATA) - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); - else - FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); - - if (argw) - return ADDLI(reg_map[base], reg_map[base], argw); - - return SLJIT_SUCCESS; - } - - FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); - reg_ar = TMP_REG1_mapped; - } - - if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { - if (argw) - FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw)); - } else { - if (compiler->cache_arg == SLJIT_MEM - && argw - compiler->cache_argw <= SIMM_16BIT_MAX - && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); - compiler->cache_argw = argw; - } - - FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); - } else { - compiler->cache_arg = SLJIT_MEM; - compiler->cache_argw = argw; - FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); - FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); - } - } - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); - else - return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); - } - - if (compiler->cache_arg == arg - && argw - compiler->cache_argw <= SIMM_16BIT_MAX - && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { - if (argw != compiler->cache_argw) { - FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); - compiler->cache_argw = argw; - } - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - if (compiler->cache_arg == SLJIT_MEM - && argw - compiler->cache_argw <= SIMM_16BIT_MAX - && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { - if (argw != compiler->cache_argw) - FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); - } else { - compiler->cache_arg = SLJIT_MEM; - FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); - } - - compiler->cache_argw = argw; - - if (!base) { - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - if (arg == next_arg - && next_argw - argw <= SIMM_16BIT_MAX - && next_argw - argw >= SIMM_16BIT_MIN) { - compiler->cache_arg = arg; - FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base])); - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); - else - return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); - } - - FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base])); - - if (flags & LOAD_DATA) - return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); - else - return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); -} - -static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) - return compiler->error; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (FAST_IS_REG(dst)) - return ADD(reg_map[dst], RA, ZERO); - - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) - FAIL_IF(ADD(RA, reg_map[src], ZERO)); - - else if (src & SLJIT_MEM) - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw)); - - else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, RA, srcw)); - - return JR(RA); -} - -static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2) -{ - sljit_s32 overflow_ra = 0; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (dst != src2) - return ADD(reg_map[dst], reg_map[src2], ZERO); - return SLJIT_SUCCESS; - - case SLJIT_MOV_U32: - case SLJIT_MOV_S32: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_S32) - return BFEXTS(reg_map[dst], reg_map[src2], 0, 31); - - return BFEXTU(reg_map[dst], reg_map[src2], 0, 31); - } else if (dst != src2) { - SLJIT_ASSERT(src2 == 0); - return ADD(reg_map[dst], reg_map[src2], ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_MOV_U8: - case SLJIT_MOV_S8: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_S8) - return BFEXTS(reg_map[dst], reg_map[src2], 0, 7); - - return BFEXTU(reg_map[dst], reg_map[src2], 0, 7); - } else if (dst != src2) { - SLJIT_ASSERT(src2 == 0); - return ADD(reg_map[dst], reg_map[src2], ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_MOV_U16: - case SLJIT_MOV_S16: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_S16) - return BFEXTS(reg_map[dst], reg_map[src2], 0, 15); - - return BFEXTU(reg_map[dst], reg_map[src2], 0, 15); - } else if (dst != src2) { - SLJIT_ASSERT(src2 == 0); - return ADD(reg_map[dst], reg_map[src2], ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2])); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2])); - - return SLJIT_SUCCESS; - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2])); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(CLZ(reg_map[dst], reg_map[src2])); - - return SLJIT_SUCCESS; - - case SLJIT_ADD: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63)); - if (src2 < 0) - FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); - } - - if (op & SLJIT_SET_E) - FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2)); - - if (op & SLJIT_SET_C) { - if (src2 >= 0) - FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2)); - else { - FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2)); - FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG)); - } - } - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); - - if (op & SLJIT_SET_O) { - FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63)); - - if (src2 < 0) - FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1)); - } - } else { - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); - FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); - - if (src1 != dst) - overflow_ra = reg_map[src1]; - else if (src2 != dst) - overflow_ra = reg_map[src2]; - else { - /* Rare ocasion. */ - FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); - overflow_ra = TMP_EREG2; - } - } - - if (op & SLJIT_SET_E) - FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2])); - - if (op & SLJIT_SET_C) - FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2])); - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2])); - - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra)); - FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); - } - } - - /* a + b >= a | b (otherwise, the carry should be set to 1). */ - if (op & SLJIT_SET_C) - FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG)); - - if (op & SLJIT_SET_O) - return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); - - return SLJIT_SUCCESS; - - case SLJIT_ADDC: - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) { - if (src2 >= 0) - FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2)); - else { - FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2)); - FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1)); - } - } - - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); - - } else { - if (op & SLJIT_SET_C) - FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2])); - - /* dst may be the same as src1 or src2. */ - FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2])); - } - - if (op & SLJIT_SET_C) - FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1)); - - FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG)); - - if (!(op & SLJIT_SET_C)) - return SLJIT_SUCCESS; - - /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ - FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1)); - FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG)); - /* Set carry flag. */ - return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1); - - case SLJIT_SUB: - if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) { - FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_O) { - FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63)); - - if (src2 < 0) - FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); - - if (src1 != dst) - overflow_ra = reg_map[src1]; - else { - /* Rare ocasion. */ - FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); - overflow_ra = TMP_EREG2; - } - } - - if (op & SLJIT_SET_E) - FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2)); - - if (op & SLJIT_SET_C) { - FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); - FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped)); - } - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); - - } else { - - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); - FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); - - if (src1 != dst) - overflow_ra = reg_map[src1]; - else { - /* Rare ocasion. */ - FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); - overflow_ra = TMP_EREG2; - } - } - - if (op & SLJIT_SET_E) - FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2])); - - if (op & (SLJIT_SET_U | SLJIT_SET_C)) - FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2])); - - if (op & SLJIT_SET_U) - FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1])); - - if (op & SLJIT_SET_S) { - FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2])); - FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1])); - } - - /* dst may be the same as src1 or src2. */ - if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) - FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); - } - - if (op & SLJIT_SET_O) { - FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra)); - FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); - return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); - } - - return SLJIT_SUCCESS; - - case SLJIT_SUBC: - if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) { - FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - if (flags & SRC2_IMM) { - if (op & SLJIT_SET_C) { - FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2)); - FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped)); - } - - /* dst may be the same as src1 or src2. */ - FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); - - } else { - if (op & SLJIT_SET_C) - FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2])); - /* dst may be the same as src1 or src2. */ - FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); - } - - if (op & SLJIT_SET_C) - FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG)); - - FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG)); - - if (op & SLJIT_SET_C) - FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO)); - - return SLJIT_SUCCESS; - - case SLJIT_MUL: - if (flags & SRC2_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2)); - src2 = TMP_REG2; - flags &= ~SRC2_IMM; - } - - FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2])); - - return SLJIT_SUCCESS; - -#define EMIT_LOGICAL(op_imm, op_norm) \ - if (flags & SRC2_IMM) { \ - FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ - ADDR_TMP_mapped, __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, reg_map[dst], reg_map[src1], \ - ADDR_TMP_mapped, __LINE__)); \ - } else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ - reg_map[src2], __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, reg_map[dst], reg_map[src1], \ - reg_map[src2], __LINE__)); \ - } - - case SLJIT_AND: - EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND); - return SLJIT_SUCCESS; - - case SLJIT_OR: - EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR); - return SLJIT_SUCCESS; - - case SLJIT_XOR: - EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR); - return SLJIT_SUCCESS; - -#define EMIT_SHIFT(op_imm, op_norm) \ - if (flags & SRC2_IMM) { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_imm, EQUAL_FLAG, reg_map[src1], \ - src2 & 0x3F, __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_imm, reg_map[dst], reg_map[src1], \ - src2 & 0x3F, __LINE__)); \ - } else { \ - if (op & SLJIT_SET_E) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ - reg_map[src2], __LINE__)); \ - if (CHECK_FLAGS(SLJIT_SET_E)) \ - FAIL_IF(push_3_buffer( \ - compiler, op_norm, reg_map[dst], reg_map[src1], \ - reg_map[src2], __LINE__)); \ - } - - case SLJIT_SHL: - EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL); - return SLJIT_SUCCESS; - - case SLJIT_LSHR: - EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU); - return SLJIT_SUCCESS; - - case SLJIT_ASHR: - EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS); - return SLJIT_SUCCESS; - } - - SLJIT_UNREACHABLE(); - return SLJIT_SUCCESS; -} - -static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) -{ - /* arg1 goes to TMP_REG1 or src reg. - arg2 goes to TMP_REG2, imm or src reg. - TMP_REG3 can be used for caching. - result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_s32 dst_r = TMP_REG2; - sljit_s32 src1_r; - sljit_sw src2_r = 0; - sljit_s32 sugg_src2_r = TMP_REG2; - - if (!(flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - } - - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - if (GET_FLAGS(op)) - flags |= UNUSED_DEST; - } else if (FAST_IS_REG(dst)) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) - sugg_src2_r = dst_r; - } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw)) - flags |= SLOW_DEST; - - if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w) { - if ((!(flags & LOGICAL_OP) - && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN)) - || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) { - flags |= SRC2_IMM; - src2_r = src2w; - } - } - - if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { - if ((!(flags & LOGICAL_OP) - && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN)) - || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) { - flags |= SRC2_IMM; - src2_r = src1w; - - /* And swap arguments. */ - src1 = src2; - src1w = src2w; - src2 = SLJIT_IMM; - /* src2w = src2_r unneeded. */ - } - } - } - - /* Source 1. */ - if (FAST_IS_REG(src1)) { - src1_r = src1; - flags |= REG1_SOURCE; - } else if (src1 & SLJIT_IMM) { - if (src1w) { - FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w)); - src1_r = TMP_REG1; - } else - src1_r = 0; - } else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC1; - src1_r = TMP_REG1; - } - - /* Source 2. */ - if (FAST_IS_REG(src2)) { - src2_r = src2; - flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) - dst_r = src2_r; - } else if (src2 & SLJIT_IMM) { - if (!(flags & SRC2_IMM)) { - if (src2w) { - FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w)); - src2_r = sugg_src2_r; - } else { - src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) - dst_r = 0; - } - } - } else { - if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w)) - FAIL_IF(compiler->error); - else - flags |= SLOW_SRC2; - src2_r = sugg_src2_r; - } - - if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { - SLJIT_ASSERT(src2_r == TMP_REG2); - if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); - } else { - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw)); - } - } else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); - else if (flags & SLOW_SRC2) - FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw)); - - FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); - - if (dst & SLJIT_MEM) { - if (!(flags & SLOW_DEST)) { - getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw); - return compiler->error; - } - - return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw, sljit_s32 type) -{ - sljit_s32 sugg_dst_ar, dst_ar; - sljit_s32 flags = GET_ALL_FLAGS(op); - sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; - - CHECK_ERROR(); - CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - op = GET_OPCODE(op); - if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32) - mem_type = INT_DATA | SIGNED_DATA; - sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2]; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); - FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } - - switch (type & 0xff) { - case SLJIT_EQUAL: - case SLJIT_NOT_EQUAL: - FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1)); - dst_ar = sugg_dst_ar; - break; - case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: - dst_ar = ULESS_FLAG; - break; - case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: - dst_ar = UGREATER_FLAG; - break; - case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: - dst_ar = LESS_FLAG; - break; - case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: - dst_ar = GREATER_FLAG; - break; - case SLJIT_OVERFLOW: - case SLJIT_NOT_OVERFLOW: - dst_ar = OVERFLOW_FLAG; - break; - case SLJIT_MUL_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1)); - dst_ar = sugg_dst_ar; - type ^= 0x1; /* Flip type bit for the XORI below. */ - break; - - default: - SLJIT_UNREACHABLE(); - dst_ar = sugg_dst_ar; - break; - } - - if (type & 0x1) { - FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1)); - dst_ar = sugg_dst_ar; - } - - if (op >= SLJIT_ADD) { - if (TMP_REG2_mapped != dst_ar) - FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO)); - return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); - } - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw); - - if (sugg_dst_ar != dst_ar) - return ADD(sugg_dst_ar, dst_ar, ZERO); - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { - CHECK_ERROR(); - CHECK(check_sljit_emit_op0(compiler, op)); - - op = GET_OPCODE(op); - switch (op) { - case SLJIT_NOP: - return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__); - - case SLJIT_BREAKPOINT: - return PI(BPT); - - case SLJIT_LMUL_UW: - case SLJIT_LMUL_SW: - case SLJIT_DIVMOD_UW: - case SLJIT_DIVMOD_SW: - case SLJIT_DIV_UW: - case SLJIT_DIV_SW: - SLJIT_UNREACHABLE(); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_U32: - return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_S32: - return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOV_U8: - return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw); - - case SLJIT_MOV_S8: - return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw); - - case SLJIT_MOV_U16: - return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw); - - case SLJIT_MOV_S16: - return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw); - - case SLJIT_MOVU: - case SLJIT_MOVU_P: - return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_U32: - return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_S32: - return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_MOVU_U8: - return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw); - - case SLJIT_MOVU_S8: - return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw); - - case SLJIT_MOVU_U16: - return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw); - - case SLJIT_MOVU_S16: - return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); - - case SLJIT_NEG: - return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); - - case SLJIT_CLZ: - return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); - - switch (GET_OPCODE(op)) { - case SLJIT_ADD: - case SLJIT_ADDC: - return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SUB: - case SLJIT_SUBC: - return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_MUL: - return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_AND: - case SLJIT_OR: - case SLJIT_XOR: - return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); - - case SLJIT_SHL: - case SLJIT_LSHR: - case SLJIT_ASHR: - if (src2 & SLJIT_IMM) - src2w &= 0x3f; - if (op & SLJIT_I32_OP) - src2w &= 0x1f; - - return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); - } - - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler) -{ - struct sljit_label *label; - - flush_buffer(compiler); - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_label(compiler)); - - if (compiler->last_label && compiler->last_label->size == compiler->size) - return compiler->last_label; - - label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label)); - PTR_FAIL_IF(!label); - set_label(label, compiler); - return label; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) -{ - sljit_s32 src_r = TMP_REG2; - struct sljit_jump *jump = NULL; - - flush_buffer(compiler); - - CHECK_ERROR(); - CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - - if (FAST_IS_REG(src)) { - if (reg_map[src] != 0) - src_r = src; - else - FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO)); - } - - if (type >= SLJIT_CALL0) { - SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); - if (src & (SLJIT_IMM | SLJIT_MEM)) { - if (src & SLJIT_IMM) - FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1)); - else { - SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - } - - FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); - - FAIL_IF(ADDI_SOLO(54, 54, -16)); - - FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG])); - - return ADDI_SOLO(54, 54, 16); - } - - /* Register input. */ - if (type >= SLJIT_CALL1) - FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); - - FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO)); - - FAIL_IF(ADDI_SOLO(54, 54, -16)); - - FAIL_IF(JALR_SOLO(reg_map[src_r])); - - return ADDI_SOLO(54, 54, 16); - } - - if (src & SLJIT_IMM) { - jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); - FAIL_IF(!jump); - set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); - jump->u.target = srcw; - FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); - - if (type >= SLJIT_FAST_CALL) { - FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO)); - jump->addr = compiler->size; - FAIL_IF(JR_SOLO(reg_map[src_r])); - } else { - jump->addr = compiler->size; - FAIL_IF(JR_SOLO(reg_map[src_r])); - } - - return SLJIT_SUCCESS; - - } else if (src & SLJIT_MEM) { - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - flush_buffer(compiler); - } - - FAIL_IF(JR_SOLO(reg_map[src_r])); - - if (jump) - jump->addr = compiler->size; - - return SLJIT_SUCCESS; -} - -#define BR_Z(src) \ - inst = BEQZ_X1 | SRCA_X1(src); \ - flags = IS_COND; - -#define BR_NZ(src) \ - inst = BNEZ_X1 | SRCA_X1(src); \ - flags = IS_COND; - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) -{ - struct sljit_jump *jump; - sljit_ins inst; - sljit_s32 flags = 0; - - flush_buffer(compiler); - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_jump(compiler, type)); - - jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); - PTR_FAIL_IF(!jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); - type &= 0xff; - - switch (type) { - case SLJIT_EQUAL: - BR_NZ(EQUAL_FLAG); - break; - case SLJIT_NOT_EQUAL: - BR_Z(EQUAL_FLAG); - break; - case SLJIT_LESS: - BR_Z(ULESS_FLAG); - break; - case SLJIT_GREATER_EQUAL: - BR_NZ(ULESS_FLAG); - break; - case SLJIT_GREATER: - BR_Z(UGREATER_FLAG); - break; - case SLJIT_LESS_EQUAL: - BR_NZ(UGREATER_FLAG); - break; - case SLJIT_SIG_LESS: - BR_Z(LESS_FLAG); - break; - case SLJIT_SIG_GREATER_EQUAL: - BR_NZ(LESS_FLAG); - break; - case SLJIT_SIG_GREATER: - BR_Z(GREATER_FLAG); - break; - case SLJIT_SIG_LESS_EQUAL: - BR_NZ(GREATER_FLAG); - break; - case SLJIT_OVERFLOW: - case SLJIT_MUL_OVERFLOW: - BR_Z(OVERFLOW_FLAG); - break; - case SLJIT_NOT_OVERFLOW: - case SLJIT_MUL_NOT_OVERFLOW: - BR_NZ(OVERFLOW_FLAG); - break; - default: - /* Not conditional branch. */ - inst = 0; - break; - } - - jump->flags |= flags; - - if (inst) { - inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6)); - PTR_FAIL_IF(PI(inst)); - } - - PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); - if (type <= SLJIT_JUMP) { - jump->addr = compiler->size; - PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped)); - } else { - SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); - /* Cannot be optimized out if type is >= CALL0. */ - jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0); - PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO)); - jump->addr = compiler->size; - PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped)); - } - - return jump; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) -{ - struct sljit_const *const_; - sljit_s32 reg; - - flush_buffer(compiler); - - CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); - ADJUST_LOCAL_OFFSET(dst, dstw); - - const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const)); - PTR_FAIL_IF(!const_); - set_const(const_, compiler); - - reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1)); - - if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); - return const_; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target) -{ - sljit_ins *inst = (sljit_ins *)addr; - - inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43); - inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43); - inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43); - SLJIT_CACHE_FLUSH(inst, inst + 3); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) -{ - sljit_ins *inst = (sljit_ins *)addr; - - inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43); - inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43); - inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43); - inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43); - SLJIT_CACHE_FLUSH(inst, inst + 4); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) -{ - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_s32 size) -{ - CHECK_ERROR(); - CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - return SLJIT_ERR_UNSUPPORTED; -} - diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c index 34a3a3d940..79a7e8bba5 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c @@ -76,6 +76,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + /* Emit ENDBR32 at function entry if needed. */ + FAIL_IF(emit_endbranch(compiler)); + args = get_arg_count(arg_types); compiler->args = args; @@ -307,14 +310,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size)); #endif - size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) + + size = 2 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) + (compiler->saveds <= 3 ? compiler->saveds : 3); #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (compiler->args > 2) size += 2; -#else - if (compiler->args > 0) - size += 2; #endif inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); @@ -367,6 +367,8 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + /* We don't support (%ebp). */ + SLJIT_ASSERT(!(b & SLJIT_MEM) || immb || reg_map[b & REG_MASK] != 5); size &= 0xf; inst_size = size; @@ -863,14 +865,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) +static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { sljit_u8 *inst; - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - CHECK_EXTRA_REGS(src, srcw, (void)0); if (FAST_IS_REG(src)) { @@ -894,3 +892,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler RET(); return SLJIT_SUCCESS; } + +static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler) +{ + sljit_s32 size, saved_size; + sljit_s32 has_f64_aligment; + + /* Don't adjust shadow stack if it isn't enabled. */ + if (!cpu_has_shadow_stack ()) + return SLJIT_SUCCESS; + + SLJIT_ASSERT(compiler->args >= 0); + SLJIT_ASSERT(compiler->local_size > 0); + +#if !defined(__APPLE__) + has_f64_aligment = compiler->options & SLJIT_F64_ALIGNMENT; +#else + has_f64_aligment = 0; +#endif + + size = compiler->local_size; + saved_size = (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) + (compiler->saveds <= 3 ? compiler->saveds : 3)) * sizeof(sljit_uw); + if (has_f64_aligment) { + /* mov TMP_REG1, [esp + local_size]. */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), size); + /* mov TMP_REG1, [TMP_REG1+ saved_size]. */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), saved_size); + /* Move return address to [esp]. */ + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, TMP_REG1, 0); + size = 0; + } else + size += saved_size; + + return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size); +} diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c index 5758711954..e85b56a61a 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c @@ -135,6 +135,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + /* Emit ENDBR64 at function entry if needed. */ + FAIL_IF(emit_endbranch(compiler)); + compiler->mode32 = 0; #ifdef _WIN64 @@ -796,14 +799,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) +static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { sljit_u8 *inst; - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); - ADJUST_LOCAL_OFFSET(src, srcw); - if (FAST_IS_REG(src)) { if (reg_map[src] < 8) { inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1); @@ -898,3 +897,22 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, return SLJIT_SUCCESS; } + +static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler) +{ + sljit_s32 tmp, size; + + /* Don't adjust shadow stack if it isn't enabled. */ + if (!cpu_has_shadow_stack ()) + return SLJIT_SUCCESS; + + size = compiler->local_size; + tmp = compiler->scratches; + if (tmp >= SLJIT_FIRST_SAVED_REG) + size += (tmp - SLJIT_FIRST_SAVED_REG + 1) * sizeof(sljit_uw); + tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; + if (SLJIT_S0 >= tmp) + size += (SLJIT_S0 - tmp + 1) * sizeof(sljit_uw); + + return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size); +} diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c index 6296da5382..ddcc5ebf76 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c @@ -506,7 +506,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); /* Second code generation pass. */ - code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size); + code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -557,7 +557,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(put_label->label); put_label->addr = (sljit_uw)code_ptr; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); + code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size); #endif put_label = put_label->next; break; @@ -629,7 +629,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = code_ptr - code; - return (void*)(code + executable_offset); + + code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + + SLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1); + return (void*)code; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) @@ -657,6 +661,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) get_cpu_features(); return cpu_has_cmov; + case SLJIT_HAS_PREFETCH: + return 1; + case SLJIT_HAS_SSE2: #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) if (cpu_has_sse2 == -1) @@ -702,6 +709,166 @@ static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw); +static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); + +static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler) +{ +#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) + /* Emit endbr32/endbr64 when CET is enabled. */ + sljit_u8 *inst; + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *inst++ = 0xf3; + *inst++ = 0x0f; + *inst++ = 0x1e; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *inst = 0xfb; +#else + *inst = 0xfa; +#endif +#else /* !SLJIT_CONFIG_X86_CET */ + SLJIT_UNUSED_ARG(compiler); +#endif /* SLJIT_CONFIG_X86_CET */ + return SLJIT_SUCCESS; +} + +#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__) + +static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg) +{ + sljit_u8 *inst; + sljit_s32 size; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + size = 5; +#else + size = 4; +#endif + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + *inst++ = 0xf3; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B); +#endif + *inst++ = 0x0f; + *inst++ = 0x1e; + *inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg) +{ + sljit_u8 *inst; + sljit_s32 size; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + size = 5; +#else + size = 4; +#endif + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + *inst++ = 0xf3; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B); +#endif + *inst++ = 0x0f; + *inst++ = 0xae; + *inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7); + return SLJIT_SUCCESS; +} + +#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */ + +static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void) +{ +#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__) + return _get_ssp() != 0; +#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */ + return 0; +#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */ +} + +static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler, + sljit_s32 src, sljit_sw srcw, sljit_s32 base, sljit_sw disp) +{ +#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__) + sljit_u8 *inst, *jz_after_cmp_inst; + sljit_uw size_jz_after_cmp_inst; + + sljit_uw size_before_rdssp_inst = compiler->size; + + /* Generate "RDSSP TMP_REG1". */ + FAIL_IF(emit_rdssp(compiler, TMP_REG1)); + + /* Load return address on shadow stack into TMP_REG1. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + SLJIT_ASSERT(reg_map[TMP_REG1] == 5); + + /* Hand code unsupported "mov 0x0(%ebp),%ebp". */ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + *inst++ = 0x8b; + *inst++ = 0x6d; + *inst = 0; +#else /* !SLJIT_CONFIG_X86_32 */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0); +#endif /* SLJIT_CONFIG_X86_32 */ + + if (src == SLJIT_UNUSED) { + /* Return address is on stack. */ + src = SLJIT_MEM1(base); + srcw = disp; + } + + /* Compare return address against TMP_REG1. */ + FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw)); + + /* Generate JZ to skip shadow stack ajdustment when shadow + stack matches normal stack. */ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = get_jump_code(SLJIT_EQUAL) - 0x10; + size_jz_after_cmp_inst = compiler->size; + jz_after_cmp_inst = inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + /* REX_W is not necessary. */ + compiler->mode32 = 1; +#endif + /* Load 1 into TMP_REG1. */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1); + + /* Generate "INCSSP TMP_REG1". */ + FAIL_IF(emit_incssp(compiler, TMP_REG1)); + + /* Jump back to "RDSSP TMP_REG1" to check shadow stack again. */ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = JMP_i8; + *inst = size_before_rdssp_inst - compiler->size; + + *jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst; +#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_UNUSED_ARG(base); + SLJIT_UNUSED_ARG(disp); +#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */ + return SLJIT_SUCCESS; +} + #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #include "sljitNativeX86_32.c" #else @@ -905,6 +1072,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #endif break; + case SLJIT_ENDBR: + return emit_endbranch(compiler); + case SLJIT_SKIP_FRAMES_BEFORE_RETURN: + return skip_frames_before_return(compiler); } return SLJIT_SUCCESS; @@ -1074,12 +1245,12 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op, *inst++ = GROUP_0F; *inst++ = PREFETCH; - if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8) - *inst |= (3 << 3); - else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16) - *inst |= (2 << 3); - else + if (op == SLJIT_PREFETCH_L1) *inst |= (1 << 3); + else if (op == SLJIT_PREFETCH_L2) + *inst |= (2 << 3); + else if (op == SLJIT_PREFETCH_L3) + *inst |= (3 << 3); return SLJIT_SUCCESS; } @@ -1284,12 +1455,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile compiler->mode32 = op_flags & SLJIT_I32_OP; #endif - if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) { - if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) - return emit_prefetch(compiler, op, src, srcw); - return SLJIT_SUCCESS; - } - op = GET_OPCODE(op); if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) { @@ -2150,6 +2315,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (!HAS_FLAGS(op)) { if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; + if (SLOW_IS_REG(dst) && src2 == dst) { + FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w)); + return emit_unary(compiler, NEG_rm, dst, 0, dst, 0); + } } if (dst == SLJIT_UNUSED) @@ -2186,6 +2355,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_op_src(compiler, op, src, srcw)); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + switch (op) { + case SLJIT_FAST_RETURN: + return emit_fast_return(compiler, src, srcw); + case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN: + /* Don't adjust shadow stack if it isn't enabled. */ + if (!cpu_has_shadow_stack ()) + return SLJIT_SUCCESS; + return adjust_shadow_stack(compiler, src, srcw, SLJIT_UNUSED, 0); + case SLJIT_PREFETCH_L1: + case SLJIT_PREFETCH_L2: + case SLJIT_PREFETCH_L3: + case SLJIT_PREFETCH_ONCE: + return emit_prefetch(compiler, op, src, srcw); + } + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); @@ -2926,15 +3122,21 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { SLJIT_UNUSED_ARG(executable_offset); + + SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset); #else sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target); #endif + SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { SLJIT_UNUSED_ARG(executable_offset); + + SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0); sljit_unaligned_store_sw((void*)addr, new_constant); + SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1); } diff --git a/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c index 8a5b2b3cfe..147175afa6 100644 --- a/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c +++ b/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c @@ -70,92 +70,112 @@ struct chunk_header { void *executable; - int fd; }; /* alloc_chunk / free_chunk : * allocate executable system memory chunks * the size is always divisible by CHUNK_SIZE - allocator_grab_lock / allocator_release_lock : - * make the allocator thread safe - * can be empty if the OS (or the application) does not support threading + SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK : + * provided as part of sljitUtils * only the allocator requires this lock, sljit is fully thread safe as it only uses local variables */ +#ifndef __NetBSD__ +#include <sys/stat.h> #include <fcntl.h> +#include <stdio.h> +#include <string.h> #ifndef O_NOATIME #define O_NOATIME 0 #endif -#ifdef __O_TMPFILE +/* this is a linux extension available since kernel 3.11 */ #ifndef O_TMPFILE -#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) -#endif +#define O_TMPFILE 020200000 #endif -int mkostemp(char *template, int flags); +#ifndef _GNU_SOURCE char *secure_getenv(const char *name); +int mkostemp(char *template, int flags); +#endif static SLJIT_INLINE int create_tempfile(void) { int fd; - char tmp_name[256]; - size_t tmp_name_len; + size_t tmp_name_len = 0; char *dir; - size_t len; - -#ifdef P_tmpdir - len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0; + struct stat st; +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + mode_t mode; +#endif - if (len > 0 && len < sizeof(tmp_name)) { - strcpy(tmp_name, P_tmpdir); - tmp_name_len = len; - } - else { - strcpy(tmp_name, "/tmp"); - tmp_name_len = 4; +#ifdef HAVE_MEMFD_CREATE + /* this is a GNU extension, make sure to use -D_GNU_SOURCE */ + fd = memfd_create("sljit", MFD_CLOEXEC); + if (fd != -1) { + fchmod(fd, 0); + return fd; } -#else - strcpy(tmp_name, "/tmp"); - tmp_name_len = 4; #endif dir = secure_getenv("TMPDIR"); + if (dir) { - len = strlen(dir); - if (len > 0 && len < sizeof(tmp_name)) { - strcpy(tmp_name, dir); - tmp_name_len = len; + tmp_name_len = strlen(dir); + if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) { + if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) + strcpy(tmp_name, dir); } } +#ifdef P_tmpdir + if (!tmp_name_len) { + tmp_name_len = strlen(P_tmpdir); + if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) + strcpy(tmp_name, P_tmpdir); + } +#endif + if (!tmp_name_len) { + strcpy(tmp_name, "/tmp"); + tmp_name_len = 4; + } + SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)); - while (tmp_name_len > 0 && tmp_name[tmp_name_len - 1] == '/') { - tmp_name_len--; - tmp_name[tmp_name_len] = '\0'; - } + if (tmp_name[tmp_name_len - 1] == '/') + tmp_name[--tmp_name_len] = '\0'; -#ifdef O_TMPFILE - fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, S_IRUSR | S_IWUSR); +#ifdef __linux__ + /* + * the previous trimming might had left an empty string if TMPDIR="/" + * so work around the problem below + */ + fd = open(tmp_name_len ? tmp_name : "/", + O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0); if (fd != -1) return fd; #endif if (tmp_name_len + 7 >= sizeof(tmp_name)) - { return -1; - } strcpy(tmp_name + tmp_name_len, "/XXXXXX"); +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + mode = umask(0777); +#endif fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME); +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + umask(mode); +#else + fchmod(fd, 0); +#endif if (fd == -1) - return fd; + return -1; if (unlink(tmp_name)) { close(fd); @@ -189,23 +209,52 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size) retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); if (retval->executable == MAP_FAILED) { - munmap(retval, size); + munmap((void *)retval, size); close(fd); return NULL; } - retval->fd = fd; + close(fd); return retval; } +#else +/* + * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to + * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed + */ +static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size) +{ + struct chunk_header *retval; + + retval = (struct chunk_header *)mmap(NULL, size, + PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC), + MAP_ANON | MAP_SHARED, -1, 0); + + if (retval == MAP_FAILED) + return NULL; + + retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP); + if (retval->executable == MAP_FAILED) { + munmap((void *)retval, size); + return NULL; + } + + if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) { + munmap(retval->executable, size); + munmap((void *)retval, size); + return NULL; + } + + return retval; +} +#endif /* NetBSD */ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) { struct chunk_header *header = ((struct chunk_header *)chunk) - 1; - int fd = header->fd; munmap(header->executable, size); - munmap(header, size); - close(fd); + munmap((void *)header, size); } /* --------------------------------------------------------------------- */ @@ -272,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) sljit_uw chunk_size; sljit_sw executable_offset; - allocator_grab_lock(); + SLJIT_ALLOCATOR_LOCK(); if (size < (64 - sizeof(struct block_header))) size = (64 - sizeof(struct block_header)); size = ALIGN_SIZE(size); @@ -297,7 +346,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) } allocated_size += size; header->size = size; - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); return MEM_START(header); } free_block = free_block->next; @@ -308,7 +357,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) chunk_header = alloc_chunk(chunk_size); if (!chunk_header) { - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); return NULL; } @@ -342,7 +391,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) next_header->size = 1; next_header->prev_size = chunk_size; next_header->executable_offset = executable_offset; - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); return MEM_START(header); } @@ -351,7 +400,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) struct block_header *header; struct free_block* free_block; - allocator_grab_lock(); + SLJIT_ALLOCATOR_LOCK(); header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); header = AS_BLOCK_HEADER(header, -header->executable_offset); allocated_size -= header->size; @@ -385,11 +434,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) if (total_size - free_block->size > (allocated_size * 3 / 2)) { total_size -= free_block->size; sljit_remove_free_block(free_block); - free_chunk(free_block, free_block->size + sizeof(struct block_header)); + free_chunk(free_block, free_block->size + + sizeof(struct chunk_header) + + sizeof(struct block_header)); } } - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); } SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) @@ -397,7 +448,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) struct free_block* free_block; struct free_block* next_free_block; - allocator_grab_lock(); + SLJIT_ALLOCATOR_LOCK(); free_block = free_blocks; while (free_block) { @@ -406,13 +457,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { total_size -= free_block->size; sljit_remove_free_block(free_block); - free_chunk(free_block, free_block->size + sizeof(struct block_header)); + free_chunk(free_block, free_block->size + + sizeof(struct chunk_header) + + sizeof(struct block_header)); } free_block = next_free_block; } SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); - allocator_release_lock(); + SLJIT_ALLOCATOR_UNLOCK(); } SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr) diff --git a/thirdparty/pcre2/src/sljit/sljitUtils.c b/thirdparty/pcre2/src/sljit/sljitUtils.c index 857492a174..08ca35cf37 100644 --- a/thirdparty/pcre2/src/sljit/sljitUtils.c +++ b/thirdparty/pcre2/src/sljit/sljitUtils.c @@ -28,220 +28,225 @@ /* Locks */ /* ------------------------------------------------------------------------ */ -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) +/* Executable Allocator */ +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \ + && !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) +#define SLJIT_ALLOCATOR_LOCK() +#define SLJIT_ALLOCATOR_UNLOCK() +#elif !(defined _WIN32) +#include <pthread.h> + +static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER; -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock) +#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock) +#else /* windows */ +static HANDLE allocator_lock; static SLJIT_INLINE void allocator_grab_lock(void) { - /* Always successful. */ + HANDLE lock; + if (SLJIT_UNLIKELY(!allocator_lock)) { + lock = CreateMutex(NULL, FALSE, NULL); + if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL)) + CloseHandle(lock); + } + WaitForSingleObject(allocator_lock, INFINITE); } -static SLJIT_INLINE void allocator_release_lock(void) -{ - /* Always successful. */ -} +#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock() +#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock) +#endif /* thread implementation */ +#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */ -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ +/* ------------------------------------------------------------------------ */ +/* Stack */ +/* ------------------------------------------------------------------------ */ -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) +#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \ + && !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \ + || ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \ + && !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \ + || (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR))) -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void) -{ - /* Always successful. */ -} +#ifndef _WIN32 +/* Provides mmap function. */ +#include <sys/types.h> +#include <sys/mman.h> -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void) -{ - /* Always successful. */ -} +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#endif /* MAP_ANONYMOUS */ +#endif /* !MAP_ANON */ -#endif /* SLJIT_UTIL_GLOBAL_LOCK */ +#ifndef MAP_ANON -#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */ +#include <fcntl.h> -#include "windows.h" +#ifdef O_CLOEXEC +#define SLJIT_CLOEXEC O_CLOEXEC +#else /* !O_CLOEXEC */ +#define SLJIT_CLOEXEC 0 +#endif /* O_CLOEXEC */ -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +/* Some old systems do not have MAP_ANON. */ +static int dev_zero = -1; -static HANDLE allocator_mutex = 0; +#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) -static SLJIT_INLINE void allocator_grab_lock(void) +static SLJIT_INLINE int open_dev_zero(void) { - /* No idea what to do if an error occures. Static mutexes should never fail... */ - if (!allocator_mutex) - allocator_mutex = CreateMutex(NULL, TRUE, NULL); - else - WaitForSingleObject(allocator_mutex, INFINITE); -} + dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC); -static SLJIT_INLINE void allocator_release_lock(void) -{ - ReleaseMutex(allocator_mutex); + return dev_zero < 0; } -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ +#else /* !SLJIT_SINGLE_THREADED */ -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) +#include <pthread.h> -static HANDLE global_mutex = 0; +static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void) +static SLJIT_INLINE int open_dev_zero(void) { - /* No idea what to do if an error occures. Static mutexes should never fail... */ - if (!global_mutex) - global_mutex = CreateMutex(NULL, TRUE, NULL); - else - WaitForSingleObject(global_mutex, INFINITE); -} + pthread_mutex_lock(&dev_zero_mutex); + if (SLJIT_UNLIKELY(dev_zero < 0)) + dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC); -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void) -{ - ReleaseMutex(global_mutex); + pthread_mutex_unlock(&dev_zero_mutex); + return dev_zero < 0; } -#endif /* SLJIT_UTIL_GLOBAL_LOCK */ - -#else /* _WIN32 */ - -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) - -#include <pthread.h> +#endif /* SLJIT_SINGLE_THREADED */ +#undef SLJIT_CLOEXEC +#endif /* !MAP_ANON */ +#endif /* !_WIN32 */ +#endif /* open_dev_zero */ -static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \ + || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) -static SLJIT_INLINE void allocator_grab_lock(void) -{ - pthread_mutex_lock(&allocator_mutex); -} +#ifdef _WIN32 -static SLJIT_INLINE void allocator_release_lock(void) -{ - pthread_mutex_unlock(&allocator_mutex); +static SLJIT_INLINE sljit_sw get_page_alignment(void) { + SYSTEM_INFO si; + static sljit_sw sljit_page_align; + if (!sljit_page_align) { + GetSystemInfo(&si); + sljit_page_align = si.dwPageSize - 1; + } + return sljit_page_align; } -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ - -#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) - -#include <pthread.h> +#else -static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; +#include <unistd.h> -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void) -{ - pthread_mutex_lock(&global_mutex); +static SLJIT_INLINE sljit_sw get_page_alignment(void) { + static sljit_sw sljit_page_align; + if (!sljit_page_align) { + sljit_page_align = sysconf(_SC_PAGESIZE); + /* Should never happen. */ + if (sljit_page_align < 0) + sljit_page_align = 4096; + sljit_page_align--; + } + return sljit_page_align; } -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void) -{ - pthread_mutex_unlock(&global_mutex); -} +#endif /* _WIN32 */ -#endif /* SLJIT_UTIL_GLOBAL_LOCK */ +#endif /* get_page_alignment() */ -#endif /* _WIN32 */ +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) -/* ------------------------------------------------------------------------ */ -/* Stack */ -/* ------------------------------------------------------------------------ */ +#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION) -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data) +{ + struct sljit_stack *stack; + void *ptr; -#ifdef _WIN32 -#include "windows.h" -#else -/* Provides mmap function. */ -#include <sys/types.h> -#include <sys/mman.h> -#ifndef MAP_ANON -#ifdef MAP_ANONYMOUS -#define MAP_ANON MAP_ANONYMOUS -#endif -#endif -/* For detecting the page size. */ -#include <unistd.h> + SLJIT_UNUSED_ARG(allocator_data); -#ifndef MAP_ANON + if (start_size > max_size || start_size < 1) + return NULL; -#include <fcntl.h> + stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data); + if (stack == NULL) + return NULL; -/* Some old systems does not have MAP_ANON. */ -static sljit_s32 dev_zero = -1; + ptr = SLJIT_MALLOC(max_size, allocator_data); + if (ptr == NULL) { + SLJIT_FREE(stack, allocator_data); + return NULL; + } -#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + stack->min_start = (sljit_u8 *)ptr; + stack->end = stack->min_start + max_size; + stack->start = stack->end - start_size; + stack->top = stack->end; + return stack; +} -static SLJIT_INLINE sljit_s32 open_dev_zero(void) +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data) { - dev_zero = open("/dev/zero", O_RDWR); - return dev_zero < 0; + SLJIT_UNUSED_ARG(allocator_data); + SLJIT_FREE((void*)stack->min_start, allocator_data); + SLJIT_FREE(stack, allocator_data); } -#else /* SLJIT_SINGLE_THREADED */ - -#include <pthread.h> - -static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; - -static SLJIT_INLINE sljit_s32 open_dev_zero(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start) { - pthread_mutex_lock(&dev_zero_mutex); - /* The dev_zero might be initialized by another thread during the waiting. */ - if (dev_zero < 0) { - dev_zero = open("/dev/zero", O_RDWR); - } - pthread_mutex_unlock(&dev_zero_mutex); - return dev_zero < 0; + if ((new_start < stack->min_start) || (new_start >= stack->end)) + return NULL; + stack->start = new_start; + return new_start; } -#endif /* SLJIT_SINGLE_THREADED */ +#else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */ -#endif +#ifdef _WIN32 -#endif +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data) +{ + SLJIT_UNUSED_ARG(allocator_data); + VirtualFree((void*)stack->min_start, 0, MEM_RELEASE); + SLJIT_FREE(stack, allocator_data); +} -#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */ +#else /* !_WIN32 */ -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data) +{ + SLJIT_UNUSED_ARG(allocator_data); + munmap((void*)stack->min_start, stack->end - stack->min_start); + SLJIT_FREE(stack, allocator_data); +} -/* Planning to make it even more clever in the future. */ -static sljit_sw sljit_page_align = 0; +#endif /* _WIN32 */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data) { struct sljit_stack *stack; void *ptr; -#ifdef _WIN32 - SYSTEM_INFO si; -#endif + sljit_sw page_align; SLJIT_UNUSED_ARG(allocator_data); + if (start_size > max_size || start_size < 1) return NULL; -#ifdef _WIN32 - if (!sljit_page_align) { - GetSystemInfo(&si); - sljit_page_align = si.dwPageSize - 1; - } -#else - if (!sljit_page_align) { - sljit_page_align = sysconf(_SC_PAGESIZE); - /* Should never happen. */ - if (sljit_page_align < 0) - sljit_page_align = 4096; - sljit_page_align--; - } -#endif - stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data); - if (!stack) + if (stack == NULL) return NULL; /* Align max_size. */ - max_size = (max_size + sljit_page_align) & ~sljit_page_align; + page_align = get_page_alignment(); + max_size = (max_size + page_align) & ~page_align; #ifdef _WIN32 ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE); @@ -258,18 +263,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj sljit_free_stack(stack, allocator_data); return NULL; } -#else +#else /* !_WIN32 */ #ifdef MAP_ANON ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); -#else - if (dev_zero < 0) { - if (open_dev_zero()) { - SLJIT_FREE(stack, allocator_data); - return NULL; - } +#else /* !MAP_ANON */ + if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) { + SLJIT_FREE(stack, allocator_data); + return NULL; } ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0); -#endif +#endif /* MAP_ANON */ if (ptr == MAP_FAILED) { SLJIT_FREE(stack, allocator_data); return NULL; @@ -277,35 +280,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj stack->min_start = (sljit_u8 *)ptr; stack->end = stack->min_start + max_size; stack->start = stack->end - start_size; -#endif +#endif /* _WIN32 */ + stack->top = stack->end; return stack; } -#undef PAGE_ALIGN - -SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data) -{ - SLJIT_UNUSED_ARG(allocator_data); -#ifdef _WIN32 - VirtualFree((void*)stack->min_start, 0, MEM_RELEASE); -#else - munmap((void*)stack->min_start, stack->end - stack->min_start); -#endif - SLJIT_FREE(stack, allocator_data); -} - SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start) { +#if defined _WIN32 || defined(POSIX_MADV_DONTNEED) sljit_uw aligned_old_start; sljit_uw aligned_new_start; + sljit_sw page_align; +#endif if ((new_start < stack->min_start) || (new_start >= stack->end)) return NULL; #ifdef _WIN32 - aligned_new_start = (sljit_uw)new_start & ~sljit_page_align; - aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align; + page_align = get_page_alignment(); + + aligned_new_start = (sljit_uw)new_start & ~page_align; + aligned_old_start = ((sljit_uw)stack->start) & ~page_align; if (aligned_new_start != aligned_old_start) { if (aligned_new_start < aligned_old_start) { if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE)) @@ -316,24 +312,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st return NULL; } } -#else - if (stack->start < new_start) { - aligned_new_start = (sljit_uw)new_start & ~sljit_page_align; - aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align; - /* If madvise is available, we release the unnecessary space. */ -#if defined(MADV_DONTNEED) - if (aligned_new_start > aligned_old_start) - madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED); #elif defined(POSIX_MADV_DONTNEED) - if (aligned_new_start > aligned_old_start) + if (stack->start < new_start) { + page_align = get_page_alignment(); + + aligned_new_start = (sljit_uw)new_start & ~page_align; + aligned_old_start = ((sljit_uw)stack->start) & ~page_align; + + if (aligned_new_start > aligned_old_start) { posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED); -#endif +#ifdef MADV_FREE + madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE); +#endif /* MADV_FREE */ + } } -#endif +#endif /* _WIN32 */ + stack->start = new_start; return new_start; } -#endif /* SLJIT_UTIL_STACK */ +#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */ -#endif +#endif /* SLJIT_UTIL_STACK */ diff --git a/thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c new file mode 100644 index 0000000000..6ef71f7d83 --- /dev/null +++ b/thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c @@ -0,0 +1,225 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + This file contains a simple W^X executable memory allocator for POSIX + like systems and Windows + + In *NIX, MAP_ANON is required (that is considered a feature) so make + sure to set the right availability macros for your system or the code + will fail to build. + + If your system doesn't support mapping of anonymous pages (ex: IRIX) it + is also likely that it doesn't need this allocator and should be using + the standard one instead. + + It allocates a separate map for each code block and may waste a lot of + memory, because whatever was requested, will be rounded up to the page + size (minimum 4KB, but could be even bigger). + + It changes the page permissions (RW <-> RX) as needed and therefore, if you + will be updating the code after it has been generated, need to make sure to + block any concurrent execution, or could result in a SIGBUS, that could + even manifest itself at a different address than the one that was being + modified. + + Only use if you are unable to use the regular allocator because of security + restrictions and adding exceptions to your application or the system are + not possible. +*/ + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + sljit_update_wx_flags((from), (to), (enable_exec)) + +#ifndef _WIN32 +#include <sys/types.h> +#include <sys/mman.h> + +#ifdef __NetBSD__ +#if defined(PROT_MPROTECT) +#define check_se_protected(ptr, size) (0) +#define SLJIT_PROT_WX PROT_MPROTECT(PROT_EXEC) +#else /* !PROT_MPROTECT */ +#ifdef _NETBSD_SOURCE +#include <sys/param.h> +#else /* !_NETBSD_SOURCE */ +typedef unsigned int u_int; +#define devmajor_t sljit_s32 +#endif /* _NETBSD_SOURCE */ +#include <sys/sysctl.h> +#include <unistd.h> + +#define check_se_protected(ptr, size) netbsd_se_protected() + +static SLJIT_INLINE int netbsd_se_protected(void) +{ + int mib[3]; + int paxflags; + size_t len = sizeof(paxflags); + + mib[0] = CTL_PROC; + mib[1] = getpid(); + mib[2] = PROC_PID_PAXFLAGS; + + if (SLJIT_UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) < 0)) + return -1; + + return (paxflags & CTL_PROC_PAXFLAGS_MPROTECT) ? -1 : 0; +} +#endif /* PROT_MPROTECT */ +#else /* POSIX */ +#define check_se_protected(ptr, size) generic_se_protected(ptr, size) + +static SLJIT_INLINE int generic_se_protected(void *ptr, sljit_uw size) +{ + if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC))) + return mprotect(ptr, size, PROT_READ | PROT_WRITE); + + return -1; +} +#endif /* NetBSD */ + +#if defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED +#define SLJIT_SE_LOCK() +#define SLJIT_SE_UNLOCK() +#else /* !SLJIT_SINGLE_THREADED */ +#include <pthread.h> +#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock) +#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock) +#endif /* SLJIT_SINGLE_THREADED */ + +#ifndef SLJIT_PROT_WX +#define SLJIT_PROT_WX 0 +#endif /* !SLJIT_PROT_WX */ + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ +#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + static int se_protected = !SLJIT_PROT_WX; + sljit_uw* ptr; + + if (SLJIT_UNLIKELY(se_protected < 0)) + return NULL; + + size += sizeof(sljit_uw); + ptr = (sljit_uw*)mmap(NULL, size, PROT_READ | PROT_WRITE | SLJIT_PROT_WX, + MAP_PRIVATE | MAP_ANON, -1, 0); + + if (ptr == MAP_FAILED) + return NULL; + + if (SLJIT_UNLIKELY(se_protected > 0)) { + SLJIT_SE_LOCK(); + se_protected = check_se_protected(ptr, size); + SLJIT_SE_UNLOCK(); + if (SLJIT_UNLIKELY(se_protected < 0)) { + munmap((void *)ptr, size); + return NULL; + } + } + + *ptr++ = size; + return ptr; +} + +#undef SLJIT_PROT_WX +#undef SLJIT_SE_UNLOCK +#undef SLJIT_SE_LOCK + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1; + munmap((void*)start_ptr, *start_ptr); +} + +static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec) +{ + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + sljit_uw start = (sljit_uw)from; + sljit_uw end = (sljit_uw)to; + int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE); + + SLJIT_ASSERT(start < end); + + start &= ~page_mask; + end = (end + page_mask) & ~page_mask; + + mprotect((void*)start, end - start, prot); +} + +#else /* windows */ + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + sljit_uw *ptr; + + size += sizeof(sljit_uw); + ptr = (sljit_uw*)VirtualAlloc(NULL, size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (!ptr) + return NULL; + + *ptr++ = size; + + return ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw); +#if defined(SLJIT_DEBUG) && SLJIT_DEBUG + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + + SLJIT_ASSERT(!(start & page_mask)); +#endif + VirtualFree((void*)start, 0, MEM_RELEASE); +} + +static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec) +{ + DWORD oldprot; + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + sljit_uw start = (sljit_uw)from; + sljit_uw end = (sljit_uw)to; + DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE; + + SLJIT_ASSERT(start < end); + + start &= ~page_mask; + end = (end + page_mask) & ~page_mask; + + VirtualProtect((void*)start, end - start, prot, &oldprot); +} + +#endif /* !windows */ + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + /* This allocator does not keep unused memory for future allocations. */ +} diff --git a/thirdparty/spirv-reflect/LICENSE b/thirdparty/spirv-reflect/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/thirdparty/spirv-reflect/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h b/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h index a61a2d2935..949f1980e7 100644 --- a/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h +++ b/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2014-2018 The Khronos Group Inc. +** Copyright (c) 2014-2020 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and/or associated documentation files (the "Materials"), @@ -31,13 +31,16 @@ /* ** Enumeration tokens for SPIR-V, in various styles: -** C, C++, C++11, JSON, Lua, Python +** C, C++, C++11, JSON, Lua, Python, C#, D ** ** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL ** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL ** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL ** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL ** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** - C# will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL ** ** Some tokens act like mask values, which can be OR'd together, ** while others are mutually exclusive. The mask-like ones have @@ -50,12 +53,12 @@ typedef unsigned int SpvId; -#define SPV_VERSION 0x10300 -#define SPV_REVISION 1 +#define SPV_VERSION 0x10500 +#define SPV_REVISION 4 static const unsigned int SpvMagicNumber = 0x07230203; -static const unsigned int SpvVersion = 0x00010300; -static const unsigned int SpvRevision = 1; +static const unsigned int SpvVersion = 0x00010500; +static const unsigned int SpvRevision = 4; static const unsigned int SpvOpCodeMask = 0xffff; static const unsigned int SpvWordCountShift = 16; @@ -77,6 +80,20 @@ typedef enum SpvExecutionModel_ { SpvExecutionModelFragment = 4, SpvExecutionModelGLCompute = 5, SpvExecutionModelKernel = 6, + SpvExecutionModelTaskNV = 5267, + SpvExecutionModelMeshNV = 5268, + SpvExecutionModelRayGenerationKHR = 5313, + SpvExecutionModelRayGenerationNV = 5313, + SpvExecutionModelIntersectionKHR = 5314, + SpvExecutionModelIntersectionNV = 5314, + SpvExecutionModelAnyHitKHR = 5315, + SpvExecutionModelAnyHitNV = 5315, + SpvExecutionModelClosestHitKHR = 5316, + SpvExecutionModelClosestHitNV = 5316, + SpvExecutionModelMissKHR = 5317, + SpvExecutionModelMissNV = 5317, + SpvExecutionModelCallableKHR = 5318, + SpvExecutionModelCallableNV = 5318, SpvExecutionModelMax = 0x7fffffff, } SpvExecutionModel; @@ -84,6 +101,8 @@ typedef enum SpvAddressingModel_ { SpvAddressingModelLogical = 0, SpvAddressingModelPhysical32 = 1, SpvAddressingModelPhysical64 = 2, + SpvAddressingModelPhysicalStorageBuffer64 = 5348, + SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, SpvAddressingModelMax = 0x7fffffff, } SpvAddressingModel; @@ -91,6 +110,8 @@ typedef enum SpvMemoryModel_ { SpvMemoryModelSimple = 0, SpvMemoryModelGLSL450 = 1, SpvMemoryModelOpenCL = 2, + SpvMemoryModelVulkan = 3, + SpvMemoryModelVulkanKHR = 3, SpvMemoryModelMax = 0x7fffffff, } SpvMemoryModel; @@ -134,7 +155,27 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeLocalSizeId = 38, SpvExecutionModeLocalSizeHintId = 39, SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeDenormPreserve = 4459, + SpvExecutionModeDenormFlushToZero = 4460, + SpvExecutionModeSignedZeroInfNanPreserve = 4461, + SpvExecutionModeRoundingModeRTE = 4462, + SpvExecutionModeRoundingModeRTZ = 4463, SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeOutputLinesNV = 5269, + SpvExecutionModeOutputPrimitivesNV = 5270, + SpvExecutionModeDerivativeGroupQuadsNV = 5289, + SpvExecutionModeDerivativeGroupLinearNV = 5290, + SpvExecutionModeOutputTrianglesNV = 5298, + SpvExecutionModePixelInterlockOrderedEXT = 5366, + SpvExecutionModePixelInterlockUnorderedEXT = 5367, + SpvExecutionModeSampleInterlockOrderedEXT = 5368, + SpvExecutionModeSampleInterlockUnorderedEXT = 5369, + SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, + SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, + SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, + SpvExecutionModeMaxWorkDimINTEL = 5894, + SpvExecutionModeNoGlobalOffsetINTEL = 5895, + SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, SpvExecutionModeMax = 0x7fffffff, } SpvExecutionMode; @@ -152,6 +193,21 @@ typedef enum SpvStorageClass_ { SpvStorageClassAtomicCounter = 10, SpvStorageClassImage = 11, SpvStorageClassStorageBuffer = 12, + SpvStorageClassCallableDataKHR = 5328, + SpvStorageClassCallableDataNV = 5328, + SpvStorageClassIncomingCallableDataKHR = 5329, + SpvStorageClassIncomingCallableDataNV = 5329, + SpvStorageClassRayPayloadKHR = 5338, + SpvStorageClassRayPayloadNV = 5338, + SpvStorageClassHitAttributeKHR = 5339, + SpvStorageClassHitAttributeNV = 5339, + SpvStorageClassIncomingRayPayloadKHR = 5342, + SpvStorageClassIncomingRayPayloadNV = 5342, + SpvStorageClassShaderRecordBufferKHR = 5343, + SpvStorageClassShaderRecordBufferNV = 5343, + SpvStorageClassPhysicalStorageBuffer = 5349, + SpvStorageClassPhysicalStorageBufferEXT = 5349, + SpvStorageClassCodeSectionINTEL = 5605, SpvStorageClassMax = 0x7fffffff, } SpvStorageClass; @@ -222,6 +278,8 @@ typedef enum SpvImageFormat_ { SpvImageFormatRg8ui = 37, SpvImageFormatR16ui = 38, SpvImageFormatR8ui = 39, + SpvImageFormatR64ui = 40, + SpvImageFormatR64i = 41, SpvImageFormatMax = 0x7fffffff, } SpvImageFormat; @@ -279,6 +337,16 @@ typedef enum SpvImageOperandsShift_ { SpvImageOperandsConstOffsetsShift = 5, SpvImageOperandsSampleShift = 6, SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMakeTexelAvailableShift = 8, + SpvImageOperandsMakeTexelAvailableKHRShift = 8, + SpvImageOperandsMakeTexelVisibleShift = 9, + SpvImageOperandsMakeTexelVisibleKHRShift = 9, + SpvImageOperandsNonPrivateTexelShift = 10, + SpvImageOperandsNonPrivateTexelKHRShift = 10, + SpvImageOperandsVolatileTexelShift = 11, + SpvImageOperandsVolatileTexelKHRShift = 11, + SpvImageOperandsSignExtendShift = 12, + SpvImageOperandsZeroExtendShift = 13, SpvImageOperandsMax = 0x7fffffff, } SpvImageOperandsShift; @@ -292,6 +360,16 @@ typedef enum SpvImageOperandsMask_ { SpvImageOperandsConstOffsetsMask = 0x00000020, SpvImageOperandsSampleMask = 0x00000040, SpvImageOperandsMinLodMask = 0x00000080, + SpvImageOperandsMakeTexelAvailableMask = 0x00000100, + SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + SpvImageOperandsMakeTexelVisibleMask = 0x00000200, + SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + SpvImageOperandsNonPrivateTexelMask = 0x00000400, + SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, + SpvImageOperandsVolatileTexelMask = 0x00000800, + SpvImageOperandsVolatileTexelKHRMask = 0x00000800, + SpvImageOperandsSignExtendMask = 0x00001000, + SpvImageOperandsZeroExtendMask = 0x00002000, } SpvImageOperandsMask; typedef enum SpvFPFastMathModeShift_ { @@ -372,6 +450,7 @@ typedef enum SpvDecoration_ { SpvDecorationNonWritable = 24, SpvDecorationNonReadable = 25, SpvDecorationUniform = 26, + SpvDecorationUniformId = 27, SpvDecorationSaturatedConversion = 28, SpvDecorationStream = 29, SpvDecorationLocation = 30, @@ -392,13 +471,41 @@ typedef enum SpvDecoration_ { SpvDecorationMaxByteOffset = 45, SpvDecorationAlignmentId = 46, SpvDecorationMaxByteOffsetId = 47, + SpvDecorationNoSignedWrap = 4469, + SpvDecorationNoUnsignedWrap = 4470, SpvDecorationExplicitInterpAMD = 4999, SpvDecorationOverrideCoverageNV = 5248, SpvDecorationPassthroughNV = 5250, SpvDecorationViewportRelativeNV = 5252, SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationPerPrimitiveNV = 5271, + SpvDecorationPerViewNV = 5272, + SpvDecorationPerTaskNV = 5273, + SpvDecorationPerVertexNV = 5285, + SpvDecorationNonUniform = 5300, + SpvDecorationNonUniformEXT = 5300, + SpvDecorationRestrictPointer = 5355, + SpvDecorationRestrictPointerEXT = 5355, + SpvDecorationAliasedPointer = 5356, + SpvDecorationAliasedPointerEXT = 5356, + SpvDecorationReferencedIndirectlyINTEL = 5602, + SpvDecorationCounterBuffer = 5634, SpvDecorationHlslCounterBufferGOOGLE = 5634, SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationUserSemantic = 5635, + SpvDecorationUserTypeGOOGLE = 5636, + SpvDecorationRegisterINTEL = 5825, + SpvDecorationMemoryINTEL = 5826, + SpvDecorationNumbanksINTEL = 5827, + SpvDecorationBankwidthINTEL = 5828, + SpvDecorationMaxPrivateCopiesINTEL = 5829, + SpvDecorationSinglepumpINTEL = 5830, + SpvDecorationDoublepumpINTEL = 5831, + SpvDecorationMaxReplicatesINTEL = 5832, + SpvDecorationSimpleDualPortINTEL = 5833, + SpvDecorationMergeINTEL = 5834, + SpvDecorationBankBitsINTEL = 5835, + SpvDecorationForcePow2DepthINTEL = 5836, SpvDecorationMax = 0x7fffffff, } SpvDecoration; @@ -457,8 +564,10 @@ typedef enum SpvBuiltIn_ { SpvBuiltInBaseVertex = 4424, SpvBuiltInBaseInstance = 4425, SpvBuiltInDrawIndex = 4426, + SpvBuiltInPrimitiveShadingRateKHR = 4432, SpvBuiltInDeviceIndex = 4438, SpvBuiltInViewIndex = 4440, + SpvBuiltInShadingRateKHR = 4444, SpvBuiltInBaryCoordNoPerspAMD = 4992, SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, @@ -473,6 +582,52 @@ typedef enum SpvBuiltIn_ { SpvBuiltInPositionPerViewNV = 5261, SpvBuiltInViewportMaskPerViewNV = 5262, SpvBuiltInFullyCoveredEXT = 5264, + SpvBuiltInTaskCountNV = 5274, + SpvBuiltInPrimitiveCountNV = 5275, + SpvBuiltInPrimitiveIndicesNV = 5276, + SpvBuiltInClipDistancePerViewNV = 5277, + SpvBuiltInCullDistancePerViewNV = 5278, + SpvBuiltInLayerPerViewNV = 5279, + SpvBuiltInMeshViewCountNV = 5280, + SpvBuiltInMeshViewIndicesNV = 5281, + SpvBuiltInBaryCoordNV = 5286, + SpvBuiltInBaryCoordNoPerspNV = 5287, + SpvBuiltInFragSizeEXT = 5292, + SpvBuiltInFragmentSizeNV = 5292, + SpvBuiltInFragInvocationCountEXT = 5293, + SpvBuiltInInvocationsPerPixelNV = 5293, + SpvBuiltInLaunchIdKHR = 5319, + SpvBuiltInLaunchIdNV = 5319, + SpvBuiltInLaunchSizeKHR = 5320, + SpvBuiltInLaunchSizeNV = 5320, + SpvBuiltInWorldRayOriginKHR = 5321, + SpvBuiltInWorldRayOriginNV = 5321, + SpvBuiltInWorldRayDirectionKHR = 5322, + SpvBuiltInWorldRayDirectionNV = 5322, + SpvBuiltInObjectRayOriginKHR = 5323, + SpvBuiltInObjectRayOriginNV = 5323, + SpvBuiltInObjectRayDirectionKHR = 5324, + SpvBuiltInObjectRayDirectionNV = 5324, + SpvBuiltInRayTminKHR = 5325, + SpvBuiltInRayTminNV = 5325, + SpvBuiltInRayTmaxKHR = 5326, + SpvBuiltInRayTmaxNV = 5326, + SpvBuiltInInstanceCustomIndexKHR = 5327, + SpvBuiltInInstanceCustomIndexNV = 5327, + SpvBuiltInObjectToWorldKHR = 5330, + SpvBuiltInObjectToWorldNV = 5330, + SpvBuiltInWorldToObjectKHR = 5331, + SpvBuiltInWorldToObjectNV = 5331, + SpvBuiltInHitTNV = 5332, + SpvBuiltInHitKindKHR = 5333, + SpvBuiltInHitKindNV = 5333, + SpvBuiltInIncomingRayFlagsKHR = 5351, + SpvBuiltInIncomingRayFlagsNV = 5351, + SpvBuiltInRayGeometryIndexKHR = 5352, + SpvBuiltInWarpsPerSMNV = 5374, + SpvBuiltInSMCountNV = 5375, + SpvBuiltInWarpIDNV = 5376, + SpvBuiltInSMIDNV = 5377, SpvBuiltInMax = 0x7fffffff, } SpvBuiltIn; @@ -493,6 +648,18 @@ typedef enum SpvLoopControlShift_ { SpvLoopControlDontUnrollShift = 1, SpvLoopControlDependencyInfiniteShift = 2, SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMinIterationsShift = 4, + SpvLoopControlMaxIterationsShift = 5, + SpvLoopControlIterationMultipleShift = 6, + SpvLoopControlPeelCountShift = 7, + SpvLoopControlPartialCountShift = 8, + SpvLoopControlInitiationIntervalINTELShift = 16, + SpvLoopControlMaxConcurrencyINTELShift = 17, + SpvLoopControlDependencyArrayINTELShift = 18, + SpvLoopControlPipelineEnableINTELShift = 19, + SpvLoopControlLoopCoalesceINTELShift = 20, + SpvLoopControlMaxInterleavingINTELShift = 21, + SpvLoopControlSpeculatedIterationsINTELShift = 22, SpvLoopControlMax = 0x7fffffff, } SpvLoopControlShift; @@ -502,6 +669,18 @@ typedef enum SpvLoopControlMask_ { SpvLoopControlDontUnrollMask = 0x00000002, SpvLoopControlDependencyInfiniteMask = 0x00000004, SpvLoopControlDependencyLengthMask = 0x00000008, + SpvLoopControlMinIterationsMask = 0x00000010, + SpvLoopControlMaxIterationsMask = 0x00000020, + SpvLoopControlIterationMultipleMask = 0x00000040, + SpvLoopControlPeelCountMask = 0x00000080, + SpvLoopControlPartialCountMask = 0x00000100, + SpvLoopControlInitiationIntervalINTELMask = 0x00010000, + SpvLoopControlMaxConcurrencyINTELMask = 0x00020000, + SpvLoopControlDependencyArrayINTELMask = 0x00040000, + SpvLoopControlPipelineEnableINTELMask = 0x00080000, + SpvLoopControlLoopCoalesceINTELMask = 0x00100000, + SpvLoopControlMaxInterleavingINTELMask = 0x00200000, + SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, } SpvLoopControlMask; typedef enum SpvFunctionControlShift_ { @@ -531,6 +710,13 @@ typedef enum SpvMemorySemanticsShift_ { SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, SpvMemorySemanticsAtomicCounterMemoryShift = 10, SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsOutputMemoryShift = 12, + SpvMemorySemanticsOutputMemoryKHRShift = 12, + SpvMemorySemanticsMakeAvailableShift = 13, + SpvMemorySemanticsMakeAvailableKHRShift = 13, + SpvMemorySemanticsMakeVisibleShift = 14, + SpvMemorySemanticsMakeVisibleKHRShift = 14, + SpvMemorySemanticsVolatileShift = 15, SpvMemorySemanticsMax = 0x7fffffff, } SpvMemorySemanticsShift; @@ -546,12 +732,25 @@ typedef enum SpvMemorySemanticsMask_ { SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, SpvMemorySemanticsImageMemoryMask = 0x00000800, + SpvMemorySemanticsOutputMemoryMask = 0x00001000, + SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, + SpvMemorySemanticsMakeAvailableMask = 0x00002000, + SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, + SpvMemorySemanticsMakeVisibleMask = 0x00004000, + SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, + SpvMemorySemanticsVolatileMask = 0x00008000, } SpvMemorySemanticsMask; typedef enum SpvMemoryAccessShift_ { SpvMemoryAccessVolatileShift = 0, SpvMemoryAccessAlignedShift = 1, SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMakePointerAvailableShift = 3, + SpvMemoryAccessMakePointerAvailableKHRShift = 3, + SpvMemoryAccessMakePointerVisibleShift = 4, + SpvMemoryAccessMakePointerVisibleKHRShift = 4, + SpvMemoryAccessNonPrivatePointerShift = 5, + SpvMemoryAccessNonPrivatePointerKHRShift = 5, SpvMemoryAccessMax = 0x7fffffff, } SpvMemoryAccessShift; @@ -560,6 +759,12 @@ typedef enum SpvMemoryAccessMask_ { SpvMemoryAccessVolatileMask = 0x00000001, SpvMemoryAccessAlignedMask = 0x00000002, SpvMemoryAccessNontemporalMask = 0x00000004, + SpvMemoryAccessMakePointerAvailableMask = 0x00000008, + SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, + SpvMemoryAccessMakePointerVisibleMask = 0x00000010, + SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, + SpvMemoryAccessNonPrivatePointerMask = 0x00000020, + SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, } SpvMemoryAccessMask; typedef enum SpvScope_ { @@ -568,6 +773,9 @@ typedef enum SpvScope_ { SpvScopeWorkgroup = 2, SpvScopeSubgroup = 3, SpvScopeInvocation = 4, + SpvScopeQueueFamily = 5, + SpvScopeQueueFamilyKHR = 5, + SpvScopeShaderCallKHR = 6, SpvScopeMax = 0x7fffffff, } SpvScope; @@ -667,6 +875,9 @@ typedef enum SpvCapability_ { SpvCapabilityGroupNonUniformShuffleRelative = 66, SpvCapabilityGroupNonUniformClustered = 67, SpvCapabilityGroupNonUniformQuad = 68, + SpvCapabilityShaderLayer = 69, + SpvCapabilityShaderViewportIndex = 70, + SpvCapabilityFragmentShadingRateKHR = 4422, SpvCapabilitySubgroupBallotKHR = 4423, SpvCapabilityDrawParameters = 4427, SpvCapabilitySubgroupVoteKHR = 4431, @@ -682,11 +893,25 @@ typedef enum SpvCapability_ { SpvCapabilityVariablePointers = 4442, SpvCapabilityAtomicStorageOps = 4445, SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityStorageBuffer8BitAccess = 4448, + SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, + SpvCapabilityStoragePushConstant8 = 4450, + SpvCapabilityDenormPreserve = 4464, + SpvCapabilityDenormFlushToZero = 4465, + SpvCapabilitySignedZeroInfNanPreserve = 4466, + SpvCapabilityRoundingModeRTE = 4467, + SpvCapabilityRoundingModeRTZ = 4468, + SpvCapabilityRayQueryProvisionalKHR = 4471, + SpvCapabilityRayQueryKHR = 4472, + SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478, + SpvCapabilityRayTracingKHR = 4479, SpvCapabilityFloat16ImageAMD = 5008, SpvCapabilityImageGatherBiasLodAMD = 5009, SpvCapabilityFragmentMaskAMD = 5010, SpvCapabilityStencilExportEXT = 5013, SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilityInt64ImageEXT = 5016, + SpvCapabilityShaderClockKHR = 5055, SpvCapabilitySampleMaskOverrideCoverageNV = 5249, SpvCapabilityGeometryShaderPassthroughNV = 5251, SpvCapabilityShaderViewportIndexLayerEXT = 5254, @@ -695,13 +920,137 @@ typedef enum SpvCapability_ { SpvCapabilityShaderStereoViewNV = 5259, SpvCapabilityPerViewAttributesNV = 5260, SpvCapabilityFragmentFullyCoveredEXT = 5265, + SpvCapabilityMeshShadingNV = 5266, + SpvCapabilityImageFootprintNV = 5282, + SpvCapabilityFragmentBarycentricNV = 5284, + SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, + SpvCapabilityFragmentDensityEXT = 5291, + SpvCapabilityShadingRateNV = 5291, SpvCapabilityGroupNonUniformPartitionedNV = 5297, + SpvCapabilityShaderNonUniform = 5301, + SpvCapabilityShaderNonUniformEXT = 5301, + SpvCapabilityRuntimeDescriptorArray = 5302, + SpvCapabilityRuntimeDescriptorArrayEXT = 5302, + SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303, + SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306, + SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + SpvCapabilitySampledImageArrayNonUniformIndexing = 5307, + SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308, + SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + SpvCapabilityStorageImageArrayNonUniformIndexing = 5309, + SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310, + SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + SpvCapabilityRayTracingNV = 5340, + SpvCapabilityVulkanMemoryModel = 5345, + SpvCapabilityVulkanMemoryModelKHR = 5345, + SpvCapabilityVulkanMemoryModelDeviceScope = 5346, + SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + SpvCapabilityPhysicalStorageBufferAddresses = 5347, + SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, + SpvCapabilityComputeDerivativeGroupLinearNV = 5350, + SpvCapabilityRayTracingProvisionalKHR = 5353, + SpvCapabilityCooperativeMatrixNV = 5357, + SpvCapabilityFragmentShaderSampleInterlockEXT = 5363, + SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, + SpvCapabilityShaderSMBuiltinsNV = 5373, + SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, + SpvCapabilityDemoteToHelperInvocationEXT = 5379, SpvCapabilitySubgroupShuffleINTEL = 5568, SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, + SpvCapabilityIntegerFunctions2INTEL = 5584, + SpvCapabilityFunctionPointersINTEL = 5603, + SpvCapabilityIndirectReferencesINTEL = 5604, + SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, + SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + SpvCapabilityFPGAMemoryAttributesINTEL = 5824, + SpvCapabilityUnstructuredLoopControlsINTEL = 5886, + SpvCapabilityFPGALoopControlsINTEL = 5888, + SpvCapabilityKernelAttributesINTEL = 5892, + SpvCapabilityFPGAKernelAttributesINTEL = 5897, + SpvCapabilityBlockingPipesINTEL = 5945, + SpvCapabilityFPGARegINTEL = 5948, + SpvCapabilityAtomicFloat32AddEXT = 6033, + SpvCapabilityAtomicFloat64AddEXT = 6034, SpvCapabilityMax = 0x7fffffff, } SpvCapability; +typedef enum SpvRayFlagsShift_ { + SpvRayFlagsOpaqueKHRShift = 0, + SpvRayFlagsNoOpaqueKHRShift = 1, + SpvRayFlagsTerminateOnFirstHitKHRShift = 2, + SpvRayFlagsSkipClosestHitShaderKHRShift = 3, + SpvRayFlagsCullBackFacingTrianglesKHRShift = 4, + SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5, + SpvRayFlagsCullOpaqueKHRShift = 6, + SpvRayFlagsCullNoOpaqueKHRShift = 7, + SpvRayFlagsSkipTrianglesKHRShift = 8, + SpvRayFlagsSkipAABBsKHRShift = 9, + SpvRayFlagsMax = 0x7fffffff, +} SpvRayFlagsShift; + +typedef enum SpvRayFlagsMask_ { + SpvRayFlagsMaskNone = 0, + SpvRayFlagsOpaqueKHRMask = 0x00000001, + SpvRayFlagsNoOpaqueKHRMask = 0x00000002, + SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + SpvRayFlagsCullOpaqueKHRMask = 0x00000040, + SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080, + SpvRayFlagsSkipTrianglesKHRMask = 0x00000100, + SpvRayFlagsSkipAABBsKHRMask = 0x00000200, +} SpvRayFlagsMask; + +typedef enum SpvRayQueryIntersection_ { + SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + SpvRayQueryIntersectionMax = 0x7fffffff, +} SpvRayQueryIntersection; + +typedef enum SpvRayQueryCommittedIntersectionType_ { + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCommittedIntersectionType; + +typedef enum SpvRayQueryCandidateIntersectionType_ { + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCandidateIntersectionType; + +typedef enum SpvFragmentShadingRateShift_ { + SpvFragmentShadingRateVertical2PixelsShift = 0, + SpvFragmentShadingRateVertical4PixelsShift = 1, + SpvFragmentShadingRateHorizontal2PixelsShift = 2, + SpvFragmentShadingRateHorizontal4PixelsShift = 3, + SpvFragmentShadingRateMax = 0x7fffffff, +} SpvFragmentShadingRateShift; + +typedef enum SpvFragmentShadingRateMask_ { + SpvFragmentShadingRateMaskNone = 0, + SpvFragmentShadingRateVertical2PixelsMask = 0x00000001, + SpvFragmentShadingRateVertical4PixelsMask = 0x00000002, + SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004, + SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, +} SpvFragmentShadingRateMask; + typedef enum SpvOp_ { SpvOpNop = 0, SpvOpUndef = 1, @@ -1043,12 +1392,29 @@ typedef enum SpvOp_ { SpvOpGroupNonUniformLogicalXor = 364, SpvOpGroupNonUniformQuadBroadcast = 365, SpvOpGroupNonUniformQuadSwap = 366, + SpvOpCopyLogical = 400, + SpvOpPtrEqual = 401, + SpvOpPtrNotEqual = 402, + SpvOpPtrDiff = 403, + SpvOpTerminateInvocation = 4416, SpvOpSubgroupBallotKHR = 4421, SpvOpSubgroupFirstInvocationKHR = 4422, SpvOpSubgroupAllKHR = 4428, SpvOpSubgroupAnyKHR = 4429, SpvOpSubgroupAllEqualKHR = 4430, SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpTraceRayKHR = 4445, + SpvOpExecuteCallableKHR = 4446, + SpvOpConvertUToAccelerationStructureKHR = 4447, + SpvOpIgnoreIntersectionKHR = 4448, + SpvOpTerminateRayKHR = 4449, + SpvOpTypeRayQueryKHR = 4472, + SpvOpRayQueryInitializeKHR = 4473, + SpvOpRayQueryTerminateKHR = 4474, + SpvOpRayQueryGenerateIntersectionKHR = 4475, + SpvOpRayQueryConfirmIntersectionKHR = 4476, + SpvOpRayQueryProceedKHR = 4477, + SpvOpRayQueryGetIntersectionTypeKHR = 4479, SpvOpGroupIAddNonUniformAMD = 5000, SpvOpGroupFAddNonUniformAMD = 5001, SpvOpGroupFMinNonUniformAMD = 5002, @@ -1059,7 +1425,27 @@ typedef enum SpvOp_ { SpvOpGroupSMaxNonUniformAMD = 5007, SpvOpFragmentMaskFetchAMD = 5011, SpvOpFragmentFetchAMD = 5012, + SpvOpReadClockKHR = 5056, + SpvOpImageSampleFootprintNV = 5283, SpvOpGroupNonUniformPartitionNV = 5296, + SpvOpWritePackedPrimitiveIndices4x8NV = 5299, + SpvOpReportIntersectionKHR = 5334, + SpvOpReportIntersectionNV = 5334, + SpvOpIgnoreIntersectionNV = 5335, + SpvOpTerminateRayNV = 5336, + SpvOpTraceNV = 5337, + SpvOpTypeAccelerationStructureKHR = 5341, + SpvOpTypeAccelerationStructureNV = 5341, + SpvOpExecuteCallableNV = 5344, + SpvOpTypeCooperativeMatrixNV = 5358, + SpvOpCooperativeMatrixLoadNV = 5359, + SpvOpCooperativeMatrixStoreNV = 5360, + SpvOpCooperativeMatrixMulAddNV = 5361, + SpvOpCooperativeMatrixLengthNV = 5362, + SpvOpBeginInvocationInterlockEXT = 5364, + SpvOpEndInvocationInterlockEXT = 5365, + SpvOpDemoteToHelperInvocationEXT = 5380, + SpvOpIsHelperInvocationEXT = 5381, SpvOpSubgroupShuffleINTEL = 5571, SpvOpSubgroupShuffleDownINTEL = 5572, SpvOpSubgroupShuffleUpINTEL = 5573, @@ -1068,10 +1454,739 @@ typedef enum SpvOp_ { SpvOpSubgroupBlockWriteINTEL = 5576, SpvOpSubgroupImageBlockReadINTEL = 5577, SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpSubgroupImageMediaBlockReadINTEL = 5580, + SpvOpSubgroupImageMediaBlockWriteINTEL = 5581, + SpvOpUCountLeadingZerosINTEL = 5585, + SpvOpUCountTrailingZerosINTEL = 5586, + SpvOpAbsISubINTEL = 5587, + SpvOpAbsUSubINTEL = 5588, + SpvOpIAddSatINTEL = 5589, + SpvOpUAddSatINTEL = 5590, + SpvOpIAverageINTEL = 5591, + SpvOpUAverageINTEL = 5592, + SpvOpIAverageRoundedINTEL = 5593, + SpvOpUAverageRoundedINTEL = 5594, + SpvOpISubSatINTEL = 5595, + SpvOpUSubSatINTEL = 5596, + SpvOpIMul32x16INTEL = 5597, + SpvOpUMul32x16INTEL = 5598, + SpvOpFunctionPointerINTEL = 5600, + SpvOpFunctionPointerCallINTEL = 5601, + SpvOpDecorateString = 5632, SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateString = 5633, SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpVmeImageINTEL = 5699, + SpvOpTypeVmeImageINTEL = 5700, + SpvOpTypeAvcImePayloadINTEL = 5701, + SpvOpTypeAvcRefPayloadINTEL = 5702, + SpvOpTypeAvcSicPayloadINTEL = 5703, + SpvOpTypeAvcMcePayloadINTEL = 5704, + SpvOpTypeAvcMceResultINTEL = 5705, + SpvOpTypeAvcImeResultINTEL = 5706, + SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710, + SpvOpTypeAvcRefResultINTEL = 5711, + SpvOpTypeAvcSicResultINTEL = 5712, + SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733, + SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735, + SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737, + SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + SpvOpSubgroupAvcImeInitializeINTEL = 5747, + SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749, + SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750, + SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765, + SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776, + SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + SpvOpSubgroupAvcFmeInitializeINTEL = 5781, + SpvOpSubgroupAvcBmeInitializeINTEL = 5782, + SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790, + SpvOpSubgroupAvcSicInitializeINTEL = 5791, + SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792, + SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803, + SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808, + SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + SpvOpLoopControlINTEL = 5887, + SpvOpReadPipeBlockingINTEL = 5946, + SpvOpWritePipeBlockingINTEL = 5947, + SpvOpFPGARegINTEL = 5949, + SpvOpRayQueryGetRayTMinKHR = 6016, + SpvOpRayQueryGetRayFlagsKHR = 6017, + SpvOpRayQueryGetIntersectionTKHR = 6018, + SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020, + SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022, + SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024, + SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025, + SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + SpvOpRayQueryGetWorldRayDirectionKHR = 6029, + SpvOpRayQueryGetWorldRayOriginKHR = 6030, + SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, + SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, + SpvOpAtomicFAddEXT = 6035, SpvOpMax = 0x7fffffff, } SpvOp; -#endif // #ifndef spirv_H +#ifdef SPV_ENABLE_UTILITY_CODE +inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case SpvOpNop: *hasResult = false; *hasResultType = false; break; + case SpvOpUndef: *hasResult = true; *hasResultType = true; break; + case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break; + case SpvOpSource: *hasResult = false; *hasResultType = false; break; + case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpName: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberName: *hasResult = false; *hasResultType = false; break; + case SpvOpString: *hasResult = true; *hasResultType = false; break; + case SpvOpLine: *hasResult = false; *hasResultType = false; break; + case SpvOpExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break; + case SpvOpExtInst: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break; + case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break; + case SpvOpCapability: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case SpvOpFunction: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break; + case SpvOpVariable: *hasResult = true; *hasResultType = true; break; + case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case SpvOpLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpStore: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break; + case SpvOpTranspose: *hasResult = true; *hasResultType = true; break; + case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageRead: *hasResult = true; *hasResultType = true; break; + case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break; + case SpvOpImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break; + case SpvOpUConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpSConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpFConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case SpvOpBitcast: *hasResult = true; *hasResultType = true; break; + case SpvOpSNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpFNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpISub: *hasResult = true; *hasResultType = true; break; + case SpvOpFSub: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpUDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpSDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpFDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpUMod: *hasResult = true; *hasResultType = true; break; + case SpvOpSRem: *hasResult = true; *hasResultType = true; break; + case SpvOpSMod: *hasResult = true; *hasResultType = true; break; + case SpvOpFRem: *hasResult = true; *hasResultType = true; break; + case SpvOpFMod: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break; + case SpvOpDot: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break; + case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break; + case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpAny: *hasResult = true; *hasResultType = true; break; + case SpvOpAll: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNan: *hasResult = true; *hasResultType = true; break; + case SpvOpIsInf: *hasResult = true; *hasResultType = true; break; + case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break; + case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break; + case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case SpvOpOrdered: *hasResult = true; *hasResultType = true; break; + case SpvOpUnordered: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break; + case SpvOpSelect: *hasResult = true; *hasResultType = true; break; + case SpvOpIEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpNot: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break; + case SpvOpBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdx: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdy: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidth: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break; + case SpvOpPhi: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpLabel: *hasResult = true; *hasResultType = false; break; + case SpvOpBranch: *hasResult = false; *hasResultType = false; break; + case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break; + case SpvOpSwitch: *hasResult = false; *hasResultType = false; break; + case SpvOpKill: *hasResult = false; *hasResultType = false; break; + case SpvOpReturn: *hasResult = false; *hasResultType = false; break; + case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break; + case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case SpvOpNoLine: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break; + case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break; + case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +#endif diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c index 3df963d1ae..0fc979a8a4 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.c +++ b/thirdparty/spirv-reflect/spirv_reflect.c @@ -27,6 +27,13 @@ #include <stdlib.h> #endif +#if defined(SPIRV_REFLECT_ENABLE_ASSERTS) + #define SPV_REFLECT_ASSERT(COND) \ + assert(COND); +#else +#define SPV_REFLECT_ASSERT(COND) +#endif + // Temporary enums until these make it into SPIR-V/Vulkan // clang-format off enum { @@ -192,7 +199,7 @@ typedef struct Parser { SpvSourceLanguage source_language; uint32_t source_language_version; uint32_t source_file_id; - String source_embedded; + const char* source_embedded; size_t node_count; Node* nodes; uint32_t entry_point_count; @@ -552,6 +559,7 @@ static void DestroyParser(Parser* p_parser) SafeFree(p_parser->nodes); SafeFree(p_parser->strings); + SafeFree(p_parser->source_embedded); SafeFree(p_parser->functions); SafeFree(p_parser->access_chains); p_parser->node_count = 0; @@ -605,6 +613,7 @@ static SpvReflectResult ParseNodes(Parser* p_parser) } // Mark source file id node p_parser->source_file_id = (uint32_t)INVALID_VALUE; + p_parser->source_embedded = NULL; // Function node uint32_t function_node = (uint32_t)INVALID_VALUE; @@ -645,6 +654,48 @@ static SpvReflectResult ParseNodes(Parser* p_parser) if (p_node->word_count >= 4) { CHECKED_READU32(p_parser, p_node->word_offset + 3, p_parser->source_file_id); } + if (p_node->word_count >= 5) { + const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 4); + + const size_t source_len = strlen(p_source); + char* p_source_temp = (char*)calloc(source_len + 1, sizeof(char*)); + + if (IsNull(p_source_temp)) { + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; + } + + #ifdef _WIN32 + strcpy_s(p_source_temp, source_len + 1, p_source); + #else + strcpy(p_source_temp, p_source); + #endif + + p_parser->source_embedded = p_source_temp; + } + } + break; + + case SpvOpSourceContinued: { + const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 1); + + const size_t source_len = strlen(p_source); + const size_t embedded_source_len = strlen(p_parser->source_embedded); + char* p_continued_source = (char*)calloc(source_len + embedded_source_len + 1, sizeof(char*)); + + if (IsNull(p_continued_source)) { + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; + } + + #ifdef _WIN32 + strcpy_s(p_continued_source, embedded_source_len + 1, p_parser->source_embedded); + strcat_s(p_continued_source, source_len + 1, p_source); + #else + strcpy(p_continued_source, p_parser->source_embedded); + strcat(p_continued_source, p_source); + #endif + + SafeFree(p_parser->source_embedded); + p_parser->source_embedded = p_continued_source; } break; @@ -680,6 +731,8 @@ static SpvReflectResult ParseNodes(Parser* p_parser) case SpvOpTypeReserveId: case SpvOpTypeQueue: case SpvOpTypePipe: + case SpvOpTypeAccelerationStructureKHR: + case SpvOpTypeRayQueryKHR: { CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id); p_node->is_type = true; @@ -889,7 +942,7 @@ static SpvReflectResult ParseStrings(Parser* p_parser) ++string_index; } } - + return SPV_REFLECT_RESULT_SUCCESS; } @@ -909,6 +962,25 @@ static SpvReflectResult ParseSource(Parser* p_parser, SpvReflectShaderModule* p_ } } } + + //Source code + if (IsNotNull(p_parser->source_embedded)) + { + const size_t source_len = strlen(p_parser->source_embedded); + char* p_source = (char*)calloc(source_len + 1, sizeof(char*)); + + if (IsNull(p_source)) { + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; + } + + #ifdef _WIN32 + strcpy_s(p_source, source_len + 1, p_parser->source_embedded); + #else + strcpy(p_source, p_parser->source_embedded); + #endif + + p_module->source_source = p_source; + } } return SPV_REFLECT_RESULT_SUCCESS; @@ -1486,6 +1558,7 @@ static SpvReflectResult ParseType( } else { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } } break; @@ -1501,6 +1574,7 @@ static SpvReflectResult ParseType( } else { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } p_type->traits.numeric.matrix.row_count = p_type->traits.numeric.vector.component_count; p_type->traits.numeric.matrix.stride = p_node->decorations.matrix_stride; @@ -1536,7 +1610,8 @@ static SpvReflectResult ParseType( result = ParseType(p_parser, p_next_node, NULL, p_module, p_type); } else { - result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } } break; @@ -1567,6 +1642,7 @@ static SpvReflectResult ParseType( p_type->traits.array.dims_count += 1; } else { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } } // Parse next dimension or element type @@ -1577,6 +1653,7 @@ static SpvReflectResult ParseType( } else { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } } } @@ -1592,6 +1669,7 @@ static SpvReflectResult ParseType( } else { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } } break; @@ -1608,6 +1686,7 @@ static SpvReflectResult ParseType( Node* p_member_node = FindNode(p_parser, member_id); if (IsNull(p_member_node)) { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); break; } @@ -1643,9 +1722,15 @@ static SpvReflectResult ParseType( } else { result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + SPV_REFLECT_ASSERT(false); } } break; + + case SpvOpTypeAccelerationStructureKHR: { + p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE; + } + break; } if (result == SPV_REFLECT_RESULT_SUCCESS) { @@ -1718,7 +1803,9 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad for (size_t i = 0; i < p_parser->node_count; ++i) { Node* p_node = &(p_parser->nodes[i]); if ((p_node->op != SpvOpVariable) || - ((p_node->storage_class != SpvStorageClassUniform) && (p_node->storage_class != SpvStorageClassUniformConstant))) + ((p_node->storage_class != SpvStorageClassUniform) && + (p_node->storage_class != SpvStorageClassStorageBuffer) && + (p_node->storage_class != SpvStorageClassUniformConstant))) { continue; } @@ -1752,7 +1839,9 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad for (size_t i = 0; i < p_parser->node_count; ++i) { Node* p_node = &(p_parser->nodes[i]); if ((p_node->op != SpvOpVariable) || - ((p_node->storage_class != SpvStorageClassUniform) && (p_node->storage_class != SpvStorageClassUniformConstant)))\ + ((p_node->storage_class != SpvStorageClassUniform) && + (p_node->storage_class != SpvStorageClassStorageBuffer) && + (p_node->storage_class != SpvStorageClassUniformConstant))) { continue; } @@ -1764,8 +1853,11 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad if (IsNull(p_type)) { return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; } - // If the type is a pointer, resolve it + // If the type is a pointer, resolve it. We need to retain the storage class + // from the pointer so that we can use it to deduce deescriptor types. + SpvStorageClass pointer_storage_class = SpvStorageClassMax; if (p_type->op == SpvOpTypePointer) { + pointer_storage_class = p_type->storage_class; // Find the type's node Node* p_type_node = FindNode(p_parser, p_type->id); if (IsNull(p_type_node)) { @@ -1788,6 +1880,18 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad p_descriptor->uav_counter_id = p_node->decorations.uav_counter_buffer.value; p_descriptor->type_description = p_type; + // If this is in the StorageBuffer storage class, it's for sure a storage + // buffer descriptor. We need to handle this case earlier because in SPIR-V + // there are two ways to indicate a storage buffer: + // 1) Uniform storage class + BufferBlock decoration, or + // 2) StorageBuffer storage class + Buffer decoration. + // The 1) way is deprecated since SPIR-V v1.3. But the Buffer decoration is + // also used together with Uniform storage class to mean uniform buffer.. + // We'll handle the pre-v1.3 cases in ParseDescriptorType(). + if (pointer_storage_class == SpvStorageClassStorageBuffer) { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER; + } + // Copy image traits if ((p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) == SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE) { memcpy(&p_descriptor->image, &p_type->traits.image, sizeof(p_descriptor->image)); @@ -1840,78 +1944,84 @@ static SpvReflectResult ParseDescriptorType(SpvReflectShaderModule* p_module) SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]); SpvReflectTypeDescription* p_type = p_descriptor->type_description; - switch (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) { - default: assert(false && "unknown type flag"); break; + if ((int)p_descriptor->descriptor_type == (int)INVALID_VALUE) { + switch (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) { + default: assert(false && "unknown type flag"); break; - case SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE: { - if (p_descriptor->image.dim == SpvDimBuffer) { - switch (p_descriptor->image.sampled) { - default: assert(false && "unknown texel buffer sampled value"); break; - case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break; - case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break; + case SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE: { + if (p_descriptor->image.dim == SpvDimBuffer) { + switch (p_descriptor->image.sampled) { + default: assert(false && "unknown texel buffer sampled value"); break; + case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break; + case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break; + } } - } - else if(p_descriptor->image.dim == SpvDimSubpassData) { - p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; - } - else { - switch (p_descriptor->image.sampled) { - default: assert(false && "unknown image sampled value"); break; - case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE; break; - case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE; break; + else if(p_descriptor->image.dim == SpvDimSubpassData) { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + } + else { + switch (p_descriptor->image.sampled) { + default: assert(false && "unknown image sampled value"); break; + case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE; break; + case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE; break; + } } } - } - break; + break; - case SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER: { - p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER; - } - break; + case SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER: { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER; + } + break; - case (SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE): { - // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096 - if (p_descriptor->image.dim == SpvDimBuffer) { - switch (p_descriptor->image.sampled) { - default: assert(false && "unknown texel buffer sampled value"); break; - case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break; - case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break; + case (SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE): { + // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096 + if (p_descriptor->image.dim == SpvDimBuffer) { + switch (p_descriptor->image.sampled) { + default: assert(false && "unknown texel buffer sampled value"); break; + case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break; + case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break; + } + } + else { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; } } - else { - p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - } - } - break; + break; - case SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK: { - if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BLOCK) { - p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - } - else if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BUFFER_BLOCK) { - p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK: { + if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BLOCK) { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + } + else if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BUFFER_BLOCK) { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER; + } + else { + assert(false && "unknown struct"); + } } - else { - assert(false && "unknown struct"); + break; + + case SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE: { + p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; } + break; } - break; } switch (p_descriptor->descriptor_type) { - case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SAMPLER; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : p_descriptor->resource_type = (SpvReflectResourceType)(SPV_REFLECT_RESOURCE_FLAG_SAMPLER | SPV_REFLECT_RESOURCE_FLAG_SRV); break; - case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; - case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; - - case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - break; + case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SAMPLER; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : p_descriptor->resource_type = (SpvReflectResourceType)(SPV_REFLECT_RESOURCE_FLAG_SAMPLER | SPV_REFLECT_RESOURCE_FLAG_SRV); break; + case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break; + case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : break; + case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break; } } @@ -1950,7 +2060,7 @@ static SpvReflectResult ParseUAVCounterBindings(SpvReflectShaderModule* p_module memset(name, 0, MAX_NODE_NAME_LENGTH); memcpy(name, p_descriptor->name, descriptor_name_length); -#if defined(WIN32) +#if defined(_WIN32) strcat_s(name, MAX_NODE_NAME_LENGTH, k_count_tag); #else strcat(name, k_count_tag); @@ -2188,6 +2298,29 @@ static SpvReflectResult ParseDescriptorBlockVariableSizes( return SPV_REFLECT_RESULT_SUCCESS; } +static void MarkSelfAndAllMemberVarsAsUsed(SpvReflectBlockVariable* p_var) +{ + // Clear the current variable's USED flag + p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED; + + SpvOp op_type = p_var->type_description->op; + switch (op_type) { + default: break; + + case SpvOpTypeArray: { + } + break; + + case SpvOpTypeStruct: { + for (uint32_t i = 0; i < p_var->member_count; ++i) { + SpvReflectBlockVariable* p_member_var = &p_var->members[i]; + MarkSelfAndAllMemberVarsAsUsed(p_member_var); + } + } + break; + } +} + static SpvReflectResult ParseDescriptorBlockVariableUsage( Parser* p_parser, SpvReflectShaderModule* p_module, @@ -2201,7 +2334,7 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage( (void)p_access_chain; (void)p_var; - // Clear the current variable's USED flag + // Clear the current variable's UNUSED flag p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED; // Parsing arrays requires overriding the op type for @@ -2229,19 +2362,33 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage( if (p_type == NULL) { return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; } - // Next access index + // Next access chain index index_index += 1; } - // Parse current var again with a type override and advanced index index - SpvReflectResult result = ParseDescriptorBlockVariableUsage( - p_parser, - p_module, - p_access_chain, - index_index, - p_type->op, - p_var); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; + + // Only continue parsing if there's remaining indices in the access + // chain. If the end of the access chain has been reach then all + // remaining variables (including those in struct hierarchies) + // are considered USED. + // + // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78 + // + if (index_index < p_access_chain->index_count) { + // Parse current var again with a type override and advanced index index + SpvReflectResult result = ParseDescriptorBlockVariableUsage( + p_parser, + p_module, + p_access_chain, + index_index, + p_type->op, + p_var); + if (result != SPV_REFLECT_RESULT_SUCCESS) { + return result; + } + } + else { + // Clear UNUSED flag for remaining variables + MarkSelfAndAllMemberVarsAsUsed(p_var); } } break; @@ -2251,26 +2398,52 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage( if (p_var->member_count == 0) { return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA; } - + // Get member variable at the access's chain current index uint32_t index = p_access_chain->indexes[index_index]; - if (index >= p_var->member_count) { return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE; } - SpvReflectBlockVariable* p_member_var = &p_var->members[index]; + + // Next access chain index + index_index += 1; + + // Only continue parsing if there's remaining indices in the access + // chain. If the end of the access chain has been reach then all + // remaining variables (including those in struct hierarchies) + // are considered USED. + // + // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78 + // if (index_index < p_access_chain->index_count) { - SpvReflectResult result = ParseDescriptorBlockVariableUsage( - p_parser, - p_module, - p_access_chain, - index_index + 1, - (SpvOp)INVALID_VALUE, - p_member_var); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; - } + SpvReflectResult result = ParseDescriptorBlockVariableUsage( + p_parser, + p_module, + p_access_chain, + index_index, + (SpvOp)INVALID_VALUE, + p_member_var); + if (result != SPV_REFLECT_RESULT_SUCCESS) { + return result; + } } + else { + // Clear UNUSED flag for remaining variables + MarkSelfAndAllMemberVarsAsUsed(p_member_var); + } + //SpvReflectBlockVariable* p_member_var = &p_var->members[index]; + //if (index_index < p_access_chain->index_count) { + // SpvReflectResult result = ParseDescriptorBlockVariableUsage( + // p_parser, + // p_module, + // p_access_chain, + // index_index + 1, + // (SpvOp)INVALID_VALUE, + // p_member_var); + // if (result != SPV_REFLECT_RESULT_SUCCESS) { + // return result; + // } + //} } break; } @@ -2342,39 +2515,69 @@ static SpvReflectResult ParseFormat( ) { SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR; - bool signedness = p_type->traits.numeric.scalar.signedness; + bool signedness = (p_type->traits.numeric.scalar.signedness != 0); + uint32_t bit_width = p_type->traits.numeric.scalar.width; if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_VECTOR) { uint32_t component_count = p_type->traits.numeric.vector.component_count; if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) { - switch (component_count) { - case 2: *p_format = SPV_REFLECT_FORMAT_R32G32_SFLOAT; break; - case 3: *p_format = SPV_REFLECT_FORMAT_R32G32B32_SFLOAT; break; - case 4: *p_format = SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT; break; + switch (bit_width) { + case 32: { + switch (component_count) { + case 2: *p_format = SPV_REFLECT_FORMAT_R32G32_SFLOAT; break; + case 3: *p_format = SPV_REFLECT_FORMAT_R32G32B32_SFLOAT; break; + case 4: *p_format = SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT; break; + } + } + case 64: { + switch (component_count) { + case 2: *p_format = SPV_REFLECT_FORMAT_R64G64_SFLOAT; break; + case 3: *p_format = SPV_REFLECT_FORMAT_R64G64B64_SFLOAT; break; + case 4: *p_format = SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT; break; + } + } } result = SPV_REFLECT_RESULT_SUCCESS; } else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) { - switch (component_count) { - case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32_SINT : SPV_REFLECT_FORMAT_R32G32_UINT; break; - case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32_SINT : SPV_REFLECT_FORMAT_R32G32B32_UINT; break; - case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32A32_SINT : SPV_REFLECT_FORMAT_R32G32B32A32_UINT; break; + switch (bit_width) { + case 32: { + switch (component_count) { + case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32_SINT : SPV_REFLECT_FORMAT_R32G32_UINT; break; + case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32_SINT : SPV_REFLECT_FORMAT_R32G32B32_UINT; break; + case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32A32_SINT : SPV_REFLECT_FORMAT_R32G32B32A32_UINT; break; + } + } + case 64: { + switch (component_count) { + case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64_SINT : SPV_REFLECT_FORMAT_R64G64_UINT; break; + case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64_SINT : SPV_REFLECT_FORMAT_R64G64B64_UINT; break; + case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64A64_SINT : SPV_REFLECT_FORMAT_R64G64B64A64_UINT; break; + } + } } result = SPV_REFLECT_RESULT_SUCCESS; } } else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) { - *p_format = SPV_REFLECT_FORMAT_R32_SFLOAT; + switch(bit_width) { + case 32: + *p_format = SPV_REFLECT_FORMAT_R32_SFLOAT; + break; + case 64: + *p_format = SPV_REFLECT_FORMAT_R64_SFLOAT; + break; + } result = SPV_REFLECT_RESULT_SUCCESS; } else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) { - if (signedness) { - *p_format = SPV_REFLECT_FORMAT_R32_SINT; - result = SPV_REFLECT_RESULT_SUCCESS; - } - else { - *p_format = SPV_REFLECT_FORMAT_R32_UINT; - result = SPV_REFLECT_RESULT_SUCCESS; - } + switch(bit_width) { + case 32: + *p_format = signedness ? SPV_REFLECT_FORMAT_R32_SINT : SPV_REFLECT_FORMAT_R32_UINT; break; + break; + case 64: + *p_format = signedness ? SPV_REFLECT_FORMAT_R64_SINT : SPV_REFLECT_FORMAT_R64_UINT; break; + } + result = SPV_REFLECT_RESULT_SUCCESS; } else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) { *p_format = SPV_REFLECT_FORMAT_UNDEFINED; @@ -2410,6 +2613,7 @@ static SpvReflectResult ParseInterfaceVariable( SpvReflectInterfaceVariable* p_member_var = &p_var->members[member_index]; SpvReflectResult result = ParseInterfaceVariable(p_parser, p_member_decorations, p_module, p_member_type, p_member_var, p_has_built_in); if (result != SPV_REFLECT_RESULT_SUCCESS) { + SPV_REFLECT_ASSERT(false); return result; } } @@ -2427,9 +2631,13 @@ static SpvReflectResult ParseInterfaceVariable( *p_has_built_in |= p_type_node_decorations->is_built_in; - SpvReflectResult result = ParseFormat(p_var->type_description, &p_var->format); - if (result != SPV_REFLECT_RESULT_SUCCESS) { - return result; + // Only parse format for interface variables that are input or output + if ((p_var->storage_class == SpvStorageClassInput) || (p_var->storage_class == SpvStorageClassOutput)) { + SpvReflectResult result = ParseFormat(p_var->type_description, &p_var->format); + if (result != SPV_REFLECT_RESULT_SUCCESS) { + SPV_REFLECT_ASSERT(false); + return result; + } } return SPV_REFLECT_RESULT_SUCCESS; @@ -2439,50 +2647,57 @@ static SpvReflectResult ParseInterfaceVariables( Parser* p_parser, SpvReflectShaderModule* p_module, SpvReflectEntryPoint* p_entry, - size_t io_var_count, - uint32_t* io_vars + uint32_t interface_variable_count, + uint32_t* p_interface_variable_ids ) { - if (io_var_count == 0) { + if (interface_variable_count == 0) { return SPV_REFLECT_RESULT_SUCCESS; } - p_entry->input_variable_count = 0; - p_entry->output_variable_count = 0; - for (size_t i = 0; i < io_var_count; ++i) { - uint32_t var_result_id = *(io_vars + i); - Node* p_node = FindNode(p_parser, var_result_id); - if (IsNull(p_node)) { - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; - } - - if (p_node->storage_class == SpvStorageClassInput) { - p_entry->input_variable_count += 1; - } - else if (p_node->storage_class == SpvStorageClassOutput) { - p_entry->output_variable_count += 1; - } - } - - if (p_entry->input_variable_count > 0) { - p_entry->input_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->input_variable_count, sizeof(*(p_entry->input_variables))); - if (IsNull(p_entry->input_variables)) { - return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; - } - } - - - if (p_entry->output_variable_count > 0) { - p_entry->output_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->output_variable_count, sizeof(*(p_entry->output_variables))); - if (IsNull(p_entry->output_variables)) { + p_entry->interface_variable_count = interface_variable_count; + p_entry->input_variable_count = 0; + p_entry->output_variable_count = 0; + for (size_t i = 0; i < interface_variable_count; ++i) { + uint32_t var_result_id = *(p_interface_variable_ids + i); + Node* p_node = FindNode(p_parser, var_result_id); + if (IsNull(p_node)) { + return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; + } + + if (p_node->storage_class == SpvStorageClassInput) { + p_entry->input_variable_count += 1; + } + else if (p_node->storage_class == SpvStorageClassOutput) { + p_entry->output_variable_count += 1; + } + } + + if (p_entry->input_variable_count > 0) { + p_entry->input_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->input_variable_count, sizeof(*(p_entry->input_variables))); + if (IsNull(p_entry->input_variables)) { + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; + } + } + + if (p_entry->output_variable_count > 0) { + p_entry->output_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->output_variable_count, sizeof(*(p_entry->output_variables))); + if (IsNull(p_entry->output_variables)) { + return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; + } + } + + if (p_entry->interface_variable_count > 0) { + p_entry->interface_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->interface_variable_count, sizeof(*(p_entry->interface_variables))); + if (IsNull(p_entry->interface_variables)) { return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; } } size_t input_index = 0; size_t output_index = 0; - for (size_t i = 0; i < io_var_count; ++i) { - uint32_t var_result_id = *(io_vars + i); + for (size_t i = 0; i < interface_variable_count; ++i) { + uint32_t var_result_id = *(p_interface_variable_ids + i); Node* p_node = FindNode(p_parser, var_result_id); if (IsNull(p_node)) { return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; @@ -2511,22 +2726,8 @@ static SpvReflectResult ParseInterfaceVariables( return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE; } - SpvReflectInterfaceVariable* p_var = NULL; - if (p_node->storage_class == SpvStorageClassInput) { - p_var = &(p_entry->input_variables[input_index]); - p_var->storage_class = SpvStorageClassInput; - ++input_index; - } - else if (p_node->storage_class == SpvStorageClassOutput) { - p_var = &(p_entry->output_variables[output_index]); - p_var->storage_class = SpvStorageClassOutput; - ++output_index; - } else { - // interface variables can only have input or output storage classes; - // anything else is either a new addition or an error. - assert(false && "Unsupported storage class for interface variable"); - return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_STORAGE_CLASS; - } + SpvReflectInterfaceVariable* p_var = &(p_entry->interface_variables[i]); + p_var->storage_class = p_node->storage_class; bool has_built_in = p_node->decorations.is_built_in; SpvReflectResult result = ParseInterfaceVariable( @@ -2537,9 +2738,20 @@ static SpvReflectResult ParseInterfaceVariables( p_var, &has_built_in); if (result != SPV_REFLECT_RESULT_SUCCESS) { + SPV_REFLECT_ASSERT(false); return result; } + // Input and output variables + if (p_var->storage_class == SpvStorageClassInput) { + p_entry->input_variables[input_index] = p_var; + ++input_index; + } + else if (p_node->storage_class == SpvStorageClassOutput) { + p_entry->output_variables[output_index] = p_var; + ++output_index; + } + // SPIR-V result id p_var->spirv_id = p_node->result_id; // Name @@ -2809,6 +3021,14 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul case SpvExecutionModelGeometry : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT; break; case SpvExecutionModelFragment : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT; break; case SpvExecutionModelGLCompute : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT; break; + case SpvExecutionModelTaskNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV; break; + case SpvExecutionModelMeshNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV; break; + case SpvExecutionModelRayGenerationKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR; break; + case SpvExecutionModelIntersectionKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR; break; + case SpvExecutionModelAnyHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR; break; + case SpvExecutionModelClosestHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break; + case SpvExecutionModelMissKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR; break; + case SpvExecutionModelCallableKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR; break; } ++entry_point_index; @@ -2823,11 +3043,11 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul p_entry_point->name = (const char*)(p_parser->spirv_code + p_node->word_offset + name_start_word_offset); uint32_t name_word_count = RoundUp(name_length_with_terminator, SPIRV_WORD_SIZE) / SPIRV_WORD_SIZE; - size_t interface_variable_count = (p_node->word_count - (name_start_word_offset + name_word_count)); - uint32_t* interface_variables = NULL; + uint32_t interface_variable_count = (p_node->word_count - (name_start_word_offset + name_word_count)); + uint32_t* p_interface_variables = NULL; if (interface_variable_count > 0) { - interface_variables = (uint32_t*)calloc(interface_variable_count, sizeof(*(interface_variables))); - if (IsNull(interface_variables)) { + p_interface_variables = (uint32_t*)calloc(interface_variable_count, sizeof(*(p_interface_variables))); + if (IsNull(p_interface_variables)) { return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED; } } @@ -2836,7 +3056,7 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul uint32_t var_result_id = (uint32_t)INVALID_VALUE; uint32_t offset = name_start_word_offset + name_word_count + var_index; CHECKED_READU32(p_parser, p_node->word_offset + offset, var_result_id); - interface_variables[var_index] = var_result_id; + p_interface_variables[var_index] = var_result_id; } result = ParseInterfaceVariables( @@ -2844,11 +3064,11 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul p_module, p_entry_point, interface_variable_count, - interface_variables); + p_interface_variables); if (result != SPV_REFLECT_RESULT_SUCCESS) { return result; } - SafeFree(interface_variables); + SafeFree(p_interface_variables); result = ParseStaticallyUsedResources( p_parser, @@ -2869,6 +3089,104 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul return SPV_REFLECT_RESULT_SUCCESS; } +static SpvReflectResult ParseExecutionModes(Parser* p_parser, SpvReflectShaderModule* p_module) +{ + assert(IsNotNull(p_parser)); + assert(IsNotNull(p_parser->nodes)); + assert(IsNotNull(p_module)); + + if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) { + for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) { + Node* p_node = &(p_parser->nodes[node_idx]); + if (p_node->op != SpvOpExecutionMode) { + continue; + } + + // Read entry point id + uint32_t entry_point_id = 0; + CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id); + + // Find entry point + SpvReflectEntryPoint* p_entry_point = NULL; + for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) { + if (p_module->entry_points[entry_point_idx].id == entry_point_id) { + p_entry_point = &p_module->entry_points[entry_point_idx]; + break; + } + } + // Bail if entry point is null + if (IsNull(p_entry_point)) { + return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT; + } + + // Read execution mode + uint32_t execution_mode = (uint32_t)INVALID_VALUE; + CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode); + + // Parse execution mode + switch (execution_mode) { + default: { + return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE; + } + break; + + case SpvExecutionModeInvocations: + case SpvExecutionModeSpacingEqual: + case SpvExecutionModeSpacingFractionalEven: + case SpvExecutionModeSpacingFractionalOdd: + case SpvExecutionModeVertexOrderCw: + case SpvExecutionModeVertexOrderCcw: + case SpvExecutionModePixelCenterInteger: + case SpvExecutionModeOriginUpperLeft: + case SpvExecutionModeOriginLowerLeft: + case SpvExecutionModeEarlyFragmentTests: + case SpvExecutionModePointMode: + case SpvExecutionModeXfb: + case SpvExecutionModeDepthReplacing: + case SpvExecutionModeDepthGreater: + case SpvExecutionModeDepthLess: + case SpvExecutionModeDepthUnchanged: + break; + + case SpvExecutionModeLocalSize: { + CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->local_size.x); + CHECKED_READU32(p_parser, p_node->word_offset + 4, p_entry_point->local_size.y); + CHECKED_READU32(p_parser, p_node->word_offset + 5, p_entry_point->local_size.z); + } + break; + + case SpvExecutionModeLocalSizeHint: + case SpvExecutionModeInputPoints: + case SpvExecutionModeInputLines: + case SpvExecutionModeInputLinesAdjacency: + case SpvExecutionModeTriangles: + case SpvExecutionModeInputTrianglesAdjacency: + case SpvExecutionModeQuads: + case SpvExecutionModeIsolines: + case SpvExecutionModeOutputVertices: + case SpvExecutionModeOutputPoints: + case SpvExecutionModeOutputLineStrip: + case SpvExecutionModeOutputTriangleStrip: + case SpvExecutionModeVecTypeHint: + case SpvExecutionModeContractionOff: + case SpvExecutionModeInitializer: + case SpvExecutionModeFinalizer: + case SpvExecutionModeSubgroupSize: + case SpvExecutionModeSubgroupsPerWorkgroup: + case SpvExecutionModeSubgroupsPerWorkgroupId: + case SpvExecutionModeLocalSizeId: + case SpvExecutionModeLocalSizeHintId: + case SpvExecutionModePostDepthCoverage: + case SpvExecutionModeStencilRefReplacingEXT: + case SpvExecutionModeOutputPrimitivesNV: + case SpvExecutionModeOutputTrianglesNV: + break; + } + } + } + return SPV_REFLECT_RESULT_SUCCESS; +} + static SpvReflectResult ParsePushConstantBlocks(Parser* p_parser, SpvReflectShaderModule* p_module) { for (size_t i = 0; i < p_parser->node_count; ++i) { @@ -3180,24 +3498,31 @@ SpvReflectResult spvReflectCreateShaderModule( if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseNodes(&parser); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseStrings(&parser); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseSource(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseFunctions(&parser); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseMemberCounts(&parser); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseNames(&parser); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseDecorations(&parser); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } // Start of reflection data parsing @@ -3215,24 +3540,31 @@ SpvReflectResult spvReflectCreateShaderModule( } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseTypes(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseDescriptorBindings(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseDescriptorType(p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseUAVCounterBindings(p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseDescriptorBlocks(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParsePushConstantBlocks(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = ParseEntryPoints(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS && p_module->entry_point_count > 0) { SpvReflectEntryPoint* p_entry = &(p_module->entry_points[0]); @@ -3244,12 +3576,20 @@ SpvReflectResult spvReflectCreateShaderModule( p_module->input_variables = p_entry->input_variables; p_module->output_variable_count = p_entry->output_variable_count; p_module->output_variables = p_entry->output_variables; + p_module->interface_variable_count = p_entry->interface_variable_count; + p_module->interface_variables = p_entry->interface_variables; } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = DisambiguateStorageBufferSrvUav(p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } if (result == SPV_REFLECT_RESULT_SUCCESS) { result = SynchronizeDescriptorSets(p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); + } + if (result == SPV_REFLECT_RESULT_SUCCESS) { + result = ParseExecutionModes(&parser, p_module); + SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS); } // Destroy module if parse was not successful @@ -3319,6 +3659,8 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) return; } + SafeFree(p_module->source_source); + // Descriptor set bindings for (size_t i = 0; i < p_module->descriptor_set_count; ++i) { SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i]; @@ -3335,11 +3677,8 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) // Entry points for (size_t i = 0; i < p_module->entry_point_count; ++i) { SpvReflectEntryPoint* p_entry = &p_module->entry_points[i]; - for (size_t j = 0; j < p_entry->input_variable_count; j++) { - SafeFreeInterfaceVariable(&p_entry->input_variables[j]); - } - for (size_t j = 0; j < p_entry->output_variable_count; j++) { - SafeFreeInterfaceVariable(&p_entry->output_variables[j]); + for (size_t j = 0; j < p_entry->interface_variable_count; j++) { + SafeFreeInterfaceVariable(&p_entry->interface_variables[j]); } for (uint32_t j = 0; j < p_entry->descriptor_set_count; ++j) { SafeFree(p_entry->descriptor_sets[j].bindings); @@ -3347,6 +3686,7 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module) SafeFree(p_entry->descriptor_sets); SafeFree(p_entry->input_variables); SafeFree(p_entry->output_variables); + SafeFree(p_entry->interface_variables); SafeFree(p_entry->used_uniforms); SafeFree(p_entry->used_push_constants); } @@ -3552,6 +3892,73 @@ SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets( return SPV_REFLECT_RESULT_SUCCESS; } +SpvReflectResult spvReflectEnumerateInterfaceVariables( + const SpvReflectShaderModule* p_module, + uint32_t* p_count, + SpvReflectInterfaceVariable** pp_variables +) +{ + if (IsNull(p_module)) { + return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; + } + if (IsNull(p_count)) { + return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; + } + + if (IsNotNull(pp_variables)) { + if (*p_count != p_module->interface_variable_count) { + return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH; + } + + for (uint32_t index = 0; index < *p_count; ++index) { + SpvReflectInterfaceVariable* p_var = &p_module->interface_variables[index]; + pp_variables[index] = p_var; + } + } + else { + *p_count = p_module->interface_variable_count; + } + + return SPV_REFLECT_RESULT_SUCCESS; +} + +SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables( + const SpvReflectShaderModule* p_module, + const char* entry_point, + uint32_t* p_count, + SpvReflectInterfaceVariable** pp_variables +) +{ + if (IsNull(p_module)) { + return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; + } + if (IsNull(p_count)) { + return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; + } + + const SpvReflectEntryPoint* p_entry = + spvReflectGetEntryPoint(p_module, entry_point); + if (IsNull(p_entry)) { + return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND; + } + + if (IsNotNull(pp_variables)) { + if (*p_count != p_entry->interface_variable_count) { + return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH; + } + + for (uint32_t index = 0; index < *p_count; ++index) { + SpvReflectInterfaceVariable* p_var = &p_entry->interface_variables[index]; + pp_variables[index] = p_var; + } + } + else { + *p_count = p_entry->interface_variable_count; + } + + return SPV_REFLECT_RESULT_SUCCESS; +} + SpvReflectResult spvReflectEnumerateInputVariables( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -3571,7 +3978,7 @@ SpvReflectResult spvReflectEnumerateInputVariables( } for (uint32_t index = 0; index < *p_count; ++index) { - SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_module->input_variables[index]; + SpvReflectInterfaceVariable* p_var = p_module->input_variables[index]; pp_variables[index] = p_var; } } @@ -3608,7 +4015,7 @@ SpvReflectResult spvReflectEnumerateEntryPointInputVariables( } for (uint32_t index = 0; index < *p_count; ++index) { - SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_entry->input_variables[index]; + SpvReflectInterfaceVariable* p_var = p_entry->input_variables[index]; pp_variables[index] = p_var; } } @@ -3638,7 +4045,7 @@ SpvReflectResult spvReflectEnumerateOutputVariables( } for (uint32_t index = 0; index < *p_count; ++index) { - SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_module->output_variables[index]; + SpvReflectInterfaceVariable* p_var = p_module->output_variables[index]; pp_variables[index] = p_var; } } @@ -3675,7 +4082,7 @@ SpvReflectResult spvReflectEnumerateEntryPointOutputVariables( } for (uint32_t index = 0; index < *p_count; ++index) { - SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_entry->output_variables[index]; + SpvReflectInterfaceVariable* p_var = p_entry->output_variables[index]; pp_variables[index] = p_var; } } @@ -3907,7 +4314,7 @@ const SpvReflectInterfaceVariable* spvReflectGetInputVariableByLocation( const SpvReflectInterfaceVariable* p_var = NULL; if (IsNotNull(p_module)) { for (uint32_t index = 0; index < p_module->input_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_module->input_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index]; if (p_potential->location == location) { p_var = p_potential; } @@ -3955,7 +4362,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocatio return NULL; } for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_entry->input_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index]; if (p_potential->location == location) { p_var = p_potential; } @@ -3991,7 +4398,7 @@ const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic( const SpvReflectInterfaceVariable* p_var = NULL; if (IsNotNull(p_module)) { for (uint32_t index = 0; index < p_module->input_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_module->input_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index]; if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) { p_var = p_potential; } @@ -4035,7 +4442,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemanti return NULL; } for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_entry->input_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index]; if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) { p_var = p_potential; } @@ -4065,7 +4472,7 @@ const SpvReflectInterfaceVariable* spvReflectGetOutputVariableByLocation( const SpvReflectInterfaceVariable* p_var = NULL; if (IsNotNull(p_module)) { for (uint32_t index = 0; index < p_module->output_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_module->output_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index]; if (p_potential->location == location) { p_var = p_potential; } @@ -4112,7 +4519,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocati return NULL; } for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_entry->output_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index]; if (p_potential->location == location) { p_var = p_potential; } @@ -4148,7 +4555,7 @@ const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic( const SpvReflectInterfaceVariable* p_var = NULL; if (IsNotNull(p_module)) { for (uint32_t index = 0; index < p_module->output_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_module->output_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index]; if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) { p_var = p_potential; } @@ -4191,7 +4598,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemant return NULL; } for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) { - const SpvReflectInterfaceVariable* p_potential = &p_entry->output_variables[index]; + const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index]; if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) { p_var = p_potential; } @@ -4297,13 +4704,13 @@ SpvReflectResult spvReflectChangeDescriptorBindingNumbers( return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED; } // Binding number - if (new_binding_number != SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE) { + if (new_binding_number != (uint32_t)SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE) { uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.binding; *p_code = new_binding_number; p_target_descriptor->binding = new_binding_number; } // Set number - if (new_set_binding != SPV_REFLECT_SET_NUMBER_DONT_CHANGE) { + if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) { uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.set; *p_code = new_set_binding; p_target_descriptor->set = new_set_binding; @@ -4311,7 +4718,7 @@ SpvReflectResult spvReflectChangeDescriptorBindingNumbers( } SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS; - if (new_set_binding != SPV_REFLECT_SET_NUMBER_DONT_CHANGE) { + if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) { result = SynchronizeDescriptorSets(p_module); } return result; @@ -4352,7 +4759,7 @@ SpvReflectResult spvReflectChangeDescriptorSetNumber( } SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS; - if (IsNotNull(p_target_set) && new_set_number != SPV_REFLECT_SET_NUMBER_DONT_CHANGE) { + if (IsNotNull(p_target_set) && new_set_number != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) { for (uint32_t index = 0; index < p_target_set->binding_count; ++index) { SpvReflectDescriptorBinding* p_descriptor = p_target_set->bindings[index]; if (p_descriptor->word_offset.set > (p_module->_internal->spirv_word_count - 1)) { @@ -4398,8 +4805,8 @@ SpvReflectResult spvReflectChangeInputVariableLocation( return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; } for (uint32_t index = 0; index < p_module->input_variable_count; ++index) { - if(&p_module->input_variables[index] == p_input_variable) { - return ChangeVariableLocation(p_module, &p_module->input_variables[index], new_location); + if(p_module->input_variables[index] == p_input_variable) { + return ChangeVariableLocation(p_module, p_module->input_variables[index], new_location); } } return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND; @@ -4418,8 +4825,8 @@ SpvReflectResult spvReflectChangeOutputVariableLocation( return SPV_REFLECT_RESULT_ERROR_NULL_POINTER; } for (uint32_t index = 0; index < p_module->output_variable_count; ++index) { - if(&p_module->output_variables[index] == p_output_variable) { - return ChangeVariableLocation(p_module, &p_module->output_variables[index], new_location); + if(p_module->output_variables[index] == p_output_variable) { + return ChangeVariableLocation(p_module, p_module->output_variables[index], new_location); } } return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND; diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h index 6554aaa2cf..a5a956e9e8 100644 --- a/thirdparty/spirv-reflect/spirv_reflect.h +++ b/thirdparty/spirv-reflect/spirv_reflect.h @@ -72,26 +72,29 @@ typedef enum SpvReflectResult { SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION, SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA, SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE, + SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT, + SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE, } SpvReflectResult; /*! @enum SpvReflectTypeFlagBits */ typedef enum SpvReflectTypeFlagBits { - SPV_REFLECT_TYPE_FLAG_UNDEFINED = 0x00000000, - SPV_REFLECT_TYPE_FLAG_VOID = 0x00000001, - SPV_REFLECT_TYPE_FLAG_BOOL = 0x00000002, - SPV_REFLECT_TYPE_FLAG_INT = 0x00000004, - SPV_REFLECT_TYPE_FLAG_FLOAT = 0x00000008, - SPV_REFLECT_TYPE_FLAG_VECTOR = 0x00000100, - SPV_REFLECT_TYPE_FLAG_MATRIX = 0x00000200, - SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE = 0x00010000, - SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER = 0x00020000, - SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE = 0x00040000, - SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK = 0x00080000, - SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x000F0000, - SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000, - SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000, + SPV_REFLECT_TYPE_FLAG_UNDEFINED = 0x00000000, + SPV_REFLECT_TYPE_FLAG_VOID = 0x00000001, + SPV_REFLECT_TYPE_FLAG_BOOL = 0x00000002, + SPV_REFLECT_TYPE_FLAG_INT = 0x00000004, + SPV_REFLECT_TYPE_FLAG_FLOAT = 0x00000008, + SPV_REFLECT_TYPE_FLAG_VECTOR = 0x00000100, + SPV_REFLECT_TYPE_FLAG_MATRIX = 0x00000200, + SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE = 0x00010000, + SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER = 0x00020000, + SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE = 0x00040000, + SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK = 0x00080000, + SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE = 0x00100000, + SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x00FF0000, + SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000, + SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000, } SpvReflectTypeFlagBits; typedef uint32_t SpvReflectTypeFlags; @@ -141,6 +144,18 @@ typedef enum SpvReflectFormat { SPV_REFLECT_FORMAT_R32G32B32A32_UINT = 107, // = VK_FORMAT_R32G32B32A32_UINT SPV_REFLECT_FORMAT_R32G32B32A32_SINT = 108, // = VK_FORMAT_R32G32B32A32_SINT SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT = 109, // = VK_FORMAT_R32G32B32A32_SFLOAT + SPV_REFLECT_FORMAT_R64_UINT = 110, // = VK_FORMAT_R64_UINT + SPV_REFLECT_FORMAT_R64_SINT = 111, // = VK_FORMAT_R64_SINT + SPV_REFLECT_FORMAT_R64_SFLOAT = 112, // = VK_FORMAT_R64_SFLOAT + SPV_REFLECT_FORMAT_R64G64_UINT = 113, // = VK_FORMAT_R64G64_UINT + SPV_REFLECT_FORMAT_R64G64_SINT = 114, // = VK_FORMAT_R64G64_SINT + SPV_REFLECT_FORMAT_R64G64_SFLOAT = 115, // = VK_FORMAT_R64G64_SFLOAT + SPV_REFLECT_FORMAT_R64G64B64_UINT = 116, // = VK_FORMAT_R64G64B64_UINT + SPV_REFLECT_FORMAT_R64G64B64_SINT = 117, // = VK_FORMAT_R64G64B64_SINT + SPV_REFLECT_FORMAT_R64G64B64_SFLOAT = 118, // = VK_FORMAT_R64G64B64_FLOAT + SPV_REFLECT_FORMAT_R64G64B64A64_UINT = 119, // = VK_FORMAT_R64G64B64A64_UINT + SPV_REFLECT_FORMAT_R64G64B64A64_SINT = 120, // = VK_FORMAT_R64G64B64A64_SINT + SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT = 121, // = VK_FORMAT_R64G64B64A64_SFLOAT } SpvReflectFormat; /*! @enum SpvReflectVariableFlagBits @@ -157,17 +172,18 @@ typedef uint32_t SpvReflectVariableFlags; */ typedef enum SpvReflectDescriptorType { - SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER = 0, // = VK_DESCRIPTOR_TYPE_SAMPLER - SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, // = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER - SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, // = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE - SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, // = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE - SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, // = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, // = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER - SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER - SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER - SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC - SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC - SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, // = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER = 0, // = VK_DESCRIPTOR_TYPE_SAMPLER + SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, // = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER + SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, // = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE + SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, // = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, // = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, // = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER + SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER + SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER + SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC + SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC + SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, // = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000 // = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR } SpvReflectDescriptorType; /*! @enum SpvReflectShaderStageFlagBits @@ -180,6 +196,15 @@ typedef enum SpvReflectShaderStageFlagBits { SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, // = VK_SHADER_STAGE_GEOMETRY_BIT SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, // = VK_SHADER_STAGE_FRAGMENT_BIT SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT = 0x00000020, // = VK_SHADER_STAGE_COMPUTE_BIT + SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV = 0x00000040, // = VK_SHADER_STAGE_TASK_BIT_NV + SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV = 0x00000080, // = VK_SHADER_STAGE_MESH_BIT_NV + SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // VK_SHADER_STAGE_RAYGEN_BIT_KHR + SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // VK_SHADER_STAGE_ANY_HIT_BIT_KHR + SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR + SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // VK_SHADER_STAGE_MISS_BIT_KHR + SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // VK_SHADER_STAGE_INTERSECTION_BIT_KHR + SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // VK_SHADER_STAGE_CALLABLE_BIT_KHR + } SpvReflectShaderStageFlagBits; /*! @enum SpvReflectGenerator @@ -365,10 +390,12 @@ typedef struct SpvReflectEntryPoint { SpvExecutionModel spirv_execution_model; SpvReflectShaderStageFlagBits shader_stage; - uint32_t input_variable_count; - SpvReflectInterfaceVariable* input_variables; - uint32_t output_variable_count; - SpvReflectInterfaceVariable* output_variables; + uint32_t input_variable_count; + SpvReflectInterfaceVariable** input_variables; + uint32_t output_variable_count; + SpvReflectInterfaceVariable** output_variables; + uint32_t interface_variable_count; + SpvReflectInterfaceVariable* interface_variables; uint32_t descriptor_set_count; SpvReflectDescriptorSet* descriptor_sets; @@ -377,6 +404,12 @@ typedef struct SpvReflectEntryPoint { uint32_t* used_uniforms; uint32_t used_push_constant_count; uint32_t* used_push_constants; + + struct LocalSize { + uint32_t x; + uint32_t y; + uint32_t z; + } local_size; } SpvReflectEntryPoint; /*! @struct SpvReflectShaderModule @@ -398,10 +431,12 @@ typedef struct SpvReflectShaderModule { SpvReflectDescriptorBinding* descriptor_bindings; uint32_t descriptor_set_count; SpvReflectDescriptorSet descriptor_sets[SPV_REFLECT_MAX_DESCRIPTOR_SETS]; - uint32_t input_variable_count; - SpvReflectInterfaceVariable* input_variables; - uint32_t output_variable_count; - SpvReflectInterfaceVariable* output_variables; + uint32_t input_variable_count; + SpvReflectInterfaceVariable** input_variables; + uint32_t output_variable_count; + SpvReflectInterfaceVariable** output_variables; + uint32_t interface_variable_count; + SpvReflectInterfaceVariable* interface_variables; uint32_t push_constant_block_count; SpvReflectBlockVariable* push_constant_blocks; @@ -582,6 +617,58 @@ SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets( ); +/*! @fn spvReflectEnumerateInterfaceVariables + @brief If the module contains multiple entry points, this will only get + the interface variables for the first one. + @param p_module Pointer to an instance of SpvReflectShaderModule. + @param p_count If pp_variables is NULL, the module's interface variable + count will be stored here. + If pp_variables is not NULL, *p_count must contain + the module's interface variable count. + @param pp_variables If NULL, the module's interface variable count will be + written to *p_count. + If non-NULL, pp_variables must point to an array with + *p_count entries, where pointers to the module's + interface variables will be written. The caller must not + free the interface variables written to this array. + @return If successful, returns SPV_REFLECT_RESULT_SUCCESS. + Otherwise, the error code indicates the cause of the + failure. + +*/ +SpvReflectResult spvReflectEnumerateInterfaceVariables( + const SpvReflectShaderModule* p_module, + uint32_t* p_count, + SpvReflectInterfaceVariable** pp_variables +); + +/*! @fn spvReflectEnumerateEntryPointInterfaceVariables + @brief Enumerate the interface variables for a given entry point. + @param entry_point The name of the entry point to get the interface variables for. + @param p_module Pointer to an instance of SpvReflectShaderModule. + @param p_count If pp_variables is NULL, the entry point's interface variable + count will be stored here. + If pp_variables is not NULL, *p_count must contain + the entry point's interface variable count. + @param pp_variables If NULL, the entry point's interface variable count will be + written to *p_count. + If non-NULL, pp_variables must point to an array with + *p_count entries, where pointers to the entry point's + interface variables will be written. The caller must not + free the interface variables written to this array. + @return If successful, returns SPV_REFLECT_RESULT_SUCCESS. + Otherwise, the error code indicates the cause of the + failure. + +*/ +SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables( + const SpvReflectShaderModule* p_module, + const char* entry_point, + uint32_t* p_count, + SpvReflectInterfaceVariable** pp_variables +); + + /*! @fn spvReflectEnumerateInputVariables @brief If the module contains multiple entry points, this will only get the input variables for the first one. @@ -1310,10 +1397,12 @@ public: SpvReflectResult EnumerateEntryPointDescriptorBindings(const char* entry_point, uint32_t* p_count, SpvReflectDescriptorBinding** pp_bindings) const; SpvReflectResult EnumerateDescriptorSets( uint32_t* p_count, SpvReflectDescriptorSet** pp_sets) const ; SpvReflectResult EnumerateEntryPointDescriptorSets(const char* entry_point, uint32_t* p_count, SpvReflectDescriptorSet** pp_sets) const ; + SpvReflectResult EnumerateInterfaceVariables(uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const; + SpvReflectResult EnumerateEntryPointInterfaceVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const; SpvReflectResult EnumerateInputVariables(uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const; - SpvReflectResult EnumerateEntryPointInputVariables(const char* entry_point, uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const; + SpvReflectResult EnumerateEntryPointInputVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const; SpvReflectResult EnumerateOutputVariables(uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const; - SpvReflectResult EnumerateEntryPointOutputVariables(const char* entry_point, uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const; + SpvReflectResult EnumerateEntryPointOutputVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const; SpvReflectResult EnumeratePushConstantBlocks(uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const; SpvReflectResult EnumerateEntryPointPushConstantBlocks(const char* entry_point, uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const; SPV_REFLECT_DEPRECATED("Renamed to EnumeratePushConstantBlocks") @@ -1361,6 +1450,11 @@ public: SpvReflectResult ChangeOutputVariableLocation(const SpvReflectInterfaceVariable* p_output_variable, uint32_t new_location); private: + // Make noncopyable + ShaderModule(const ShaderModule&); + ShaderModule& operator=(const ShaderModule&); + +private: mutable SpvReflectResult m_result = SPV_REFLECT_RESULT_NOT_READY; SpvReflectShaderModule m_module = {}; }; @@ -1591,6 +1685,48 @@ inline SpvReflectResult ShaderModule::EnumerateEntryPointDescriptorSets( } +/*! @fn EnumerateInterfaceVariables + + @param count + @param pp_variables + @return + +*/ +inline SpvReflectResult ShaderModule::EnumerateInterfaceVariables( + uint32_t* p_count, + SpvReflectInterfaceVariable** pp_variables +) const +{ + m_result = spvReflectEnumerateInterfaceVariables( + &m_module, + p_count, + pp_variables); + return m_result; +} + +/*! @fn EnumerateEntryPointInterfaceVariables + + @param entry_point + @param count + @param pp_variables + @return + +*/ +inline SpvReflectResult ShaderModule::EnumerateEntryPointInterfaceVariables( + const char* entry_point, + uint32_t* p_count, + SpvReflectInterfaceVariable** pp_variables +) const +{ + m_result = spvReflectEnumerateEntryPointInterfaceVariables( + &m_module, + entry_point, + p_count, + pp_variables); + return m_result; +} + + /*! @fn EnumerateInputVariables @param count diff --git a/thirdparty/zstd/common/bitstream.h b/thirdparty/zstd/common/bitstream.h index 37b99c01ee..d9a2730104 100644 --- a/thirdparty/zstd/common/bitstream.h +++ b/thirdparty/zstd/common/bitstream.h @@ -17,7 +17,6 @@ #if defined (__cplusplus) extern "C" { #endif - /* * This API consists of small unitary functions, which must be inlined for best performance. * Since link-time-optimization is not available for all compilers, @@ -36,10 +35,12 @@ extern "C" { /*========================================= * Target specific =========================================*/ -#if defined(__BMI__) && defined(__GNUC__) -# include <immintrin.h> /* support for bextr (experimental) */ -#elif defined(__ICCARM__) -# include <intrinsics.h> +#ifndef ZSTD_NO_INTRINSICS +# if defined(__BMI__) && defined(__GNUC__) +# include <immintrin.h> /* support for bextr (experimental) */ +# elif defined(__ICCARM__) +# include <intrinsics.h> +# endif #endif #define STREAM_ACCUMULATOR_MIN_32 25 @@ -141,8 +142,12 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val) assert(val != 0); { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - return _BitScanReverse ( &r, val ) ? (unsigned)r : 0; +# if STATIC_BMI2 == 1 + return _lzcnt_u32(val) ^ 31; +# else + unsigned long r = 0; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; +# endif # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # elif defined(__ICCARM__) /* IAR Intrinsic */ @@ -198,7 +203,7 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits) { - MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32); + DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32); assert(nbBits < BIT_MASK_SIZE); assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; @@ -271,7 +276,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) */ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) { - if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } bitD->start = (const char*)srcBuffer; bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); @@ -317,12 +322,12 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si return srcSize; } -MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) +MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start) { return bitContainer >> start; } -MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) +MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) { U32 const regMask = sizeof(bitContainer)*8 - 1; /* if start > regMask, bitstream is corrupted, and result is undefined */ @@ -330,10 +335,14 @@ MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 co return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; } -MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) +MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) { +#if defined(STATIC_BMI2) && STATIC_BMI2 == 1 + return _bzhi_u64(bitContainer, nbBits); +#else assert(nbBits < BIT_MASK_SIZE); return bitContainer & BIT_mask[nbBits]; +#endif } /*! BIT_lookBits() : @@ -342,7 +351,7 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) * On 32-bits, maxNbBits==24. * On 64-bits, maxNbBits==56. * @return : value extracted */ -MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) { /* arbitrate between double-shift and shift+mask */ #if 1 @@ -365,7 +374,7 @@ MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); } -MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) { bitD->bitsConsumed += nbBits; } @@ -374,7 +383,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) * Read (consume) next n bits from local register and update. * Pay attention to not read more than nbBits contained into local register. * @return : extracted value. */ -MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) +MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) { size_t const value = BIT_lookBits(bitD, nbBits); BIT_skipBits(bitD, nbBits); diff --git a/thirdparty/zstd/common/compiler.h b/thirdparty/zstd/common/compiler.h index 95e9483521..3e454f38c1 100644 --- a/thirdparty/zstd/common/compiler.h +++ b/thirdparty/zstd/common/compiler.h @@ -39,6 +39,17 @@ #endif /** + On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC). + This explictly marks such functions as __cdecl so that the code will still compile + if a CC other than __cdecl has been made the default. +*/ +#if defined(_MSC_VER) +# define WIN_CDECL __cdecl +#else +# define WIN_CDECL +#endif + +/** * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant * parameters. They must be inlined for the compiler to eliminate the constant * branches. @@ -114,12 +125,12 @@ # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) -# elif defined(__aarch64__) -# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))) -# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))) # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) +# elif defined(__aarch64__) +# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))) +# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))) # else # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */ # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */ @@ -172,4 +183,106 @@ # pragma warning(disable : 4324) /* disable: C4324: padded structure */ #endif +/*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/ +#ifndef STATIC_BMI2 +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) +# ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2 +# define STATIC_BMI2 1 +# endif +# endif +#endif + +#ifndef STATIC_BMI2 + #define STATIC_BMI2 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +/* detects whether we are being compiled under msan */ +#ifndef ZSTD_MEMORY_SANITIZER +# if __has_feature(memory_sanitizer) +# define ZSTD_MEMORY_SANITIZER 1 +# else +# define ZSTD_MEMORY_SANITIZER 0 +# endif +#endif + +#if ZSTD_MEMORY_SANITIZER +/* Not all platforms that support msan provide sanitizers/msan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include <stddef.h> /* size_t */ +#define ZSTD_DEPS_NEED_STDINT +#include "zstd_deps.h" /* intptr_t */ + +/* Make memory region fully initialized (without changing its contents). */ +void __msan_unpoison(const volatile void *a, size_t size); + +/* Make memory region fully uninitialized (without changing its contents). + This is a legacy interface that does not update origin information. Use + __msan_allocated_memory() instead. */ +void __msan_poison(const volatile void *a, size_t size); + +/* Returns the offset of the first (at least partially) poisoned byte in the + memory range, or -1 if the whole range is good. */ +intptr_t __msan_test_shadow(const volatile void *x, size_t size); +#endif + +/* detects whether we are being compiled under asan */ +#ifndef ZSTD_ADDRESS_SANITIZER +# if __has_feature(address_sanitizer) +# define ZSTD_ADDRESS_SANITIZER 1 +# elif defined(__SANITIZE_ADDRESS__) +# define ZSTD_ADDRESS_SANITIZER 1 +# else +# define ZSTD_ADDRESS_SANITIZER 0 +# endif +#endif + +#if ZSTD_ADDRESS_SANITIZER +/* Not all platforms that support asan provide sanitizers/asan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include <stddef.h> /* size_t */ + +/** + * Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable. + * + * This memory must be previously allocated by your program. Instrumented + * code is forbidden from accessing addresses in this region until it is + * unpoisoned. This function is not guaranteed to poison the entire region - + * it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan + * alignment restrictions. + * + * \note This function is not thread-safe because no two threads can poison or + * unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_poison_memory_region(void const volatile *addr, size_t size); + +/** + * Marks a memory region (<c>[addr, addr+size)</c>) as addressable. + * + * This memory must be previously allocated by your program. Accessing + * addresses in this region is allowed until this region is poisoned again. + * This function could unpoison a super-region of <c>[addr, addr+size)</c> due + * to ASan alignment restrictions. + * + * \note This function is not thread-safe because no two threads can + * poison or unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#endif + #endif /* ZSTD_COMPILER_H */ diff --git a/thirdparty/zstd/common/cpu.h b/thirdparty/zstd/common/cpu.h index 6e8a974f62..cb210593ea 100644 --- a/thirdparty/zstd/common/cpu.h +++ b/thirdparty/zstd/common/cpu.h @@ -16,8 +16,6 @@ * https://github.com/facebook/folly/blob/master/folly/CpuId.h */ -#include <string.h> - #include "mem.h" #ifdef _MSC_VER diff --git a/thirdparty/zstd/common/debug.h b/thirdparty/zstd/common/debug.h index ac6224888d..8b5734366c 100644 --- a/thirdparty/zstd/common/debug.h +++ b/thirdparty/zstd/common/debug.h @@ -51,15 +51,6 @@ extern "C" { #endif -/* DEBUGFILE can be defined externally, - * typically through compiler command line. - * note : currently useless. - * Value must be stderr or stdout */ -#ifndef DEBUGFILE -# define DEBUGFILE stderr -#endif - - /* recommended values for DEBUGLEVEL : * 0 : release mode, no debug, all run-time checks disabled * 1 : enables assert() only, no display @@ -76,7 +67,8 @@ extern "C" { */ #if (DEBUGLEVEL>=1) -# include <assert.h> +# define ZSTD_DEPS_NEED_ASSERT +# include "zstd_deps.h" #else # ifndef assert /* assert may be already defined, due to prior #include <assert.h> */ # define assert(condition) ((void)0) /* disable assert (default) */ @@ -84,7 +76,8 @@ extern "C" { #endif #if (DEBUGLEVEL>=2) -# include <stdio.h> +# define ZSTD_DEPS_NEED_IO +# include "zstd_deps.h" extern int g_debuglevel; /* the variable is only declared, it actually lives in debug.c, and is shared by the whole process. @@ -92,14 +85,14 @@ extern int g_debuglevel; /* the variable is only declared, It's useful when enabling very verbose levels on selective conditions (such as position in src) */ -# define RAWLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - fprintf(stderr, __VA_ARGS__); \ +# define RAWLOG(l, ...) { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__VA_ARGS__); \ } } -# define DEBUGLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ - fprintf(stderr, " \n"); \ +# define DEBUGLOG(l, ...) { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \ + ZSTD_DEBUG_PRINT(" \n"); \ } } #else # define RAWLOG(l, ...) {} /* disabled */ diff --git a/thirdparty/zstd/common/entropy_common.c b/thirdparty/zstd/common/entropy_common.c index 9d3e4e8e36..f9fcb1acfc 100644 --- a/thirdparty/zstd/common/entropy_common.c +++ b/thirdparty/zstd/common/entropy_common.c @@ -38,8 +38,31 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } /*-************************************************************** * FSE NCount encoding-decoding ****************************************************************/ -size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, - const void* headerBuffer, size_t hbSize) +static U32 FSE_ctz(U32 val) +{ + assert(val != 0); + { +# if defined(_MSC_VER) /* Visual */ + unsigned long r=0; + return _BitScanForward(&r, val) ? (unsigned)r : 0; +# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ + return __builtin_ctz(val); +# elif defined(__ICCARM__) /* IAR Intrinsic */ + return __CTZ(val); +# else /* Software version */ + U32 count = 0; + while ((val & 1) == 0) { + val >>= 1; + ++count; + } + return count; +# endif + } +} + +FORCE_INLINE_TEMPLATE +size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) { const BYTE* const istart = (const BYTE*) headerBuffer; const BYTE* const iend = istart + hbSize; @@ -50,23 +73,23 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t U32 bitStream; int bitCount; unsigned charnum = 0; + unsigned const maxSV1 = *maxSVPtr + 1; int previous0 = 0; - if (hbSize < 4) { - /* This function only works when hbSize >= 4 */ - char buffer[4]; - memset(buffer, 0, sizeof(buffer)); - memcpy(buffer, headerBuffer, hbSize); + if (hbSize < 8) { + /* This function only works when hbSize >= 8 */ + char buffer[8] = {0}; + ZSTD_memcpy(buffer, headerBuffer, hbSize); { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, buffer, sizeof(buffer)); if (FSE_isError(countSize)) return countSize; if (countSize > hbSize) return ERROR(corruption_detected); return countSize; } } - assert(hbSize >= 4); + assert(hbSize >= 8); /* init */ - memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ + ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ bitStream = MEM_readLE32(ip); nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); @@ -77,36 +100,58 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t threshold = 1<<nbBits; nbBits++; - while ((remaining>1) & (charnum<=*maxSVPtr)) { + for (;;) { if (previous0) { - unsigned n0 = charnum; - while ((bitStream & 0xFFFF) == 0xFFFF) { - n0 += 24; - if (ip < iend-5) { - ip += 2; - bitStream = MEM_readLE32(ip) >> bitCount; + /* Count the number of repeats. Each time the + * 2-bit repeat code is 0b11 there is another + * repeat. + * Avoid UB by setting the high bit to 1. + */ + int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; + while (repeats >= 12) { + charnum += 3 * 12; + if (LIKELY(ip <= iend-7)) { + ip += 3; } else { - bitStream >>= 16; - bitCount += 16; - } } - while ((bitStream & 3) == 3) { - n0 += 3; - bitStream >>= 2; - bitCount += 2; + bitCount -= (int)(8 * (iend - 7 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; } - n0 += bitStream & 3; + charnum += 3 * repeats; + bitStream >>= 2 * repeats; + bitCount += 2 * repeats; + + /* Add the final repeat which isn't 0b11. */ + assert((bitStream & 3) < 3); + charnum += bitStream & 3; bitCount += 2; - if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); - while (charnum < n0) normalizedCounter[charnum++] = 0; - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + + /* This is an error, but break and return an error + * at the end, because returning out of a loop makes + * it harder for the compiler to optimize. + */ + if (charnum >= maxSV1) break; + + /* We don't need to set the normalized count to 0 + * because we already memset the whole buffer to 0. + */ + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { assert((bitCount >> 3) <= 3); /* For first condition to work */ ip += bitCount>>3; bitCount &= 7; - bitStream = MEM_readLE32(ip) >> bitCount; } else { - bitStream >>= 2; - } } - { int const max = (2*threshold-1) - remaining; + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } + { + int const max = (2*threshold-1) - remaining; int count; if ((bitStream & (threshold-1)) < (U32)max) { @@ -119,24 +164,43 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t } count--; /* extra accuracy */ - remaining -= count < 0 ? -count : count; /* -1 means +1 */ + /* When it matters (small blocks), this is a + * predictable branch, because we don't use -1. + */ + if (count >= 0) { + remaining -= count; + } else { + assert(count == -1); + remaining += count; + } normalizedCounter[charnum++] = (short)count; previous0 = !count; - while (remaining < threshold) { - nbBits--; - threshold >>= 1; + + assert(threshold > 1); + if (remaining < threshold) { + /* This branch can be folded into the + * threshold update condition because we + * know that threshold > 1. + */ + if (remaining <= 1) break; + nbBits = BIT_highbit32(remaining) + 1; + threshold = 1 << (nbBits - 1); } + if (charnum >= maxSV1) break; - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { ip += bitCount>>3; bitCount &= 7; } else { bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; ip = iend - 4; } - bitStream = MEM_readLE32(ip) >> (bitCount & 31); - } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ + bitStream = MEM_readLE32(ip) >> bitCount; + } } if (remaining != 1) return ERROR(corruption_detected); + /* Only possible when there are too many zeros. */ + if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall); if (bitCount > 32) return ERROR(corruption_detected); *maxSVPtr = charnum-1; @@ -144,6 +208,43 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t return ip-istart; } +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_readNCount_body_default( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +#if DYNAMIC_BMI2 +TARGET_ATTRIBUTE("bmi2") static size_t FSE_readNCount_body_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} +#endif + +size_t FSE_readNCount_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); + } +#endif + (void)bmi2; + return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +size_t FSE_readNCount( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); +} + /*! HUF_readStats() : Read compact Huffman tree, saved by HUF_writeCTable(). @@ -156,6 +257,17 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, const void* src, size_t srcSize) { + U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int bmi2) +{ U32 weightTotal; const BYTE* ip = (const BYTE*) src; size_t iSize; @@ -163,7 +275,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, if (!srcSize) return ERROR(srcSize_wrong); iSize = ip[0]; - /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ + /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ if (iSize >= 128) { /* special header */ oSize = iSize - 127; @@ -177,14 +289,14 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, huffWeight[n+1] = ip[n/2] & 15; } } } else { /* header compressed with FSE (normal case) */ - FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ + /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2); if (FSE_isError(oSize)) return oSize; } /* collect weight stats */ - memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); weightTotal = 0; { U32 n; for (n=0; n<oSize; n++) { if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected); @@ -214,3 +326,37 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, *nbSymbolsPtr = (U32)(oSize+1); return iSize+1; } + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +static TARGET_ATTRIBUTE("bmi2") size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1); +} +#endif + +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); + } +#endif + (void)bmi2; + return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); +} diff --git a/thirdparty/zstd/common/error_private.c b/thirdparty/zstd/common/error_private.c index cd437529c1..45bba5305b 100644 --- a/thirdparty/zstd/common/error_private.c +++ b/thirdparty/zstd/common/error_private.c @@ -48,6 +48,7 @@ const char* ERR_getErrorString(ERR_enum code) case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong"; + case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; case PREFIX(maxCode): default: return notErrorCode; } diff --git a/thirdparty/zstd/common/error_private.h b/thirdparty/zstd/common/error_private.h index 982cf8e9fe..71b37b8dfa 100644 --- a/thirdparty/zstd/common/error_private.h +++ b/thirdparty/zstd/common/error_private.h @@ -21,7 +21,7 @@ extern "C" { /* **************************************** * Dependencies ******************************************/ -#include <stddef.h> /* size_t */ +#include "zstd_deps.h" /* size_t */ #include "zstd_errors.h" /* enum list */ diff --git a/thirdparty/zstd/common/fse.h b/thirdparty/zstd/common/fse.h index ff54e70ea7..dd5fc44e80 100644 --- a/thirdparty/zstd/common/fse.h +++ b/thirdparty/zstd/common/fse.h @@ -23,7 +23,7 @@ extern "C" { /*-***************************************** * Dependencies ******************************************/ -#include <stddef.h> /* size_t, ptrdiff_t */ +#include "zstd_deps.h" /* size_t, ptrdiff_t */ /*-***************************************** @@ -137,10 +137,16 @@ FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize /*! FSE_normalizeCount(): normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + useLowProbCount is a boolean parameter which trades off compressed size for + faster header decoding. When it is set to 1, the compressed data will be slightly + smaller. And when it is set to 0, FSE_readNCount() and FSE_buildDTable() will be + faster. If you are compressing a small amount of data (< 2 KB) then useLowProbCount=0 + is a good default, since header deserialization makes a big speed difference. + Otherwise, useLowProbCount=1 is a good default, since the speed difference is small. @return : tableLog, or an errorCode, which can be tested using FSE_isError() */ FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, - const unsigned* count, size_t srcSize, unsigned maxSymbolValue); + const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount); /*! FSE_NCountWriteBound(): Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. @@ -228,6 +234,13 @@ FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize); +/*! FSE_readNCount_bmi2(): + * Same as FSE_readNCount() but pass bmi2=1 when your CPU supports BMI2 and 0 otherwise. + */ +FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize, int bmi2); + /*! Constructor and Destructor of FSE_DTable. Note that its size depends on 'tableLog' */ typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ @@ -288,12 +301,12 @@ If there is an error, the function will return an error code, which can be teste *******************************************/ /* FSE buffer bounds */ #define FSE_NCOUNTBOUND 512 -#define FSE_BLOCKBOUND(size) (size + (size>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */) +#define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */) #define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ /* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ -#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) -#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog)) +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog))) /* or use the size to malloc() space directly. Pay attention to alignment restrictions though */ #define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable)) @@ -309,9 +322,9 @@ unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsi /* FSE_compress_wksp() : * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable. + * FSE_COMPRESS_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable. */ -#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) ) +#define FSE_COMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) ) size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); @@ -322,18 +335,30 @@ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); /* FSE_buildCTable_wksp() : * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). - * `wkspSize` must be >= `(1<<tableLog)`. + * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`. */ +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (maxSymbolValue + 2 + (1ull << (tableLog - 2))) +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)) size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); +#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8) +#define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned)) +FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); +/**< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */ + size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits); /**< build a fake FSE_DTable, designed to read a flat distribution where each symbol uses nbBits */ size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue); /**< build a fake FSE_DTable, designed to always generate the same symbolValue */ -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog); -/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */ +#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue)) +#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned)) +size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize); +/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)` */ + +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2); +/**< Same as FSE_decompress_wksp() but with dynamic BMI2 support. Pass 1 if your CPU supports BMI2 or 0 if it doesn't. */ typedef enum { FSE_repeat_none, /**< Cannot use the previous table */ @@ -644,6 +669,9 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) #ifndef FSE_DEFAULT_MEMORY_USAGE # define FSE_DEFAULT_MEMORY_USAGE 13 #endif +#if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE) +# error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE" +#endif /*!FSE_MAX_SYMBOL_VALUE : * Maximum symbol value authorized. @@ -677,7 +705,7 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) # error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" #endif -#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3) +#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) #endif /* FSE_STATIC_LINKING_ONLY */ diff --git a/thirdparty/zstd/common/fse_decompress.c b/thirdparty/zstd/common/fse_decompress.c index bcc2223ccc..c164430f99 100644 --- a/thirdparty/zstd/common/fse_decompress.c +++ b/thirdparty/zstd/common/fse_decompress.c @@ -16,13 +16,14 @@ /* ************************************************************** * Includes ****************************************************************/ -#include <stdlib.h> /* malloc, free, qsort */ -#include <string.h> /* memcpy, memset */ +#include "debug.h" /* assert */ #include "bitstream.h" #include "compiler.h" #define FSE_STATIC_LINKING_ONLY #include "fse.h" #include "error_private.h" +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* ************************************************************** @@ -59,25 +60,27 @@ FSE_DTable* FSE_createDTable (unsigned tableLog) { if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; - return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); + return (FSE_DTable*)ZSTD_malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); } void FSE_freeDTable (FSE_DTable* dt) { - free(dt); + ZSTD_free(dt); } -size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) { void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); - U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; + U16* symbolNext = (U16*)workSpace; + BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1); U32 const maxSV1 = maxSymbolValue + 1; U32 const tableSize = 1 << tableLog; U32 highThreshold = tableSize-1; /* Sanity Checks */ + if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge); if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); @@ -95,11 +98,57 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0; symbolNext[s] = normalizedCounter[s]; } } } - memcpy(dt, &DTableH, sizeof(DTableH)); + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); } /* Spread symbols */ - { U32 const tableMask = tableSize-1; + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { + U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s<maxSV1; ++s, sv += add) { + int i; + int const n = normalizedCounter[s]; + MEM_write64(spread + pos, sv); + for (i = 8; i < n; i += 8) { + MEM_write64(spread + pos + i, sv); + } + pos += n; + } + } + /* Now we spread those positions across the table. + * The benefit of doing it in two stages is that we avoid the the + * variable size inner loop, which caused lots of branch misses. + * Now we can run through all the positions without any branch misses. + * We unroll the loop twice, since that is what emperically worked best. + */ + { + size_t position = 0; + size_t s; + size_t const unroll = 2; + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableDecode[uPosition].symbol = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); + } + } else { + U32 const tableMask = tableSize-1; U32 const step = FSE_TABLESTEP(tableSize); U32 s, position = 0; for (s=0; s<maxSV1; s++) { @@ -124,6 +173,11 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned return 0; } +size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) +{ + return FSE_buildDTable_internal(dt, normalizedCounter, maxSymbolValue, tableLog, workSpace, wkspSize); +} + #ifndef FSE_COMMONDEFS_ONLY @@ -251,36 +305,89 @@ size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, } -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog) +size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0); +} + +FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( + void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize, + unsigned maxLog, void* workSpace, size_t wkspSize, + int bmi2) { const BYTE* const istart = (const BYTE*)cSrc; const BYTE* ip = istart; short counting[FSE_MAX_SYMBOL_VALUE+1]; unsigned tableLog; unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + FSE_DTable* const dtable = (FSE_DTable*)workSpace; /* normal FSE decoding mode */ - size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + size_t const NCountLength = FSE_readNCount_bmi2(counting, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); if (FSE_isError(NCountLength)) return NCountLength; - /* if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); */ /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + assert(NCountLength <= cSrcSize); ip += NCountLength; cSrcSize -= NCountLength; - CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); + if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge); + workSpace = dtable + FSE_DTABLE_SIZE_U32(tableLog); + wkspSize -= FSE_DTABLE_SIZE(tableLog); + + CHECK_F( FSE_buildDTable_internal(dtable, counting, maxSymbolValue, tableLog, workSpace, wkspSize) ); + + { + const void* ptr = dtable; + const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1); + return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0); + } +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +TARGET_ATTRIBUTE("bmi2") static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1); +} +#endif - return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); + } +#endif + (void)bmi2; + return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); } typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) { + U32 wksp[FSE_BUILD_DTABLE_WKSP_SIZE_U32(FSE_TABLELOG_ABSOLUTE_MAX, FSE_MAX_SYMBOL_VALUE)]; + return FSE_buildDTable_wksp(dt, normalizedCounter, maxSymbolValue, tableLog, wksp, sizeof(wksp)); +} + size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) { - DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ - return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); + /* Static analyzer seems unable to understand this table will be properly initialized later */ + U32 wksp[FSE_DECOMPRESS_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)]; + return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, FSE_MAX_TABLELOG, wksp, sizeof(wksp)); } - +#endif #endif /* FSE_COMMONDEFS_ONLY */ diff --git a/thirdparty/zstd/common/huf.h b/thirdparty/zstd/common/huf.h index ef432685da..1afef90c7c 100644 --- a/thirdparty/zstd/common/huf.h +++ b/thirdparty/zstd/common/huf.h @@ -20,7 +20,7 @@ extern "C" { #define HUF_H_298734234 /* *** Dependencies *** */ -#include <stddef.h> /* size_t */ +#include "zstd_deps.h" /* size_t */ /* *** library symbols visibility *** */ @@ -111,6 +111,8 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, /* *** Dependencies *** */ #include "mem.h" /* U32 */ +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" /* *** Constants *** */ @@ -133,12 +135,16 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, #define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ /* static allocation of HUF's Compression Table */ +/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */ +struct HUF_CElt_s { + U16 val; + BYTE nbBits; +}; /* typedef'd to HUF_CElt */ +typedef struct HUF_CElt_s HUF_CElt; /* consider it an incomplete type */ #define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */ #define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32)) #define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ - U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \ - void* name##hv = &(name##hb); \ - HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */ + HUF_CElt name[HUF_CTABLE_SIZE_U32(maxSymbolValue)] /* no final ; */ /* static allocation of HUF's DTable */ typedef U32 HUF_DTable; @@ -184,7 +190,6 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, * or to save and regenerate 'CTable' using external methods. */ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); -typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */ size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); @@ -226,6 +231,19 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, const void* src, size_t srcSize); +/*! HUF_readStats_wksp() : + * Same as HUF_readStats() but takes an external workspace which must be + * 4-byte aligned and its size must be >= HUF_READ_STATS_WORKSPACE_SIZE. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +#define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1) +#define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workspace, size_t wkspSize, + int bmi2); + /** HUF_readCTable() : * Loading a CTable saved with HUF_writeCTable() */ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights); @@ -332,6 +350,9 @@ size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstS #endif size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2); +#endif #endif /* HUF_STATIC_LINKING_ONLY */ diff --git a/thirdparty/zstd/common/mem.h b/thirdparty/zstd/common/mem.h index 89c8aea7d2..4728ef767b 100644 --- a/thirdparty/zstd/common/mem.h +++ b/thirdparty/zstd/common/mem.h @@ -18,8 +18,10 @@ extern "C" { /*-**************************************** * Dependencies ******************************************/ -#include <stddef.h> /* size_t, ptrdiff_t */ -#include <string.h> /* memcpy */ +#include <stddef.h> /* size_t, ptrdiff_t */ +#include "compiler.h" /* __has_builtin */ +#include "debug.h" /* DEBUG_STATIC_ASSERT */ +#include "zstd_deps.h" /* ZSTD_memcpy */ /*-**************************************** @@ -39,93 +41,15 @@ extern "C" { # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ #endif -#ifndef __has_builtin -# define __has_builtin(x) 0 /* compat. with non-clang compilers */ -#endif - -/* code only tested on 32 and 64 bits systems */ -#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; } -MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } - -/* detects whether we are being compiled under msan */ -#if defined (__has_feature) -# if __has_feature(memory_sanitizer) -# define MEMORY_SANITIZER 1 -# endif -#endif - -#if defined (MEMORY_SANITIZER) -/* Not all platforms that support msan provide sanitizers/msan_interface.h. - * We therefore declare the functions we need ourselves, rather than trying to - * include the header file... */ - -#include <stdint.h> /* intptr_t */ - -/* Make memory region fully initialized (without changing its contents). */ -void __msan_unpoison(const volatile void *a, size_t size); - -/* Make memory region fully uninitialized (without changing its contents). - This is a legacy interface that does not update origin information. Use - __msan_allocated_memory() instead. */ -void __msan_poison(const volatile void *a, size_t size); - -/* Returns the offset of the first (at least partially) poisoned byte in the - memory range, or -1 if the whole range is good. */ -intptr_t __msan_test_shadow(const volatile void *x, size_t size); -#endif - -/* detects whether we are being compiled under asan */ -#if defined (__has_feature) -# if __has_feature(address_sanitizer) -# define ADDRESS_SANITIZER 1 -# endif -#elif defined(__SANITIZE_ADDRESS__) -# define ADDRESS_SANITIZER 1 -#endif - -#if defined (ADDRESS_SANITIZER) -/* Not all platforms that support asan provide sanitizers/asan_interface.h. - * We therefore declare the functions we need ourselves, rather than trying to - * include the header file... */ - -/** - * Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable. - * - * This memory must be previously allocated by your program. Instrumented - * code is forbidden from accessing addresses in this region until it is - * unpoisoned. This function is not guaranteed to poison the entire region - - * it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan - * alignment restrictions. - * - * \note This function is not thread-safe because no two threads can poison or - * unpoison memory in the same memory region simultaneously. - * - * \param addr Start of memory region. - * \param size Size of memory region. */ -void __asan_poison_memory_region(void const volatile *addr, size_t size); - -/** - * Marks a memory region (<c>[addr, addr+size)</c>) as addressable. - * - * This memory must be previously allocated by your program. Accessing - * addresses in this region is allowed until this region is poisoned again. - * This function could unpoison a super-region of <c>[addr, addr+size)</c> due - * to ASan alignment restrictions. - * - * \note This function is not thread-safe because no two threads can - * poison or unpoison memory in the same memory region simultaneously. - * - * \param addr Start of memory region. - * \param size Size of memory region. */ -void __asan_unpoison_memory_region(void const volatile *addr, size_t size); -#endif - - /*-************************************************************** * Basic Types *****************************************************************/ #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include <stdint.h> +# if defined(_AIX) +# include <inttypes.h> +# else +# include <stdint.h> /* intptr_t */ +# endif typedef uint8_t BYTE; typedef uint16_t U16; typedef int16_t S16; @@ -157,7 +81,53 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); /*-************************************************************** -* Memory I/O +* Memory I/O API +*****************************************************************/ +/*=== Static platform detection ===*/ +MEM_STATIC unsigned MEM_32bits(void); +MEM_STATIC unsigned MEM_64bits(void); +MEM_STATIC unsigned MEM_isLittleEndian(void); + +/*=== Native unaligned read/write ===*/ +MEM_STATIC U16 MEM_read16(const void* memPtr); +MEM_STATIC U32 MEM_read32(const void* memPtr); +MEM_STATIC U64 MEM_read64(const void* memPtr); +MEM_STATIC size_t MEM_readST(const void* memPtr); + +MEM_STATIC void MEM_write16(void* memPtr, U16 value); +MEM_STATIC void MEM_write32(void* memPtr, U32 value); +MEM_STATIC void MEM_write64(void* memPtr, U64 value); + +/*=== Little endian unaligned read/write ===*/ +MEM_STATIC U16 MEM_readLE16(const void* memPtr); +MEM_STATIC U32 MEM_readLE24(const void* memPtr); +MEM_STATIC U32 MEM_readLE32(const void* memPtr); +MEM_STATIC U64 MEM_readLE64(const void* memPtr); +MEM_STATIC size_t MEM_readLEST(const void* memPtr); + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); + +/*=== Big endian unaligned read/write ===*/ +MEM_STATIC U32 MEM_readBE32(const void* memPtr); +MEM_STATIC U64 MEM_readBE64(const void* memPtr); +MEM_STATIC size_t MEM_readBEST(const void* memPtr); + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); + +/*=== Byteswap ===*/ +MEM_STATIC U32 MEM_swap32(U32 in); +MEM_STATIC U64 MEM_swap64(U64 in); +MEM_STATIC size_t MEM_swapST(size_t in); + + +/*-************************************************************** +* Memory I/O Implementation *****************************************************************/ /* MEM_FORCE_MEMORY_ACCESS : * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. @@ -236,37 +206,37 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = MEM_STATIC U16 MEM_read16(const void* memPtr) { - U16 val; memcpy(&val, memPtr, sizeof(val)); return val; + U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; } MEM_STATIC U32 MEM_read32(const void* memPtr) { - U32 val; memcpy(&val, memPtr, sizeof(val)); return val; + U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; } MEM_STATIC U64 MEM_read64(const void* memPtr) { - U64 val; memcpy(&val, memPtr, sizeof(val)); return val; + U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; } MEM_STATIC size_t MEM_readST(const void* memPtr) { - size_t val; memcpy(&val, memPtr, sizeof(val)); return val; + size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; } MEM_STATIC void MEM_write16(void* memPtr, U16 value) { - memcpy(memPtr, &value, sizeof(value)); + ZSTD_memcpy(memPtr, &value, sizeof(value)); } MEM_STATIC void MEM_write32(void* memPtr, U32 value) { - memcpy(memPtr, &value, sizeof(value)); + ZSTD_memcpy(memPtr, &value, sizeof(value)); } MEM_STATIC void MEM_write64(void* memPtr, U64 value) { - memcpy(memPtr, &value, sizeof(value)); + ZSTD_memcpy(memPtr, &value, sizeof(value)); } #endif /* MEM_FORCE_MEMORY_ACCESS */ @@ -445,6 +415,9 @@ MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) MEM_writeBE64(memPtr, (U64)val); } +/* code only tested on 32 and 64 bits systems */ +MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } + #if defined (__cplusplus) } diff --git a/thirdparty/zstd/common/pool.c b/thirdparty/zstd/common/pool.c index aa4b4de0d3..4c1b83376f 100644 --- a/thirdparty/zstd/common/pool.c +++ b/thirdparty/zstd/common/pool.c @@ -10,9 +10,9 @@ /* ====== Dependencies ======= */ -#include <stddef.h> /* size_t */ +#include "zstd_deps.h" /* size_t */ #include "debug.h" /* assert */ -#include "zstd_internal.h" /* ZSTD_malloc, ZSTD_free */ +#include "zstd_internal.h" /* ZSTD_customMalloc, ZSTD_customFree */ #include "pool.h" /* ====== Compiler specifics ====== */ @@ -105,6 +105,10 @@ static void* POOL_thread(void* opaque) { assert(0); /* Unreachable */ } +POOL_ctx* ZSTD_createThreadPool(size_t numThreads) { + return POOL_create (numThreads, 0); +} + POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) { return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem); } @@ -115,14 +119,14 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, /* Check parameters */ if (!numThreads) { return NULL; } /* Allocate the context and zero initialize */ - ctx = (POOL_ctx*)ZSTD_calloc(sizeof(POOL_ctx), customMem); + ctx = (POOL_ctx*)ZSTD_customCalloc(sizeof(POOL_ctx), customMem); if (!ctx) { return NULL; } /* Initialize the job queue. * It needs one extra space since one space is wasted to differentiate * empty and full queues. */ ctx->queueSize = queueSize + 1; - ctx->queue = (POOL_job*)ZSTD_malloc(ctx->queueSize * sizeof(POOL_job), customMem); + ctx->queue = (POOL_job*)ZSTD_customMalloc(ctx->queueSize * sizeof(POOL_job), customMem); ctx->queueHead = 0; ctx->queueTail = 0; ctx->numThreadsBusy = 0; @@ -136,7 +140,7 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, } ctx->shutdown = 0; /* Allocate space for the thread handles */ - ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem); + ctx->threads = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), customMem); ctx->threadCapacity = 0; ctx->customMem = customMem; /* Check for errors */ @@ -179,12 +183,14 @@ void POOL_free(POOL_ctx *ctx) { ZSTD_pthread_mutex_destroy(&ctx->queueMutex); ZSTD_pthread_cond_destroy(&ctx->queuePushCond); ZSTD_pthread_cond_destroy(&ctx->queuePopCond); - ZSTD_free(ctx->queue, ctx->customMem); - ZSTD_free(ctx->threads, ctx->customMem); - ZSTD_free(ctx, ctx->customMem); + ZSTD_customFree(ctx->queue, ctx->customMem); + ZSTD_customFree(ctx->threads, ctx->customMem); + ZSTD_customFree(ctx, ctx->customMem); } - +void ZSTD_freeThreadPool (ZSTD_threadPool* pool) { + POOL_free (pool); +} size_t POOL_sizeof(POOL_ctx *ctx) { if (ctx==NULL) return 0; /* supports sizeof NULL */ @@ -203,11 +209,11 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads) return 0; } /* numThreads > threadCapacity */ - { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem); + { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem); if (!threadPool) return 1; /* replace existing thread pool */ - memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool)); - ZSTD_free(ctx->threads, ctx->customMem); + ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool)); + ZSTD_customFree(ctx->threads, ctx->customMem); ctx->threads = threadPool; /* Initialize additional threads */ { size_t threadId; @@ -301,7 +307,7 @@ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) struct POOL_ctx_s { int dummy; }; -static POOL_ctx g_ctx; +static POOL_ctx g_poolCtx; POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) { return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem); @@ -311,11 +317,11 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customM (void)numThreads; (void)queueSize; (void)customMem; - return &g_ctx; + return &g_poolCtx; } void POOL_free(POOL_ctx* ctx) { - assert(!ctx || ctx == &g_ctx); + assert(!ctx || ctx == &g_poolCtx); (void)ctx; } @@ -337,7 +343,7 @@ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) { size_t POOL_sizeof(POOL_ctx* ctx) { if (ctx==NULL) return 0; /* supports sizeof NULL */ - assert(ctx == &g_ctx); + assert(ctx == &g_poolCtx); return sizeof(*ctx); } diff --git a/thirdparty/zstd/common/pool.h b/thirdparty/zstd/common/pool.h index 259bafc975..63954ca6ca 100644 --- a/thirdparty/zstd/common/pool.h +++ b/thirdparty/zstd/common/pool.h @@ -16,7 +16,7 @@ extern "C" { #endif -#include <stddef.h> /* size_t */ +#include "zstd_deps.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */ #include "../zstd.h" diff --git a/thirdparty/zstd/common/threading.c b/thirdparty/zstd/common/threading.c index e2edb313eb..92cf57c195 100644 --- a/thirdparty/zstd/common/threading.c +++ b/thirdparty/zstd/common/threading.c @@ -78,11 +78,12 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr) #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32) -#include <stdlib.h> +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr) { - *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); + *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t)); if (!*mutex) return 1; return pthread_mutex_init(*mutex, attr); @@ -94,14 +95,14 @@ int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) return 0; { int const ret = pthread_mutex_destroy(*mutex); - free(*mutex); + ZSTD_free(*mutex); return ret; } } int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr) { - *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); + *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t)); if (!*cond) return 1; return pthread_cond_init(*cond, attr); @@ -113,7 +114,7 @@ int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond) return 0; { int const ret = pthread_cond_destroy(*cond); - free(*cond); + ZSTD_free(*cond); return ret; } } diff --git a/thirdparty/zstd/common/xxhash.c b/thirdparty/zstd/common/xxhash.c index 597de18fc8..e708df3c33 100644 --- a/thirdparty/zstd/common/xxhash.c +++ b/thirdparty/zstd/common/xxhash.c @@ -77,14 +77,12 @@ * Includes & Memory related functions ***************************************/ /* Modify the local functions below should you wish to use some other memory routines */ -/* for malloc(), free() */ -#include <stdlib.h> -#include <stddef.h> /* size_t */ -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/* for memcpy() */ -#include <string.h> -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } +/* for ZSTD_malloc(), ZSTD_free() */ +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */ +static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); } +static void XXH_free (void* p) { ZSTD_free(p); } +static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); } #ifndef XXH_STATIC_LINKING_ONLY # define XXH_STATIC_LINKING_ONLY @@ -95,49 +93,13 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp /* ************************************* * Compiler Specific Options ***************************************/ -#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# define INLINE_KEYWORD inline -#else -# define INLINE_KEYWORD -#endif - -#if defined(__GNUC__) || defined(__ICCARM__) -# define FORCE_INLINE_ATTR __attribute__((always_inline)) -#elif defined(_MSC_VER) -# define FORCE_INLINE_ATTR __forceinline -#else -# define FORCE_INLINE_ATTR -#endif - -#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR - - -#ifdef _MSC_VER -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -#endif +#include "compiler.h" /* ************************************* * Basic Types ***************************************/ -#ifndef MEM_MODULE -# define MEM_MODULE -# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include <stdint.h> - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -# else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */ -# endif -#endif - +#include "mem.h" /* BYTE, U32, U64, size_t */ #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) @@ -163,14 +125,14 @@ static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } static U32 XXH_read32(const void* memPtr) { U32 val; - memcpy(&val, memPtr, sizeof(val)); + ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; } static U64 XXH_read64(const void* memPtr) { U64 val; - memcpy(&val, memPtr, sizeof(val)); + ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; } @@ -307,12 +269,12 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } ****************************/ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState) { - memcpy(dstState, srcState, sizeof(*dstState)); + ZSTD_memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState) { - memcpy(dstState, srcState, sizeof(*dstState)); + ZSTD_memcpy(dstState, srcState, sizeof(*dstState)); } @@ -554,12 +516,12 @@ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) { XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ + ZSTD_memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ state.v1 = seed + PRIME32_1 + PRIME32_2; state.v2 = seed + PRIME32_2; state.v3 = seed + 0; state.v4 = seed - PRIME32_1; - memcpy(statePtr, &state, sizeof(state)); + ZSTD_memcpy(statePtr, &state, sizeof(state)); return XXH_OK; } @@ -567,12 +529,12 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int s XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) { XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ + ZSTD_memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ state.v1 = seed + PRIME64_1 + PRIME64_2; state.v2 = seed + PRIME64_2; state.v3 = seed + 0; state.v4 = seed - PRIME64_1; - memcpy(statePtr, &state, sizeof(state)); + ZSTD_memcpy(statePtr, &state, sizeof(state)); return XXH_OK; } @@ -843,14 +805,14 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); - memcpy(dst, &hash, sizeof(*dst)); + ZSTD_memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); - memcpy(dst, &hash, sizeof(*dst)); + ZSTD_memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) diff --git a/thirdparty/zstd/common/xxhash.h b/thirdparty/zstd/common/xxhash.h index 4207eba832..eceb55d5e0 100644 --- a/thirdparty/zstd/common/xxhash.h +++ b/thirdparty/zstd/common/xxhash.h @@ -55,7 +55,7 @@ extern "C" { /* **************************** * Definitions ******************************/ -#include <stddef.h> /* size_t */ +#include "zstd_deps.h" typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; diff --git a/thirdparty/zstd/common/zstd_common.c b/thirdparty/zstd/common/zstd_common.c index 91fe3323a5..939e9f08fa 100644 --- a/thirdparty/zstd/common/zstd_common.c +++ b/thirdparty/zstd/common/zstd_common.c @@ -13,8 +13,8 @@ /*-************************************* * Dependencies ***************************************/ -#include <stdlib.h> /* malloc, calloc, free */ -#include <string.h> /* memset */ +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ #include "error_private.h" #include "zstd_internal.h" @@ -53,31 +53,31 @@ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString /*=************************************************************** * Custom allocator ****************************************************************/ -void* ZSTD_malloc(size_t size, ZSTD_customMem customMem) +void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) { if (customMem.customAlloc) return customMem.customAlloc(customMem.opaque, size); - return malloc(size); + return ZSTD_malloc(size); } -void* ZSTD_calloc(size_t size, ZSTD_customMem customMem) +void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) { if (customMem.customAlloc) { /* calloc implemented as malloc+memset; * not as efficient as calloc, but next best guess for custom malloc */ void* const ptr = customMem.customAlloc(customMem.opaque, size); - memset(ptr, 0, size); + ZSTD_memset(ptr, 0, size); return ptr; } - return calloc(1, size); + return ZSTD_calloc(1, size); } -void ZSTD_free(void* ptr, ZSTD_customMem customMem) +void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) { if (ptr!=NULL) { if (customMem.customFree) customMem.customFree(customMem.opaque, ptr); else - free(ptr); + ZSTD_free(ptr); } } diff --git a/thirdparty/zstd/common/zstd_deps.h b/thirdparty/zstd/common/zstd_deps.h new file mode 100644 index 0000000000..0fb8b7818b --- /dev/null +++ b/thirdparty/zstd/common/zstd_deps.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016-2020, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides common libc dependencies that zstd requires. + * The purpose is to allow replacing this file with a custom implementation + * to compile zstd without libc support. + */ + +/* Need: + * NULL + * INT_MAX + * UINT_MAX + * ZSTD_memcpy() + * ZSTD_memset() + * ZSTD_memmove() + */ +#ifndef ZSTD_DEPS_COMMON +#define ZSTD_DEPS_COMMON + +#include <limits.h> +#include <stddef.h> +#include <string.h> + +#if defined(__GNUC__) && __GNUC__ >= 4 +# define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l)) +#else +# define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) memset((p),(v),(l)) +#endif + +#endif /* ZSTD_DEPS_COMMON */ + +/* Need: + * ZSTD_malloc() + * ZSTD_free() + * ZSTD_calloc() + */ +#ifdef ZSTD_DEPS_NEED_MALLOC +#ifndef ZSTD_DEPS_MALLOC +#define ZSTD_DEPS_MALLOC + +#include <stdlib.h> + +#define ZSTD_malloc(s) malloc(s) +#define ZSTD_calloc(n,s) calloc((n), (s)) +#define ZSTD_free(p) free((p)) + +#endif /* ZSTD_DEPS_MALLOC */ +#endif /* ZSTD_DEPS_NEED_MALLOC */ + +/* + * Provides 64-bit math support. + * Need: + * U64 ZSTD_div64(U64 dividend, U32 divisor) + */ +#ifdef ZSTD_DEPS_NEED_MATH64 +#ifndef ZSTD_DEPS_MATH64 +#define ZSTD_DEPS_MATH64 + +#define ZSTD_div64(dividend, divisor) ((dividend) / (divisor)) + +#endif /* ZSTD_DEPS_MATH64 */ +#endif /* ZSTD_DEPS_NEED_MATH64 */ + +/* Need: + * assert() + */ +#ifdef ZSTD_DEPS_NEED_ASSERT +#ifndef ZSTD_DEPS_ASSERT +#define ZSTD_DEPS_ASSERT + +#include <assert.h> + +#endif /* ZSTD_DEPS_ASSERT */ +#endif /* ZSTD_DEPS_NEED_ASSERT */ + +/* Need: + * ZSTD_DEBUG_PRINT() + */ +#ifdef ZSTD_DEPS_NEED_IO +#ifndef ZSTD_DEPS_IO +#define ZSTD_DEPS_IO + +#include <stdio.h> +#define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__) + +#endif /* ZSTD_DEPS_IO */ +#endif /* ZSTD_DEPS_NEED_IO */ + +/* Only requested when <stdint.h> is known to be present. + * Need: + * intptr_t + */ +#ifdef ZSTD_DEPS_NEED_STDINT +#ifndef ZSTD_DEPS_STDINT +#define ZSTD_DEPS_STDINT + +#include <stdint.h> + +#endif /* ZSTD_DEPS_STDINT */ +#endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/thirdparty/zstd/common/zstd_errors.h b/thirdparty/zstd/common/zstd_errors.h index 998398e7e5..6d0d003004 100644 --- a/thirdparty/zstd/common/zstd_errors.h +++ b/thirdparty/zstd/common/zstd_errors.h @@ -77,6 +77,7 @@ typedef enum { ZSTD_error_frameIndex_tooLarge = 100, ZSTD_error_seekableIO = 102, ZSTD_error_dstBuffer_wrong = 104, + ZSTD_error_srcBuffer_wrong = 105, ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ } ZSTD_ErrorCode; diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h index 3bc7e55a0a..0991f20a08 100644 --- a/thirdparty/zstd/common/zstd_internal.h +++ b/thirdparty/zstd/common/zstd_internal.h @@ -19,7 +19,7 @@ /*-************************************* * Dependencies ***************************************/ -#ifdef __aarch64__ +#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) #include <arm_neon.h> #endif #include "compiler.h" @@ -139,7 +139,7 @@ void _force_has_format_string(const char *format, ...) { #define ZSTD_REP_NUM 3 /* number of repcodes */ #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) -static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; +static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; #define KB *(1 <<10) #define MB *(1 <<20) @@ -153,13 +153,13 @@ static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; #define BIT0 1 #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 -static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; -static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; +static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; +static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; #define ZSTD_FRAMEIDSIZE 4 /* magic number size */ #define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ -static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; +static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; #define ZSTD_FRAMECHECKSUMSIZE 4 @@ -186,61 +186,75 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy #define OffFSELog 8 #define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog) -static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 2, 2, 3, 3, - 4, 6, 7, 8, 9,10,11,12, - 13,14,15,16 }; -static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 2, 1, 1, 1, 1, 1, - -1,-1,-1,-1 }; +#define ZSTD_MAX_HUF_HEADER_SIZE 128 /* header + <= 127 byte tree description */ +/* Each table cannot take more than #symbols * FSELog bits */ +#define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8) + +static UNUSED_ATTR const U32 LL_bits[MaxLL+1] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, + 4, 6, 7, 8, 9,10,11,12, + 13,14,15,16 +}; +static UNUSED_ATTR const S16 LL_defaultNorm[MaxLL+1] = { + 4, 3, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 2, 1, 1, 1, 1, 1, + -1,-1,-1,-1 +}; #define LL_DEFAULTNORMLOG 6 /* for static allocation */ -static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG; - -static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 7, 8, 9,10,11, - 12,13,14,15,16 }; -static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1,-1,-1, - -1,-1,-1,-1,-1 }; +static UNUSED_ATTR const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG; + +static UNUSED_ATTR const U32 ML_bits[MaxML+1] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 7, 8, 9,10,11, + 12,13,14,15,16 +}; +static UNUSED_ATTR const S16 ML_defaultNorm[MaxML+1] = { + 1, 4, 3, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1,-1,-1, + -1,-1,-1,-1,-1 +}; #define ML_DEFAULTNORMLOG 6 /* for static allocation */ -static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG; - -static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - -1,-1,-1,-1,-1 }; +static UNUSED_ATTR const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG; + +static UNUSED_ATTR const S16 OF_defaultNorm[DefaultMaxOff+1] = { + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + -1,-1,-1,-1,-1 +}; #define OF_DEFAULTNORMLOG 5 /* for static allocation */ -static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; +static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; /*-******************************************* * Shared functions to include for inlining *********************************************/ static void ZSTD_copy8(void* dst, const void* src) { -#ifdef __aarch64__ +#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src)); #else - memcpy(dst, src, 8); + ZSTD_memcpy(dst, src, 8); #endif } #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } static void ZSTD_copy16(void* dst, const void* src) { -#ifdef __aarch64__ +#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src)); #else - memcpy(dst, src, 16); + ZSTD_memcpy(dst, src, 16); #endif } #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; } @@ -255,13 +269,13 @@ typedef enum { } ZSTD_overlap_e; /*! ZSTD_wildcopy() : - * Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0) + * Custom version of ZSTD_memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0) * @param ovtype controls the overlap detection * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart. * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart. * The src buffer must be before the dst buffer. */ -MEM_STATIC FORCE_INLINE_ATTR +MEM_STATIC FORCE_INLINE_ATTR void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype) { ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src; @@ -284,14 +298,16 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e * one COPY16() in the first call. Then, do two calls per loop since * at that point it is more likely to have a high trip count. */ -#ifndef __aarch64__ +#ifdef __aarch64__ do { COPY16(op, ip); } while (op < oend); #else - COPY16(op, ip); - if (op >= oend) return; + ZSTD_copy16(op, ip); + if (16 >= length) return; + op += 16; + ip += 16; do { COPY16(op, ip); COPY16(op, ip); @@ -305,7 +321,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, { size_t const length = MIN(dstCapacity, srcSize); if (length > 0) { - memcpy(dst, src, length); + ZSTD_memcpy(dst, src, length); } return length; } @@ -320,28 +336,39 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, * In which case, resize it down to free some memory */ #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 +/* Controls whether the input/output buffer is buffered or stable. */ +typedef enum { + ZSTD_bm_buffered = 0, /* Buffer the input/output */ + ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */ +} ZSTD_bufferMode_e; + /*-******************************************* * Private declarations *********************************************/ typedef struct seqDef_s { - U32 offset; + U32 offset; /* Offset code of the sequence */ U16 litLength; U16 matchLength; } seqDef; typedef struct { seqDef* sequencesStart; - seqDef* sequences; + seqDef* sequences; /* ptr to end of sequences */ BYTE* litStart; - BYTE* lit; + BYTE* lit; /* ptr to end of literals */ BYTE* llCode; BYTE* mlCode; BYTE* ofCode; size_t maxNbSeq; size_t maxNbLit; - U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */ - U32 longLengthPos; + + /* longLengthPos and longLengthID to allow us to represent either a single litLength or matchLength + * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment + * the existing value of the litLength or matchLength by 0x10000. + */ + U32 longLengthID; /* 0 == no longLength; 1 == Represent the long literal; 2 == Represent the long match; */ + U32 longLengthPos; /* Index of the sequence to apply long length modification to */ } seqStore_t; typedef struct { @@ -384,9 +411,9 @@ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBu void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */ /* custom memory allocation functions */ -void* ZSTD_malloc(size_t size, ZSTD_customMem customMem); -void* ZSTD_calloc(size_t size, ZSTD_customMem customMem); -void ZSTD_free(void* ptr, ZSTD_customMem customMem); +void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem); +void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem); +void ZSTD_customFree(void* ptr, ZSTD_customMem customMem); MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */ @@ -394,8 +421,12 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus assert(val != 0); { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - return _BitScanReverse(&r, val) ? (unsigned)r : 0; +# if STATIC_BMI2 == 1 + return _lzcnt_u32(val)^31; +# else + unsigned long r=0; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; +# endif # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ return __builtin_clz (val) ^ 31; # elif defined(__ICCARM__) /* IAR Intrinsic */ diff --git a/thirdparty/zstd/compress/fse_compress.c b/thirdparty/zstd/compress/fse_compress.c index a42759814f..304a82b3cc 100644 --- a/thirdparty/zstd/compress/fse_compress.c +++ b/thirdparty/zstd/compress/fse_compress.c @@ -15,8 +15,6 @@ /* ************************************************************** * Includes ****************************************************************/ -#include <stdlib.h> /* malloc, free, qsort */ -#include <string.h> /* memcpy, memset */ #include "../common/compiler.h" #include "../common/mem.h" /* U32, U16, etc. */ #include "../common/debug.h" /* assert, DEBUGLOG */ @@ -25,6 +23,9 @@ #define FSE_STATIC_LINKING_ONLY #include "../common/fse.h" #include "../common/error_private.h" +#define ZSTD_DEPS_NEED_MALLOC +#define ZSTD_DEPS_NEED_MATH64 +#include "../common/zstd_deps.h" /* ZSTD_malloc, ZSTD_free, ZSTD_memcpy, ZSTD_memset */ /* ************************************************************** @@ -74,13 +75,15 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ; FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); U32 const step = FSE_TABLESTEP(tableSize); - U32 cumul[FSE_MAX_SYMBOL_VALUE+2]; - FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace; + U32* cumul = (U32*)workSpace; + FSE_FUNCTION_TYPE* tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSymbolValue + 2)); + U32 highThreshold = tableSize-1; + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* Must be 4 byte aligned */ + if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge); /* CTable header */ - if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge); tableU16[-2] = (U16) tableLog; tableU16[-1] = (U16) maxSymbolValue; assert(tableLog < 16); /* required for threshold strategy to work */ @@ -89,7 +92,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ #ifdef __clang_analyzer__ - memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */ + ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */ #endif /* symbol start positions */ @@ -168,12 +171,13 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, return 0; } - +#ifndef ZSTD_NO_UNUSED_FUNCTIONS size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) { FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */ return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol)); } +#endif @@ -307,10 +311,10 @@ FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog) size_t size; if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); - return (FSE_CTable*)malloc(size); + return (FSE_CTable*)ZSTD_malloc(size); } -void FSE_freeCTable (FSE_CTable* ct) { free(ct); } +void FSE_freeCTable (FSE_CTable* ct) { ZSTD_free(ct); } /* provides the minimum logSize to safely represent a distribution */ static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) @@ -341,11 +345,10 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); } - /* Secondary normalization method. To be used when primary method fails. */ -static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue) +static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount) { short const NOT_YET_ASSIGNED = -2; U32 s; @@ -362,7 +365,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, continue; } if (count[s] <= lowThreshold) { - norm[s] = -1; + norm[s] = lowProbCount; distributed++; total -= count[s]; continue; @@ -414,7 +417,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, { U64 const vStepLog = 62 - tableLog; U64 const mid = (1ULL << (vStepLog-1)) - 1; - U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */ + U64 const rStep = ZSTD_div64((((U64)1<<vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */ U64 tmpTotal = mid; for (s=0; s<=maxSymbolValue; s++) { if (norm[s]==NOT_YET_ASSIGNED) { @@ -431,10 +434,9 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, return 0; } - size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t total, - unsigned maxSymbolValue) + unsigned maxSymbolValue, unsigned useLowProbCount) { /* Sanity checks */ if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; @@ -443,8 +445,9 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; + short const lowProbCount = useLowProbCount ? -1 : 1; U64 const scale = 62 - tableLog; - U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */ + U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */ U64 const vStep = 1ULL<<(scale-20); int stillToDistribute = 1<<tableLog; unsigned s; @@ -456,7 +459,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, if (count[s] == total) return 0; /* rle special case */ if (count[s] == 0) { normalizedCounter[s]=0; continue; } if (count[s] <= lowThreshold) { - normalizedCounter[s] = -1; + normalizedCounter[s] = lowProbCount; stillToDistribute--; } else { short proba = (short)((count[s]*step) >> scale); @@ -470,7 +473,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, } } if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { /* corner case, need another normalization method */ - size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount); if (FSE_isError(errorCode)) return errorCode; } else normalizedCounter[largest] += (short)stillToDistribute; @@ -625,6 +628,7 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize, size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } +#ifndef ZSTD_NO_UNUSED_FUNCTIONS /* FSE_compress_wksp() : * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). * `wkspSize` size must be `(1<<tableLog)`. @@ -643,7 +647,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable)); /* init conditions */ - if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge); + if (wkspSize < FSE_COMPRESS_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge); if (srcSize <= 1) return 0; /* Not compressible */ if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE; if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG; @@ -656,7 +660,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src } tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); - CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) ); + CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue, /* useLowProbCount */ srcSize >= 2048) ); /* Write table description header */ { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); @@ -678,13 +682,16 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src typedef struct { FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)]; - BYTE scratchBuffer[1 << FSE_MAX_TABLELOG]; + union { + U32 hist_wksp[HIST_WKSP_SIZE_U32]; + BYTE scratchBuffer[1 << FSE_MAX_TABLELOG]; + } workspace; } fseWkspMax_t; size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) { fseWkspMax_t scratchBuffer; - DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */ + DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_COMPRESS_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer)); } @@ -693,6 +700,6 @@ size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcS { return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG); } - +#endif #endif /* FSE_COMMONDEFS_ONLY */ diff --git a/thirdparty/zstd/compress/hist.c b/thirdparty/zstd/compress/hist.c index 61e08c7968..a9659d11ad 100644 --- a/thirdparty/zstd/compress/hist.c +++ b/thirdparty/zstd/compress/hist.c @@ -34,7 +34,7 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, unsigned maxSymbolValue = *maxSymbolValuePtr; unsigned largestCount=0; - memset(count, 0, (maxSymbolValue+1) * sizeof(*count)); + ZSTD_memset(count, 0, (maxSymbolValue+1) * sizeof(*count)); if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; } while (ip<end) { @@ -60,9 +60,9 @@ typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e; * this design makes better use of OoO cpus, * and is noticeably faster when some values are heavily repeated. * But it needs some additional workspace for intermediate tables. - * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32. + * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32. * @return : largest histogram frequency, - * or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */ + * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */ static size_t HIST_count_parallel_wksp( unsigned* count, unsigned* maxSymbolValuePtr, const void* source, size_t sourceSize, @@ -71,22 +71,21 @@ static size_t HIST_count_parallel_wksp( { const BYTE* ip = (const BYTE*)source; const BYTE* const iend = ip+sourceSize; - unsigned maxSymbolValue = *maxSymbolValuePtr; + size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count); unsigned max=0; U32* const Counting1 = workSpace; U32* const Counting2 = Counting1 + 256; U32* const Counting3 = Counting2 + 256; U32* const Counting4 = Counting3 + 256; - memset(workSpace, 0, 4*256*sizeof(unsigned)); - /* safety checks */ + assert(*maxSymbolValuePtr <= 255); if (!sourceSize) { - memset(count, 0, maxSymbolValue + 1); + ZSTD_memset(count, 0, countSize); *maxSymbolValuePtr = 0; return 0; } - if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */ + ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned)); /* by stripes of 16 bytes */ { U32 cached = MEM_read32(ip); ip += 4; @@ -118,21 +117,18 @@ static size_t HIST_count_parallel_wksp( /* finish last symbols */ while (ip<iend) Counting1[*ip++]++; - if (check) { /* verify stats will fit into destination table */ - U32 s; for (s=255; s>maxSymbolValue; s--) { - Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s]; - if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall); - } } - { U32 s; - if (maxSymbolValue > 255) maxSymbolValue = 255; - for (s=0; s<=maxSymbolValue; s++) { - count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s]; - if (count[s] > max) max = count[s]; + for (s=0; s<256; s++) { + Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s]; + if (Counting1[s] > max) max = Counting1[s]; } } - while (!count[maxSymbolValue]) maxSymbolValue--; - *maxSymbolValuePtr = maxSymbolValue; + { unsigned maxSymbolValue = 255; + while (!Counting1[maxSymbolValue]) maxSymbolValue--; + if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall); + *maxSymbolValuePtr = maxSymbolValue; + ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */ + } return (size_t)max; } @@ -152,14 +148,6 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace); } -/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ -size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize) -{ - unsigned tmpCounters[HIST_WKSP_SIZE_U32]; - return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters)); -} - /* HIST_count_wksp() : * Same as HIST_count(), but using an externally provided scratch buffer. * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ @@ -175,9 +163,19 @@ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize); } +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters)); +} + size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize) { unsigned tmpCounters[HIST_WKSP_SIZE_U32]; return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters)); } +#endif diff --git a/thirdparty/zstd/compress/hist.h b/thirdparty/zstd/compress/hist.h index 77e3ec4fb1..fb9ead6834 100644 --- a/thirdparty/zstd/compress/hist.h +++ b/thirdparty/zstd/compress/hist.h @@ -14,7 +14,7 @@ ****************************************************************** */ /* --- dependencies --- */ -#include <stddef.h> /* size_t */ +#include "../common/zstd_deps.h" /* size_t */ /* --- simple histogram functions --- */ diff --git a/thirdparty/zstd/compress/huf_compress.c b/thirdparty/zstd/compress/huf_compress.c index 546879868a..302e08864d 100644 --- a/thirdparty/zstd/compress/huf_compress.c +++ b/thirdparty/zstd/compress/huf_compress.c @@ -23,8 +23,7 @@ /* ************************************************************** * Includes ****************************************************************/ -#include <string.h> /* memcpy, memset */ -#include <stdio.h> /* printf (debug) */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ #include "../common/compiler.h" #include "../common/bitstream.h" #include "hist.h" @@ -70,7 +69,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; - BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER]; + U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)]; unsigned count[HUF_TABLELOG_MAX+1]; S16 norm[HUF_TABLELOG_MAX+1]; @@ -85,7 +84,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight } tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue); - CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) ); + CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) ); /* Write table description header */ { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) ); @@ -103,11 +102,6 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight } -struct HUF_CElt_s { - U16 val; - BYTE nbBits; -}; /* typedef'd to HUF_CElt within "huf.h" */ - /*! HUF_writeCTable() : `CTable` : Huffman tree to save, using huf representation. @return : size of saved CTable */ @@ -156,6 +150,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void /* get symbol weights */ CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); + *hasZeroWeights = (rankVal[0] > 0); /* check result */ if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); @@ -164,16 +159,14 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void /* Prepare base value per rank */ { U32 n, nextRankStart = 0; for (n=1; n<=tableLog; n++) { - U32 current = nextRankStart; + U32 curr = nextRankStart; nextRankStart += (rankVal[n] << (n-1)); - rankVal[n] = current; + rankVal[n] = curr; } } /* fill nbBits */ - *hasZeroWeights = 0; { U32 n; for (n=0; n<nbSymbols; n++) { const U32 w = huffWeight[n]; - *hasZeroWeights |= (w == 0); CTable[n].nbBits = (BYTE)(tableLog + 1 - w) & -(w != 0); } } @@ -212,32 +205,63 @@ typedef struct nodeElt_s { BYTE nbBits; } nodeElt; +/** + * HUF_setMaxHeight(): + * Enforces maxNbBits on the Huffman tree described in huffNode. + * + * It sets all nodes with nbBits > maxNbBits to be maxNbBits. Then it adjusts + * the tree to so that it is a valid canonical Huffman tree. + * + * @pre The sum of the ranks of each symbol == 2^largestBits, + * where largestBits == huffNode[lastNonNull].nbBits. + * @post The sum of the ranks of each symbol == 2^largestBits, + * where largestBits is the return value <= maxNbBits. + * + * @param huffNode The Huffman tree modified in place to enforce maxNbBits. + * @param lastNonNull The symbol with the lowest count in the Huffman tree. + * @param maxNbBits The maximum allowed number of bits, which the Huffman tree + * may not respect. After this function the Huffman tree will + * respect maxNbBits. + * @return The maximum number of bits of the Huffman tree after adjustment, + * necessarily no more than maxNbBits. + */ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits) { const U32 largestBits = huffNode[lastNonNull].nbBits; - if (largestBits <= maxNbBits) return largestBits; /* early exit : no elt > maxNbBits */ + /* early exit : no elt > maxNbBits, so the tree is already valid. */ + if (largestBits <= maxNbBits) return largestBits; /* there are several too large elements (at least >= 2) */ { int totalCost = 0; const U32 baseCost = 1 << (largestBits - maxNbBits); int n = (int)lastNonNull; + /* Adjust any ranks > maxNbBits to maxNbBits. + * Compute totalCost, which is how far the sum of the ranks is + * we are over 2^largestBits after adjust the offending ranks. + */ while (huffNode[n].nbBits > maxNbBits) { totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)); huffNode[n].nbBits = (BYTE)maxNbBits; - n --; - } /* n stops at huffNode[n].nbBits <= maxNbBits */ - while (huffNode[n].nbBits == maxNbBits) n--; /* n end at index of smallest symbol using < maxNbBits */ + n--; + } + /* n stops at huffNode[n].nbBits <= maxNbBits */ + assert(huffNode[n].nbBits <= maxNbBits); + /* n end at index of smallest symbol using < maxNbBits */ + while (huffNode[n].nbBits == maxNbBits) --n; - /* renorm totalCost */ - totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */ + /* renorm totalCost from 2^largestBits to 2^maxNbBits + * note : totalCost is necessarily a multiple of baseCost */ + assert((totalCost & (baseCost - 1)) == 0); + totalCost >>= (largestBits - maxNbBits); + assert(totalCost > 0); /* repay normalized cost */ { U32 const noSymbol = 0xF0F0F0F0; U32 rankLast[HUF_TABLELOG_MAX+2]; - /* Get pos of last (smallest) symbol per rank */ - memset(rankLast, 0xF0, sizeof(rankLast)); + /* Get pos of last (smallest = lowest cum. count) symbol per rank */ + ZSTD_memset(rankLast, 0xF0, sizeof(rankLast)); { U32 currentNbBits = maxNbBits; int pos; for (pos=n ; pos >= 0; pos--) { @@ -247,34 +271,65 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits) } } while (totalCost > 0) { + /* Try to reduce the next power of 2 above totalCost because we + * gain back half the rank. + */ U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1; for ( ; nBitsToDecrease > 1; nBitsToDecrease--) { U32 const highPos = rankLast[nBitsToDecrease]; U32 const lowPos = rankLast[nBitsToDecrease-1]; if (highPos == noSymbol) continue; + /* Decrease highPos if no symbols of lowPos or if it is + * not cheaper to remove 2 lowPos than highPos. + */ if (lowPos == noSymbol) break; { U32 const highTotal = huffNode[highPos].count; U32 const lowTotal = 2 * huffNode[lowPos].count; if (highTotal <= lowTotal) break; } } /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */ + assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1); /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */ while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) - nBitsToDecrease ++; + nBitsToDecrease++; + assert(rankLast[nBitsToDecrease] != noSymbol); + /* Increase the number of bits to gain back half the rank cost. */ totalCost -= 1 << (nBitsToDecrease-1); + huffNode[rankLast[nBitsToDecrease]].nbBits++; + + /* Fix up the new rank. + * If the new rank was empty, this symbol is now its smallest. + * Otherwise, this symbol will be the largest in the new rank so no adjustment. + */ if (rankLast[nBitsToDecrease-1] == noSymbol) - rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */ - huffNode[rankLast[nBitsToDecrease]].nbBits ++; + rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; + /* Fix up the old rank. + * If the symbol was at position 0, meaning it was the highest weight symbol in the tree, + * it must be the only symbol in its rank, so the old rank now has no symbols. + * Otherwise, since the Huffman nodes are sorted by count, the previous position is now + * the smallest node in the rank. If the previous position belongs to a different rank, + * then the rank is now empty. + */ if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */ rankLast[nBitsToDecrease] = noSymbol; else { rankLast[nBitsToDecrease]--; if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease) rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */ - } } /* while (totalCost > 0) */ - + } + } /* while (totalCost > 0) */ + + /* If we've removed too much weight, then we have to add it back. + * To avoid overshooting again, we only adjust the smallest rank. + * We take the largest nodes from the lowest rank 0 and move them + * to rank 1. There's guaranteed to be enough rank 0 symbols because + * TODO. + */ while (totalCost < 0) { /* Sometimes, cost correction overshoot */ - if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */ + /* special case : no rank 1 symbol (using maxNbBits-1); + * let's create one from largest rank 0 (using maxNbBits). + */ + if (rankLast[1] == noSymbol) { while (huffNode[n].nbBits == maxNbBits) n--; huffNode[n+1].nbBits--; assert(n >= 0); @@ -285,14 +340,16 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits) huffNode[ rankLast[1] + 1 ].nbBits--; rankLast[1]++; totalCost ++; - } } } /* there are several too large elements (at least >= 2) */ + } + } /* repay normalized cost */ + } /* there are several too large elements (at least >= 2) */ return maxNbBits; } typedef struct { U32 base; - U32 current; + U32 curr; } rankPos; typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32]; @@ -304,21 +361,45 @@ typedef struct { rankPos rankPosition[RANK_POSITION_TABLE_SIZE]; } HUF_buildCTable_wksp_tables; +/** + * HUF_sort(): + * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order. + * + * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled. + * Must have (maxSymbolValue + 1) entries. + * @param[in] count Histogram of the symbols. + * @param[in] maxSymbolValue Maximum symbol value. + * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries. + */ static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue, rankPos* rankPosition) { - U32 n; - - memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE); - for (n=0; n<=maxSymbolValue; n++) { - U32 r = BIT_highbit32(count[n] + 1); - rankPosition[r].base ++; + int n; + int const maxSymbolValue1 = (int)maxSymbolValue + 1; + + /* Compute base and set curr to base. + * For symbol s let lowerRank = BIT_highbit32(count[n]+1) and rank = lowerRank + 1. + * Then 2^lowerRank <= count[n]+1 <= 2^rank. + * We attribute each symbol to lowerRank's base value, because we want to know where + * each rank begins in the output, so for rank R we want to count ranks R+1 and above. + */ + ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE); + for (n = 0; n < maxSymbolValue1; ++n) { + U32 lowerRank = BIT_highbit32(count[n] + 1); + rankPosition[lowerRank].base++; } - for (n=30; n>0; n--) rankPosition[n-1].base += rankPosition[n].base; - for (n=0; n<32; n++) rankPosition[n].current = rankPosition[n].base; - for (n=0; n<=maxSymbolValue; n++) { + assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0); + for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) { + rankPosition[n-1].base += rankPosition[n].base; + rankPosition[n-1].curr = rankPosition[n-1].base; + } + /* Sort */ + for (n = 0; n < maxSymbolValue1; ++n) { U32 const c = count[n]; U32 const r = BIT_highbit32(c+1) + 1; - U32 pos = rankPosition[r].current++; + U32 pos = rankPosition[r].curr++; + /* Insert into the correct position in the rank. + * We have at most 256 symbols, so this insertion should be fine. + */ while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count)) { huffNode[pos] = huffNode[pos-1]; pos--; @@ -335,28 +416,20 @@ static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValu */ #define STARTNODE (HUF_SYMBOLVALUE_MAX+1) -size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize) +/* HUF_buildTree(): + * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree. + * + * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array. + * @param maxSymbolValue The maximum symbol value. + * @return The smallest node in the Huffman tree (by count). + */ +static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue) { - HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace; - nodeElt* const huffNode0 = wksp_tables->huffNodeTbl; - nodeElt* const huffNode = huffNode0+1; + nodeElt* const huffNode0 = huffNode - 1; int nonNullRank; int lowS, lowN; int nodeNb = STARTNODE; int n, nodeRoot; - - /* safety checks */ - if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ - if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) - return ERROR(workSpace_tooSmall); - if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; - if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) - return ERROR(maxSymbolValue_tooLarge); - memset(huffNode0, 0, sizeof(huffNodeTable)); - - /* sort, decreasing order */ - HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition); - /* init for parents */ nonNullRank = (int)maxSymbolValue; while(huffNode[nonNullRank].count == 0) nonNullRank--; @@ -383,42 +456,72 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo for (n=0; n<=nonNullRank; n++) huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + return nonNullRank; +} + +/** + * HUF_buildCTableFromTree(): + * Build the CTable given the Huffman tree in huffNode. + * + * @param[out] CTable The output Huffman CTable. + * @param huffNode The Huffman tree. + * @param nonNullRank The last and smallest node in the Huffman tree. + * @param maxSymbolValue The maximum symbol value. + * @param maxNbBits The exact maximum number of bits used in the Huffman tree. + */ +static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits) +{ + /* fill result into ctable (val, nbBits) */ + int n; + U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0}; + U16 valPerRank[HUF_TABLELOG_MAX+1] = {0}; + int const alphabetSize = (int)(maxSymbolValue + 1); + for (n=0; n<=nonNullRank; n++) + nbPerRank[huffNode[n].nbBits]++; + /* determine starting value per rank */ + { U16 min = 0; + for (n=(int)maxNbBits; n>0; n--) { + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + for (n=0; n<alphabetSize; n++) + CTable[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */ + for (n=0; n<alphabetSize; n++) + CTable[n].val = valPerRank[CTable[n].nbBits]++; /* assign value within rank, symbol order */ +} + +size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize) +{ + HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace; + nodeElt* const huffNode0 = wksp_tables->huffNodeTbl; + nodeElt* const huffNode = huffNode0+1; + int nonNullRank; + + /* safety checks */ + if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) + return ERROR(workSpace_tooSmall); + if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(maxSymbolValue_tooLarge); + ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable)); + + /* sort, decreasing order */ + HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition); + + /* build tree */ + nonNullRank = HUF_buildTree(huffNode, maxSymbolValue); + /* enforce maxTableLog */ maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits); + if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */ - /* fill result into tree (val, nbBits) */ - { U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0}; - U16 valPerRank[HUF_TABLELOG_MAX+1] = {0}; - int const alphabetSize = (int)(maxSymbolValue + 1); - if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */ - for (n=0; n<=nonNullRank; n++) - nbPerRank[huffNode[n].nbBits]++; - /* determine stating value per rank */ - { U16 min = 0; - for (n=(int)maxNbBits; n>0; n--) { - valPerRank[n] = min; /* get starting value within each rank */ - min += nbPerRank[n]; - min >>= 1; - } } - for (n=0; n<alphabetSize; n++) - tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */ - for (n=0; n<alphabetSize; n++) - tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */ - } + HUF_buildCTableFromTree(tree, huffNode, nonNullRank, maxSymbolValue, maxNbBits); return maxNbBits; } -/** HUF_buildCTable() : - * @return : maxNbBits - * Note : count is used before tree is written, so they can safely overlap - */ -size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits) -{ - HUF_buildCTable_wksp_tables workspace; - return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace)); -} - size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) { size_t nbBits = 0; @@ -633,25 +736,26 @@ typedef struct { } HUF_compress_tables_t; /* HUF_compress_internal() : - * `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ + * `workSpace_align4` must be aligned on 4-bytes boundaries, + * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */ static size_t HUF_compress_internal (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, HUF_nbStreams_e nbStreams, - void* workSpace, size_t wkspSize, + void* workSpace_align4, size_t wkspSize, HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat, const int bmi2) { - HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace; + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4; BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; BYTE* op = ostart; HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE); + assert(((size_t)workSpace_align4 & 3) == 0); /* must be aligned on 4-bytes boundaries */ /* checks & inits */ - if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall); if (!srcSize) return 0; /* Uncompressed */ if (!dstSize) return 0; /* cannot fit anything within dst budget */ @@ -669,7 +773,7 @@ HUF_compress_internal (void* dst, size_t dstSize, } /* Scan input and build symbol stats */ - { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) ); + { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) ); if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */ } @@ -695,7 +799,7 @@ HUF_compress_internal (void* dst, size_t dstSize, CHECK_F(maxBits); huffLog = (U32)maxBits; /* Zero unused symbols in CTable, so we can check it for validity */ - memset(table->CTable + (maxSymbolValue + 1), 0, + ZSTD_memset(table->CTable + (maxSymbolValue + 1), 0, sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt))); } @@ -716,7 +820,7 @@ HUF_compress_internal (void* dst, size_t dstSize, op += hSize; if (repeat) { *repeat = HUF_repeat_none; } if (oldHufTable) - memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */ + ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */ } return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, @@ -747,14 +851,6 @@ size_t HUF_compress1X_repeat (void* dst, size_t dstSize, repeat, preferRepeat, bmi2); } -size_t HUF_compress1X (void* dst, size_t dstSize, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned huffLog) -{ - unsigned workSpace[HUF_WORKSPACE_SIZE_U32]; - return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace)); -} - /* HUF_compress4X_repeat(): * compress input using 4 streams. * provide workspace to generate compression tables */ @@ -784,6 +880,25 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize, hufTable, repeat, preferRepeat, bmi2); } +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +/** HUF_buildCTable() : + * @return : maxNbBits + * Note : count is used before tree is written, so they can safely overlap + */ +size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits) +{ + HUF_buildCTable_wksp_tables workspace; + return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace)); +} + +size_t HUF_compress1X (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog) +{ + unsigned workSpace[HUF_WORKSPACE_SIZE_U32]; + return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace)); +} + size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog) @@ -796,3 +911,4 @@ size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSi { return HUF_compress2(dst, maxDstSize, src, srcSize, 255, HUF_TABLELOG_DEFAULT); } +#endif diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c index 3f963b1cff..386b051df6 100644 --- a/thirdparty/zstd/compress/zstd_compress.c +++ b/thirdparty/zstd/compress/zstd_compress.c @@ -11,8 +11,7 @@ /*-************************************* * Dependencies ***************************************/ -#include <limits.h> /* INT_MAX */ -#include <string.h> /* memset */ +#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */ #include "../common/cpu.h" #include "../common/mem.h" #include "hist.h" /* HIST_countFast_wksp */ @@ -30,6 +29,19 @@ #include "zstd_ldm.h" #include "zstd_compress_superblock.h" +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! + * COMPRESS_HEAPMODE : + * Select how default decompression function ZSTD_compress() allocates its context, + * on stack (0, default), or into heap (1). + * Note that functions with explicit context such as ZSTD_compressCCtx() are unaffected. + */ +#ifndef ZSTD_COMPRESS_HEAPMODE +# define ZSTD_COMPRESS_HEAPMODE 0 +#endif + /*-************************************* * Helper functions @@ -52,6 +64,7 @@ size_t ZSTD_compressBound(size_t srcSize) { struct ZSTD_CDict_s { const void* dictContent; size_t dictContentSize; + ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */ U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */ ZSTD_cwksp workspace; ZSTD_matchState_t matchState; @@ -69,7 +82,7 @@ ZSTD_CCtx* ZSTD_createCCtx(void) static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) { assert(cctx != NULL); - memset(cctx, 0, sizeof(*cctx)); + ZSTD_memset(cctx, 0, sizeof(*cctx)); cctx->customMem = memManager; cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); { size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters); @@ -82,8 +95,8 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) { ZSTD_STATIC_ASSERT(zcss_init==0); ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; - { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem); + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem); if (!cctx) return NULL; ZSTD_initCCtx(cctx, customMem); return cctx; @@ -96,20 +109,20 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) ZSTD_CCtx* cctx; if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */ if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */ - ZSTD_cwksp_init(&ws, workspace, workspaceSize); + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx)); if (cctx == NULL) return NULL; - memset(cctx, 0, sizeof(ZSTD_CCtx)); + ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx)); ZSTD_cwksp_move(&cctx->workspace, &ws); cctx->staticSize = workspaceSize; /* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */ - if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL; + if (!ZSTD_cwksp_check_available(&cctx->workspace, ENTROPY_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL; cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); - cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, HUF_WORKSPACE_SIZE); + cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, ENTROPY_WORKSPACE_SIZE); cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); return cctx; } @@ -119,10 +132,10 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) */ static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx) { - ZSTD_free(cctx->localDict.dictBuffer, cctx->customMem); + ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem); ZSTD_freeCDict(cctx->localDict.cdict); - memset(&cctx->localDict, 0, sizeof(cctx->localDict)); - memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); + ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict)); + ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); cctx->cdict = NULL; } @@ -153,7 +166,7 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx); ZSTD_freeCCtxContent(cctx); if (!cctxInWorkspace) { - ZSTD_free(cctx, cctx->customMem); + ZSTD_customFree(cctx, cctx->customMem); } } return 0; @@ -189,15 +202,32 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) /* private API call, for dictBuilder only */ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } +/* Returns 1 if compression parameters are such that we should + * enable long distance matching (wlog >= 27, strategy >= btopt). + * Returns 0 otherwise. + */ +static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const cParams) { + return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27; +} + static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( ZSTD_compressionParameters cParams) { ZSTD_CCtx_params cctxParams; - memset(&cctxParams, 0, sizeof(cctxParams)); + /* should not matter, as all cParams are presumed properly defined */ + ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT); cctxParams.cParams = cParams; - cctxParams.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */ + + if (ZSTD_CParams_shouldEnableLdm(&cParams)) { + DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params"); + cctxParams.ldmParams.enableLdm = 1; + /* LDM is enabled by default for optimal parser and window size >= 128MB */ + ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams); + assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog); + assert(cctxParams.ldmParams.hashRateLog < 32); + } + assert(!ZSTD_checkCParams(cParams)); - cctxParams.fParams.contentSizeFlag = 1; return cctxParams; } @@ -205,13 +235,12 @@ static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced( ZSTD_customMem customMem) { ZSTD_CCtx_params* params; - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; - params = (ZSTD_CCtx_params*)ZSTD_calloc( + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + params = (ZSTD_CCtx_params*)ZSTD_customCalloc( sizeof(ZSTD_CCtx_params), customMem); if (!params) { return NULL; } + ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); params->customMem = customMem; - params->compressionLevel = ZSTD_CLEVEL_DEFAULT; - params->fParams.contentSizeFlag = 1; return params; } @@ -223,7 +252,7 @@ ZSTD_CCtx_params* ZSTD_createCCtxParams(void) size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params) { if (params == NULL) { return 0; } - ZSTD_free(params, params->customMem); + ZSTD_customFree(params, params->customMem); return 0; } @@ -234,7 +263,7 @@ size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params) size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) { RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); - memset(cctxParams, 0, sizeof(*cctxParams)); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); cctxParams->compressionLevel = compressionLevel; cctxParams->fParams.contentSizeFlag = 1; return 0; @@ -244,7 +273,7 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete { RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , ""); - memset(cctxParams, 0, sizeof(*cctxParams)); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); assert(!ZSTD_checkCParams(params.cParams)); cctxParams->cParams = params.cParams; cctxParams->fParams = params.fParams; @@ -354,6 +383,11 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) #endif return bounds; + case ZSTD_c_enableDedicatedDictSearch: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + case ZSTD_c_enableLongDistanceMatching: bounds.lowerBound = 0; bounds.upperBound = 1; @@ -397,7 +431,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) return bounds; case ZSTD_c_forceAttachDict: - ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy); + ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad); bounds.lowerBound = ZSTD_dictDefaultAttach; bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */ return bounds; @@ -418,6 +452,22 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) bounds.upperBound = ZSTD_SRCSIZEHINT_MAX; return bounds; + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + bounds.lowerBound = (int)ZSTD_bm_buffered; + bounds.upperBound = (int)ZSTD_bm_stable; + return bounds; + + case ZSTD_c_blockDelimiters: + bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters; + bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters; + return bounds; + + case ZSTD_c_validateSequences: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + default: bounds.error = ERROR(parameter_unsupported); return bounds; @@ -465,6 +515,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) case ZSTD_c_jobSize: case ZSTD_c_overlapLog: case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: case ZSTD_c_enableLongDistanceMatching: case ZSTD_c_ldmHashLog: case ZSTD_c_ldmMinMatch: @@ -474,6 +525,10 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) case ZSTD_c_literalCompressionMode: case ZSTD_c_targetCBlockSize: case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: default: return 0; } @@ -515,12 +570,17 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) case ZSTD_c_jobSize: case ZSTD_c_overlapLog: case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: case ZSTD_c_enableLongDistanceMatching: case ZSTD_c_ldmHashLog: case ZSTD_c_ldmMinMatch: case ZSTD_c_ldmBucketSizeLog: case ZSTD_c_targetCBlockSize: case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: break; default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); @@ -541,9 +601,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, case ZSTD_c_compressionLevel : { FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); - if (value) { /* 0 : does not change current level */ + if (value == 0) + CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else CCtxParams->compressionLevel = value; - } if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel; return 0; /* return type (size_t) cannot represent negative values */ } @@ -667,6 +728,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, return CCtxParams->rsyncable; #endif + case ZSTD_c_enableDedicatedDictSearch : + CCtxParams->enableDedicatedDictSearch = (value!=0); + return CCtxParams->enableDedicatedDictSearch; + case ZSTD_c_enableLongDistanceMatching : CCtxParams->ldmParams.enableLdm = (value!=0); return CCtxParams->ldmParams.enableLdm; @@ -707,6 +772,26 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, CCtxParams->srcSizeHint = value; return CCtxParams->srcSizeHint; + case ZSTD_c_stableInBuffer: + BOUNDCHECK(ZSTD_c_stableInBuffer, value); + CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->inBufferMode; + + case ZSTD_c_stableOutBuffer: + BOUNDCHECK(ZSTD_c_stableOutBuffer, value); + CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->outBufferMode; + + case ZSTD_c_blockDelimiters: + BOUNDCHECK(ZSTD_c_blockDelimiters, value); + CCtxParams->blockDelimiters = (ZSTD_sequenceFormat_e)value; + return CCtxParams->blockDelimiters; + + case ZSTD_c_validateSequences: + BOUNDCHECK(ZSTD_c_validateSequences, value); + CCtxParams->validateSequences = value; + return CCtxParams->validateSequences; + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); } } @@ -794,6 +879,9 @@ size_t ZSTD_CCtxParams_getParameter( *value = CCtxParams->rsyncable; break; #endif + case ZSTD_c_enableDedicatedDictSearch : + *value = CCtxParams->enableDedicatedDictSearch; + break; case ZSTD_c_enableLongDistanceMatching : *value = CCtxParams->ldmParams.enableLdm; break; @@ -815,6 +903,18 @@ size_t ZSTD_CCtxParams_getParameter( case ZSTD_c_srcSizeHint : *value = (int)CCtxParams->srcSizeHint; break; + case ZSTD_c_stableInBuffer : + *value = (int)CCtxParams->inBufferMode; + break; + case ZSTD_c_stableOutBuffer : + *value = (int)CCtxParams->outBufferMode; + break; + case ZSTD_c_blockDelimiters : + *value = (int)CCtxParams->blockDelimiters; + break; + case ZSTD_c_validateSequences : + *value = (int)CCtxParams->validateSequences; + break; default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); } return 0; @@ -850,6 +950,14 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo return 0; } +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams( + int const compressionLevel, + size_t const dictSize); +static int ZSTD_dedicatedDictSearch_isSupported( + const ZSTD_compressionParameters* cParams); +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams); + /** * Initializes the local dict using the requested parameters. * NOTE: This does not use the pledged src size, because it may be used for more @@ -858,8 +966,6 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) { ZSTD_localDict* const dl = &cctx->localDict; - ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams( - &cctx->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN, dl->dictSize); if (dl->dict == NULL) { /* No local dictionary. */ assert(dl->dictBuffer == NULL); @@ -876,12 +982,12 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) assert(cctx->cdict == NULL); assert(cctx->prefixDict.dict == NULL); - dl->cdict = ZSTD_createCDict_advanced( + dl->cdict = ZSTD_createCDict_advanced2( dl->dict, dl->dictSize, ZSTD_dlm_byRef, dl->dictContentType, - cParams, + &cctx->requestedParams, cctx->customMem); RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed"); cctx->cdict = dl->cdict; @@ -894,8 +1000,6 @@ size_t ZSTD_CCtx_loadDictionary_advanced( { RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, "Can't load a dictionary when ctx is not in init stage."); - RETURN_ERROR_IF(cctx->staticSize, memory_allocation, - "no malloc for static CCtx"); DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize); ZSTD_clearAllDicts(cctx); /* in case one already exists */ if (dict == NULL || dictSize == 0) /* no dictionary mode */ @@ -903,9 +1007,12 @@ size_t ZSTD_CCtx_loadDictionary_advanced( if (dictLoadMethod == ZSTD_dlm_byRef) { cctx->localDict.dict = dict; } else { - void* dictBuffer = ZSTD_malloc(dictSize, cctx->customMem); + void* dictBuffer; + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "no malloc for static CCtx"); + dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem); RETURN_ERROR_IF(!dictBuffer, memory_allocation, "NULL pointer!"); - memcpy(dictBuffer, dict, dictSize); + ZSTD_memcpy(dictBuffer, dict, dictSize); cctx->localDict.dictBuffer = dictBuffer; cctx->localDict.dict = dictBuffer; } @@ -938,6 +1045,14 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) return 0; } +size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a pool when ctx not in init stage."); + cctx->pool = pool; + return 0; +} + size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) { return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent); @@ -1022,24 +1137,73 @@ U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) return hashLog - btScale; } +/** ZSTD_dictAndWindowLog() : + * Returns an adjusted window log that is large enough to fit the source and the dictionary. + * The zstd format says that the entire dictionary is valid if one byte of the dictionary + * is within the window. So the hashLog and chainLog should be large enough to reference both + * the dictionary and the window. So we must use this adjusted dictAndWindowLog when downsizing + * the hashLog and windowLog. + * NOTE: srcSize must not be ZSTD_CONTENTSIZE_UNKNOWN. + */ +static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize) +{ + const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX; + /* No dictionary ==> No change */ + if (dictSize == 0) { + return windowLog; + } + assert(windowLog <= ZSTD_WINDOWLOG_MAX); + assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */ + { + U64 const windowSize = 1ULL << windowLog; + U64 const dictAndWindowSize = dictSize + windowSize; + /* If the window size is already large enough to fit both the source and the dictionary + * then just use the window size. Otherwise adjust so that it fits the dictionary and + * the window. + */ + if (windowSize >= dictSize + srcSize) { + return windowLog; /* Window size large enough already */ + } else if (dictAndWindowSize >= maxWindowSize) { + return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */ + } else { + return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1; + } + } +} + /** ZSTD_adjustCParams_internal() : * optimize `cPar` for a specified input (`srcSize` and `dictSize`). * mostly downsize to reduce memory consumption and initialization latency. * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known. + * `mode` is the mode for parameter adjustment. See docs for `ZSTD_cParamMode_e`. * note : `srcSize==0` means 0! * condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */ static ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, unsigned long long srcSize, - size_t dictSize) + size_t dictSize, + ZSTD_cParamMode_e mode) { - static const U64 minSrcSize = 513; /* (1<<9) + 1 */ - static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); + const U64 minSrcSize = 513; /* (1<<9) + 1 */ + const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); assert(ZSTD_checkCParams(cPar)==0); if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN) srcSize = minSrcSize; + switch (mode) { + case ZSTD_cpm_noAttachDict: + case ZSTD_cpm_unknown: + case ZSTD_cpm_createCDict: + break; + case ZSTD_cpm_attachDict: + dictSize = 0; + break; + default: + assert(0); + break; + } + /* resize windowLog if input is small enough, to use less memory */ if ( (srcSize < maxWindowResize) && (dictSize < maxWindowResize) ) { @@ -1049,10 +1213,11 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, ZSTD_highbit32(tSize-1) + 1; if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; } - if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1; - { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); - if (cycleLog > cPar.windowLog) - cPar.chainLog -= (cycleLog - cPar.windowLog); + { U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize); + U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1; + if (cycleLog > dictAndWindowLog) + cPar.chainLog -= (cycleLog - dictAndWindowLog); } if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) @@ -1068,31 +1233,38 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar, { cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */ if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN; - return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize); + return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown); } -static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize); -static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize); +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode); +static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode); + +static void ZSTD_overrideCParams( + ZSTD_compressionParameters* cParams, + const ZSTD_compressionParameters* overrides) +{ + if (overrides->windowLog) cParams->windowLog = overrides->windowLog; + if (overrides->hashLog) cParams->hashLog = overrides->hashLog; + if (overrides->chainLog) cParams->chainLog = overrides->chainLog; + if (overrides->searchLog) cParams->searchLog = overrides->searchLog; + if (overrides->minMatch) cParams->minMatch = overrides->minMatch; + if (overrides->targetLength) cParams->targetLength = overrides->targetLength; + if (overrides->strategy) cParams->strategy = overrides->strategy; +} ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( - const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize) + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) { ZSTD_compressionParameters cParams; if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) { srcSizeHint = CCtxParams->srcSizeHint; } - cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize); + cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode); if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; - if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog; - if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog; - if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog; - if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog; - if (CCtxParams->cParams.minMatch) cParams.minMatch = CCtxParams->cParams.minMatch; - if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength; - if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy; + ZSTD_overrideCParams(&cParams, &CCtxParams->cParams); assert(!ZSTD_checkCParams(cParams)); /* srcSizeHint == 0 means 0 */ - return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize); + return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode); } static size_t @@ -1123,45 +1295,61 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, return tableSpace + optSpace; } -size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) +static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( + const ZSTD_compressionParameters* cParams, + const ldmParams_t* ldmParams, + const int isStatic, + const size_t buffInSize, + const size_t buffOutSize, + const U64 pledgedSrcSize) { - RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); - { ZSTD_compressionParameters const cParams = - ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0); - size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); - U32 const divider = (cParams.minMatch==3) ? 3 : 4; - size_t const maxNbSeq = blockSize / divider; - size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) - + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef)) - + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); - size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE); - size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); - size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1); + size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << cParams->windowLog), pledgedSrcSize)); + size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); + U32 const divider = (cParams->minMatch==3) ? 3 : 4; + size_t const maxNbSeq = blockSize / divider; + size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) + + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef)) + + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); + size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE); + size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); + size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, /* forCCtx */ 1); - size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams); - size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq)); + size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams); + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize); + size_t const ldmSeqSpace = ldmParams->enableLdm ? + ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0; - /* estimateCCtxSize is for one-shot compression. So no buffers should - * be needed. However, we still allocate two 0-sized buffers, which can - * take space under ASAN. */ - size_t const bufferSpace = ZSTD_cwksp_alloc_size(0) - + ZSTD_cwksp_alloc_size(0); - size_t const cctxSpace = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)); + size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + + ZSTD_cwksp_alloc_size(buffOutSize); - size_t const neededSpace = - cctxSpace + - entropySpace + - blockStateSpace + - ldmSpace + - ldmSeqSpace + - matchStateSize + - tokenSpace + - bufferSpace; + size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0; - DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace); - return neededSpace; - } + size_t const neededSpace = + cctxSpace + + entropySpace + + blockStateSpace + + ldmSpace + + ldmSeqSpace + + matchStateSize + + tokenSpace + + bufferSpace; + + DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace); + return neededSpace; +} + +size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) +{ + ZSTD_compressionParameters const cParams = + ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + + RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); + /* estimateCCtxSize is for one-shot compression. So no buffers should + * be needed. However, we still allocate two 0-sized buffers, which can + * take space under ASAN. */ + return ZSTD_estimateCCtxSize_usingCCtxParams_internal( + &cParams, ¶ms->ldmParams, 1, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN); } size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) @@ -1172,7 +1360,7 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel) { - ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0); + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); return ZSTD_estimateCCtxSize_usingCParams(cParams); } @@ -1191,15 +1379,18 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params) { RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); { ZSTD_compressionParameters const cParams = - ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0); - size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params); + ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); - size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize; - size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1; - size_t const streamingSize = ZSTD_cwksp_alloc_size(inBuffSize) - + ZSTD_cwksp_alloc_size(outBuffSize); - - return CCtxSize + streamingSize; + size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered) + ? ((size_t)1 << cParams.windowLog) + blockSize + : 0; + size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered) + ? ZSTD_compressBound(blockSize) + 1 + : 0; + + return ZSTD_estimateCCtxSize_usingCCtxParams_internal( + &cParams, ¶ms->ldmParams, 1, inBuffSize, outBuffSize, + ZSTD_CONTENTSIZE_UNKNOWN); } } @@ -1211,7 +1402,7 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams) static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) { - ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0); + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); return ZSTD_estimateCStreamSize_usingCParams(cParams); } @@ -1305,16 +1496,6 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) } /** - * Indicates whether this compression proceeds directly from user-provided - * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or - * whether the context needs to buffer the input/output (ZSTDb_buffered). - */ -typedef enum { - ZSTDb_not_buffered, - ZSTDb_buffered -} ZSTD_buffered_policy_e; - -/** * Controls, for this matchState reset, whether the tables need to be cleared / * prepared for the coming compression (ZSTDcrp_makeClean), or whether the * tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a @@ -1441,45 +1622,32 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); U32 const divider = (params.cParams.minMatch==3) ? 3 : 4; size_t const maxNbSeq = blockSize / divider; - size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) - + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef)) - + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); - size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0; - size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0; - size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1); + size_t const buffOutSize = (zbuff == ZSTDb_buffered && params.outBufferMode == ZSTD_bm_buffered) + ? ZSTD_compressBound(blockSize) + 1 + : 0; + size_t const buffInSize = (zbuff == ZSTDb_buffered && params.inBufferMode == ZSTD_bm_buffered) + ? windowSize + blockSize + : 0; size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize); - ZSTD_indexResetPolicy_e needsIndexReset = zc->initialized ? ZSTDirp_continue : ZSTDirp_reset; + int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window); + ZSTD_indexResetPolicy_e needsIndexReset = + (!indexTooClose && zc->initialized) ? ZSTDirp_continue : ZSTDirp_reset; - if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) { - needsIndexReset = ZSTDirp_reset; - } + size_t const neededSpace = + ZSTD_estimateCCtxSize_usingCCtxParams_internal( + ¶ms.cParams, ¶ms.ldmParams, zc->staticSize != 0, + buffInSize, buffOutSize, pledgedSrcSize); + FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0); /* Check if workspace is large enough, alloc a new one if needed */ - { size_t const cctxSpace = zc->staticSize ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0; - size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE); - size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); - size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + ZSTD_cwksp_alloc_size(buffOutSize); - size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams); - size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq)); - - size_t const neededSpace = - cctxSpace + - entropySpace + - blockStateSpace + - ldmSpace + - ldmSeqSpace + - matchStateSize + - tokenSpace + - bufferSpace; - + { int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace; int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace); - DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers", - neededSpace>>10, matchStateSize>>10, bufferSpace>>10); + DEBUGLOG(4, "Need %zu B workspace", neededSpace); DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); if (workspaceTooSmall || workspaceWasteful) { @@ -1503,7 +1671,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock"); zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock"); - zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, HUF_WORKSPACE_SIZE); + zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, ENTROPY_WORKSPACE_SIZE); RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace"); } } @@ -1534,6 +1702,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->seqStore.maxNbLit = blockSize; /* buffers */ + zc->bufferedPolicy = zbuff; zc->inBuffSize = buffInSize; zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize); zc->outBuffSize = buffOutSize; @@ -1546,7 +1715,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, ((size_t)1) << (params.ldmParams.hashLog - params.ldmParams.bucketSizeLog); zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize); - memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize); + ZSTD_memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize); } /* sequences storage */ @@ -1570,7 +1739,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, /* TODO: avoid memset? */ size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog; zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t)); - memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); + ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq)); zc->maxNbLdmSequences = maxNbLdmSeq; @@ -1579,6 +1748,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->ldmState.loadedDictEnd = 0; } + /* Due to alignment, when reusing a workspace, we can actually consume + * up to 3 extra bytes for alignment. See the comments in zstd_cwksp.h + */ + assert(ZSTD_cwksp_used(ws) >= neededSpace && + ZSTD_cwksp_used(ws) <= neededSpace + 3); + DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); zc->initialized = 1; @@ -1618,12 +1793,14 @@ static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict, U64 pledgedSrcSize) { size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy]; - return ( pledgedSrcSize <= cutoff - || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN - || params->attachDictPref == ZSTD_dictForceAttach ) - && params->attachDictPref != ZSTD_dictForceCopy - && !params->forceWindow; /* dictMatchState isn't correctly - * handled in _enforceMaxDist */ + int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch; + return dedicatedDictSearch + || ( ( pledgedSrcSize <= cutoff + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || params->attachDictPref == ZSTD_dictForceAttach ) + && params->attachDictPref != ZSTD_dictForceCopy + && !params->forceWindow ); /* dictMatchState isn't correctly + * handled in _enforceMaxDist */ } static size_t @@ -1633,17 +1810,24 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff) { - { const ZSTD_compressionParameters* const cdict_cParams = &cdict->matchState.cParams; + { + ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams; unsigned const windowLog = params.cParams.windowLog; assert(windowLog != 0); /* Resize working context table params for input only, since the dict * has its own tables. */ - /* pledgeSrcSize == 0 means 0! */ - params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0); + /* pledgedSrcSize == 0 means 0! */ + + if (cdict->matchState.dedicatedDictSearch) { + ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams); + } + + params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize, + cdict->dictContentSize, ZSTD_cpm_attachDict); params.cParams.windowLog = windowLog; FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, ZSTDcrp_makeClean, zbuff), ""); - assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); + assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy); } { const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc @@ -1670,7 +1854,7 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, cctx->dictID = cdict->dictID; /* copy block state */ - memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); return 0; } @@ -1683,6 +1867,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, { const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; + assert(!cdict->matchState.dedicatedDictSearch); + DEBUGLOG(4, "copying dictionary into context"); { unsigned const windowLog = params.cParams.windowLog; @@ -1703,10 +1889,10 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, { size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog); size_t const hSize = (size_t)1 << cdict_cParams->hashLog; - memcpy(cctx->blockState.matchState.hashTable, + ZSTD_memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, hSize * sizeof(U32)); - memcpy(cctx->blockState.matchState.chainTable, + ZSTD_memcpy(cctx->blockState.matchState.chainTable, cdict->matchState.chainTable, chainSize * sizeof(U32)); } @@ -1715,7 +1901,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, { int const h3log = cctx->blockState.matchState.hashLog3; size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; assert(cdict->matchState.hashLog3 == 0); - memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); + ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); } ZSTD_cwksp_mark_tables_clean(&cctx->workspace); @@ -1731,7 +1917,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, cctx->dictID = cdict->dictID; /* copy block state */ - memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); return 0; } @@ -1775,7 +1961,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong, "Can't copy a ctx that's not in init stage."); - memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); + ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); { ZSTD_CCtx_params params = dstCCtx->requestedParams; /* Copy only compression parameters related to tables. */ params.cParams = srcCCtx->appliedParams.cParams; @@ -1797,13 +1983,13 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, int const h3log = srcCCtx->blockState.matchState.hashLog3; size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; - memcpy(dstCCtx->blockState.matchState.hashTable, + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, hSize * sizeof(U32)); - memcpy(dstCCtx->blockState.matchState.chainTable, + ZSTD_memcpy(dstCCtx->blockState.matchState.chainTable, srcCCtx->blockState.matchState.chainTable, chainSize * sizeof(U32)); - memcpy(dstCCtx->blockState.matchState.hashTable3, + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable3, srcCCtx->blockState.matchState.hashTable3, h3Size * sizeof(U32)); } @@ -1821,7 +2007,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, dstCCtx->dictID = srcCCtx->dictID; /* copy block state */ - memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock)); + ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock)); return 0; } @@ -1834,7 +2020,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize) { ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; - ZSTD_buffered_policy_e const zbuff = (ZSTD_buffered_policy_e)(srcCCtx->inBuffSize>0); + ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy; ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1); if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN); @@ -1861,7 +2047,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */ assert(size < (1U<<31)); /* can be casted to int */ -#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) /* To validate that the table re-use logic is sound, and that we don't * access table space that we haven't cleaned, we re-"poison" the table * space every time we mark it dirty. @@ -1958,10 +2144,10 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) return (cctxParams->targetCBlockSize != 0); } -/* ZSTD_compressSequences_internal(): +/* ZSTD_entropyCompressSequences_internal(): * actually compresses both literals and sequences */ MEM_STATIC size_t -ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, +ZSTD_entropyCompressSequences_internal(seqStore_t* seqStorePtr, const ZSTD_entropyCTables_t* prevEntropy, ZSTD_entropyCTables_t* nextEntropy, const ZSTD_CCtx_params* cctxParams, @@ -1971,7 +2157,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, { const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; ZSTD_strategy const strategy = cctxParams->cParams.strategy; - unsigned count[MaxSeq+1]; + unsigned* count = (unsigned*)entropyWorkspace; FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable; FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; @@ -1987,8 +2173,12 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, BYTE* seqHead; BYTE* lastNCount = NULL; - DEBUGLOG(5, "ZSTD_compressSequences_internal (nbSeq=%zu)", nbSeq); + entropyWorkspace = count + (MaxSeq + 1); + entropyWkspSize -= (MaxSeq + 1) * sizeof(*count); + + DEBUGLOG(4, "ZSTD_entropyCompressSequences_internal (nbSeq=%zu)", nbSeq); ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); + assert(entropyWkspSize >= HUF_WORKSPACE_SIZE); /* Compress literals */ { const BYTE* const literals = seqStorePtr->litStart; @@ -2023,7 +2213,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, assert(op <= oend); if (nbSeq==0) { /* Copy the old tables over as if we repeated them */ - memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); + ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); return (size_t)(op - ostart); } @@ -2148,7 +2338,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, } MEM_STATIC size_t -ZSTD_compressSequences(seqStore_t* seqStorePtr, +ZSTD_entropyCompressSequences(seqStore_t* seqStorePtr, const ZSTD_entropyCTables_t* prevEntropy, ZSTD_entropyCTables_t* nextEntropy, const ZSTD_CCtx_params* cctxParams, @@ -2157,7 +2347,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr, void* entropyWorkspace, size_t entropyWkspSize, int bmi2) { - size_t const cSize = ZSTD_compressSequences_internal( + size_t const cSize = ZSTD_entropyCompressSequences_internal( seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity, entropyWorkspace, entropyWkspSize, bmi2); @@ -2167,13 +2357,13 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr, */ if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity)) return 0; /* block not compressed */ - FORWARD_IF_ERROR(cSize, "ZSTD_compressSequences_internal failed"); + FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSequences_internal failed"); /* Check compressibility */ { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy); if (cSize >= maxCSize) return 0; /* block not compressed */ } - + DEBUGLOG(4, "ZSTD_entropyCompressSequences() cSize: %zu\n", cSize); return cSize; } @@ -2182,7 +2372,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr, * assumption : strat is a valid strategy */ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode) { - static const ZSTD_blockCompressor blockCompressor[3][ZSTD_STRATEGY_MAX+1] = { + static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { { ZSTD_compressBlock_fast /* default for 0 */, ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, @@ -2212,7 +2402,17 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo ZSTD_compressBlock_btlazy2_dictMatchState, ZSTD_compressBlock_btopt_dictMatchState, ZSTD_compressBlock_btultra_dictMatchState, - ZSTD_compressBlock_btultra_dictMatchState } + ZSTD_compressBlock_btultra_dictMatchState }, + { NULL /* default for 0 */, + NULL, + NULL, + ZSTD_compressBlock_greedy_dedicatedDictSearch, + ZSTD_compressBlock_lazy_dedicatedDictSearch, + ZSTD_compressBlock_lazy2_dedicatedDictSearch, + NULL, + NULL, + NULL, + NULL } }; ZSTD_blockCompressor selectedCompressor; ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); @@ -2226,7 +2426,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr, const BYTE* anchor, size_t lastLLSize) { - memcpy(seqStorePtr->lit, anchor, lastLLSize); + ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } @@ -2247,7 +2447,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) /* Assert that we have correctly flushed the ctx params into the ms's copy */ ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams); if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) { - ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch); + if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) { + ZSTD_ldm_skipRawSeqStoreBytes(&zc->externSeqStore, srcSize); + } else { + ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch); + } return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */ } ZSTD_resetSeqStore(&(zc->seqStore)); @@ -2263,10 +2467,10 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) /* limited update after a very long match */ { const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; - const U32 current = (U32)(istart-base); + const U32 curr = (U32)(istart-base); if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */ - if (current > ms->nextToUpdate + 384) - ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384)); + if (curr > ms->nextToUpdate + 384) + ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384)); } /* select and store sequences */ @@ -2286,7 +2490,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) src, srcSize); assert(zc->externSeqStore.pos <= zc->externSeqStore.size); } else if (zc->appliedParams.ldmParams.enableLdm) { - rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0}; + rawSeqStore_t ldmSeqStore = kNullRawSeqStore; ldmSeqStore.seq = zc->ldmSequences; ldmSeqStore.capacity = zc->maxNbLdmSequences; @@ -2303,6 +2507,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) assert(ldmSeqStore.pos == ldmSeqStore.size); } else { /* not long range mode */ ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode); + ms->ldmSeqStore = NULL; lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); } { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize; @@ -2314,17 +2519,25 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc) { const seqStore_t* seqStore = ZSTD_getSeqStore(zc); - const seqDef* seqs = seqStore->sequencesStart; - size_t seqsSize = seqStore->sequences - seqs; + const seqDef* seqStoreSeqs = seqStore->sequencesStart; + size_t seqStoreSeqSize = seqStore->sequences - seqStoreSeqs; + size_t seqStoreLiteralsSize = (size_t)(seqStore->lit - seqStore->litStart); + size_t literalsRead = 0; + size_t lastLLSize; ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex]; - size_t i; size_t position; int repIdx; + size_t i; + repcodes_t updatedRepcodes; assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences); - for (i = 0, position = 0; i < seqsSize; ++i) { - outSeqs[i].offset = seqs[i].offset; - outSeqs[i].litLength = seqs[i].litLength; - outSeqs[i].matchLength = seqs[i].matchLength + MINMATCH; + /* Ensure we have enough space for last literals "sequence" */ + assert(zc->seqCollector.maxSequences >= seqStoreSeqSize + 1); + ZSTD_memcpy(updatedRepcodes.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); + for (i = 0; i < seqStoreSeqSize; ++i) { + U32 rawOffset = seqStoreSeqs[i].offset - ZSTD_REP_NUM; + outSeqs[i].litLength = seqStoreSeqs[i].litLength; + outSeqs[i].matchLength = seqStoreSeqs[i].matchLength + MINMATCH; + outSeqs[i].rep = 0; if (i == seqStore->longLengthPos) { if (seqStore->longLengthID == 1) { @@ -2334,39 +2547,44 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc) } } - if (outSeqs[i].offset <= ZSTD_REP_NUM) { - outSeqs[i].rep = outSeqs[i].offset; - repIdx = (unsigned int)i - outSeqs[i].offset; - - if (outSeqs[i].litLength == 0) { - if (outSeqs[i].offset < 3) { - --repIdx; + if (seqStoreSeqs[i].offset <= ZSTD_REP_NUM) { + /* Derive the correct offset corresponding to a repcode */ + outSeqs[i].rep = seqStoreSeqs[i].offset; + if (outSeqs[i].litLength != 0) { + rawOffset = updatedRepcodes.rep[outSeqs[i].rep - 1]; + } else { + if (outSeqs[i].rep == 3) { + rawOffset = updatedRepcodes.rep[0] - 1; } else { - repIdx = (unsigned int)i - 1; + rawOffset = updatedRepcodes.rep[outSeqs[i].rep]; } - ++outSeqs[i].rep; - } - assert(repIdx >= -3); - outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1]; - if (outSeqs[i].rep == 4) { - --outSeqs[i].offset; } - } else { - outSeqs[i].offset -= ZSTD_REP_NUM; } - - position += outSeqs[i].litLength; - outSeqs[i].matchPos = (unsigned int)position; - position += outSeqs[i].matchLength; + outSeqs[i].offset = rawOffset; + /* seqStoreSeqs[i].offset == offCode+1, and ZSTD_updateRep() expects offCode + so we provide seqStoreSeqs[i].offset - 1 */ + updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, + seqStoreSeqs[i].offset - 1, + seqStoreSeqs[i].litLength == 0); + literalsRead += outSeqs[i].litLength; } - zc->seqCollector.seqIndex += seqsSize; + /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0. + * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker + * for the block boundary, according to the API. + */ + assert(seqStoreLiteralsSize >= literalsRead); + lastLLSize = seqStoreLiteralsSize - literalsRead; + outSeqs[i].litLength = (U32)lastLLSize; + outSeqs[i].matchLength = outSeqs[i].offset = outSeqs[i].rep = 0; + seqStoreSeqSize++; + zc->seqCollector.seqIndex += seqStoreSeqSize; } -size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, - size_t outSeqsSize, const void* src, size_t srcSize) +size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, + size_t outSeqsSize, const void* src, size_t srcSize) { const size_t dstCapacity = ZSTD_compressBound(srcSize); - void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem); + void* dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem); SeqCollector seqCollector; RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!"); @@ -2378,16 +2596,47 @@ size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, zc->seqCollector = seqCollector; ZSTD_compress2(zc, dst, dstCapacity, src, srcSize); - ZSTD_free(dst, ZSTD_defaultCMem); + ZSTD_customFree(dst, ZSTD_defaultCMem); return zc->seqCollector.seqIndex; } -/* Returns true if the given block is a RLE block */ -static int ZSTD_isRLE(const BYTE *ip, size_t length) { +size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) { + size_t in = 0; + size_t out = 0; + for (; in < seqsSize; ++in) { + if (sequences[in].offset == 0 && sequences[in].matchLength == 0) { + if (in != seqsSize - 1) { + sequences[in+1].litLength += sequences[in].litLength; + } + } else { + sequences[out] = sequences[in]; + ++out; + } + } + return out; +} + +/* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */ +static int ZSTD_isRLE(const BYTE* src, size_t length) { + const BYTE* ip = src; + const BYTE value = ip[0]; + const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL); + const size_t unrollSize = sizeof(size_t) * 4; + const size_t unrollMask = unrollSize - 1; + const size_t prefixLength = length & unrollMask; size_t i; - if (length < 2) return 1; - for (i = 1; i < length; ++i) { - if (ip[0] != ip[i]) return 0; + size_t u; + if (length == 1) return 1; + /* Check if prefix is RLE first before using unrolled loop */ + if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) { + return 0; + } + for (i = prefixLength; i != length; i += unrollSize) { + for (u = 0; u < unrollSize; u += sizeof(size_t)) { + if (MEM_readST(ip + i + u) != valueST) { + return 0; + } + } } return 1; } @@ -2434,18 +2683,25 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, if (zc->seqCollector.collectSequences) { ZSTD_copyBlockSequences(zc); + ZSTD_confirmRepcodesAndEntropyTables(zc); return 0; } /* encode sequences and literals */ - cSize = ZSTD_compressSequences(&zc->seqStore, + cSize = ZSTD_entropyCompressSequences(&zc->seqStore, &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, &zc->appliedParams, dst, dstCapacity, srcSize, - zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */, + zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */, zc->bmi2); + if (zc->seqCollector.collectSequences) { + ZSTD_copyBlockSequences(zc); + return 0; + } + + if (frame && /* We don't want to emit our first block as a RLE even if it qualifies because * doing so will cause the decoder (cli only) to throw a "should consume all input error." @@ -2593,7 +2849,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx, assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX); - DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize); + DEBUGLOG(4, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize); if (cctx->appliedParams.fParams.checksumFlag && srcSize) XXH64_update(&cctx->xxhState, src, srcSize); @@ -2673,7 +2929,6 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, "dst buf is too small to fit worst-case frame header size."); DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode); - if (params->format == ZSTD_f_zstd1) { MEM_writeLE32(dst, ZSTD_MAGICNUMBER); pos = 4; @@ -2725,6 +2980,7 @@ size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSe cctx->externSeqStore.size = nbSeq; cctx->externSeqStore.capacity = nbSeq; cctx->externSeqStore.pos = 0; + cctx->externSeqStore.posInSequence = 0; return 0; } @@ -2862,8 +3118,12 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, case ZSTD_greedy: case ZSTD_lazy: case ZSTD_lazy2: - if (chunk >= HASH_READ_SIZE) + if (chunk >= HASH_READ_SIZE && ms->dedicatedDictSearch) { + assert(chunk == remaining); /* must load everything in one go */ + ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, ichunk-HASH_READ_SIZE); + } else if (chunk >= HASH_READ_SIZE) { ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE); + } break; case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ @@ -2887,22 +3147,28 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, /* Dictionaries that assign zero probability to symbols that show up causes problems - when FSE encoding. Refuse dictionaries that assign zero probability to symbols - that we may encounter during compression. - NOTE: This behavior is not standard and could be improved in the future. */ -static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) { + * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check + * and only dictionaries with 100% valid symbols can be assumed valid. + */ +static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) +{ U32 s; - RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted, "dict fse tables don't have all symbols"); + if (dictMaxSymbolValue < maxSymbolValue) { + return FSE_repeat_check; + } for (s = 0; s <= maxSymbolValue; ++s) { - RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted, "dict fse tables don't have all symbols"); + if (normalizedCounter[s] == 0) { + return FSE_repeat_check; + } } - return 0; + return FSE_repeat_valid; } size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, - short* offcodeNCount, unsigned* offcodeMaxValue, const void* const dict, size_t dictSize) { + short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff; const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */ const BYTE* const dictEnd = dictPtr + dictSize; dictPtr += 8; @@ -2924,16 +3190,16 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, } { unsigned offcodeLog; - size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); - /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ /* fill all offset symbols to avoid garbage at end of table */ RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( bs->entropy.fse.offcodeCTable, offcodeNCount, MaxOff, offcodeLog, workspace, HUF_WORKSPACE_SIZE)), dictionary_corrupted, ""); + /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ dictPtr += offcodeHeaderSize; } @@ -2942,13 +3208,12 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); - /* Every match length code must have non-zero probability */ - FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML), ""); RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( bs->entropy.fse.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE)), dictionary_corrupted, ""); + bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML); dictPtr += matchlengthHeaderSize; } @@ -2957,13 +3222,12 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); - /* Every literal length code must have non-zero probability */ - FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL), ""); RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( bs->entropy.fse.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE)), dictionary_corrupted, ""); + bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL); dictPtr += litlengthHeaderSize; } @@ -2973,12 +3237,28 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, bs->rep[2] = MEM_readLE32(dictPtr+8); dictPtr += 12; + { size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + U32 offcodeMax = MaxOff; + if (dictContentSize <= ((U32)-1) - 128 KB) { + U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */ + offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */ + } + /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */ + bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)); + + /* All repCodes must be <= dictContentSize and != 0 */ + { U32 u; + for (u=0; u<3; u++) { + RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, ""); + RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, ""); + } } } + return dictPtr - (const BYTE*)dict; } /* Dictionary format : * See : - * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format */ /*! ZSTD_loadZstdDictionary() : * @return : dictID, or an error code @@ -2995,8 +3275,6 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, { const BYTE* dictPtr = (const BYTE*)dict; const BYTE* const dictEnd = dictPtr + dictSize; - short offcodeNCount[MaxOff+1]; - unsigned offcodeMaxValue = MaxOff; size_t dictID; size_t eSize; @@ -3005,32 +3283,16 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY); dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ ); - eSize = ZSTD_loadCEntropy(bs, workspace, offcodeNCount, &offcodeMaxValue, dict, dictSize); + eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize); FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed"); dictPtr += eSize; - { size_t const dictContentSize = (size_t)(dictEnd - dictPtr); - U32 offcodeMax = MaxOff; - if (dictContentSize <= ((U32)-1) - 128 KB) { - U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */ - offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */ - } - /* All offset values <= dictContentSize + 128 KB must be representable */ - FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)), ""); - /* All repCodes must be <= dictContentSize and != 0*/ - { U32 u; - for (u=0; u<3; u++) { - RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, ""); - RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, ""); - } } - - bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid; - bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid; - bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid; + { + size_t const dictContentSize = (size_t)(dictEnd - dictPtr); FORWARD_IF_ERROR(ZSTD_loadDictionaryContent( ms, NULL, ws, params, dictPtr, dictContentSize, dtlm), ""); - return dictID; } + return dictID; } /** ZSTD_compress_insertDictionary() : @@ -3074,7 +3336,7 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, } #define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB) -#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6) +#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL) /*! ZSTD_compressBegin_internal() : * @return : 0, or an error code */ @@ -3106,7 +3368,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, ZSTD_compress_insertDictionary( cctx->blockState.prevCBlock, &cctx->blockState.matchState, &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent, - cdict->dictContentSize, dictContentType, dtlm, + cdict->dictContentSize, cdict->dictContentType, dtlm, cctx->entropyWorkspace) : ZSTD_compress_insertDictionary( cctx->blockState.prevCBlock, &cctx->blockState.matchState, @@ -3153,7 +3415,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) { - ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); + ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict); ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms); DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize); @@ -3234,7 +3496,6 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, return cSize + endResult; } - static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, @@ -3287,7 +3548,7 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) { - ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0); + ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict); ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms); DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize); assert(params.fParams.contentSizeFlag == 1); @@ -3309,10 +3570,17 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, int compressionLevel) { size_t result; +#if ZSTD_COMPRESS_HEAPMODE + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed"); + result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtx(cctx); +#else ZSTD_CCtx ctxBody; ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem); result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */ +#endif return result; } @@ -3335,7 +3603,7 @@ size_t ZSTD_estimateCDictSize_advanced( size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel) { - ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy); } @@ -3353,20 +3621,25 @@ static size_t ZSTD_initCDict_internal( const void* dictBuffer, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, - ZSTD_compressionParameters cParams) + ZSTD_CCtx_params params) { DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType); - assert(!ZSTD_checkCParams(cParams)); - cdict->matchState.cParams = cParams; + assert(!ZSTD_checkCParams(params.cParams)); + cdict->matchState.cParams = params.cParams; + cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch; + if (cdict->matchState.dedicatedDictSearch && dictSize > ZSTD_CHUNKSIZE_MAX) { + cdict->matchState.dedicatedDictSearch = 0; + } if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { cdict->dictContent = dictBuffer; } else { void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*))); RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!"); cdict->dictContent = internalBuffer; - memcpy(internalBuffer, dictBuffer, dictSize); + ZSTD_memcpy(internalBuffer, dictBuffer, dictSize); } cdict->dictContentSize = dictSize; + cdict->dictContentType = dictContentType; cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE); @@ -3376,18 +3649,15 @@ static size_t ZSTD_initCDict_internal( FORWARD_IF_ERROR(ZSTD_reset_matchState( &cdict->matchState, &cdict->workspace, - &cParams, + ¶ms.cParams, ZSTDcrp_makeClean, ZSTDirp_reset, ZSTD_resetTarget_CDict), ""); /* (Maybe) load the dictionary * Skips loading the dictionary if it is < 8 bytes. */ - { ZSTD_CCtx_params params; - memset(¶ms, 0, sizeof(params)); - params.compressionLevel = ZSTD_CLEVEL_DEFAULT; + { params.compressionLevel = ZSTD_CLEVEL_DEFAULT; params.fParams.contentSizeFlag = 1; - params.cParams = cParams; { size_t const dictID = ZSTD_compress_insertDictionary( &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace, ¶ms, cdict->dictContent, cdict->dictContentSize, @@ -3401,13 +3671,11 @@ static size_t ZSTD_initCDict_internal( return 0; } -ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, +static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType, ZSTD_compressionParameters cParams, ZSTD_customMem customMem) { - DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (unsigned)dictContentType); - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; { size_t const workspaceSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + @@ -3415,16 +3683,16 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))); - void* const workspace = ZSTD_malloc(workspaceSize, customMem); + void* const workspace = ZSTD_customMalloc(workspaceSize, customMem); ZSTD_cwksp ws; ZSTD_CDict* cdict; if (!workspace) { - ZSTD_free(workspace, customMem); + ZSTD_customFree(workspace, customMem); return NULL; } - ZSTD_cwksp_init(&ws, workspace, workspaceSize); + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc); cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); assert(cdict != NULL); @@ -3432,35 +3700,94 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, cdict->customMem = customMem; cdict->compressionLevel = 0; /* signals advanced API usage */ - if (ZSTD_isError( ZSTD_initCDict_internal(cdict, - dictBuffer, dictSize, - dictLoadMethod, dictContentType, - cParams) )) { - ZSTD_freeCDict(cdict); - return NULL; - } - return cdict; } } +ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_memset(&cctxParams, 0, sizeof(cctxParams)); + ZSTD_CCtxParams_init(&cctxParams, 0); + cctxParams.cParams = cParams; + cctxParams.customMem = customMem; + return ZSTD_createCDict_advanced2( + dictBuffer, dictSize, + dictLoadMethod, dictContentType, + &cctxParams, customMem); +} + +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* originalCctxParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams = *originalCctxParams; + ZSTD_compressionParameters cParams; + ZSTD_CDict* cdict; + + DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode %u", (unsigned)dictContentType); + if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + + if (cctxParams.enableDedicatedDictSearch) { + cParams = ZSTD_dedicatedDictSearch_getCParams( + cctxParams.compressionLevel, dictSize); + ZSTD_overrideCParams(&cParams, &cctxParams.cParams); + } else { + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) { + /* Fall back to non-DDSS params */ + cctxParams.enableDedicatedDictSearch = 0; + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + cctxParams.cParams = cParams; + + cdict = ZSTD_createCDict_advanced_internal(dictSize, + dictLoadMethod, cctxParams.cParams, + customMem); + + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + cctxParams) )) { + ZSTD_freeCDict(cdict); + return NULL; + } + + return cdict; +} + ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel) { - ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); - ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, cParams, ZSTD_defaultCMem); if (cdict) - cdict->compressionLevel = compressionLevel == 0 ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; return cdict; } ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel) { - ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); - return ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; } size_t ZSTD_freeCDict(ZSTD_CDict* cdict) @@ -3470,7 +3797,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict) int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict); ZSTD_cwksp_free(&cdict->workspace, cMem); if (!cdictInWorkspace) { - ZSTD_free(cdict, cMem); + ZSTD_customFree(cdict, cMem); } return 0; } @@ -3503,12 +3830,13 @@ const ZSTD_CDict* ZSTD_initStaticCDict( + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + matchStateSize; ZSTD_CDict* cdict; + ZSTD_CCtx_params params; if ((size_t)workspace & 7) return NULL; /* 8-aligned */ { ZSTD_cwksp ws; - ZSTD_cwksp_init(&ws, workspace, workspaceSize); + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); if (cdict == NULL) return NULL; ZSTD_cwksp_move(&cdict->workspace, &ws); @@ -3518,10 +3846,13 @@ const ZSTD_CDict* ZSTD_initStaticCDict( (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize)); if (workspaceSize < neededSize) return NULL; + ZSTD_CCtxParams_init(¶ms, 0); + params.cParams = cParams; + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, dict, dictSize, dictLoadMethod, dictContentType, - cParams) )) + params) )) return NULL; return cdict; @@ -3533,6 +3864,17 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) return cdict->matchState.cParams; } +/*! ZSTD_getDictID_fromCDict() : + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; + return cdict->dictID; +} + + /* ZSTD_compressBegin_usingCDict_advanced() : * cdict must be != NULL */ size_t ZSTD_compressBegin_usingCDict_advanced( @@ -3640,32 +3982,12 @@ size_t ZSTD_CStreamOutSize(void) return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; } -static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx, - const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType, - const ZSTD_CDict* const cdict, - ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize) +static ZSTD_cParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize) { - DEBUGLOG(4, "ZSTD_resetCStream_internal"); - /* Finalize the compression parameters */ - params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, dictSize); - /* params are supposed to be fully validated at this point */ - assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); - assert(!((dict) && (cdict))); /* either dict or cdict, not both */ - - FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, - dict, dictSize, dictContentType, ZSTD_dtlm_fast, - cdict, - ¶ms, pledgedSrcSize, - ZSTDb_buffered) , ""); - - cctx->inToCompress = 0; - cctx->inBuffPos = 0; - cctx->inBuffTarget = cctx->blockSize - + (cctx->blockSize == pledgedSrcSize); /* for small input: avoid automatic flush on reaching end of block, since it would require to add a 3-bytes null block to end frame */ - cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0; - cctx->streamStage = zcss_load; - cctx->frameEnded = 0; - return 0; /* ready to go */ + if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) + return ZSTD_cpm_attachDict; + else + return ZSTD_cpm_noAttachDict; } /* ZSTD_resetCStream(): @@ -3815,12 +4137,17 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, /* check expectations */ DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (unsigned)flushMode); - assert(zcs->inBuff != NULL); - assert(zcs->inBuffSize > 0); - assert(zcs->outBuff != NULL); - assert(zcs->outBuffSize > 0); + if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) { + assert(zcs->inBuff != NULL); + assert(zcs->inBuffSize > 0); + } + if (zcs->appliedParams.outBufferMode == ZSTD_bm_buffered) { + assert(zcs->outBuff != NULL); + assert(zcs->outBuffSize > 0); + } assert(output->pos <= output->size); assert(input->pos <= input->size); + assert((U32)flushMode <= (U32)ZSTD_e_end); while (someMoreWork) { switch(zcs->streamStage) @@ -3830,7 +4157,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, case zcss_load: if ( (flushMode == ZSTD_e_end) - && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip)) /* enough dstCapacity */ + && ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip) /* Enough output space */ + || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */ && (zcs->inBuffPos == 0) ) { /* shortcut to compression pass directly into output buffer */ size_t const cSize = ZSTD_compressEnd(zcs, @@ -3843,8 +4171,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); someMoreWork = 0; break; } - /* complete loading into inBuffer */ - { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; + /* complete loading into inBuffer in buffered mode */ + if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) { + size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; size_t const loaded = ZSTD_limitCopy( zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip); @@ -3864,31 +4193,49 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, } /* compress current block (note : this stage cannot be stopped in the middle) */ DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode); - { void* cDst; + { int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered); + void* cDst; size_t cSize; - size_t const iSize = zcs->inBuffPos - zcs->inToCompress; size_t oSize = oend-op; - unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend); - if (oSize >= ZSTD_compressBound(iSize)) + size_t const iSize = inputBuffered + ? zcs->inBuffPos - zcs->inToCompress + : MIN((size_t)(iend - ip), zcs->blockSize); + if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) cDst = op; /* compress into output buffer, to skip flush stage */ else cDst = zcs->outBuff, oSize = zcs->outBuffSize; - cSize = lastBlock ? - ZSTD_compressEnd(zcs, cDst, oSize, - zcs->inBuff + zcs->inToCompress, iSize) : - ZSTD_compressContinue(zcs, cDst, oSize, - zcs->inBuff + zcs->inToCompress, iSize); - FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); - zcs->frameEnded = lastBlock; - /* prepare next block */ - zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize; - if (zcs->inBuffTarget > zcs->inBuffSize) - zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; - DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u", - (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize); - if (!lastBlock) - assert(zcs->inBuffTarget <= zcs->inBuffSize); - zcs->inToCompress = zcs->inBuffPos; + if (inputBuffered) { + unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend); + cSize = lastBlock ? + ZSTD_compressEnd(zcs, cDst, oSize, + zcs->inBuff + zcs->inToCompress, iSize) : + ZSTD_compressContinue(zcs, cDst, oSize, + zcs->inBuff + zcs->inToCompress, iSize); + FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); + zcs->frameEnded = lastBlock; + /* prepare next block */ + zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize; + if (zcs->inBuffTarget > zcs->inBuffSize) + zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; + DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u", + (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize); + if (!lastBlock) + assert(zcs->inBuffTarget <= zcs->inBuffSize); + zcs->inToCompress = zcs->inBuffPos; + } else { + unsigned const lastBlock = (ip + iSize == iend); + assert(flushMode == ZSTD_e_end /* Already validated */); + cSize = lastBlock ? + ZSTD_compressEnd(zcs, cDst, oSize, ip, iSize) : + ZSTD_compressContinue(zcs, cDst, oSize, ip, iSize); + /* Consume the input prior to error checking to mirror buffered mode. */ + if (iSize > 0) + ip += iSize; + FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); + zcs->frameEnded = lastBlock; + if (lastBlock) + assert(ip == iend); + } if (cDst == op) { /* no need to flush */ op += cSize; if (zcs->frameEnded) { @@ -3905,6 +4252,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, /* fall-through */ case zcss_flush: DEBUGLOG(5, "flush stage"); + assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered); { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op), zcs->outBuff + zcs->outBuffFlushedSize, toFlush); @@ -3959,6 +4307,116 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf return ZSTD_nextInputSizeHint_MTorST(zcs); } +/* After a compression call set the expected input/output buffer. + * This is validated at the start of the next compression call. + */ +static void ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, ZSTD_outBuffer const* output, ZSTD_inBuffer const* input) +{ + if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) { + cctx->expectedInBuffer = *input; + } + if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) { + cctx->expectedOutBufferSize = output->size - output->pos; + } +} + +/* Validate that the input/output buffers match the expectations set by + * ZSTD_setBufferExpectations. + */ +static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx, + ZSTD_outBuffer const* output, + ZSTD_inBuffer const* input, + ZSTD_EndDirective endOp) +{ + if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) { + ZSTD_inBuffer const expect = cctx->expectedInBuffer; + if (expect.src != input->src || expect.pos != input->pos || expect.size != input->size) + RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer enabled but input differs!"); + if (endOp != ZSTD_e_end) + RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer can only be used with ZSTD_e_end!"); + } + if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) { + size_t const outBufferSize = output->size - output->pos; + if (cctx->expectedOutBufferSize != outBufferSize) + RETURN_ERROR(dstBuffer_wrong, "ZSTD_c_stableOutBuffer enabled but output size differs!"); + } + return 0; +} + +static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, + ZSTD_EndDirective endOp, + size_t inSize) { + ZSTD_CCtx_params params = cctx->requestedParams; + ZSTD_prefixDict const prefixDict = cctx->prefixDict; + FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */ + ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */ + assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */ + if (cctx->cdict) + params.compressionLevel = cctx->cdict->compressionLevel; /* let cdict take priority in terms of compression level */ + DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage"); + if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-fix pledgedSrcSize */ + { + size_t const dictSize = prefixDict.dict + ? prefixDict.dictSize + : (cctx->cdict ? cctx->cdict->dictContentSize : 0); + ZSTD_cParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, ¶ms, cctx->pledgedSrcSizePlusOne - 1); + params.cParams = ZSTD_getCParamsFromCCtxParams( + ¶ms, cctx->pledgedSrcSizePlusOne-1, + dictSize, mode); + } + + if (ZSTD_CParams_shouldEnableLdm(¶ms.cParams)) { + /* Enable LDM by default for optimal parser and window size >= 128MB */ + DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)"); + params.ldmParams.enableLdm = 1; + } + +#ifdef ZSTD_MULTITHREAD + if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { + params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */ + } + if (params.nbWorkers > 0) { + /* mt context creation */ + if (cctx->mtctx == NULL) { + DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u", + params.nbWorkers); + cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem, cctx->pool); + RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!"); + } + /* mt compression */ + DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers); + FORWARD_IF_ERROR( ZSTDMT_initCStream_internal( + cctx->mtctx, + prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, + cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , ""); + cctx->streamStage = zcss_load; + cctx->appliedParams = params; + } else +#endif + { U64 const pledgedSrcSize = cctx->pledgedSrcSizePlusOne - 1; + assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); + FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, + prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, ZSTD_dtlm_fast, + cctx->cdict, + ¶ms, pledgedSrcSize, + ZSTDb_buffered) , ""); + assert(cctx->appliedParams.nbWorkers == 0); + cctx->inToCompress = 0; + cctx->inBuffPos = 0; + if (cctx->appliedParams.inBufferMode == ZSTD_bm_buffered) { + /* for small input: avoid automatic flush on reaching end of block, since + * it would require to add a 3-bytes null block to end frame + */ + cctx->inBuffTarget = cctx->blockSize + (cctx->blockSize == pledgedSrcSize); + } else { + cctx->inBuffTarget = 0; + } + cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0; + cctx->streamStage = zcss_load; + cctx->frameEnded = 0; + } + return 0; +} size_t ZSTD_compressStream2( ZSTD_CCtx* cctx, ZSTD_outBuffer* output, @@ -3967,82 +4425,65 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx, { DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp); /* check conditions */ - RETURN_ERROR_IF(output->pos > output->size, GENERIC, "invalid buffer"); - RETURN_ERROR_IF(input->pos > input->size, GENERIC, "invalid buffer"); - assert(cctx!=NULL); + RETURN_ERROR_IF(output->pos > output->size, dstSize_tooSmall, "invalid output buffer"); + RETURN_ERROR_IF(input->pos > input->size, srcSize_wrong, "invalid input buffer"); + RETURN_ERROR_IF((U32)endOp > (U32)ZSTD_e_end, parameter_outOfBound, "invalid endDirective"); + assert(cctx != NULL); /* transparent initialization stage */ if (cctx->streamStage == zcss_init) { - ZSTD_CCtx_params params = cctx->requestedParams; - ZSTD_prefixDict const prefixDict = cctx->prefixDict; - FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */ - memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */ - assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */ - DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage"); - if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1; /* auto-fix pledgedSrcSize */ - params.cParams = ZSTD_getCParamsFromCCtxParams( - &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/); - - -#ifdef ZSTD_MULTITHREAD - if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { - params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */ - } - if (params.nbWorkers > 0) { - /* mt context creation */ - if (cctx->mtctx == NULL) { - DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u", - params.nbWorkers); - cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem); - RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!"); - } - /* mt compression */ - DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers); - FORWARD_IF_ERROR( ZSTDMT_initCStream_internal( - cctx->mtctx, - prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, - cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , ""); - cctx->streamStage = zcss_load; - cctx->appliedParams.nbWorkers = params.nbWorkers; - } else -#endif - { FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx, - prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, - cctx->cdict, - params, cctx->pledgedSrcSizePlusOne-1) , ""); - assert(cctx->streamStage == zcss_load); - assert(cctx->appliedParams.nbWorkers == 0); - } } + FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, endOp, input->size), "CompressStream2 initialization failed"); + ZSTD_setBufferExpectations(cctx, output, input); /* Set initial buffer expectations now that we've initialized */ + } /* end of transparent initialization stage */ + FORWARD_IF_ERROR(ZSTD_checkBufferStability(cctx, output, input, endOp), "invalid buffers"); /* compression stage */ #ifdef ZSTD_MULTITHREAD if (cctx->appliedParams.nbWorkers > 0) { - int const forceMaxProgress = (endOp == ZSTD_e_flush || endOp == ZSTD_e_end); size_t flushMin; - assert(forceMaxProgress || endOp == ZSTD_e_continue /* Protection for a new flush type */); if (cctx->cParamsChanged) { ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams); cctx->cParamsChanged = 0; } - do { + for (;;) { + size_t const ipos = input->pos; + size_t const opos = output->pos; flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); if ( ZSTD_isError(flushMin) || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only); } FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed"); - } while (forceMaxProgress && flushMin != 0 && output->pos < output->size); + + if (endOp == ZSTD_e_continue) { + /* We only require some progress with ZSTD_e_continue, not maximal progress. + * We're done if we've consumed or produced any bytes, or either buffer is + * full. + */ + if (input->pos != ipos || output->pos != opos || input->pos == input->size || output->pos == output->size) + break; + } else { + assert(endOp == ZSTD_e_flush || endOp == ZSTD_e_end); + /* We require maximal progress. We're done when the flush is complete or the + * output buffer is full. + */ + if (flushMin == 0 || output->pos == output->size) + break; + } + } DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic"); /* Either we don't require maximum forward progress, we've finished the * flush, or we are out of output space. */ - assert(!forceMaxProgress || flushMin == 0 || output->pos == output->size); + assert(endOp == ZSTD_e_continue || flushMin == 0 || output->pos == output->size); + ZSTD_setBufferExpectations(cctx, output, input); return flushMin; } #endif FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , ""); DEBUGLOG(5, "completed ZSTD_compressStream2"); + ZSTD_setBufferExpectations(cctx, output, input); return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */ } @@ -4065,14 +4506,22 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) { + ZSTD_bufferMode_e const originalInBufferMode = cctx->requestedParams.inBufferMode; + ZSTD_bufferMode_e const originalOutBufferMode = cctx->requestedParams.outBufferMode; DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize); ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only); + /* Enable stable input/output buffers. */ + cctx->requestedParams.inBufferMode = ZSTD_bm_stable; + cctx->requestedParams.outBufferMode = ZSTD_bm_stable; { size_t oPos = 0; size_t iPos = 0; size_t const result = ZSTD_compressStream2_simpleArgs(cctx, dst, dstCapacity, &oPos, src, srcSize, &iPos, ZSTD_e_end); + /* Reset to the original values. */ + cctx->requestedParams.inBufferMode = originalInBufferMode; + cctx->requestedParams.outBufferMode = originalOutBufferMode; FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed"); if (result != 0) { /* compression not completed, due to lack of output space */ assert(oPos == dstCapacity); @@ -4083,6 +4532,409 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx, } } +typedef struct { + U32 idx; /* Index in array of ZSTD_Sequence */ + U32 posInSequence; /* Position within sequence at idx */ + size_t posInSrc; /* Number of bytes given by sequences provided so far */ +} ZSTD_sequencePosition; + +/* Returns a ZSTD error code if sequence is not valid */ +static size_t ZSTD_validateSequence(U32 offCode, U32 matchLength, + size_t posInSrc, U32 windowLog, size_t dictSize, U32 minMatch) { + size_t offsetBound; + U32 windowSize = 1 << windowLog; + /* posInSrc represents the amount of data the the decoder would decode up to this point. + * As long as the amount of data decoded is less than or equal to window size, offsets may be + * larger than the total length of output decoded in order to reference the dict, even larger than + * window size. After output surpasses windowSize, we're limited to windowSize offsets again. + */ + offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize; + RETURN_ERROR_IF(offCode > offsetBound + ZSTD_REP_MOVE, corruption_detected, "Offset too large!"); + RETURN_ERROR_IF(matchLength < minMatch, corruption_detected, "Matchlength too small"); + return 0; +} + +/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */ +static U32 ZSTD_finalizeOffCode(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) { + U32 offCode = rawOffset + ZSTD_REP_MOVE; + U32 repCode = 0; + + if (!ll0 && rawOffset == rep[0]) { + repCode = 1; + } else if (rawOffset == rep[1]) { + repCode = 2 - ll0; + } else if (rawOffset == rep[2]) { + repCode = 3 - ll0; + } else if (ll0 && rawOffset == rep[0] - 1) { + repCode = 3; + } + if (repCode) { + /* ZSTD_storeSeq expects a number in the range [0, 2] to represent a repcode */ + offCode = repCode - 1; + } + return offCode; +} + +/* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of + * ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter. + */ +static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize) { + U32 idx = seqPos->idx; + BYTE const* ip = (BYTE const*)(src); + const BYTE* const iend = ip + blockSize; + repcodes_t updatedRepcodes; + U32 dictSize; + U32 litLength; + U32 matchLength; + U32 ll0; + U32 offCode; + + if (cctx->cdict) { + dictSize = (U32)cctx->cdict->dictContentSize; + } else if (cctx->prefixDict.dict) { + dictSize = (U32)cctx->prefixDict.dictSize; + } else { + dictSize = 0; + } + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t)); + for (; (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0) && idx < inSeqsSize; ++idx) { + litLength = inSeqs[idx].litLength; + matchLength = inSeqs[idx].matchLength; + ll0 = litLength == 0; + offCode = ZSTD_finalizeOffCode(inSeqs[idx].offset, updatedRepcodes.rep, ll0); + updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0); + + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength); + if (cctx->appliedParams.validateSequences) { + seqPos->posInSrc += litLength + matchLength; + FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc, + cctx->appliedParams.cParams.windowLog, dictSize, + cctx->appliedParams.cParams.minMatch), + "Sequence validation failed"); + } + RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH); + ip += matchLength + litLength; + } + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t)); + + if (inSeqs[idx].litLength) { + DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength); + ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength); + ip += inSeqs[idx].litLength; + seqPos->posInSrc += inSeqs[idx].litLength; + } + RETURN_ERROR_IF(ip != iend, corruption_detected, "Blocksize doesn't agree with block delimiter!"); + seqPos->idx = idx+1; + return 0; +} + +/* Returns the number of bytes to move the current read position back by. Only non-zero + * if we ended up splitting a sequence. Otherwise, it may return a ZSTD error if something + * went wrong. + * + * This function will attempt to scan through blockSize bytes represented by the sequences + * in inSeqs, storing any (partial) sequences. + * + * Occasionally, we may want to change the actual number of bytes we consumed from inSeqs to + * avoid splitting a match, or to avoid splitting a match such that it would produce a match + * smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block. + */ +static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize) { + U32 idx = seqPos->idx; + U32 startPosInSequence = seqPos->posInSequence; + U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize; + size_t dictSize; + BYTE const* ip = (BYTE const*)(src); + BYTE const* iend = ip + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */ + repcodes_t updatedRepcodes; + U32 bytesAdjustment = 0; + U32 finalMatchSplit = 0; + U32 litLength; + U32 matchLength; + U32 rawOffset; + U32 offCode; + + if (cctx->cdict) { + dictSize = cctx->cdict->dictContentSize; + } else if (cctx->prefixDict.dict) { + dictSize = cctx->prefixDict.dictSize; + } else { + dictSize = 0; + } + DEBUGLOG(5, "ZSTD_copySequencesToSeqStore: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize); + DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength); + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t)); + while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) { + const ZSTD_Sequence currSeq = inSeqs[idx]; + litLength = currSeq.litLength; + matchLength = currSeq.matchLength; + rawOffset = currSeq.offset; + + /* Modify the sequence depending on where endPosInSequence lies */ + if (endPosInSequence >= currSeq.litLength + currSeq.matchLength) { + if (startPosInSequence >= litLength) { + startPosInSequence -= litLength; + litLength = 0; + matchLength -= startPosInSequence; + } else { + litLength -= startPosInSequence; + } + /* Move to the next sequence */ + endPosInSequence -= currSeq.litLength + currSeq.matchLength; + startPosInSequence = 0; + idx++; + } else { + /* This is the final (partial) sequence we're adding from inSeqs, and endPosInSequence + does not reach the end of the match. So, we have to split the sequence */ + DEBUGLOG(6, "Require a split: diff: %u, idx: %u PIS: %u", + currSeq.litLength + currSeq.matchLength - endPosInSequence, idx, endPosInSequence); + if (endPosInSequence > litLength) { + U32 firstHalfMatchLength; + litLength = startPosInSequence >= litLength ? 0 : litLength - startPosInSequence; + firstHalfMatchLength = endPosInSequence - startPosInSequence - litLength; + if (matchLength > blockSize && firstHalfMatchLength >= cctx->appliedParams.cParams.minMatch) { + /* Only ever split the match if it is larger than the block size */ + U32 secondHalfMatchLength = currSeq.matchLength + currSeq.litLength - endPosInSequence; + if (secondHalfMatchLength < cctx->appliedParams.cParams.minMatch) { + /* Move the endPosInSequence backward so that it creates match of minMatch length */ + endPosInSequence -= cctx->appliedParams.cParams.minMatch - secondHalfMatchLength; + bytesAdjustment = cctx->appliedParams.cParams.minMatch - secondHalfMatchLength; + firstHalfMatchLength -= bytesAdjustment; + } + matchLength = firstHalfMatchLength; + /* Flag that we split the last match - after storing the sequence, exit the loop, + but keep the value of endPosInSequence */ + finalMatchSplit = 1; + } else { + /* Move the position in sequence backwards so that we don't split match, and break to store + * the last literals. We use the original currSeq.litLength as a marker for where endPosInSequence + * should go. We prefer to do this whenever it is not necessary to split the match, or if doing so + * would cause the first half of the match to be too small + */ + bytesAdjustment = endPosInSequence - currSeq.litLength; + endPosInSequence = currSeq.litLength; + break; + } + } else { + /* This sequence ends inside the literals, break to store the last literals */ + break; + } + } + /* Check if this offset can be represented with a repcode */ + { U32 ll0 = (litLength == 0); + offCode = ZSTD_finalizeOffCode(rawOffset, updatedRepcodes.rep, ll0); + updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0); + } + + if (cctx->appliedParams.validateSequences) { + seqPos->posInSrc += litLength + matchLength; + FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc, + cctx->appliedParams.cParams.windowLog, dictSize, + cctx->appliedParams.cParams.minMatch), + "Sequence validation failed"); + } + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength); + RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH); + ip += matchLength + litLength; + } + DEBUGLOG(5, "Ending seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength); + assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength); + seqPos->idx = idx; + seqPos->posInSequence = endPosInSequence; + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t)); + + iend -= bytesAdjustment; + if (ip != iend) { + /* Store any last literals */ + U32 lastLLSize = (U32)(iend - ip); + assert(ip <= iend); + DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize); + ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize); + seqPos->posInSrc += lastLLSize; + } + + return bytesAdjustment; +} + +typedef size_t (*ZSTD_sequenceCopier) (ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize); +static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode) { + ZSTD_sequenceCopier sequenceCopier = NULL; + assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode)); + if (mode == ZSTD_sf_explicitBlockDelimiters) { + return ZSTD_copySequencesToSeqStoreExplicitBlockDelim; + } else if (mode == ZSTD_sf_noBlockDelimiters) { + return ZSTD_copySequencesToSeqStoreNoBlockDelim; + } + assert(sequenceCopier != NULL); + return sequenceCopier; +} + +/* Compress, block-by-block, all of the sequences given. + * + * Returns the cumulative size of all compressed blocks (including their headers), otherwise a ZSTD error. + */ +static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize) { + size_t cSize = 0; + U32 lastBlock; + size_t blockSize; + size_t compressedSeqsSize; + size_t remaining = srcSize; + ZSTD_sequencePosition seqPos = {0, 0, 0}; + + BYTE const* ip = (BYTE const*)src; + BYTE* op = (BYTE*)dst; + ZSTD_sequenceCopier sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters); + + DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize); + /* Special case: empty frame */ + if (remaining == 0) { + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "No room for empty frame block header"); + MEM_writeLE32(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + cSize += ZSTD_blockHeaderSize; + } + + while (remaining) { + size_t cBlockSize; + size_t additionalByteAdjustment; + lastBlock = remaining <= cctx->blockSize; + blockSize = lastBlock ? (U32)remaining : (U32)cctx->blockSize; + ZSTD_resetSeqStore(&cctx->seqStore); + DEBUGLOG(4, "Working on new block. Blocksize: %zu", blockSize); + + additionalByteAdjustment = sequenceCopier(cctx, &seqPos, inSeqs, inSeqsSize, ip, blockSize); + FORWARD_IF_ERROR(additionalByteAdjustment, "Bad sequence copy"); + blockSize -= additionalByteAdjustment; + + /* If blocks are too small, emit as a nocompress block */ + if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) { + cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed"); + DEBUGLOG(4, "Block too small, writing out nocompress block: cSize: %zu", cBlockSize); + cSize += cBlockSize; + ip += blockSize; + op += cBlockSize; + remaining -= blockSize; + dstCapacity -= cBlockSize; + continue; + } + + compressedSeqsSize = ZSTD_entropyCompressSequences(&cctx->seqStore, + &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy, + &cctx->appliedParams, + op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize, + blockSize, + cctx->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */, + cctx->bmi2); + FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed"); + DEBUGLOG(4, "Compressed sequences size: %zu", compressedSeqsSize); + + if (!cctx->isFirstBlock && + ZSTD_maybeRLE(&cctx->seqStore) && + ZSTD_isRLE((BYTE const*)src, srcSize)) { + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + compressedSeqsSize = 1; + } + + if (compressedSeqsSize == 0) { + /* ZSTD_noCompressBlock writes the block header as well */ + cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed"); + DEBUGLOG(4, "Writing out nocompress block, size: %zu", cBlockSize); + } else if (compressedSeqsSize == 1) { + cBlockSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cBlockSize, "RLE compress block failed"); + DEBUGLOG(4, "Writing out RLE block, size: %zu", cBlockSize); + } else { + U32 cBlockHeader; + /* Error checking and repcodes update */ + ZSTD_confirmRepcodesAndEntropyTables(cctx); + if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + /* Write block header into beginning of block*/ + cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3); + MEM_writeLE24(op, cBlockHeader); + cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize; + DEBUGLOG(4, "Writing out compressed block, size: %zu", cBlockSize); + } + + cSize += cBlockSize; + DEBUGLOG(4, "cSize running total: %zu", cSize); + + if (lastBlock) { + break; + } else { + ip += blockSize; + op += cBlockSize; + remaining -= blockSize; + dstCapacity -= cBlockSize; + cctx->isFirstBlock = 0; + } + } + + return cSize; +} + +size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize) { + BYTE* op = (BYTE*)dst; + size_t cSize = 0; + size_t compressedBlocksSize = 0; + size_t frameHeaderSize = 0; + + /* Transparent initialization stage, same as compressStream2() */ + DEBUGLOG(3, "ZSTD_compressSequences()"); + assert(cctx != NULL); + FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed"); + /* Begin writing output, starting with frame header */ + frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, &cctx->appliedParams, srcSize, cctx->dictID); + op += frameHeaderSize; + dstCapacity -= frameHeaderSize; + cSize += frameHeaderSize; + if (cctx->appliedParams.fParams.checksumFlag && srcSize) { + XXH64_update(&cctx->xxhState, src, srcSize); + } + /* cSize includes block header size and compressed sequences size */ + compressedBlocksSize = ZSTD_compressSequences_internal(cctx, + op, dstCapacity, + inSeqs, inSeqsSize, + src, srcSize); + FORWARD_IF_ERROR(compressedBlocksSize, "Compressing blocks failed!"); + cSize += compressedBlocksSize; + dstCapacity -= compressedBlocksSize; + + if (cctx->appliedParams.fParams.checksumFlag) { + U32 const checksum = (U32) XXH64_digest(&cctx->xxhState); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum"); + DEBUGLOG(4, "Write checksum : %08X", (unsigned)checksum); + MEM_writeLE32((char*)dst + cSize, checksum); + cSize += 4; + } + + DEBUGLOG(3, "Final compressed size: %zu", cSize); + return cSize; +} + /*====== Finalize ======*/ /*! ZSTD_flushStream() : @@ -4223,25 +5075,103 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV }, }; +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict); + switch (cParams.strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG; + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } + return cParams; +} + +static int ZSTD_dedicatedDictSearch_isSupported( + ZSTD_compressionParameters const* cParams) +{ + return (cParams->strategy >= ZSTD_greedy) && (cParams->strategy <= ZSTD_lazy2); +} + +/** + * Reverses the adjustment applied to cparams when enabling dedicated dict + * search. This is used to recover the params set to be used in the working + * context. (Otherwise, those tables would also grow.) + */ +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams) { + switch (cParams->strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG; + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } +} + +static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) +{ + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + case ZSTD_cpm_createCDict: + break; + case ZSTD_cpm_attachDict: + dictSize = 0; + break; + default: + assert(0); + break; + } + { int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN; + size_t const addedSize = unknown && dictSize > 0 ? 500 : 0; + return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize; + } +} + /*! ZSTD_getCParams_internal() : * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown. - * Use dictSize == 0 for unknown or unused. */ -static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) + * Use dictSize == 0 for unknown or unused. + * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_cParamMode_e`. */ +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) { - int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN; - size_t const addedSize = unknown && dictSize > 0 ? 500 : 0; - U64 const rSize = unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize; + U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode); U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); - int row = compressionLevel; + int row; DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel); + + /* row */ if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ - if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */ - if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; + else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */ + else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; + else row = compressionLevel; + { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; - if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel); /* acceleration factor */ + /* acceleration factor */ + if (compressionLevel < 0) { + int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel); + cp.targetLength = (unsigned)(-clampedCompressionLevel); + } /* refine parameters based on srcSize & dictSize */ - return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); + return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode); } } @@ -4251,18 +5181,18 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) { if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; - return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize); + return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); } /*! ZSTD_getParams() : * same idea as ZSTD_getCParams() * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). * Fields of `ZSTD_frameParameters` are set to default values */ -static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) { +static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) { ZSTD_parameters params; - ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize); + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode); DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel); - memset(¶ms, 0, sizeof(params)); + ZSTD_memset(¶ms, 0, sizeof(params)); params.cParams = cParams; params.fParams.contentSizeFlag = 1; return params; @@ -4274,5 +5204,5 @@ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned lo * Fields of `ZSTD_frameParameters` are set to default values */ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) { if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; - return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize); + return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); } diff --git a/thirdparty/zstd/compress/zstd_compress_internal.h b/thirdparty/zstd/compress/zstd_compress_internal.h index db73f6ce21..c04998b8b1 100644 --- a/thirdparty/zstd/compress/zstd_compress_internal.h +++ b/thirdparty/zstd/compress/zstd_compress_internal.h @@ -28,7 +28,6 @@ extern "C" { #endif - /*-************************************* * Constants ***************************************/ @@ -64,7 +63,7 @@ typedef struct { } ZSTD_localDict; typedef struct { - U32 CTable[HUF_CTABLE_SIZE_U32(255)]; + HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)]; HUF_repeat repeatMode; } ZSTD_hufCTables_t; @@ -83,11 +82,28 @@ typedef struct { } ZSTD_entropyCTables_t; typedef struct { - U32 off; - U32 len; + U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */ + U32 len; /* Raw length of match */ } ZSTD_match_t; typedef struct { + U32 offset; /* Offset of sequence */ + U32 litLength; /* Length of literals prior to match */ + U32 matchLength; /* Raw length of match */ +} rawSeq; + +typedef struct { + rawSeq* seq; /* The start of the sequences */ + size_t pos; /* The index in seq where reading stopped. pos <= size. */ + size_t posInSequence; /* The position within the sequence at seq[pos] where reading + stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */ + size_t size; /* The number of sequences. <= capacity. */ + size_t capacity; /* The capacity starting from `seq` pointer */ +} rawSeqStore_t; + +UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; + +typedef struct { int price; U32 off; U32 mlen; @@ -147,9 +163,13 @@ struct ZSTD_matchState_t { U32* hashTable; U32* hashTable3; U32* chainTable; + int dedicatedDictSearch; /* Indicates whether this matchState is using the + * dedicated dictionary search structure. + */ optState_t opt; /* optimal parser state */ const ZSTD_matchState_t* dictMatchState; ZSTD_compressionParameters cParams; + const rawSeqStore_t* ldmSeqStore; }; typedef struct { @@ -182,19 +202,6 @@ typedef struct { } ldmParams_t; typedef struct { - U32 offset; - U32 litLength; - U32 matchLength; -} rawSeq; - -typedef struct { - rawSeq* seq; /* The start of the sequences */ - size_t pos; /* The position where reading stopped. <= size. */ - size_t size; /* The number of sequences. <= capacity. */ - size_t capacity; /* The capacity starting from `seq` pointer */ -} rawSeqStore_t; - -typedef struct { int collectSequences; ZSTD_Sequence* seqStart; size_t seqIndex; @@ -228,10 +235,34 @@ struct ZSTD_CCtx_params_s { /* Long distance matching parameters */ ldmParams_t ldmParams; + /* Dedicated dict search algorithm trigger */ + int enableDedicatedDictSearch; + + /* Input/output buffer modes */ + ZSTD_bufferMode_e inBufferMode; + ZSTD_bufferMode_e outBufferMode; + + /* Sequence compression API */ + ZSTD_sequenceFormat_e blockDelimiters; + int validateSequences; + /* Internal use, for createCCtxParams() and freeCCtxParams() only */ ZSTD_customMem customMem; }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */ +#define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2)) +#define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE) + +/** + * Indicates whether this compression proceeds directly from user-provided + * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or + * whether the context needs to buffer the input/output (ZSTDb_buffered). + */ +typedef enum { + ZSTDb_not_buffered, + ZSTDb_buffered +} ZSTD_buffered_policy_e; + struct ZSTD_CCtx_s { ZSTD_compressionStage_e stage; int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */ @@ -247,6 +278,7 @@ struct ZSTD_CCtx_s { unsigned long long producedCSize; XXH64_state_t xxhState; ZSTD_customMem customMem; + ZSTD_threadPool* pool; size_t staticSize; SeqCollector seqCollector; int isFirstBlock; @@ -258,7 +290,10 @@ struct ZSTD_CCtx_s { size_t maxNbLdmSequences; rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */ ZSTD_blockState_t blockState; - U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */ + U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */ + + /* Wether we are streaming or not */ + ZSTD_buffered_policy_e bufferedPolicy; /* streaming */ char* inBuff; @@ -273,6 +308,10 @@ struct ZSTD_CCtx_s { ZSTD_cStreamStage streamStage; U32 frameEnded; + /* Stable in/out buffer verification */ + ZSTD_inBuffer expectedInBuffer; + size_t expectedOutBufferSize; + /* Dictionary */ ZSTD_localDict localDict; const ZSTD_CDict* cdict; @@ -286,8 +325,32 @@ struct ZSTD_CCtx_s { typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e; -typedef enum { ZSTD_noDict = 0, ZSTD_extDict = 1, ZSTD_dictMatchState = 2 } ZSTD_dictMode_e; - +typedef enum { + ZSTD_noDict = 0, + ZSTD_extDict = 1, + ZSTD_dictMatchState = 2, + ZSTD_dedicatedDictSearch = 3 +} ZSTD_dictMode_e; + +typedef enum { + ZSTD_cpm_noAttachDict = 0, /* Compression with ZSTD_noDict or ZSTD_extDict. + * In this mode we use both the srcSize and the dictSize + * when selecting and adjusting parameters. + */ + ZSTD_cpm_attachDict = 1, /* Compression with ZSTD_dictMatchState or ZSTD_dedicatedDictSearch. + * In this mode we only take the srcSize into account when selecting + * and adjusting parameters. + */ + ZSTD_cpm_createCDict = 2, /* Creating a CDict. + * In this mode we take both the source size and the dictionary size + * into account when selecting and adjusting the parameters. + */ + ZSTD_cpm_unknown = 3, /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams. + * We don't know what these parameters are for. We default to the legacy + * behavior of taking both the source size and the dict size into account + * when selecting and adjusting parameters. + */ +} ZSTD_cParamMode_e; typedef size_t (*ZSTD_blockCompressor) ( ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -345,7 +408,7 @@ MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 con newReps.rep[1] = rep[0]; newReps.rep[0] = currentOffset; } else { /* repCode == 0 */ - memcpy(&newReps, rep, sizeof(newReps)); + ZSTD_memcpy(&newReps, rep, sizeof(newReps)); } } return newReps; @@ -372,7 +435,7 @@ MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const voi RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity, dstSize_tooSmall, "dst buf too small for uncompressed block"); MEM_writeLE24(dst, cBlockHeader24); - memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); + ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); return ZSTD_blockHeaderSize + srcSize; } @@ -498,8 +561,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val) if (MEM_isLittleEndian()) { if (MEM_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r = 0; - return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; +# if STATIC_BMI2 + return _tzcnt_u64(val) >> 3; +# else + unsigned long r = 0; + return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; +# endif # elif defined(__GNUC__) && (__GNUC__ >= 4) return (__builtin_ctzll((U64)val) >> 3); # else @@ -530,8 +597,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val) } else { /* Big Endian CPU */ if (MEM_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r = 0; - return _BitScanReverse64( &r, val ) ? (unsigned)(r >> 3) : 0; +# if STATIC_BMI2 + return _lzcnt_u64(val) >> 3; +# else + unsigned long r = 0; + return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0; +# endif # elif defined(__GNUC__) && (__GNUC__ >= 4) return (__builtin_clzll(val) >> 3); # else @@ -626,7 +697,8 @@ static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; } static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); } -MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) { switch(mls) { @@ -742,7 +814,7 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms) return ZSTD_window_hasExtDict(ms->window) ? ZSTD_extDict : ms->dictMatchState != NULL ? - ZSTD_dictMatchState : + (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) : ZSTD_noDict; } @@ -754,8 +826,8 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms) MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, void const* srcEnd) { - U32 const current = (U32)((BYTE const*)srcEnd - window.base); - return current > ZSTD_CURRENT_MAX; + U32 const curr = (U32)((BYTE const*)srcEnd - window.base); + return curr > ZSTD_CURRENT_MAX; } /** @@ -791,14 +863,14 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, * windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32. */ U32 const cycleMask = (1U << cycleLog) - 1; - U32 const current = (U32)((BYTE const*)src - window->base); - U32 const currentCycle0 = current & cycleMask; + U32 const curr = (U32)((BYTE const*)src - window->base); + U32 const currentCycle0 = curr & cycleMask; /* Exclude zero so that newCurrent - maxDist >= 1. */ U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0; U32 const newCurrent = currentCycle1 + maxDist; - U32 const correction = current - newCurrent; + U32 const correction = curr - newCurrent; assert((maxDist & cycleMask) == 0); - assert(current > newCurrent); + assert(curr > newCurrent); /* Loose bound, should be around 1<<29 (see above) */ assert(correction > 1<<28); @@ -919,7 +991,7 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window, } MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) { - memset(window, 0, sizeof(*window)); + ZSTD_memset(window, 0, sizeof(*window)); window->base = (BYTE const*)""; window->dictBase = (BYTE const*)""; window->dictLimit = 1; /* start from 1, so that 1st position is valid */ @@ -973,12 +1045,16 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window, /** * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix. */ -MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog) +MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog) { U32 const maxDistance = 1U << windowLog; U32 const lowestValid = ms->window.lowLimit; - U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary + * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't + * valid for the entire block. So this check is sufficient to find the lowest valid match index. + */ U32 const matchLowest = isDictionary ? lowestValid : withinWindow; return matchLowest; } @@ -986,12 +1062,15 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current /** * Returns the lowest allowed match index in the prefix. */ -MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog) +MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog) { U32 const maxDistance = 1U << windowLog; U32 const lowestValid = ms->window.dictLimit; - U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When computing the lowest prefix index we need to take the dictionary into account to handle + * the edge case where the dictionary and the source are contiguous in memory. + */ U32 const matchLowest = isDictionary ? lowestValid : withinWindow; return matchLowest; } @@ -1045,7 +1124,6 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max) * assumptions : magic number supposed already checked * and dictSize >= 8 */ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, - short* offcodeNCount, unsigned* offcodeMaxValue, const void* const dict, size_t dictSize); void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs); @@ -1061,7 +1139,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs); * Note: srcSizeHint == 0 means 0! */ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( - const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize); + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode); /*! ZSTD_initCStream_internal() : * Private use only. Init streaming operation. diff --git a/thirdparty/zstd/compress/zstd_compress_literals.c b/thirdparty/zstd/compress/zstd_compress_literals.c index 17e7168d89..6dd1c1447a 100644 --- a/thirdparty/zstd/compress/zstd_compress_literals.c +++ b/thirdparty/zstd/compress/zstd_compress_literals.c @@ -35,7 +35,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, assert(0); } - memcpy(ostart + flSize, src, srcSize); + ZSTD_memcpy(ostart + flSize, src, srcSize); DEBUGLOG(5, "Raw literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize)); return srcSize + flSize; } @@ -86,7 +86,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, disableLiteralCompression, (U32)srcSize); /* Prepare nextEntropy assuming reusing the existing table */ - memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); if (disableLiteralCompression) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); @@ -118,11 +118,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, } if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) { - memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); } if (cLitSize==1) { - memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); } diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.c b/thirdparty/zstd/compress/zstd_compress_sequences.c index f9f8097c83..be30c08c6b 100644 --- a/thirdparty/zstd/compress/zstd_compress_sequences.c +++ b/thirdparty/zstd/compress/zstd_compress_sequences.c @@ -51,6 +51,19 @@ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) { } /** + * Returns true if we should use ncount=-1 else we should + * use ncount=1 for low probability symbols instead. + */ +static unsigned ZSTD_useLowProbCount(size_t const nbSeq) +{ + /* Heuristic: This should cover most blocks <= 16K and + * start to fade out after 16K to about 32K depending on + * comprssibility. + */ + return nbSeq >= 2048; +} + +/** * Returns the cost in bytes of encoding the normalized count header. * Returns an error if any of the helper functions return an error. */ @@ -60,7 +73,7 @@ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max, BYTE wksp[FSE_NCOUNTBOUND]; S16 norm[MaxSeq + 1]; const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); - FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max), ""); + FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), ""); return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog); } @@ -239,7 +252,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity, *op = codeTable[0]; return 1; case set_repeat: - memcpy(nextCTable, prevCTable, prevCTableSize); + ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize); return 0; case set_basic: FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */ @@ -253,7 +266,8 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity, nbSeq_1--; } assert(nbSeq_1 > 1); - FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max), ""); + assert(entropyWorkspaceSize >= FSE_BUILD_CTABLE_WORKSPACE_SIZE(MaxSeq, MaxFSELog)); + FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), ""); { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */ FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed"); FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), ""); diff --git a/thirdparty/zstd/compress/zstd_compress_superblock.c b/thirdparty/zstd/compress/zstd_compress_superblock.c index b693866c0a..e23e619eef 100644 --- a/thirdparty/zstd/compress/zstd_compress_superblock.c +++ b/thirdparty/zstd/compress/zstd_compress_superblock.c @@ -29,7 +29,7 @@ * This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */ typedef struct { symbolEncodingType_e hType; - BYTE hufDesBuffer[500]; /* TODO give name to this value */ + BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE]; size_t hufDesSize; } ZSTD_hufCTablesMetadata_t; @@ -42,7 +42,7 @@ typedef struct { symbolEncodingType_e llType; symbolEncodingType_e ofType; symbolEncodingType_e mlType; - BYTE fseTablesBuffer[500]; /* TODO give name to this value */ + BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE]; size_t fseTablesSize; size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */ } ZSTD_fseCTablesMetadata_t; @@ -79,7 +79,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize); /* Prepare nextEntropy assuming reusing the existing table */ - memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); if (disableLiteralsCompression) { DEBUGLOG(5, "set_basic - disabled"); @@ -118,7 +118,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz } /* Build Huffman Tree */ - memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable)); + ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable)); huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue); { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue, huffLog, @@ -137,14 +137,14 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue); if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) { DEBUGLOG(5, "set_repeat - smaller"); - memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); hufMetadata->hType = set_repeat; return 0; } } if (newCSize + hSize >= srcSize) { DEBUGLOG(5, "set_basic - no gains"); - memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); hufMetadata->hType = set_basic; return 0; } @@ -188,7 +188,7 @@ static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr, assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE)); DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq); - memset(workspace, 0, wkspSize); + ZSTD_memset(workspace, 0, wkspSize); fseMetadata->lastCountSize = 0; /* convert length/distances into codes */ @@ -348,7 +348,7 @@ static size_t ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat); if (writeEntropy && hufMetadata->hType == set_compressed) { - memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize); + ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize); op += hufMetadata->hufDesSize; cLitSize += hufMetadata->hufDesSize; DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize); @@ -474,7 +474,7 @@ static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables const U32 MLtype = fseMetadata->mlType; DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize); *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); - memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize); + ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize); op += fseMetadata->fseTablesSize; } else { const U32 repeat = set_repeat; @@ -603,7 +603,7 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type, const BYTE* codeTable, unsigned maxCode, size_t nbSeq, const FSE_CTable* fseCTable, const U32* additionalBits, - short const* defaultNorm, U32 defaultNormLog, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, void* workspace, size_t wkspSize) { unsigned* const countWksp = (unsigned*)workspace; @@ -615,7 +615,11 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type, HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ if (type == set_basic) { - cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max); + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + cSymbolTypeSizeEstimateInBits = max <= defaultMax + ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max) + : ERROR(GENERIC); } else if (type == set_rle) { cSymbolTypeSizeEstimateInBits = 0; } else if (type == set_compressed || type == set_repeat) { @@ -643,15 +647,15 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable, size_t cSeqSizeEstimate = 0; cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, nbSeq, fseTables->offcodeCTable, NULL, - OF_defaultNorm, OF_defaultNormLog, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, workspace, wkspSize); cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL, nbSeq, fseTables->litlengthCTable, LL_bits, - LL_defaultNorm, LL_defaultNormLog, + LL_defaultNorm, LL_defaultNormLog, MaxLL, workspace, wkspSize); cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML, nbSeq, fseTables->matchlengthCTable, ML_bits, - ML_defaultNorm, ML_defaultNormLog, + ML_defaultNorm, ML_defaultNormLog, MaxML, workspace, wkspSize); if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; return cSeqSizeEstimate + sequencesSectionHeaderSize; @@ -790,7 +794,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, } while (!lastSequence); if (writeLitEntropy) { DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten"); - memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf)); + ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf)); } if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) { /* If we haven't written our entropy tables, then we've violated our contract and @@ -809,11 +813,11 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, if (sp < send) { seqDef const* seq; repcodes_t rep; - memcpy(&rep, prevCBlock->rep, sizeof(rep)); + ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep)); for (seq = sstart; seq < sp; ++seq) { rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0); } - memcpy(nextCBlock->rep, &rep, sizeof(rep)); + ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep)); } } DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed"); @@ -831,7 +835,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, &zc->blockState.nextCBlock->entropy, &zc->appliedParams, &entropyMetadata, - zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */), ""); + zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), ""); return ZSTD_compressSubBlock_multi(&zc->seqStore, zc->blockState.prevCBlock, @@ -841,5 +845,5 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, dst, dstCapacity, src, srcSize, zc->bmi2, lastBlock, - zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */); + zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */); } diff --git a/thirdparty/zstd/compress/zstd_cwksp.h b/thirdparty/zstd/compress/zstd_cwksp.h index a25c9263b7..d65170b39c 100644 --- a/thirdparty/zstd/compress/zstd_cwksp.h +++ b/thirdparty/zstd/compress/zstd_cwksp.h @@ -45,6 +45,16 @@ typedef enum { } ZSTD_cwksp_alloc_phase_e; /** + * Used to describe whether the workspace is statically allocated (and will not + * necessarily ever be freed), or if it's dynamically allocated and we can + * expect a well-formed caller to free this. + */ +typedef enum { + ZSTD_cwksp_dynamic_alloc, + ZSTD_cwksp_static_alloc +} ZSTD_cwksp_static_alloc_e; + +/** * Zstd fits all its internal datastructures into a single continuous buffer, * so that it only needs to perform a single OS allocation (or so that a buffer * can be provided to it and it can perform no allocations at all). This buffer @@ -92,7 +102,7 @@ typedef enum { * * - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict, * so that literally everything fits in a single buffer. Note: if present, - * this must be the first object in the workspace, since ZSTD_free{CCtx, + * this must be the first object in the workspace, since ZSTD_customFree{CCtx, * CDict}() rely on a pointer comparison to see whether one or two frees are * required. * @@ -137,9 +147,10 @@ typedef struct { void* tableValidEnd; void* allocStart; - int allocFailed; + BYTE allocFailed; int workspaceOversizedDuration; ZSTD_cwksp_alloc_phase_e phase; + ZSTD_cwksp_static_alloc_e isStatic; } ZSTD_cwksp; /*-************************************* @@ -178,7 +189,9 @@ MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) { * else is though. */ MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) { -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + if (size == 0) + return 0; +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; #else return size; @@ -228,7 +241,10 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal( ZSTD_cwksp_internal_advance_phase(ws, phase); alloc = (BYTE *)ws->allocStart - bytes; -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + if (bytes == 0) + return NULL; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) /* over-reserve space */ alloc = (BYTE *)alloc - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; #endif @@ -247,11 +263,13 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal( } ws->allocStart = alloc; -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on * either size. */ alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; - __asan_unpoison_memory_region(alloc, bytes); + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } #endif return alloc; @@ -296,8 +314,10 @@ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) { } ws->tableEnd = end; -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) - __asan_unpoison_memory_region(alloc, bytes); +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } #endif return alloc; @@ -311,7 +331,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) { void* alloc = ws->objectEnd; void* end = (BYTE*)alloc + roundedBytes; -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) /* over-reserve space */ end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; #endif @@ -332,11 +352,13 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) { ws->tableEnd = end; ws->tableValidEnd = end; -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on * either size. */ alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; - __asan_unpoison_memory_region(alloc, bytes); + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } #endif return alloc; @@ -345,7 +367,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) { MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) { DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty"); -#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) /* To validate that the table re-use logic is sound, and that we don't * access table space that we haven't cleaned, we re-"poison" the table * space every time we mark it dirty. */ @@ -380,7 +402,7 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { assert(ws->tableValidEnd >= ws->objectEnd); assert(ws->tableValidEnd <= ws->allocStart); if (ws->tableValidEnd < ws->tableEnd) { - memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd); + ZSTD_memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd); } ZSTD_cwksp_mark_tables_clean(ws); } @@ -392,8 +414,12 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) { DEBUGLOG(4, "cwksp: clearing tables!"); -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) - { +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; __asan_poison_memory_region(ws->objectEnd, size); } @@ -410,7 +436,7 @@ MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) { MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { DEBUGLOG(4, "cwksp: clearing!"); -#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) /* To validate that the context re-use logic is sound, and that we don't * access stuff that this compression hasn't initialized, we re-"poison" * the workspace (or at least the non-static, non-table parts of it) @@ -421,8 +447,12 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { } #endif -#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) - { +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd; __asan_poison_memory_region(ws->objectEnd, size); } @@ -442,7 +472,7 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { * Any existing values in the workspace are ignored (the previously managed * buffer, if present, must be separately freed). */ -MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) { +MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) { DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size); assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */ ws->workspace = start; @@ -450,24 +480,25 @@ MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) { ws->objectEnd = ws->workspace; ws->tableValidEnd = ws->objectEnd; ws->phase = ZSTD_cwksp_alloc_objects; + ws->isStatic = isStatic; ZSTD_cwksp_clear(ws); ws->workspaceOversizedDuration = 0; ZSTD_cwksp_assert_internal_consistency(ws); } MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) { - void* workspace = ZSTD_malloc(size, customMem); + void* workspace = ZSTD_customMalloc(size, customMem); DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size); RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!"); - ZSTD_cwksp_init(ws, workspace, size); + ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc); return 0; } MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) { void *ptr = ws->workspace; DEBUGLOG(4, "cwksp: freeing workspace"); - memset(ws, 0, sizeof(ZSTD_cwksp)); - ZSTD_free(ptr, customMem); + ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp)); + ZSTD_customFree(ptr, customMem); } /** @@ -476,13 +507,18 @@ MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) { */ MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) { *dst = *src; - memset(src, 0, sizeof(ZSTD_cwksp)); + ZSTD_memset(src, 0, sizeof(ZSTD_cwksp)); } MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) { return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace); } +MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace) + + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart); +} + MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { return ws->allocFailed; } diff --git a/thirdparty/zstd/compress/zstd_double_fast.c b/thirdparty/zstd/compress/zstd_double_fast.c index 27eed66cfe..ef12a524f7 100644 --- a/thirdparty/zstd/compress/zstd_double_fast.c +++ b/thirdparty/zstd/compress/zstd_double_fast.c @@ -31,15 +31,15 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, * is empty. */ for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { - U32 const current = (U32)(ip - base); + U32 const curr = (U32)(ip - base); U32 i; for (i = 0; i < fastHashFillStep; ++i) { size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls); size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8); if (i == 0) - hashSmall[smHash] = current + i; + hashSmall[smHash] = curr + i; if (i == 0 || hashLarge[lgHash] == 0) - hashLarge[lgHash] = current + i; + hashLarge[lgHash] = curr + i; /* Only load extra positions for ZSTD_dtlm_full */ if (dtlm == ZSTD_dtlm_fast) break; @@ -108,9 +108,9 @@ size_t ZSTD_compressBlock_doubleFast_generic( /* init */ ip += (dictAndPrefixLength == 0); if (dictMode == ZSTD_noDict) { - U32 const current = (U32)(ip - base); - U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog); - U32 const maxRep = current - windowLow; + U32 const curr = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0; if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; } @@ -129,17 +129,17 @@ size_t ZSTD_compressBlock_doubleFast_generic( size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); size_t const dictHL = ZSTD_hashPtr(ip, dictHBitsL, 8); size_t const dictHS = ZSTD_hashPtr(ip, dictHBitsS, mls); - U32 const current = (U32)(ip-base); + U32 const curr = (U32)(ip-base); U32 const matchIndexL = hashLong[h2]; U32 matchIndexS = hashSmall[h]; const BYTE* matchLong = base + matchIndexL; const BYTE* match = base + matchIndexS; - const U32 repIndex = current + 1 - offset_1; + const U32 repIndex = curr + 1 - offset_1; const BYTE* repMatch = (dictMode == ZSTD_dictMatchState && repIndex < prefixLowestIndex) ? dictBase + (repIndex - dictIndexDelta) : base + repIndex; - hashLong[h2] = hashSmall[h] = current; /* update hash tables */ + hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ /* check dictMatchState repcode */ if (dictMode == ZSTD_dictMatchState @@ -177,7 +177,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) { mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8; - offset = (U32)(current - dictMatchIndexL - dictIndexDelta); + offset = (U32)(curr - dictMatchIndexL - dictIndexDelta); while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */ goto _match_found; } } @@ -209,7 +209,7 @@ _search_next_long: size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8); U32 const matchIndexL3 = hashLong[hl3]; const BYTE* matchL3 = base + matchIndexL3; - hashLong[hl3] = current + 1; + hashLong[hl3] = curr + 1; /* check prefix long +1 match */ if (matchIndexL3 > prefixLowestIndex) { @@ -228,7 +228,7 @@ _search_next_long: if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) { mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8; ip++; - offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta); + offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta); while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */ goto _match_found; } } } @@ -236,7 +236,7 @@ _search_next_long: /* if no long +1 match, explore the short match we found */ if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) { mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4; - offset = (U32)(current - matchIndexS); + offset = (U32)(curr - matchIndexS); while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ } else { mLength = ZSTD_count(ip+4, match+4, iend) + 4; @@ -260,7 +260,7 @@ _match_stored: if (ip <= ilimit) { /* Complementary insertion */ /* done after iLimit test, as candidates could be > iend-8 */ - { U32 const indexToInsert = current+2; + { U32 const indexToInsert = curr+2; hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; @@ -401,12 +401,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base; const BYTE* matchLong = matchLongBase + matchLongIndex; - const U32 current = (U32)(ip-base); - const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */ + const U32 curr = (U32)(ip-base); + const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */ const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; size_t mLength; - hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */ + hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */ & (repIndex > dictStartIndex)) @@ -421,7 +421,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart; U32 offset; mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8; - offset = current - matchLongIndex; + offset = curr - matchLongIndex; while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ offset_2 = offset_1; offset_1 = offset; @@ -433,19 +433,19 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base; const BYTE* match3 = match3Base + matchIndex3; U32 offset; - hashLong[h3] = current + 1; + hashLong[h3] = curr + 1; if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) { const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend; const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart; mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8; ip++; - offset = current+1 - matchIndex3; + offset = curr+1 - matchIndex3; while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */ } else { const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4; - offset = current - matchIndex; + offset = curr - matchIndex; while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ } offset_2 = offset_1; @@ -464,7 +464,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( if (ip <= ilimit) { /* Complementary insertion */ /* done after iLimit test, as candidates could be > iend-8 */ - { U32 const indexToInsert = current+2; + { U32 const indexToInsert = curr+2; hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; diff --git a/thirdparty/zstd/compress/zstd_fast.c b/thirdparty/zstd/compress/zstd_fast.c index 85a3a7a91e..db7ce83d0a 100644 --- a/thirdparty/zstd/compress/zstd_fast.c +++ b/thirdparty/zstd/compress/zstd_fast.c @@ -29,16 +29,16 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms, * Insert the other positions if their hash entry is empty. */ for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { - U32 const current = (U32)(ip - base); + U32 const curr = (U32)(ip - base); size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls); - hashTable[hash0] = current; + hashTable[hash0] = curr; if (dtlm == ZSTD_dtlm_fast) continue; /* Only load extra positions for ZSTD_dtlm_full */ { U32 p; for (p = 1; p < fastHashFillStep; ++p) { size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls); if (hashTable[hash] == 0) { /* not yet filled */ - hashTable[hash] = current + p; + hashTable[hash] = curr + p; } } } } } @@ -72,9 +72,9 @@ ZSTD_compressBlock_fast_generic( DEBUGLOG(5, "ZSTD_compressBlock_fast_generic"); ip0 += (ip0 == prefixStart); ip1 = ip0 + 1; - { U32 const current = (U32)(ip0 - base); - U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog); - U32 const maxRep = current - windowLow; + { U32 const curr = (U32)(ip0 - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0; if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; } @@ -258,14 +258,14 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ size_t mLength; size_t const h = ZSTD_hashPtr(ip, hlog, mls); - U32 const current = (U32)(ip-base); + U32 const curr = (U32)(ip-base); U32 const matchIndex = hashTable[h]; const BYTE* match = base + matchIndex; - const U32 repIndex = current + 1 - offset_1; + const U32 repIndex = curr + 1 - offset_1; const BYTE* repMatch = (repIndex < prefixStartIndex) ? dictBase + (repIndex - dictIndexDelta) : base + repIndex; - hashTable[h] = current; /* update hash table */ + hashTable[h] = curr; /* update hash table */ if ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex isn't overlapping dict + prefix */ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { @@ -284,7 +284,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( continue; } else { /* found a dict match */ - U32 const offset = (U32)(current-dictMatchIndex-dictIndexDelta); + U32 const offset = (U32)(curr-dictMatchIndex-dictIndexDelta); mLength = ZSTD_count_2segments(ip+4, dictMatch+4, iend, dictEnd, prefixStart) + 4; while (((ip>anchor) & (dictMatch>dictStart)) && (ip[-1] == dictMatch[-1])) { @@ -316,8 +316,8 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( if (ip <= ilimit) { /* Fill Table */ - assert(base+current+2 > istart); /* check base overflow */ - hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2; /* here because current+2 could be > iend-8 */ + assert(base+curr+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */ hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base); /* check immediate repcode */ @@ -410,13 +410,13 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( const U32 matchIndex = hashTable[h]; const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base; const BYTE* match = matchBase + matchIndex; - const U32 current = (U32)(ip-base); - const U32 repIndex = current + 1 - offset_1; + const U32 curr = (U32)(ip-base); + const U32 repIndex = curr + 1 - offset_1; const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; - hashTable[h] = current; /* update hash table */ - DEBUGLOG(7, "offset_1 = %u , current = %u", offset_1, current); - assert(offset_1 <= current +1); /* check repIndex */ + hashTable[h] = curr; /* update hash table */ + DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr); + assert(offset_1 <= curr +1); /* check repIndex */ if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex)) && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { @@ -435,7 +435,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( } { const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; - U32 const offset = current - matchIndex; + U32 const offset = curr - matchIndex; size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4; while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ offset_2 = offset_1; offset_1 = offset; /* update offset history */ @@ -446,7 +446,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( if (ip <= ilimit) { /* Fill Table */ - hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2; + hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base); /* check immediate repcode */ while (ip <= ilimit) { diff --git a/thirdparty/zstd/compress/zstd_lazy.c b/thirdparty/zstd/compress/zstd_lazy.c index 4cf5c88b53..49ec1b09ef 100644 --- a/thirdparty/zstd/compress/zstd_lazy.c +++ b/thirdparty/zstd/compress/zstd_lazy.c @@ -58,11 +58,11 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms, /** ZSTD_insertDUBT1() : * sort one already inserted but unsorted position - * assumption : current >= btlow == (current - btmask) + * assumption : curr >= btlow == (curr - btmask) * doesn't fail */ static void ZSTD_insertDUBT1(ZSTD_matchState_t* ms, - U32 current, const BYTE* inputEnd, + U32 curr, const BYTE* inputEnd, U32 nbCompares, U32 btLow, const ZSTD_dictMode_e dictMode) { @@ -74,41 +74,41 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms, const BYTE* const base = ms->window.base; const BYTE* const dictBase = ms->window.dictBase; const U32 dictLimit = ms->window.dictLimit; - const BYTE* const ip = (current>=dictLimit) ? base + current : dictBase + current; - const BYTE* const iend = (current>=dictLimit) ? inputEnd : dictBase + dictLimit; + const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr; + const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; const BYTE* match; - U32* smallerPtr = bt + 2*(current&btMask); + U32* smallerPtr = bt + 2*(curr&btMask); U32* largerPtr = smallerPtr + 1; U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */ U32 dummy32; /* to be nullified at the end */ U32 const windowValid = ms->window.lowLimit; U32 const maxDistance = 1U << cParams->windowLog; - U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid; + U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid; DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)", - current, dictLimit, windowLow); - assert(current >= btLow); + curr, dictLimit, windowLow); + assert(curr >= btLow); assert(ip < iend); /* condition for ZSTD_count */ while (nbCompares-- && (matchIndex > windowLow)) { U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ - assert(matchIndex < current); + assert(matchIndex < curr); /* note : all candidates are now supposed sorted, * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */ if ( (dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit) /* both in current segment*/ - || (current < dictLimit) /* both in extDict */) { + || (curr < dictLimit) /* both in extDict */) { const BYTE* const mBase = ( (dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) ? base : dictBase; assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */ - || (current < dictLimit) ); + || (curr < dictLimit) ); match = mBase + matchIndex; matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); } else { @@ -119,7 +119,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms, } DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ", - current, matchIndex, (U32)matchLength); + curr, matchIndex, (U32)matchLength); if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ @@ -168,7 +168,7 @@ ZSTD_DUBT_findBetterDictMatch ( const BYTE* const base = ms->window.base; const BYTE* const prefixStart = base + ms->window.dictLimit; - U32 const current = (U32)(ip-base); + U32 const curr = (U32)(ip-base); const BYTE* const dictBase = dms->window.base; const BYTE* const dictEnd = dms->window.nextSrc; U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base); @@ -195,10 +195,10 @@ ZSTD_DUBT_findBetterDictMatch ( if (matchLength > bestLength) { U32 matchIndex = dictMatchIndex + dictIndexDelta; - if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) { + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) { DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)", - current, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + current - matchIndex, dictMatchIndex, matchIndex); - bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; + curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + curr - matchIndex, dictMatchIndex, matchIndex); + bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex; } if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */ break; /* drop, to guarantee consistency (miss a little bit of compression) */ @@ -218,9 +218,9 @@ ZSTD_DUBT_findBetterDictMatch ( } if (bestLength >= MINMATCH) { - U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex; + U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex; DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)", - current, (U32)bestLength, (U32)*offsetPtr, mIndex); + curr, (U32)bestLength, (U32)*offsetPtr, mIndex); } return bestLength; @@ -241,13 +241,13 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, U32 matchIndex = hashTable[h]; const BYTE* const base = ms->window.base; - U32 const current = (U32)(ip-base); - U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog); + U32 const curr = (U32)(ip-base); + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); U32* const bt = ms->chainTable; U32 const btLog = cParams->chainLog - 1; U32 const btMask = (1 << btLog) - 1; - U32 const btLow = (btMask >= current) ? 0 : current - btMask; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; U32 const unsortLimit = MAX(btLow, windowLow); U32* nextCandidate = bt + 2*(matchIndex&btMask); @@ -256,8 +256,9 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, U32 nbCandidates = nbCompares; U32 previousCandidate = 0; - DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", current); + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr); assert(ip <= iend-8); /* required for h calculation */ + assert(dictMode != ZSTD_dedicatedDictSearch); /* reach end of unsorted candidates list */ while ( (matchIndex > unsortLimit) @@ -299,14 +300,14 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, const U32 dictLimit = ms->window.dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; - U32* smallerPtr = bt + 2*(current&btMask); - U32* largerPtr = bt + 2*(current&btMask) + 1; - U32 matchEndIdx = current + 8 + 1; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr + 8 + 1; U32 dummy32; /* to be nullified at the end */ size_t bestLength = 0; matchIndex = hashTable[h]; - hashTable[h] = current; /* Update Hash Table */ + hashTable[h] = curr; /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { U32* const nextPtr = bt + 2*(matchIndex & btMask); @@ -326,8 +327,8 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, if (matchLength > bestLength) { if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; - if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) - bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) + bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex; if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ if (dictMode == ZSTD_dictMatchState) { nbCompares = 0; /* in addition to avoiding checking any @@ -363,12 +364,12 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, mls, dictMode); } - assert(matchEndIdx > current+8); /* ensure nextToUpdate is increased */ + assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */ ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ if (bestLength >= MINMATCH) { - U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex; + U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex; DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)", - current, (U32)bestLength, (U32)*offsetPtr, mIndex); + curr, (U32)bestLength, (U32)*offsetPtr, mIndex); } return bestLength; } @@ -446,7 +447,7 @@ static size_t ZSTD_BtFindBestMatch_extDict_selectMLS ( /* Update chains up to ip (excluded) Assumption : always within prefix (i.e. not within extDict) */ -static U32 ZSTD_insertAndFindFirstIndex_internal( +FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal( ZSTD_matchState_t* ms, const ZSTD_compressionParameters* const cParams, const BYTE* ip, U32 const mls) @@ -475,6 +476,121 @@ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) { return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch); } +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32* const hashTable = ms->hashTable; + U32* const chainTable = ms->chainTable; + U32 const chainSize = 1 << ms->cParams.chainLog; + U32 idx = ms->nextToUpdate; + U32 const minChain = chainSize < target ? target - chainSize : idx; + U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const cacheSize = bucketSize - 1; + U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize; + U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts; + + /* We know the hashtable is oversized by a factor of `bucketSize`. + * We are going to temporarily pretend `bucketSize == 1`, keeping only a + * single entry. We will use the rest of the space to construct a temporary + * chaintable. + */ + U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + U32* const tmpHashTable = hashTable; + U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog); + U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; + U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx; + + U32 hashIdx; + + assert(ms->cParams.chainLog <= 24); + assert(ms->cParams.hashLog >= ms->cParams.chainLog); + assert(idx != 0); + assert(tmpMinChain <= minChain); + + /* fill conventional hash table and conventional chain table */ + for ( ; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch); + if (idx >= tmpMinChain) { + tmpChainTable[idx - tmpMinChain] = hashTable[h]; + } + tmpHashTable[h] = idx; + } + + /* sort chains into ddss chain table */ + { + U32 chainPos = 0; + for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) { + U32 count; + U32 countBeyondMinChain = 0; + U32 i = tmpHashTable[hashIdx]; + for (count = 0; i >= tmpMinChain && count < cacheSize; count++) { + /* skip through the chain to the first position that won't be + * in the hash cache bucket */ + if (i < minChain) { + countBeyondMinChain++; + } + i = tmpChainTable[i - tmpMinChain]; + } + if (count == cacheSize) { + for (count = 0; count < chainLimit;) { + if (i < minChain) { + if (!i || countBeyondMinChain++ > cacheSize) { + /* only allow pulling `cacheSize` number of entries + * into the cache or chainTable beyond `minChain`, + * to replace the entries pulled out of the + * chainTable into the cache. This lets us reach + * back further without increasing the total number + * of entries in the chainTable, guaranteeing the + * DDSS chain table will fit into the space + * allocated for the regular one. */ + break; + } + } + chainTable[chainPos++] = i; + count++; + if (i < tmpMinChain) { + break; + } + i = tmpChainTable[i - tmpMinChain]; + } + } else { + count = 0; + } + if (count) { + tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count; + } else { + tmpHashTable[hashIdx] = 0; + } + } + assert(chainPos <= chainSize); /* I believe this is guaranteed... */ + } + + /* move chain pointers into the last entry of each hash bucket */ + for (hashIdx = (1 << hashLog); hashIdx; ) { + U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const chainPackedPointer = tmpHashTable[hashIdx]; + U32 i; + for (i = 0; i < cacheSize; i++) { + hashTable[bucketIdx + i] = 0; + } + hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer; + } + + /* fill the buckets of the hash table */ + for (idx = ms->nextToUpdate; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch) + << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 i; + /* Shift hash cache down 1. */ + for (i = cacheSize - 1; i; i--) + hashTable[h + i] = hashTable[h + i - 1]; + hashTable[h] = idx; + } + + ms->nextToUpdate = target; +} + /* inlining is important to hardwire a hot branch (template emulation) */ FORCE_INLINE_TEMPLATE @@ -493,20 +609,33 @@ size_t ZSTD_HcFindBestMatch_generic ( const U32 dictLimit = ms->window.dictLimit; const BYTE* const prefixStart = base + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; - const U32 current = (U32)(ip-base); + const U32 curr = (U32)(ip-base); const U32 maxDistance = 1U << cParams->windowLog; const U32 lowestValid = ms->window.lowLimit; - const U32 withinMaxDistance = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; const U32 isDictionary = (ms->loadedDictEnd != 0); const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; - const U32 minChain = current > chainSize ? current - chainSize : 0; + const U32 minChain = curr > chainSize ? curr - chainSize : 0; U32 nbAttempts = 1U << cParams->searchLog; size_t ml=4-1; + const ZSTD_matchState_t* const dms = ms->dictMatchState; + const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch + ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch + ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + + U32 matchIndex; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32* entry = &dms->hashTable[ddsIdx]; + PREFETCH_L1(entry); + } + /* HC4 match finder */ - U32 matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls); + matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls); - for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) { + for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) { size_t currentMl=0; if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { const BYTE* const match = base + matchIndex; @@ -523,7 +652,7 @@ size_t ZSTD_HcFindBestMatch_generic ( /* save best solution */ if (currentMl > ml) { ml = currentMl; - *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; + *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ } @@ -531,8 +660,92 @@ size_t ZSTD_HcFindBestMatch_generic ( matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); } - if (dictMode == ZSTD_dictMatchState) { - const ZSTD_matchState_t* const dms = ms->dictMatchState; + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32 ddsLowestIndex = dms->window.dictLimit; + const BYTE* const ddsBase = dms->window.base; + const BYTE* const ddsEnd = dms->window.nextSrc; + const U32 ddsSize = (U32)(ddsEnd - ddsBase); + const U32 ddsIndexDelta = dictLimit - ddsSize; + const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG); + const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1; + U32 ddsAttempt; + + for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) { + PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]); + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 const chainIndex = chainPackedPointer >> 8; + + PREFETCH_L1(&dms->chainTable[chainIndex]); + } + + for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->hashTable[ddsIdx + ddsAttempt]; + match = ddsBase + matchIndex; + + if (!matchIndex) { + return ml; + } + + /* guaranteed by table construction */ + (void)ddsLowestIndex; + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE; + if (ip+currentMl == iLimit) { + /* best possible, avoids read overflow on next attempt */ + return ml; + } + } + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 chainIndex = chainPackedPointer >> 8; + U32 const chainLength = chainPackedPointer & 0xFF; + U32 const chainAttempts = nbAttempts - ddsAttempt; + U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts; + U32 chainAttempt; + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) { + PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]); + } + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->chainTable[chainIndex]; + match = ddsBase + matchIndex; + + /* guaranteed by table construction */ + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE; + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + } else if (dictMode == ZSTD_dictMatchState) { const U32* const dmsChainTable = dms->chainTable; const U32 dmsChainSize = (1 << dms->cParams.chainLog); const U32 dmsChainMask = dmsChainSize - 1; @@ -545,7 +758,7 @@ size_t ZSTD_HcFindBestMatch_generic ( matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)]; - for ( ; (matchIndex>dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) { + for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) { size_t currentMl=0; const BYTE* const match = dmsBase + matchIndex; assert(match+4 <= dmsEnd); @@ -555,11 +768,12 @@ size_t ZSTD_HcFindBestMatch_generic ( /* save best solution */ if (currentMl > ml) { ml = currentMl; - *offsetPtr = current - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE; + *offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ } if (matchIndex <= dmsMinChain) break; + matchIndex = dmsChainTable[matchIndex & dmsChainMask]; } } @@ -600,6 +814,22 @@ static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS ( } +static size_t ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS ( + ZSTD_matchState_t* ms, + const BYTE* ip, const BYTE* const iLimit, + size_t* offsetPtr) +{ + switch(ms->cParams.minMatch) + { + default : /* includes case 3 */ + case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dedicatedDictSearch); + case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dedicatedDictSearch); + case 7 : + case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dedicatedDictSearch); + } +} + + FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* const iLimit, @@ -641,39 +871,62 @@ ZSTD_compressBlock_lazy_generic( typedef size_t (*searchMax_f)( ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); - searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ? - (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS - : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) : - (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_selectMLS - : ZSTD_HcFindBestMatch_selectMLS); + + /** + * This table is indexed first by the four ZSTD_dictMode_e values, and then + * by the two searchMethod_e values. NULLs are placed for configurations + * that should never occur (extDict modes go to the other implementation + * below and there is no DDSS for binary tree search yet). + */ + const searchMax_f searchFuncs[4][2] = { + { + ZSTD_HcFindBestMatch_selectMLS, + ZSTD_BtFindBestMatch_selectMLS + }, + { + NULL, + NULL + }, + { + ZSTD_HcFindBestMatch_dictMatchState_selectMLS, + ZSTD_BtFindBestMatch_dictMatchState_selectMLS + }, + { + ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS, + NULL + } + }; + + searchMax_f const searchMax = searchFuncs[dictMode][searchMethod == search_binaryTree]; U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0; + const int isDMS = dictMode == ZSTD_dictMatchState; + const int isDDS = dictMode == ZSTD_dedicatedDictSearch; + const int isDxS = isDMS || isDDS; const ZSTD_matchState_t* const dms = ms->dictMatchState; - const U32 dictLowestIndex = dictMode == ZSTD_dictMatchState ? - dms->window.dictLimit : 0; - const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ? - dms->window.base : NULL; - const BYTE* const dictLowest = dictMode == ZSTD_dictMatchState ? - dictBase + dictLowestIndex : NULL; - const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ? - dms->window.nextSrc : NULL; - const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ? + const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0; + const BYTE* const dictBase = isDxS ? dms->window.base : NULL; + const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL; + const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL; + const U32 dictIndexDelta = isDxS ? prefixLowestIndex - (U32)(dictEnd - dictBase) : 0; const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest)); + assert(searchMax != NULL); + DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u)", (U32)dictMode); /* init */ ip += (dictAndPrefixLength == 0); if (dictMode == ZSTD_noDict) { - U32 const current = (U32)(ip - base); - U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, ms->cParams.windowLog); - U32 const maxRep = current - windowLow; + U32 const curr = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog); + U32 const maxRep = curr - windowLow; if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0; if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0; } - if (dictMode == ZSTD_dictMatchState) { + if (isDxS) { /* dictMatchState repCode checks don't currently handle repCode == 0 * disabling. */ assert(offset_1 <= dictAndPrefixLength); @@ -693,9 +946,9 @@ ZSTD_compressBlock_lazy_generic( const BYTE* start=ip+1; /* check repCode */ - if (dictMode == ZSTD_dictMatchState) { + if (isDxS) { const U32 repIndex = (U32)(ip - base) + 1 - offset_1; - const BYTE* repMatch = (dictMode == ZSTD_dictMatchState + const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch) && repIndex < prefixLowestIndex) ? dictBase + (repIndex - dictIndexDelta) : base + repIndex; @@ -736,7 +989,7 @@ ZSTD_compressBlock_lazy_generic( if ((mlRep >= 4) && (gain2 > gain1)) matchLength = mlRep, offset = 0, start = ip; } - if (dictMode == ZSTD_dictMatchState) { + if (isDxS) { const U32 repIndex = (U32)(ip - base) - offset_1; const BYTE* repMatch = repIndex < prefixLowestIndex ? dictBase + (repIndex - dictIndexDelta) : @@ -771,7 +1024,7 @@ ZSTD_compressBlock_lazy_generic( if ((mlRep >= 4) && (gain2 > gain1)) matchLength = mlRep, offset = 0, start = ip; } - if (dictMode == ZSTD_dictMatchState) { + if (isDxS) { const U32 repIndex = (U32)(ip - base) - offset_1; const BYTE* repMatch = repIndex < prefixLowestIndex ? dictBase + (repIndex - dictIndexDelta) : @@ -809,7 +1062,7 @@ ZSTD_compressBlock_lazy_generic( && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */ { start--; matchLength++; } } - if (dictMode == ZSTD_dictMatchState) { + if (isDxS) { U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE)); const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex; const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest; @@ -825,12 +1078,11 @@ _storeSequence: } /* check immediate repcode */ - if (dictMode == ZSTD_dictMatchState) { + if (isDxS) { while (ip <= ilimit) { U32 const current2 = (U32)(ip-base); U32 const repIndex = current2 - offset_2; - const BYTE* repMatch = dictMode == ZSTD_dictMatchState - && repIndex < prefixLowestIndex ? + const BYTE* repMatch = repIndex < prefixLowestIndex ? dictBase - dictIndexDelta + repIndex : base + repIndex; if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */) @@ -925,6 +1177,28 @@ size_t ZSTD_compressBlock_greedy_dictMatchState( } +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch); +} + + FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_lazy_extDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, @@ -968,11 +1242,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( size_t matchLength=0; size_t offset=0; const BYTE* start=ip+1; - U32 current = (U32)(ip-base); + U32 curr = (U32)(ip-base); /* check repCode */ - { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current+1, windowLog); - const U32 repIndex = (U32)(current+1 - offset_1); + { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog); + const U32 repIndex = (U32)(curr+1 - offset_1); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */ @@ -999,11 +1273,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( if (depth>=1) while (ip<ilimit) { ip ++; - current++; + curr++; /* check repCode */ if (offset) { - const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current, windowLog); - const U32 repIndex = (U32)(current - offset_1); + const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog); + const U32 repIndex = (U32)(curr - offset_1); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */ @@ -1030,11 +1304,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( /* let's find an even better one */ if ((depth==2) && (ip<ilimit)) { ip ++; - current++; + curr++; /* check repCode */ if (offset) { - const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current, windowLog); - const U32 repIndex = (U32)(current - offset_1); + const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog); + const U32 repIndex = (U32)(curr - offset_1); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */ diff --git a/thirdparty/zstd/compress/zstd_lazy.h b/thirdparty/zstd/compress/zstd_lazy.h index 581936f03b..d0214d5e73 100644 --- a/thirdparty/zstd/compress/zstd_lazy.h +++ b/thirdparty/zstd/compress/zstd_lazy.h @@ -17,8 +17,18 @@ extern "C" { #include "zstd_compress_internal.h" +/** + * Dedicated Dictionary Search Structure bucket log. In the + * ZSTD_dedicatedDictSearch mode, the hashTable has + * 2 ** ZSTD_LAZY_DDSS_BUCKET_LOG entries in each bucket, rather than just + * one. + */ +#define ZSTD_LAZY_DDSS_BUCKET_LOG 2 + U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip); +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip); + void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */ size_t ZSTD_compressBlock_btlazy2( @@ -47,6 +57,16 @@ size_t ZSTD_compressBlock_greedy_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + size_t ZSTD_compressBlock_greedy_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); diff --git a/thirdparty/zstd/compress/zstd_ldm.c b/thirdparty/zstd/compress/zstd_ldm.c index 8c47948358..3f3d7c46ab 100644 --- a/thirdparty/zstd/compress/zstd_ldm.c +++ b/thirdparty/zstd/compress/zstd_ldm.c @@ -27,13 +27,6 @@ void ZSTD_ldm_adjustParameters(ldmParams_t* params, DEBUGLOG(4, "ZSTD_ldm_adjustParameters"); if (!params->bucketSizeLog) params->bucketSizeLog = LDM_BUCKET_SIZE_LOG; if (!params->minMatchLength) params->minMatchLength = LDM_MIN_MATCH_LENGTH; - if (cParams->strategy >= ZSTD_btopt) { - /* Get out of the way of the optimal parser */ - U32 const minMatch = MAX(cParams->targetLength, params->minMatchLength); - assert(minMatch >= ZSTD_LDM_MINMATCH_MIN); - assert(minMatch <= ZSTD_LDM_MINMATCH_MAX); - params->minMatchLength = minMatch; - } if (params->hashLog == 0) { params->hashLog = MAX(ZSTD_HASHLOG_MIN, params->windowLog - LDM_HASH_RLOG); assert(params->hashLog <= ZSTD_HASHLOG_MAX); @@ -150,10 +143,10 @@ static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState, * We count only bytes where pMatch >= pBase and pIn >= pAnchor. */ static size_t ZSTD_ldm_countBackwardsMatch( const BYTE* pIn, const BYTE* pAnchor, - const BYTE* pMatch, const BYTE* pBase) + const BYTE* pMatch, const BYTE* pMatchBase) { size_t matchLength = 0; - while (pIn > pAnchor && pMatch > pBase && pIn[-1] == pMatch[-1]) { + while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) { pIn--; pMatch--; matchLength++; @@ -161,6 +154,27 @@ static size_t ZSTD_ldm_countBackwardsMatch( return matchLength; } +/** ZSTD_ldm_countBackwardsMatch_2segments() : + * Returns the number of bytes that match backwards from pMatch, + * even with the backwards match spanning 2 different segments. + * + * On reaching `pMatchBase`, start counting from mEnd */ +static size_t ZSTD_ldm_countBackwardsMatch_2segments( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase, + const BYTE* pExtDictStart, const BYTE* pExtDictEnd) +{ + size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase); + if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) { + /* If backwards match is entirely in the extDict or prefix, immediately return */ + return matchLength; + } + DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength); + matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart); + DEBUGLOG(7, "final backwards match length = %zu", matchLength); + return matchLength; +} + /** ZSTD_ldm_fillFastTables() : * * Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies. @@ -246,10 +260,10 @@ void ZSTD_ldm_fillHashTable( * (after a long match, only update tables a limited amount). */ static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor) { - U32 const current = (U32)(anchor - ms->window.base); - if (current > ms->nextToUpdate + 1024) { + U32 const curr = (U32)(anchor - ms->window.base); + if (curr > ms->nextToUpdate + 1024) { ms->nextToUpdate = - current - MIN(512, current - ms->nextToUpdate - 1024); + curr - MIN(512, curr - ms->nextToUpdate - 1024); } } @@ -286,7 +300,7 @@ static size_t ZSTD_ldm_generateSequences_internal( while (ip <= ilimit) { size_t mLength; - U32 const current = (U32)(ip - base); + U32 const curr = (U32)(ip - base); size_t forwardMatchLength = 0, backwardMatchLength = 0; ldmEntry_t* bestEntry = NULL; if (ip != istart) { @@ -336,8 +350,9 @@ static size_t ZSTD_ldm_generateSequences_internal( continue; } curBackwardMatchLength = - ZSTD_ldm_countBackwardsMatch(ip, anchor, pMatch, - lowMatchPtr); + ZSTD_ldm_countBackwardsMatch_2segments(ip, anchor, + pMatch, lowMatchPtr, + dictStart, dictEnd); curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength; } else { /* !extDict */ @@ -365,7 +380,7 @@ static size_t ZSTD_ldm_generateSequences_internal( /* No match found -- continue searching */ if (bestEntry == NULL) { ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, - hBits, current, + hBits, curr, *params); ip++; continue; @@ -377,11 +392,11 @@ static size_t ZSTD_ldm_generateSequences_internal( { /* Store the sequence: - * ip = current - backwardMatchLength + * ip = curr - backwardMatchLength * The match is at (bestEntry->offset - backwardMatchLength) */ U32 const matchIndex = bestEntry->offset; - U32 const offset = current - matchIndex; + U32 const offset = curr - matchIndex; rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size; /* Out of sequence storage */ @@ -562,6 +577,23 @@ static rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore, return sequence; } +void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) { + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -577,6 +609,15 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, BYTE const* ip = istart; DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize); + /* If using opt parser, use LDMs only as candidates rather than always accepting them */ + if (cParams->strategy >= ZSTD_btopt) { + size_t lastLLSize; + ms->ldmSeqStore = rawSeqStore; + lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize); + ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize); + return lastLLSize; + } + assert(rawSeqStore->pos <= rawSeqStore->size); assert(rawSeqStore->size <= rawSeqStore->capacity); /* Loop through each sequence and apply the block compressor to the lits */ diff --git a/thirdparty/zstd/compress/zstd_ldm.h b/thirdparty/zstd/compress/zstd_ldm.h index 229ea05a9e..6561024e4c 100644 --- a/thirdparty/zstd/compress/zstd_ldm.h +++ b/thirdparty/zstd/compress/zstd_ldm.h @@ -78,6 +78,12 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch); +/* ZSTD_ldm_skipRawSeqStoreBytes(): + * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'. + * Not to be used in conjunction with ZSTD_ldm_skipSequences(). + * Must be called for data with is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes); /** ZSTD_ldm_getTableSize() : * Estimate the space needed for long distance matching tables or 0 if LDM is diff --git a/thirdparty/zstd/compress/zstd_opt.c b/thirdparty/zstd/compress/zstd_opt.c index 36fff050cf..e55c459deb 100644 --- a/thirdparty/zstd/compress/zstd_opt.c +++ b/thirdparty/zstd/compress/zstd_opt.c @@ -386,32 +386,32 @@ static U32 ZSTD_insertBt1( const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; const BYTE* match; - const U32 current = (U32)(ip-base); - const U32 btLow = btMask >= current ? 0 : current - btMask; - U32* smallerPtr = bt + 2*(current&btMask); + const U32 curr = (U32)(ip-base); + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + U32* smallerPtr = bt + 2*(curr&btMask); U32* largerPtr = smallerPtr + 1; U32 dummy32; /* to be nullified at the end */ U32 const windowLow = ms->window.lowLimit; - U32 matchEndIdx = current+8+1; + U32 matchEndIdx = curr+8+1; size_t bestLength = 8; U32 nbCompares = 1U << cParams->searchLog; #ifdef ZSTD_C_PREDICT - U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0); - U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1); + U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0); + U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1); predictedSmall += (predictedSmall>0); predictedLarge += (predictedLarge>0); #endif /* ZSTD_C_PREDICT */ - DEBUGLOG(8, "ZSTD_insertBt1 (%u)", current); + DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr); assert(ip <= iend-8); /* required for h calculation */ - hashTable[h] = current; /* Update Hash Table */ + hashTable[h] = curr; /* Update Hash Table */ assert(windowLow > 0); while (nbCompares-- && (matchIndex >= windowLow)) { U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ - assert(matchIndex < current); + assert(matchIndex < curr); #ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */ const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */ @@ -474,8 +474,8 @@ static U32 ZSTD_insertBt1( *smallerPtr = *largerPtr = 0; { U32 positions = 0; if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */ - assert(matchEndIdx > current + 8); - return MAX(positions, matchEndIdx - (current + 8)); + assert(matchEndIdx > curr + 8); + return MAX(positions, matchEndIdx - (curr + 8)); } } @@ -519,7 +519,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( const ZSTD_compressionParameters* const cParams = &ms->cParams; U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); const BYTE* const base = ms->window.base; - U32 const current = (U32)(ip-base); + U32 const curr = (U32)(ip-base); U32 const hashLog = cParams->hashLog; U32 const minMatch = (mls==3) ? 3 : 4; U32* const hashTable = ms->hashTable; @@ -533,12 +533,12 @@ U32 ZSTD_insertBtAndGetAllMatches ( U32 const dictLimit = ms->window.dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; - U32 const btLow = (btMask >= current) ? 0 : current - btMask; - U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog); + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); U32 const matchLow = windowLow ? windowLow : 1; - U32* smallerPtr = bt + 2*(current&btMask); - U32* largerPtr = bt + 2*(current&btMask) + 1; - U32 matchEndIdx = current+8+1; /* farthest referenced position of any match => detects repetitive patterns */ + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */ U32 dummy32; /* to be nullified at the end */ U32 mnum = 0; U32 nbCompares = 1U << cParams->searchLog; @@ -557,7 +557,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit; size_t bestLength = lengthToBeat-1; - DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", current); + DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr); /* check repCode */ assert(ll0 <= 1); /* necessarily 1 or 0 */ @@ -565,29 +565,29 @@ U32 ZSTD_insertBtAndGetAllMatches ( U32 repCode; for (repCode = ll0; repCode < lastR; repCode++) { U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; - U32 const repIndex = current - repOffset; + U32 const repIndex = curr - repOffset; U32 repLen = 0; - assert(current >= dictLimit); - if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < current-dictLimit) { /* equivalent to `current > repIndex >= dictLimit` */ + assert(curr >= dictLimit); + if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */ /* We must validate the repcode offset because when we're using a dictionary the * valid offset range shrinks when the dictionary goes out of bounds. */ if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) { repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch; } - } else { /* repIndex < dictLimit || repIndex >= current */ + } else { /* repIndex < dictLimit || repIndex >= curr */ const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ? dmsBase + repIndex - dmsIndexDelta : dictBase + repIndex; - assert(current >= windowLow); + assert(curr >= windowLow); if ( dictMode == ZSTD_extDict - && ( ((repOffset-1) /*intentional overflow*/ < current - windowLow) /* equivalent to `current > repIndex >= windowLow` */ + && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */ & (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */) && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch; } if (dictMode == ZSTD_dictMatchState - && ( ((repOffset-1) /*intentional overflow*/ < current - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `current > repIndex >= dmsLowLimit` */ + && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */ & ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */ && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch; @@ -609,7 +609,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( if ((mls == 3) /*static*/ && (bestLength < mls)) { U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip); if ((matchIndex3 >= matchLow) - & (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) { + & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) { size_t mlen; if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) { const BYTE* const match = base + matchIndex3; @@ -624,26 +624,26 @@ U32 ZSTD_insertBtAndGetAllMatches ( DEBUGLOG(8, "found small match with hlog3, of length %u", (U32)mlen); bestLength = mlen; - assert(current > matchIndex3); + assert(curr > matchIndex3); assert(mnum==0); /* no prior solution */ - matches[0].off = (current - matchIndex3) + ZSTD_REP_MOVE; + matches[0].off = (curr - matchIndex3) + ZSTD_REP_MOVE; matches[0].len = (U32)mlen; mnum = 1; if ( (mlen > sufficient_len) | (ip+mlen == iLimit) ) { /* best possible length */ - ms->nextToUpdate = current+1; /* skip insertion */ + ms->nextToUpdate = curr+1; /* skip insertion */ return 1; } } } /* no dictMatchState lookup: dicts don't have a populated HC3 table */ } - hashTable[h] = current; /* Update Hash Table */ + hashTable[h] = curr; /* Update Hash Table */ while (nbCompares-- && (matchIndex >= matchLow)) { U32* const nextPtr = bt + 2*(matchIndex & btMask); const BYTE* match; size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ - assert(current > matchIndex); + assert(curr > matchIndex); if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) { assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */ @@ -660,12 +660,12 @@ U32 ZSTD_insertBtAndGetAllMatches ( if (matchLength > bestLength) { DEBUGLOG(8, "found match of length %u at distance %u (offCode=%u)", - (U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE); + (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE); assert(matchEndIdx > matchIndex); if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; bestLength = matchLength; - matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE; + matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE; matches[mnum].len = (U32)matchLength; mnum++; if ( (matchLength > ZSTD_OPT_NUM) @@ -708,11 +708,11 @@ U32 ZSTD_insertBtAndGetAllMatches ( if (matchLength > bestLength) { matchIndex = dictMatchIndex + dmsIndexDelta; DEBUGLOG(8, "found dms match of length %u at distance %u (offCode=%u)", - (U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE); + (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE); if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; bestLength = matchLength; - matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE; + matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE; matches[mnum].len = (U32)matchLength; mnum++; if ( (matchLength > ZSTD_OPT_NUM) @@ -733,7 +733,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( } } - assert(matchEndIdx > current+8); + assert(matchEndIdx > curr+8); ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ return mnum; } @@ -764,6 +764,140 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches ( } } +/************************* +* LDM helper functions * +*************************/ + +/* Struct containing info needed to make decision about ldm inclusion */ +typedef struct { + rawSeqStore_t seqStore; /* External match candidates store for this block */ + U32 startPosInBlock; /* Start position of the current match candidate */ + U32 endPosInBlock; /* End position of the current match candidate */ + U32 offset; /* Offset of the match candidate */ +} ZSTD_optLdm_t; + +/* ZSTD_optLdm_skipRawSeqStoreBytes(): + * Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'. + */ +static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) { + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +/* ZSTD_opt_getNextMatchAndUpdateSeqStore(): + * Calculates the beginning and end of the next match in the current block. + * Updates 'pos' and 'posInSequence' of the ldmSeqStore. + */ +static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 blockBytesRemaining) { + rawSeq currSeq; + U32 currBlockEndPos; + U32 literalsBytesRemaining; + U32 matchBytesRemaining; + + /* Setting match end position to MAX to ensure we never use an LDM during this block */ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + return; + } + /* Calculate appropriate bytes left in matchLength and litLength after adjusting + based on ldmSeqStore->posInSequence */ + currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos]; + assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength); + currBlockEndPos = currPosInBlock + blockBytesRemaining; + literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ? + currSeq.litLength - (U32)optLdm->seqStore.posInSequence : + 0; + matchBytesRemaining = (literalsBytesRemaining == 0) ? + currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) : + currSeq.matchLength; + + /* If there are more literal bytes than bytes remaining in block, no ldm is possible */ + if (literalsBytesRemaining >= blockBytesRemaining) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining); + return; + } + + /* Matches may be < MINMATCH by this process. In that case, we will reject them + when we are deciding whether or not to add the ldm */ + optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining; + optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining; + optLdm->offset = currSeq.offset; + + if (optLdm->endPosInBlock > currBlockEndPos) { + /* Match ends after the block ends, we can't use the whole match */ + optLdm->endPosInBlock = currBlockEndPos; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock); + } else { + /* Consume nb of bytes equal to size of sequence left */ + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining); + } +} + +/* ZSTD_optLdm_maybeAddMatch(): + * Adds a match if it's long enough, based on it's 'matchStartPosInBlock' + * and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches' + */ +static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches, + ZSTD_optLdm_t* optLdm, U32 currPosInBlock) { + U32 posDiff = currPosInBlock - optLdm->startPosInBlock; + /* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */ + U32 candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff; + U32 candidateOffCode = optLdm->offset + ZSTD_REP_MOVE; + + /* Ensure that current block position is not outside of the match */ + if (currPosInBlock < optLdm->startPosInBlock + || currPosInBlock >= optLdm->endPosInBlock + || candidateMatchLength < MINMATCH) { + return; + } + + if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) { + DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u", + candidateOffCode, candidateMatchLength, currPosInBlock); + matches[*nbMatches].len = candidateMatchLength; + matches[*nbMatches].off = candidateOffCode; + (*nbMatches)++; + } +} + +/* ZSTD_optLdm_processMatchCandidate(): + * Wrapper function to update ldm seq store and call ldm functions as necessary. + */ +static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches, + U32 currPosInBlock, U32 remainingBytes) { + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + return; + } + + if (currPosInBlock >= optLdm->endPosInBlock) { + if (currPosInBlock > optLdm->endPosInBlock) { + /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily + * at the end of a match from the ldm seq store, and will often be some bytes + * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots" + */ + U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot); + } + ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes); + } + ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock); +} /*-******************************* * Optimal parser @@ -817,6 +951,11 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, ZSTD_optimal_t* const opt = optStatePtr->priceTable; ZSTD_match_t* const matches = optStatePtr->matchTable; ZSTD_optimal_t lastSequence; + ZSTD_optLdm_t optLdm; + + optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore; + optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0; + ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip)); /* init */ DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u", @@ -832,7 +971,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, /* find first match */ { U32 const litlen = (U32)(ip - anchor); U32 const ll0 = !litlen; - U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch); + U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch); + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(ip-istart), (U32)(iend - ip)); if (!nbMatches) { ip++; continue; } /* initialize opt[0] */ @@ -925,9 +1066,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, if (opt[cur].mlen != 0) { U32 const prev = cur - opt[cur].mlen; repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0); - memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t)); + ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t)); } else { - memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t)); + ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t)); } /* last match must start at a minimum distance of 8 from oend */ @@ -945,8 +1086,12 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0; U32 const previousPrice = opt[cur].price; U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel); - U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch); + U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch); U32 matchNb; + + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(inr-istart), (U32)(iend-inr)); + if (!nbMatches) { DEBUGLOG(7, "rPos:%u : no match found", cur); continue; @@ -1010,9 +1155,9 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ */ if (lastSequence.mlen != 0) { repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0); - memcpy(rep, &reps, sizeof(reps)); + ZSTD_memcpy(rep, &reps, sizeof(reps)); } else { - memcpy(rep, opt[cur].rep, sizeof(repcodes_t)); + ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t)); } { U32 const storeEnd = cur + 1; @@ -1110,7 +1255,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms, const void* src, size_t srcSize) { U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */ - memcpy(tmpRep, rep, sizeof(tmpRep)); + ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep)); DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize); assert(ms->opt.litLengthSum == 0); /* first block */ @@ -1143,7 +1288,7 @@ size_t ZSTD_compressBlock_btultra2( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { - U32 const current = (U32)((const BYTE*)src - ms->window.base); + U32 const curr = (U32)((const BYTE*)src - ms->window.base); DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize); /* 2-pass strategy: @@ -1158,7 +1303,7 @@ size_t ZSTD_compressBlock_btultra2( if ( (ms->opt.litLengthSum==0) /* first block */ && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */ && (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */ - && (current == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */ + && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */ && (srcSize > ZSTD_PREDEF_THRESHOLD) ) { ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize); diff --git a/thirdparty/zstd/compress/zstdmt_compress.c b/thirdparty/zstd/compress/zstdmt_compress.c index 1e3c8fdbee..50454a50b9 100644 --- a/thirdparty/zstd/compress/zstdmt_compress.c +++ b/thirdparty/zstd/compress/zstdmt_compress.c @@ -20,8 +20,7 @@ /* ====== Dependencies ====== */ -#include <string.h> /* memcpy, memset */ -#include <limits.h> /* INT_MAX, UINT_MAX */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset, INT_MAX, UINT_MAX */ #include "../common/mem.h" /* MEM_STATIC */ #include "../common/pool.h" /* threadpool */ #include "../common/threading.h" /* mutex */ @@ -106,11 +105,11 @@ typedef struct ZSTDMT_bufferPool_s { static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbWorkers, ZSTD_customMem cMem) { unsigned const maxNbBuffers = 2*nbWorkers + 3; - ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_calloc( + ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_customCalloc( sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem); if (bufPool==NULL) return NULL; if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) { - ZSTD_free(bufPool, cMem); + ZSTD_customFree(bufPool, cMem); return NULL; } bufPool->bufferSize = 64 KB; @@ -127,10 +126,10 @@ static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool) if (!bufPool) return; /* compatibility with free on NULL */ for (u=0; u<bufPool->totalBuffers; u++) { DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->bTable[u].start); - ZSTD_free(bufPool->bTable[u].start, bufPool->cMem); + ZSTD_customFree(bufPool->bTable[u].start, bufPool->cMem); } ZSTD_pthread_mutex_destroy(&bufPool->poolMutex); - ZSTD_free(bufPool, bufPool->cMem); + ZSTD_customFree(bufPool, bufPool->cMem); } /* only works at initialization, not during compression */ @@ -201,13 +200,13 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool) } /* size conditions not respected : scratch this buffer, create new one */ DEBUGLOG(5, "ZSTDMT_getBuffer: existing buffer does not meet size conditions => freeing"); - ZSTD_free(buf.start, bufPool->cMem); + ZSTD_customFree(buf.start, bufPool->cMem); } ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); /* create new buffer */ DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer"); { buffer_t buffer; - void* const start = ZSTD_malloc(bSize, bufPool->cMem); + void* const start = ZSTD_customMalloc(bSize, bufPool->cMem); buffer.start = start; /* note : start can be NULL if malloc fails ! */ buffer.capacity = (start==NULL) ? 0 : bSize; if (start==NULL) { @@ -229,13 +228,13 @@ static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer) { size_t const bSize = bufPool->bufferSize; if (buffer.capacity < bSize) { - void* const start = ZSTD_malloc(bSize, bufPool->cMem); + void* const start = ZSTD_customMalloc(bSize, bufPool->cMem); buffer_t newBuffer; newBuffer.start = start; newBuffer.capacity = start == NULL ? 0 : bSize; if (start != NULL) { assert(newBuffer.capacity >= buffer.capacity); - memcpy(newBuffer.start, buffer.start, buffer.capacity); + ZSTD_memcpy(newBuffer.start, buffer.start, buffer.capacity); DEBUGLOG(5, "ZSTDMT_resizeBuffer: created buffer of size %u", (U32)bSize); return newBuffer; } @@ -261,14 +260,12 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf) ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); /* Reached bufferPool capacity (should not happen) */ DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing "); - ZSTD_free(buf.start, bufPool->cMem); + ZSTD_customFree(buf.start, bufPool->cMem); } /* ===== Seq Pool Wrapper ====== */ -static rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0}; - typedef ZSTDMT_bufferPool ZSTDMT_seqPool; static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool) @@ -278,7 +275,7 @@ static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool) static rawSeqStore_t bufferToSeq(buffer_t buffer) { - rawSeqStore_t seq = {NULL, 0, 0, 0}; + rawSeqStore_t seq = kNullRawSeqStore; seq.seq = (rawSeq*)buffer.start; seq.capacity = buffer.capacity / sizeof(rawSeq); return seq; @@ -354,7 +351,7 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool) for (cid=0; cid<pool->totalCCtx; cid++) ZSTD_freeCCtx(pool->cctx[cid]); /* note : compatible with free on NULL */ ZSTD_pthread_mutex_destroy(&pool->poolMutex); - ZSTD_free(pool, pool->cMem); + ZSTD_customFree(pool, pool->cMem); } /* ZSTDMT_createCCtxPool() : @@ -362,12 +359,12 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool) static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers, ZSTD_customMem cMem) { - ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc( + ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_customCalloc( sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem); assert(nbWorkers > 0); if (!cctxPool) return NULL; if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) { - ZSTD_free(cctxPool, cMem); + ZSTD_customFree(cctxPool, cMem); return NULL; } cctxPool->cMem = cMem; @@ -478,7 +475,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState, serialState->ldmState.hashPower = ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength); } else { - memset(¶ms.ldmParams, 0, sizeof(params.ldmParams)); + ZSTD_memset(¶ms.ldmParams, 0, sizeof(params.ldmParams)); } serialState->nextJobID = 0; if (params.fParams.checksumFlag) @@ -499,18 +496,18 @@ ZSTDMT_serialState_reset(serialState_t* serialState, ZSTD_window_init(&serialState->ldmState.window); /* Resize tables and output space if necessary. */ if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) { - ZSTD_free(serialState->ldmState.hashTable, cMem); - serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_malloc(hashSize, cMem); + ZSTD_customFree(serialState->ldmState.hashTable, cMem); + serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_customMalloc(hashSize, cMem); } if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) { - ZSTD_free(serialState->ldmState.bucketOffsets, cMem); - serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_malloc(bucketSize, cMem); + ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem); + serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(bucketSize, cMem); } if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets) return 1; /* Zero the tables */ - memset(serialState->ldmState.hashTable, 0, hashSize); - memset(serialState->ldmState.bucketOffsets, 0, bucketSize); + ZSTD_memset(serialState->ldmState.hashTable, 0, hashSize); + ZSTD_memset(serialState->ldmState.bucketOffsets, 0, bucketSize); /* Update window state and fill hash table with dict */ serialState->ldmState.loadedDictEnd = 0; @@ -537,7 +534,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState, static int ZSTDMT_serialState_init(serialState_t* serialState) { int initError = 0; - memset(serialState, 0, sizeof(*serialState)); + ZSTD_memset(serialState, 0, sizeof(*serialState)); initError |= ZSTD_pthread_mutex_init(&serialState->mutex, NULL); initError |= ZSTD_pthread_cond_init(&serialState->cond, NULL); initError |= ZSTD_pthread_mutex_init(&serialState->ldmWindowMutex, NULL); @@ -552,8 +549,8 @@ static void ZSTDMT_serialState_free(serialState_t* serialState) ZSTD_pthread_cond_destroy(&serialState->cond); ZSTD_pthread_mutex_destroy(&serialState->ldmWindowMutex); ZSTD_pthread_cond_destroy(&serialState->ldmWindowCond); - ZSTD_free(serialState->ldmState.hashTable, cMem); - ZSTD_free(serialState->ldmState.bucketOffsets, cMem); + ZSTD_customFree(serialState->ldmState.hashTable, cMem); + ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem); } static void ZSTDMT_serialState_update(serialState_t* serialState, @@ -820,7 +817,6 @@ struct ZSTDMT_CCtx_s { roundBuff_t roundBuff; serialState_t serial; rsyncState_t rsync; - unsigned singleBlockingThread; unsigned jobIDMask; unsigned doneJobID; unsigned nextJobID; @@ -832,6 +828,7 @@ struct ZSTDMT_CCtx_s { ZSTD_customMem cMem; ZSTD_CDict* cdictLocal; const ZSTD_CDict* cdict; + unsigned providedFactory: 1; }; static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZSTD_customMem cMem) @@ -842,7 +839,7 @@ static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZS ZSTD_pthread_mutex_destroy(&jobTable[jobNb].job_mutex); ZSTD_pthread_cond_destroy(&jobTable[jobNb].job_cond); } - ZSTD_free(jobTable, cMem); + ZSTD_customFree(jobTable, cMem); } /* ZSTDMT_allocJobsTable() @@ -854,7 +851,7 @@ static ZSTDMT_jobDescription* ZSTDMT_createJobsTable(U32* nbJobsPtr, ZSTD_custom U32 const nbJobs = 1 << nbJobsLog2; U32 jobNb; ZSTDMT_jobDescription* const jobTable = (ZSTDMT_jobDescription*) - ZSTD_calloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem); + ZSTD_customCalloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem); int initError = 0; if (jobTable==NULL) return NULL; *nbJobsPtr = nbJobs; @@ -885,12 +882,12 @@ static size_t ZSTDMT_expandJobsTable (ZSTDMT_CCtx* mtctx, U32 nbWorkers) { /* ZSTDMT_CCtxParam_setNbWorkers(): * Internal use only */ -size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers) +static size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers) { return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers); } -MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem) +MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool) { ZSTDMT_CCtx* mtctx; U32 nbJobs = nbWorkers + 2; @@ -903,12 +900,19 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, /* invalid custom allocator */ return NULL; - mtctx = (ZSTDMT_CCtx*) ZSTD_calloc(sizeof(ZSTDMT_CCtx), cMem); + mtctx = (ZSTDMT_CCtx*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtx), cMem); if (!mtctx) return NULL; ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers); mtctx->cMem = cMem; mtctx->allJobsCompleted = 1; - mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem); + if (pool != NULL) { + mtctx->factory = pool; + mtctx->providedFactory = 1; + } + else { + mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem); + mtctx->providedFactory = 0; + } mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem); assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0); /* ensure nbJobs is a power of 2 */ mtctx->jobIDMask = nbJobs - 1; @@ -925,22 +929,18 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, return mtctx; } -ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem) +ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool) { #ifdef ZSTD_MULTITHREAD - return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem); + return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem, pool); #else (void)nbWorkers; (void)cMem; + (void)pool; return NULL; #endif } -ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers) -{ - return ZSTDMT_createCCtx_advanced(nbWorkers, ZSTD_defaultCMem); -} - /* ZSTDMT_releaseAllJobResources() : * note : ensure all workers are killed first ! */ @@ -957,7 +957,7 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx) ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff); /* Clear the job description, but keep the mutex/cond */ - memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID])); + ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID])); mtctx->jobs[jobID].job_mutex = mutex; mtctx->jobs[jobID].job_cond = cond; } @@ -984,7 +984,8 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx) size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx) { if (mtctx==NULL) return 0; /* compatible with free on NULL */ - POOL_free(mtctx->factory); /* stop and free worker threads */ + if (!mtctx->providedFactory) + POOL_free(mtctx->factory); /* stop and free worker threads */ ZSTDMT_releaseAllJobResources(mtctx); /* release job resources into pools first */ ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem); ZSTDMT_freeBufferPool(mtctx->bufPool); @@ -993,8 +994,8 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx) ZSTDMT_serialState_free(&mtctx->serial); ZSTD_freeCDict(mtctx->cdictLocal); if (mtctx->roundBuff.buffer) - ZSTD_free(mtctx->roundBuff.buffer, mtctx->cMem); - ZSTD_free(mtctx, mtctx->cMem); + ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem); + ZSTD_customFree(mtctx, mtctx->cMem); return 0; } @@ -1011,65 +1012,6 @@ size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx) + mtctx->roundBuff.capacity; } -/* Internal only */ -size_t -ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, - ZSTDMT_parameter parameter, - int value) -{ - DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter"); - switch(parameter) - { - case ZSTDMT_p_jobSize : - DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter : set jobSize to %i", value); - return ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, value); - case ZSTDMT_p_overlapLog : - DEBUGLOG(4, "ZSTDMT_p_overlapLog : %i", value); - return ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, value); - case ZSTDMT_p_rsyncable : - DEBUGLOG(4, "ZSTD_p_rsyncable : %i", value); - return ZSTD_CCtxParams_setParameter(params, ZSTD_c_rsyncable, value); - default : - return ERROR(parameter_unsupported); - } -} - -size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value) -{ - DEBUGLOG(4, "ZSTDMT_setMTCtxParameter"); - return ZSTDMT_CCtxParam_setMTCtxParameter(&mtctx->params, parameter, value); -} - -size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value) -{ - switch (parameter) { - case ZSTDMT_p_jobSize: - return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_jobSize, value); - case ZSTDMT_p_overlapLog: - return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_overlapLog, value); - case ZSTDMT_p_rsyncable: - return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_rsyncable, value); - default: - return ERROR(parameter_unsupported); - } -} - -/* Sets parameters relevant to the compression job, - * initializing others to default values. */ -static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(const ZSTD_CCtx_params* params) -{ - ZSTD_CCtx_params jobParams = *params; - /* Clear parameters related to multithreading */ - jobParams.forceWindow = 0; - jobParams.nbWorkers = 0; - jobParams.jobSize = 0; - jobParams.overlapLog = 0; - jobParams.rsyncable = 0; - memset(&jobParams.ldmParams, 0, sizeof(ldmParams_t)); - memset(&jobParams.customMem, 0, sizeof(ZSTD_customMem)); - return jobParams; -} - /* ZSTDMT_resize() : * @return : error code if fails, 0 on success */ @@ -1098,7 +1040,7 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)", compressionLevel); mtctx->params.compressionLevel = compressionLevel; - { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0); + { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); cParams.windowLog = saved_wlog; mtctx->params.cParams = cParams; } @@ -1185,8 +1127,8 @@ static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params) if (params->ldmParams.enableLdm) { /* In Long Range Mode, the windowLog is typically oversized. * In which case, it's preferable to determine the jobSize - * based on chainLog instead. */ - jobLog = MAX(21, params->cParams.chainLog + 4); + * based on cycleLog instead. */ + jobLog = MAX(21, ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy) + 3); } else { jobLog = MAX(20, params->cParams.windowLog + 2); } @@ -1240,174 +1182,6 @@ static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params) return (ovLog==0) ? 0 : (size_t)1 << ovLog; } -static unsigned -ZSTDMT_computeNbJobs(const ZSTD_CCtx_params* params, size_t srcSize, unsigned nbWorkers) -{ - assert(nbWorkers>0); - { size_t const jobSizeTarget = (size_t)1 << ZSTDMT_computeTargetJobLog(params); - size_t const jobMaxSize = jobSizeTarget << 2; - size_t const passSizeMax = jobMaxSize * nbWorkers; - unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1; - unsigned const nbJobsLarge = multiplier * nbWorkers; - unsigned const nbJobsMax = (unsigned)(srcSize / jobSizeTarget) + 1; - unsigned const nbJobsSmall = MIN(nbJobsMax, nbWorkers); - return (multiplier>1) ? nbJobsLarge : nbJobsSmall; -} } - -/* ZSTDMT_compress_advanced_internal() : - * This is a blocking function : it will only give back control to caller after finishing its compression job. - */ -static size_t -ZSTDMT_compress_advanced_internal( - ZSTDMT_CCtx* mtctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_CDict* cdict, - ZSTD_CCtx_params params) -{ - ZSTD_CCtx_params const jobParams = ZSTDMT_initJobCCtxParams(¶ms); - size_t const overlapSize = ZSTDMT_computeOverlapSize(¶ms); - unsigned const nbJobs = ZSTDMT_computeNbJobs(¶ms, srcSize, params.nbWorkers); - size_t const proposedJobSize = (srcSize + (nbJobs-1)) / nbJobs; - size_t const avgJobSize = (((proposedJobSize-1) & 0x1FFFF) < 0x7FFF) ? proposedJobSize + 0xFFFF : proposedJobSize; /* avoid too small last block */ - const char* const srcStart = (const char*)src; - size_t remainingSrcSize = srcSize; - unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbJobs : (unsigned)(dstCapacity / ZSTD_compressBound(avgJobSize)); /* presumes avgJobSize >= 256 KB, which should be the case */ - size_t frameStartPos = 0, dstBufferPos = 0; - assert(jobParams.nbWorkers == 0); - assert(mtctx->cctxPool->totalCCtx == params.nbWorkers); - - params.jobSize = (U32)avgJobSize; - DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: nbJobs=%2u (rawSize=%u bytes; fixedSize=%u) ", - nbJobs, (U32)proposedJobSize, (U32)avgJobSize); - - if ((nbJobs==1) | (params.nbWorkers<=1)) { /* fallback to single-thread mode : this is a blocking invocation anyway */ - ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0]; - DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: fallback to single-thread mode"); - if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, jobParams.fParams); - return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, &jobParams); - } - - assert(avgJobSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), required to compress directly into Dst (no additional buffer) */ - ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgJobSize) ); - /* LDM doesn't even try to load the dictionary in single-ingestion mode */ - if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize, NULL, 0, ZSTD_dct_auto)) - return ERROR(memory_allocation); - - FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) , ""); /* only expands if necessary */ - - { unsigned u; - for (u=0; u<nbJobs; u++) { - size_t const jobSize = MIN(remainingSrcSize, avgJobSize); - size_t const dstBufferCapacity = ZSTD_compressBound(jobSize); - buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity }; - buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : g_nullBuffer; - size_t dictSize = u ? overlapSize : 0; - - mtctx->jobs[u].prefix.start = srcStart + frameStartPos - dictSize; - mtctx->jobs[u].prefix.size = dictSize; - mtctx->jobs[u].src.start = srcStart + frameStartPos; - mtctx->jobs[u].src.size = jobSize; assert(jobSize > 0); /* avoid job.src.size == 0 */ - mtctx->jobs[u].consumed = 0; - mtctx->jobs[u].cSize = 0; - mtctx->jobs[u].cdict = (u==0) ? cdict : NULL; - mtctx->jobs[u].fullFrameSize = srcSize; - mtctx->jobs[u].params = jobParams; - /* do not calculate checksum within sections, but write it in header for first section */ - mtctx->jobs[u].dstBuff = dstBuffer; - mtctx->jobs[u].cctxPool = mtctx->cctxPool; - mtctx->jobs[u].bufPool = mtctx->bufPool; - mtctx->jobs[u].seqPool = mtctx->seqPool; - mtctx->jobs[u].serial = &mtctx->serial; - mtctx->jobs[u].jobID = u; - mtctx->jobs[u].firstJob = (u==0); - mtctx->jobs[u].lastJob = (u==nbJobs-1); - - DEBUGLOG(5, "ZSTDMT_compress_advanced_internal: posting job %u (%u bytes)", u, (U32)jobSize); - DEBUG_PRINTHEX(6, mtctx->jobs[u].prefix.start, 12); - POOL_add(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[u]); - - frameStartPos += jobSize; - dstBufferPos += dstBufferCapacity; - remainingSrcSize -= jobSize; - } } - - /* collect result */ - { size_t error = 0, dstPos = 0; - unsigned jobID; - for (jobID=0; jobID<nbJobs; jobID++) { - DEBUGLOG(5, "waiting for job %u ", jobID); - ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex); - while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) { - DEBUGLOG(5, "waiting for jobCompleted signal from job %u", jobID); - ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex); - } - ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex); - DEBUGLOG(5, "ready to write job %u ", jobID); - - { size_t const cSize = mtctx->jobs[jobID].cSize; - if (ZSTD_isError(cSize)) error = cSize; - if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall); - if (jobID) { /* note : job 0 is written directly at dst, which is correct position */ - if (!error) - memmove((char*)dst + dstPos, mtctx->jobs[jobID].dstBuff.start, cSize); /* may overlap when job compressed within dst */ - if (jobID >= compressWithinDst) { /* job compressed into its own buffer, which must be released */ - DEBUGLOG(5, "releasing buffer %u>=%u", jobID, compressWithinDst); - ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff); - } } - mtctx->jobs[jobID].dstBuff = g_nullBuffer; - mtctx->jobs[jobID].cSize = 0; - dstPos += cSize ; - } - } /* for (jobID=0; jobID<nbJobs; jobID++) */ - - DEBUGLOG(4, "checksumFlag : %u ", params.fParams.checksumFlag); - if (params.fParams.checksumFlag) { - U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState); - if (dstPos + 4 > dstCapacity) { - error = ERROR(dstSize_tooSmall); - } else { - DEBUGLOG(4, "writing checksum : %08X \n", checksum); - MEM_writeLE32((char*)dst + dstPos, checksum); - dstPos += 4; - } } - - if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos); - return error ? error : dstPos; - } -} - -size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_CDict* cdict, - ZSTD_parameters params, - int overlapLog) -{ - ZSTD_CCtx_params cctxParams = mtctx->params; - cctxParams.cParams = params.cParams; - cctxParams.fParams = params.fParams; - assert(ZSTD_OVERLAPLOG_MIN <= overlapLog && overlapLog <= ZSTD_OVERLAPLOG_MAX); - cctxParams.overlapLog = overlapLog; - return ZSTDMT_compress_advanced_internal(mtctx, - dst, dstCapacity, - src, srcSize, - cdict, cctxParams); -} - - -size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - int compressionLevel) -{ - ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0); - int const overlapLog = ZSTDMT_overlapLog_default(params.cParams.strategy); - params.fParams.contentSizeFlag = 1; - return ZSTDMT_compress_advanced(mtctx, dst, dstCapacity, src, srcSize, NULL, params, overlapLog); -} - - /* ====================================== */ /* ======= Streaming API ======= */ /* ====================================== */ @@ -1432,16 +1206,6 @@ size_t ZSTDMT_initCStream_internal( if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN; if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX; - mtctx->singleBlockingThread = (pledgedSrcSize <= ZSTDMT_JOBSIZE_MIN); /* do not trigger multi-threading when srcSize is too small */ - if (mtctx->singleBlockingThread) { - ZSTD_CCtx_params const singleThreadParams = ZSTDMT_initJobCCtxParams(¶ms); - DEBUGLOG(5, "ZSTDMT_initCStream_internal: switch to single blocking thread mode"); - assert(singleThreadParams.nbWorkers == 0); - return ZSTD_initCStream_internal(mtctx->cctxPool->cctx[0], - dict, dictSize, cdict, - &singleThreadParams, pledgedSrcSize); - } - DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers); if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */ @@ -1504,8 +1268,8 @@ size_t ZSTDMT_initCStream_internal( size_t const capacity = MAX(windowSize, sectionsSize) + slackSize; if (mtctx->roundBuff.capacity < capacity) { if (mtctx->roundBuff.buffer) - ZSTD_free(mtctx->roundBuff.buffer, mtctx->cMem); - mtctx->roundBuff.buffer = (BYTE*)ZSTD_malloc(capacity, mtctx->cMem); + ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem); + mtctx->roundBuff.buffer = (BYTE*)ZSTD_customMalloc(capacity, mtctx->cMem); if (mtctx->roundBuff.buffer == NULL) { mtctx->roundBuff.capacity = 0; return ERROR(memory_allocation); @@ -1530,53 +1294,6 @@ size_t ZSTDMT_initCStream_internal( return 0; } -size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, - const void* dict, size_t dictSize, - ZSTD_parameters params, - unsigned long long pledgedSrcSize) -{ - ZSTD_CCtx_params cctxParams = mtctx->params; /* retrieve sticky params */ - DEBUGLOG(4, "ZSTDMT_initCStream_advanced (pledgedSrcSize=%u)", (U32)pledgedSrcSize); - cctxParams.cParams = params.cParams; - cctxParams.fParams = params.fParams; - return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, ZSTD_dct_auto, NULL, - cctxParams, pledgedSrcSize); -} - -size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx, - const ZSTD_CDict* cdict, - ZSTD_frameParameters fParams, - unsigned long long pledgedSrcSize) -{ - ZSTD_CCtx_params cctxParams = mtctx->params; - if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */ - cctxParams.cParams = ZSTD_getCParamsFromCDict(cdict); - cctxParams.fParams = fParams; - return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, ZSTD_dct_auto, cdict, - cctxParams, pledgedSrcSize); -} - - -/* ZSTDMT_resetCStream() : - * pledgedSrcSize can be zero == unknown (for the time being) - * prefer using ZSTD_CONTENTSIZE_UNKNOWN, - * as `0` might mean "empty" in the future */ -size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize) -{ - if (!pledgedSrcSize) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; - return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, 0, mtctx->params, - pledgedSrcSize); -} - -size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel) { - ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0); - ZSTD_CCtx_params cctxParams = mtctx->params; /* retrieve sticky params */ - DEBUGLOG(4, "ZSTDMT_initCStream (cLevel=%i)", compressionLevel); - cctxParams.cParams = params.cParams; - cctxParams.fParams = params.fParams; - return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN); -} - /* ZSTDMT_writeLastEmptyBlock() * Write a single empty block with an end-of-frame to finish a frame. @@ -1740,7 +1457,7 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u assert(cSize >= mtctx->jobs[wJobID].dstFlushed); assert(mtctx->jobs[wJobID].dstBuff.start != NULL); if (toFlush > 0) { - memcpy((char*)output->dst + output->pos, + ZSTD_memcpy((char*)output->dst + output->pos, (const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed, toFlush); } @@ -1894,7 +1611,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx) return 0; } ZSTDMT_waitForLdmComplete(mtctx, buffer); - memmove(start, mtctx->inBuff.prefix.start, prefixSize); + ZSTD_memmove(start, mtctx->inBuff.prefix.start, prefixSize); mtctx->inBuff.prefix.start = start; mtctx->roundBuff.pos = prefixSize; } @@ -1968,6 +1685,16 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) pos = 0; prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH; hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); + if ((hash & hitMask) == hitMask) { + /* We're already at a sync point so don't load any more until + * we're able to flush this sync point. + * This likely happened because the job table was full so we + * couldn't add our job. + */ + syncPoint.toLoad = 0; + syncPoint.flush = 1; + return syncPoint; + } } else { /* We don't have enough bytes buffered to initialize the hash, but * we know we have at least RSYNC_LENGTH bytes total. @@ -2022,34 +1749,11 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, assert(output->pos <= output->size); assert(input->pos <= input->size); - if (mtctx->singleBlockingThread) { /* delegate to single-thread (synchronous) */ - return ZSTD_compressStream2(mtctx->cctxPool->cctx[0], output, input, endOp); - } - if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) { /* current frame being ended. Only flush/end are allowed */ return ERROR(stage_wrong); } - /* single-pass shortcut (note : synchronous-mode) */ - if ( (!mtctx->params.rsyncable) /* rsyncable mode is disabled */ - && (mtctx->nextJobID == 0) /* just started */ - && (mtctx->inBuff.filled == 0) /* nothing buffered */ - && (!mtctx->jobReady) /* no job already created */ - && (endOp == ZSTD_e_end) /* end order */ - && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough space in dst */ - size_t const cSize = ZSTDMT_compress_advanced_internal(mtctx, - (char*)output->dst + output->pos, output->size - output->pos, - (const char*)input->src + input->pos, input->size - input->pos, - mtctx->cdict, mtctx->params); - if (ZSTD_isError(cSize)) return cSize; - input->pos = input->size; - output->pos += cSize; - mtctx->allJobsCompleted = 1; - mtctx->frameEnded = 1; - return 0; - } - /* fill input buffer */ if ( (!mtctx->jobReady) && (input->size > input->pos) ) { /* support NULL input */ @@ -2072,13 +1776,21 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, assert(mtctx->inBuff.buffer.capacity >= mtctx->targetSectionSize); DEBUGLOG(5, "ZSTDMT_compressStream_generic: adding %u bytes on top of %u to buffer of size %u", (U32)syncPoint.toLoad, (U32)mtctx->inBuff.filled, (U32)mtctx->targetSectionSize); - memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad); + ZSTD_memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad); input->pos += syncPoint.toLoad; mtctx->inBuff.filled += syncPoint.toLoad; forwardInputProgress = syncPoint.toLoad>0; } - if ((input->pos < input->size) && (endOp == ZSTD_e_end)) - endOp = ZSTD_e_flush; /* can't end now : not all input consumed */ + } + if ((input->pos < input->size) && (endOp == ZSTD_e_end)) { + /* Can't end yet because the input is not fully consumed. + * We are in one of these cases: + * - mtctx->inBuff is NULL & empty: we couldn't get an input buffer so don't create a new job. + * - We filled the input buffer: flush this job but don't end the frame. + * - We hit a synchronization point: flush this job but don't end the frame. + */ + assert(mtctx->inBuff.filled == 0 || mtctx->inBuff.filled == mtctx->targetSectionSize || mtctx->params.rsyncable); + endOp = ZSTD_e_flush; } if ( (mtctx->jobReady) @@ -2097,47 +1809,3 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, return remainingToFlush; } } - - -size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input) -{ - FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) , ""); - - /* recommended next input size : fill current input buffer */ - return mtctx->targetSectionSize - mtctx->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */ -} - - -static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_EndDirective endFrame) -{ - size_t const srcSize = mtctx->inBuff.filled; - DEBUGLOG(5, "ZSTDMT_flushStream_internal"); - - if ( mtctx->jobReady /* one job ready for a worker to pick up */ - || (srcSize > 0) /* still some data within input buffer */ - || ((endFrame==ZSTD_e_end) && !mtctx->frameEnded)) { /* need a last 0-size block to end frame */ - DEBUGLOG(5, "ZSTDMT_flushStream_internal : create a new job (%u bytes, end:%u)", - (U32)srcSize, (U32)endFrame); - FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) , ""); - } - - /* check if there is any data available to flush */ - return ZSTDMT_flushProduced(mtctx, output, 1 /* blockToFlush */, endFrame); -} - - -size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output) -{ - DEBUGLOG(5, "ZSTDMT_flushStream"); - if (mtctx->singleBlockingThread) - return ZSTD_flushStream(mtctx->cctxPool->cctx[0], output); - return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_flush); -} - -size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output) -{ - DEBUGLOG(4, "ZSTDMT_endStream"); - if (mtctx->singleBlockingThread) - return ZSTD_endStream(mtctx->cctxPool->cctx[0], output); - return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_end); -} diff --git a/thirdparty/zstd/compress/zstdmt_compress.h b/thirdparty/zstd/compress/zstdmt_compress.h index 89914eb7f8..0a9e551c99 100644 --- a/thirdparty/zstd/compress/zstdmt_compress.h +++ b/thirdparty/zstd/compress/zstdmt_compress.h @@ -19,26 +19,14 @@ /* Note : This is an internal API. * These APIs used to be exposed with ZSTDLIB_API, * because it used to be the only way to invoke MT compression. - * Now, it's recommended to use ZSTD_compress2 and ZSTD_compressStream2() - * instead. - * - * If you depend on these APIs and can't switch, then define - * ZSTD_LEGACY_MULTITHREADED_API when making the dynamic library. - * However, we may completely remove these functions in a future - * release, so please switch soon. + * Now, you must use ZSTD_compress2 and ZSTD_compressStream2() instead. * * This API requires ZSTD_MULTITHREAD to be defined during compilation, * otherwise ZSTDMT_createCCtx*() will fail. */ -#ifdef ZSTD_LEGACY_MULTITHREADED_API -# define ZSTDMT_API ZSTDLIB_API -#else -# define ZSTDMT_API -#endif - /* === Dependencies === */ -#include <stddef.h> /* size_t */ +#include "../common/zstd_deps.h" /* size_t */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */ #include "../zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */ @@ -54,78 +42,34 @@ #define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB)) +/* ======================================================== + * === Private interface, for use by ZSTD_compress.c === + * === Not exposed in libzstd. Never invoke directly === + * ======================================================== */ + /* === Memory management === */ typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx; /* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */ -ZSTDMT_API ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers); -/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */ -ZSTDMT_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, - ZSTD_customMem cMem); -ZSTDMT_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx); - -ZSTDMT_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx); - - -/* === Simple one-pass compression function === */ - -ZSTDMT_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - int compressionLevel); - +ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, + ZSTD_customMem cMem, + ZSTD_threadPool *pool); +size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx); +size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx); /* === Streaming functions === */ -ZSTDMT_API size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel); -ZSTDMT_API size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize); /**< if srcSize is not known at reset time, use ZSTD_CONTENTSIZE_UNKNOWN. Note: for compatibility with older programs, 0 means the same as ZSTD_CONTENTSIZE_UNKNOWN, but it will change in the future to mean "empty" */ - -ZSTDMT_API size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx); -ZSTDMT_API size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input); - -ZSTDMT_API size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */ -ZSTDMT_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */ - - -/* === Advanced functions and parameters === */ - -ZSTDMT_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_CDict* cdict, - ZSTD_parameters params, - int overlapLog); - -ZSTDMT_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, - const void* dict, size_t dictSize, /* dict can be released after init, a local copy is preserved within zcs */ - ZSTD_parameters params, - unsigned long long pledgedSrcSize); /* pledgedSrcSize is optional and can be zero == unknown */ - -ZSTDMT_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx, - const ZSTD_CDict* cdict, - ZSTD_frameParameters fparams, - unsigned long long pledgedSrcSize); /* note : zero means empty */ - -/* ZSTDMT_parameter : - * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */ -typedef enum { - ZSTDMT_p_jobSize, /* Each job is compressed in parallel. By default, this value is dynamically determined depending on compression parameters. Can be set explicitly here. */ - ZSTDMT_p_overlapLog, /* Each job may reload a part of previous job to enhance compression ratio; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window. This is a "sticky" parameter : its value will be re-used on next compression job */ - ZSTDMT_p_rsyncable /* Enables rsyncable mode. */ -} ZSTDMT_parameter; - -/* ZSTDMT_setMTCtxParameter() : - * allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter. - * The function must be called typically after ZSTD_createCCtx() but __before ZSTDMT_init*() !__ - * Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions. - * @return : 0, or an error code (which can be tested using ZSTD_isError()) */ -ZSTDMT_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value); - -/* ZSTDMT_getMTCtxParameter() : - * Query the ZSTDMT_CCtx for a parameter value. - * @return : 0, or an error code (which can be tested using ZSTD_isError()) */ -ZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value); +size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx); +/*! ZSTDMT_initCStream_internal() : + * Private use only. Init streaming operation. + * expects params to be valid. + * must receive dict, or cdict, or none, but not both. + * @return : 0, or an error code */ +size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, + const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, unsigned long long pledgedSrcSize); /*! ZSTDMT_compressStream_generic() : * Combines ZSTDMT_compressStream() with optional ZSTDMT_flushStream() or ZSTDMT_endStream() @@ -134,16 +78,10 @@ ZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter * 0 if fully flushed * or an error code * note : needs to be init using any ZSTD_initCStream*() variant */ -ZSTDMT_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, - ZSTD_outBuffer* output, - ZSTD_inBuffer* input, - ZSTD_EndDirective endOp); - - -/* ======================================================== - * === Private interface, for use by ZSTD_compress.c === - * === Not exposed in libzstd. Never invoke directly === - * ======================================================== */ +size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp); /*! ZSTDMT_toFlushNow() * Tell how many bytes are ready to be flushed immediately. @@ -153,15 +91,6 @@ ZSTDMT_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, * therefore flushing is limited by speed of oldest job. */ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx); -/*! ZSTDMT_CCtxParam_setMTCtxParameter() - * like ZSTDMT_setMTCtxParameter(), but into a ZSTD_CCtx_Params */ -size_t ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, int value); - -/*! ZSTDMT_CCtxParam_setNbWorkers() - * Set nbWorkers, and clamp it. - * Also reset jobSize and overlapLog */ -size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers); - /*! ZSTDMT_updateCParams_whileCompressing() : * Updates only a selected set of compression parameters, to remain compatible with current frame. * New parameters will be applied to next compression job. */ @@ -174,17 +103,6 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx); -/*! ZSTDMT_initCStream_internal() : - * Private use only. Init streaming operation. - * expects params to be valid. - * must receive dict, or cdict, or none, but not both. - * @return : 0, or an error code */ -size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, - const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, - const ZSTD_CDict* cdict, - ZSTD_CCtx_params params, unsigned long long pledgedSrcSize); - - #if defined (__cplusplus) } #endif diff --git a/thirdparty/zstd/decompress/huf_decompress.c b/thirdparty/zstd/decompress/huf_decompress.c index 68293a1309..1418206718 100644 --- a/thirdparty/zstd/decompress/huf_decompress.c +++ b/thirdparty/zstd/decompress/huf_decompress.c @@ -15,7 +15,7 @@ /* ************************************************************** * Dependencies ****************************************************************/ -#include <string.h> /* memcpy, memset */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ #include "../common/compiler.h" #include "../common/bitstream.h" /* BIT_* */ #include "../common/fse.h" /* to compress headers */ @@ -103,7 +103,7 @@ typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) { DTableDesc dtd; - memcpy(&dtd, table, sizeof(dtd)); + ZSTD_memcpy(&dtd, table, sizeof(dtd)); return dtd; } @@ -115,29 +115,51 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) /*-***************************/ typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */ +/** + * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at + * a time. + */ +static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) { + U64 D4; + if (MEM_isLittleEndian()) { + D4 = symbol + (nbBits << 8); + } else { + D4 = (symbol << 8) + nbBits; + } + D4 *= 0x0001000100010001ULL; + return D4; +} + +typedef struct { + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + BYTE symbols[HUF_SYMBOLVALUE_MAX + 1]; + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; +} HUF_ReadDTableX1_Workspace; + + size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) { + return HUF_readDTableX1_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0); +} + +size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2) +{ U32 tableLog = 0; U32 nbSymbols = 0; size_t iSize; void* const dtPtr = DTable + 1; HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr; + HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace; - U32* rankVal; - BYTE* huffWeight; - size_t spaceUsed32 = 0; - - rankVal = (U32 *)workSpace + spaceUsed32; - spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; - huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32); - spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - - if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); + DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp)); + if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge); DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); - /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ - iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); + iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2); if (HUF_isError(iSize)) return iSize; /* Table header */ @@ -145,52 +167,117 @@ size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ dtd.tableType = 0; dtd.tableLog = (BYTE)tableLog; - memcpy(DTable, &dtd, sizeof(dtd)); + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); } - /* Calculate starting value for each rank */ - { U32 n, nextRankStart = 0; - for (n=1; n<tableLog+1; n++) { - U32 const current = nextRankStart; - nextRankStart += (rankVal[n] << (n-1)); - rankVal[n] = current; - } } + /* Compute symbols and rankStart given rankVal: + * + * rankVal already contains the number of values of each weight. + * + * symbols contains the symbols ordered by weight. First are the rankVal[0] + * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on. + * symbols[0] is filled (but unused) to avoid a branch. + * + * rankStart contains the offset where each rank belongs in the DTable. + * rankStart[0] is not filled because there are no entries in the table for + * weight 0. + */ + { + int n; + int nextRankStart = 0; + int const unroll = 4; + int const nLimit = (int)nbSymbols - unroll + 1; + for (n=0; n<(int)tableLog+1; n++) { + U32 const curr = nextRankStart; + nextRankStart += wksp->rankVal[n]; + wksp->rankStart[n] = curr; + } + for (n=0; n < nLimit; n += unroll) { + int u; + for (u=0; u < unroll; ++u) { + size_t const w = wksp->huffWeight[n+u]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u); + } + } + for (; n < (int)nbSymbols; ++n) { + size_t const w = wksp->huffWeight[n]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)n; + } + } - /* fill DTable */ - { U32 n; - size_t const nEnd = nbSymbols; - for (n=0; n<nEnd; n++) { - size_t const w = huffWeight[n]; - size_t const length = (1 << w) >> 1; - size_t const uStart = rankVal[w]; - size_t const uEnd = uStart + length; - size_t u; - HUF_DEltX1 D; - D.byte = (BYTE)n; - D.nbBits = (BYTE)(tableLog + 1 - w); - rankVal[w] = (U32)uEnd; - if (length < 4) { - /* Use length in the loop bound so the compiler knows it is short. */ - for (u = 0; u < length; ++u) - dt[uStart + u] = D; - } else { - /* Unroll the loop 4 times, we know it is a power of 2. */ - for (u = uStart; u < uEnd; u += 4) { - dt[u + 0] = D; - dt[u + 1] = D; - dt[u + 2] = D; - dt[u + 3] = D; - } } } } + /* fill DTable + * We fill all entries of each weight in order. + * That way length is a constant for each iteration of the outter loop. + * We can switch based on the length to a different inner loop which is + * optimized for that particular case. + */ + { + U32 w; + int symbol=wksp->rankVal[0]; + int rankStart=0; + for (w=1; w<tableLog+1; ++w) { + int const symbolCount = wksp->rankVal[w]; + int const length = (1 << w) >> 1; + int uStart = rankStart; + BYTE const nbBits = (BYTE)(tableLog + 1 - w); + int s; + int u; + switch (length) { + case 1: + for (s=0; s<symbolCount; ++s) { + HUF_DEltX1 D; + D.byte = wksp->symbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart] = D; + uStart += 1; + } + break; + case 2: + for (s=0; s<symbolCount; ++s) { + HUF_DEltX1 D; + D.byte = wksp->symbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart+0] = D; + dt[uStart+1] = D; + uStart += 2; + } + break; + case 4: + for (s=0; s<symbolCount; ++s) { + U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + uStart += 4; + } + break; + case 8: + for (s=0; s<symbolCount; ++s) { + U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + MEM_write64(dt + uStart + 4, D4); + uStart += 8; + } + break; + default: + for (s=0; s<symbolCount; ++s) { + U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits); + for (u=0; u < length; u += 16) { + MEM_write64(dt + uStart + u + 0, D4); + MEM_write64(dt + uStart + u + 4, D4); + MEM_write64(dt + uStart + u + 8, D4); + MEM_write64(dt + uStart + u + 12, D4); + } + assert(u == length); + uStart += length; + } + break; + } + symbol += symbolCount; + rankStart += symbolCount * length; + } + } return iSize; } -size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_readDTableX1_wksp(DTable, src, srcSize, - workSpace, sizeof(workSpace)); -} - FORCE_INLINE_TEMPLATE BYTE HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog) { @@ -389,20 +476,6 @@ size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, } -size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - -size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); - return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize); -} - size_t HUF_decompress4X1_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -419,8 +492,7 @@ static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size { const BYTE* ip = (const BYTE*) cSrc; - size_t const hSize = HUF_readDTableX1_wksp (dctx, cSrc, cSrcSize, - workSpace, wkspSize); + size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; cSrcSize -= hSize; @@ -436,18 +508,6 @@ size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, } -size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} -size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); - return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); -} - #endif /* HUF_FORCE_DECOMPRESS_X2 */ @@ -474,7 +534,7 @@ static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 co U32 rankVal[HUF_TABLELOG_MAX + 1]; /* get pre-calculated rankVal */ - memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal)); /* fill skipped values */ if (minWeight>1) { @@ -516,7 +576,7 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, const U32 minBits = nbBitsBaseline - maxWeight; U32 s; - memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal)); /* fill DTable */ for (s=0; s<sortedListSize; s++) { @@ -581,11 +641,11 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); rankStart = rankStart0 + 1; - memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); + ZSTD_memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); - /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); if (HUF_isError(iSize)) return iSize; @@ -599,9 +659,9 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, /* Get start index of each weight */ { U32 w, nextRankStart = 0; for (w=1; w<maxW+1; w++) { - U32 current = nextRankStart; + U32 curr = nextRankStart; nextRankStart += rankStats[w]; - rankStart[w] = current; + rankStart[w] = curr; } rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ sizeOfSort = nextRankStart; @@ -624,9 +684,9 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, U32 nextRankVal = 0; U32 w; for (w=1; w<maxW+1; w++) { - U32 current = nextRankVal; + U32 curr = nextRankVal; nextRankVal += rankStats[w] << (w+rescale); - rankVal0[w] = current; + rankVal0[w] = curr; } } { U32 const minBits = tableLog+1 - maxW; U32 consumed; @@ -644,23 +704,16 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, dtd.tableLog = (BYTE)maxTableLog; dtd.tableType = 1; - memcpy(DTable, &dtd, sizeof(dtd)); + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); return iSize; } -size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_readDTableX2_wksp(DTable, src, srcSize, - workSpace, sizeof(workSpace)); -} - FORCE_INLINE_TEMPLATE U32 HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) { size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - memcpy(op, dt+val, 2); + ZSTD_memcpy(op, dt+val, 2); BIT_skipBits(DStream, dt[val].nbBits); return dt[val].length; } @@ -669,7 +722,7 @@ FORCE_INLINE_TEMPLATE U32 HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) { size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - memcpy(op, dt+val, 1); + ZSTD_memcpy(op, dt+val, 1); if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits); else { if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { @@ -890,20 +943,6 @@ size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, } -size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); - return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); -} - size_t HUF_decompress4X2_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -937,20 +976,6 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, } -size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); - return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); -} - #endif /* HUF_FORCE_DECOMPRESS_X1 */ @@ -1051,67 +1076,6 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) } -typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); - -size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ -#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) - static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 }; -#endif - - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ - if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ - if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); -#if defined(HUF_FORCE_DECOMPRESS_X1) - (void)algoNb; - assert(algoNb == 0); - return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize); -#elif defined(HUF_FORCE_DECOMPRESS_X2) - (void)algoNb; - assert(algoNb == 1); - return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); -#else - return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); -#endif - } -} - -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ - if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ - if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); -#if defined(HUF_FORCE_DECOMPRESS_X1) - (void)algoNb; - assert(algoNb == 0); - return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); -#elif defined(HUF_FORCE_DECOMPRESS_X2) - (void)algoNb; - assert(algoNb == 1); - return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); -#else - return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : - HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ; -#endif - } -} - -size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - - size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, @@ -1145,8 +1109,8 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, /* validation checks */ if (dstSize == 0) return ERROR(dstSize_tooSmall); if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ - if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ - if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); #if defined(HUF_FORCE_DECOMPRESS_X1) @@ -1168,14 +1132,6 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, } } -size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2) { @@ -1199,7 +1155,7 @@ size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstS { const BYTE* ip = (const BYTE*) cSrc; - size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize); + size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; cSrcSize -= hSize; @@ -1246,3 +1202,149 @@ size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t ds #endif } } + +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_readDTableX1_wksp(DTable, src, srcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); + return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize); +} +#endif + +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_readDTableX2_wksp(DTable, src, srcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); + return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); +} +#endif + +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} +size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); + return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); +} +#endif + +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); + return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); +} +#endif + +typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); + +size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ +#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) + static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 }; +#endif + + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); +#else + return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); +#endif + } +} + +size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); +#else + return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : + HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ; +#endif + } +} + +size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} +#endif diff --git a/thirdparty/zstd/decompress/zstd_ddict.c b/thirdparty/zstd/decompress/zstd_ddict.c index c8cb8ecc95..f5cc23b387 100644 --- a/thirdparty/zstd/decompress/zstd_ddict.c +++ b/thirdparty/zstd/decompress/zstd_ddict.c @@ -14,7 +14,7 @@ /*-******************************************************* * Dependencies *********************************************************/ -#include <string.h> /* memcpy, memmove, memset */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ #include "../common/cpu.h" /* bmi2 */ #include "../common/mem.h" /* low level memory routines */ #define FSE_STATIC_LINKING_ONLY @@ -127,11 +127,11 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, ddict->dictContent = dict; if (!dict) dictSize = 0; } else { - void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem); + void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem); ddict->dictBuffer = internalBuffer; ddict->dictContent = internalBuffer; if (!internalBuffer) return ERROR(memory_allocation); - memcpy(internalBuffer, dict, dictSize); + ZSTD_memcpy(internalBuffer, dict, dictSize); } ddict->dictSize = dictSize; ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ @@ -147,9 +147,9 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, ZSTD_customMem customMem) { - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; - { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem); + { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem); if (ddict == NULL) return NULL; ddict->cMem = customMem; { size_t const initResult = ZSTD_initDDict_internal(ddict, @@ -198,7 +198,7 @@ const ZSTD_DDict* ZSTD_initStaticDDict( if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */ if (sBufferSize < neededSpace) return NULL; if (dictLoadMethod == ZSTD_dlm_byCopy) { - memcpy(ddict+1, dict, dictSize); /* local copy */ + ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */ dict = ddict+1; } if (ZSTD_isError( ZSTD_initDDict_internal(ddict, @@ -213,8 +213,8 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict) { if (ddict==NULL) return 0; /* support free on NULL */ { ZSTD_customMem const cMem = ddict->cMem; - ZSTD_free(ddict->dictBuffer, cMem); - ZSTD_free(ddict, cMem); + ZSTD_customFree(ddict->dictBuffer, cMem); + ZSTD_customFree(ddict, cMem); return 0; } } diff --git a/thirdparty/zstd/decompress/zstd_ddict.h b/thirdparty/zstd/decompress/zstd_ddict.h index af307efd3d..8906a71c94 100644 --- a/thirdparty/zstd/decompress/zstd_ddict.h +++ b/thirdparty/zstd/decompress/zstd_ddict.h @@ -15,7 +15,7 @@ /*-******************************************************* * Dependencies *********************************************************/ -#include <stddef.h> /* size_t */ +#include "../common/zstd_deps.h" /* size_t */ #include "../zstd.h" /* ZSTD_DDict, and several public functions */ diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c index be5c7cfc33..21f846bc77 100644 --- a/thirdparty/zstd/decompress/zstd_decompress.c +++ b/thirdparty/zstd/decompress/zstd_decompress.c @@ -55,7 +55,7 @@ /*-******************************************************* * Dependencies *********************************************************/ -#include <string.h> /* memcpy, memmove, memset */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ #include "../common/cpu.h" /* bmi2 */ #include "../common/mem.h" /* low level memory routines */ #define FSE_STATIC_LINKING_ONLY @@ -94,11 +94,18 @@ static size_t ZSTD_startingInputLength(ZSTD_format_e format) return startingInputLength; } +static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx) +{ + assert(dctx->streamStage == zdss_init); + dctx->format = ZSTD_f_zstd1; + dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + dctx->outBufferMode = ZSTD_bm_buffered; + dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum; +} + static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) { - dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */ dctx->staticSize = 0; - dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; dctx->ddict = NULL; dctx->ddictLocal = NULL; dctx->dictEnd = NULL; @@ -113,7 +120,8 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) dctx->noForwardProgress = 0; dctx->oversizedDuration = 0; dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); - dctx->outBufferMode = ZSTD_obm_buffered; + ZSTD_DCtx_resetParameters(dctx); + dctx->validateChecksum = 1; #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION dctx->dictContentEndForFuzzing = NULL; #endif @@ -134,9 +142,9 @@ ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) { - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; - { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem); + { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem); if (!dctx) return NULL; dctx->customMem = customMem; ZSTD_initDCtx_internal(dctx); @@ -164,13 +172,13 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx"); { ZSTD_customMem const cMem = dctx->customMem; ZSTD_clearDict(dctx); - ZSTD_free(dctx->inBuff, cMem); + ZSTD_customFree(dctx->inBuff, cMem); dctx->inBuff = NULL; #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) if (dctx->legacyContext) ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); #endif - ZSTD_free(dctx, cMem); + ZSTD_customFree(dctx, cMem); return 0; } } @@ -179,7 +187,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) { size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); - memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ + ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ } @@ -246,7 +254,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s const BYTE* ip = (const BYTE*)src; size_t const minInputSize = ZSTD_startingInputLength(format); - memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */ + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */ if (srcSize < minInputSize) return minInputSize; RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter"); @@ -256,7 +264,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s /* skippable frame */ if (srcSize < ZSTD_SKIPPABLEHEADERSIZE) return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */ - memset(zfhPtr, 0, sizeof(*zfhPtr)); + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE); zfhPtr->frameType = ZSTD_skippableFrame; return 0; @@ -446,7 +454,8 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t he RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID), dictionary_wrong, ""); #endif - if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0); + dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0; + if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0); return 0; } @@ -461,7 +470,7 @@ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret) static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize) { ZSTD_frameSizeInfo frameSizeInfo; - memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo)); + ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo)); #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) if (ZSTD_isLegacy(src, srcSize)) @@ -516,7 +525,7 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize ip += 4; } - frameSizeInfo.compressedSize = ip - ipstart; + frameSizeInfo.compressedSize = (size_t)(ip - ipstart); frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) ? zfh.frameContentSize : nbBlocks * zfh.blockSizeMax; @@ -579,12 +588,12 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize) { DEBUGLOG(5, "ZSTD_copyRawBlock"); + RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, ""); if (dst == NULL) { if (srcSize == 0) return 0; RETURN_ERROR(dstBuffer_null, ""); } - RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, ""); - memcpy(dst, src, srcSize); + ZSTD_memcpy(dst, src, srcSize); return srcSize; } @@ -592,12 +601,12 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, BYTE b, size_t regenSize) { + RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, ""); if (dst == NULL) { if (regenSize == 0) return 0; RETURN_ERROR(dstBuffer_null, ""); } - RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, ""); - memset(dst, b, regenSize); + ZSTD_memset(dst, b, regenSize); return regenSize; } @@ -647,13 +656,13 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, switch(blockProperties.blockType) { case bt_compressed: - decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1); + decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1); break; case bt_raw : - decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize); + decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize); break; case bt_rle : - decodedSize = ZSTD_setRleBlock(op, oend-op, *ip, blockProperties.origSize); + decodedSize = ZSTD_setRleBlock(op, (size_t)(oend-op), *ip, blockProperties.origSize); break; case bt_reserved : default: @@ -661,7 +670,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, } if (ZSTD_isError(decodedSize)) return decodedSize; - if (dctx->fParams.checksumFlag) + if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, op, decodedSize); if (decodedSize != 0) op += decodedSize; @@ -676,11 +685,13 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, corruption_detected, ""); } if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ - U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); - U32 checkRead; RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, ""); - checkRead = MEM_readLE32(ip); - RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, ""); + if (!dctx->forceIgnoreChecksum) { + U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); + U32 checkRead; + checkRead = MEM_readLE32(ip); + RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, ""); + } ip += 4; remainingSrcSize -= 4; } @@ -688,7 +699,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, /* Allow caller to get size read */ *srcPtr = ip; *srcSizePtr = remainingSrcSize; - return op-ostart; + return (size_t)(op-ostart); } static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, @@ -721,7 +732,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); if (ZSTD_isError(decodedSize)) return decodedSize; - assert(decodedSize <=- dstCapacity); + assert(decodedSize <= dstCapacity); dst = (BYTE*)dst + decodedSize; dstCapacity -= decodedSize; @@ -761,15 +772,13 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown) && (moreThan1Frame==1), srcSize_wrong, - "at least one frame successfully completed, but following " - "bytes are garbage: it's more likely to be a srcSize error, " - "specifying more bytes than compressed size of frame(s). This " - "error message replaces ERROR(prefix_unknown), which would be " - "confusing, as the first header is actually correct. Note that " - "one could be unlucky, it might be a corruption error instead, " - "happening right at the place where we expect zstd magic " - "bytes. But this is _much_ less likely than a srcSize field " - "error."); + "At least one frame successfully completed, " + "but following bytes are garbage: " + "it's more likely to be a srcSize error, " + "specifying more input bytes than size of frame(s). " + "Note: one could be unlucky, it might be a corruption error instead, " + "happening right at the place where we expect zstd magic bytes. " + "But this is _much_ less likely than a srcSize field error."); if (ZSTD_isError(res)) return res; assert(res <= dstCapacity); if (res != 0) @@ -781,7 +790,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed"); - return (BYTE*)dst - (BYTE*)dststart; + return (size_t)((BYTE*)dst - (BYTE*)dststart); } size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, @@ -899,21 +908,21 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c if (dctx->format == ZSTD_f_zstd1) { /* allows header */ assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */ if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ - memcpy(dctx->headerBuffer, src, srcSize); + ZSTD_memcpy(dctx->headerBuffer, src, srcSize); dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize; /* remaining to load to get full skippable frame header */ dctx->stage = ZSTDds_decodeSkippableHeader; return 0; } } dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format); if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize; - memcpy(dctx->headerBuffer, src, srcSize); + ZSTD_memcpy(dctx->headerBuffer, src, srcSize); dctx->expected = dctx->headerSize - srcSize; dctx->stage = ZSTDds_decodeFrameHeader; return 0; case ZSTDds_decodeFrameHeader: assert(src != NULL); - memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize); + ZSTD_memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize); FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize), ""); dctx->expected = ZSTD_blockHeaderSize; dctx->stage = ZSTDds_decodeBlockHeader; @@ -977,7 +986,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum"); DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize); dctx->decodedSize += rSize; - if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize); + if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, dst, rSize); dctx->previousDstEnd = (char*)dst + rSize; /* Stay on the same stage until we are finished streaming the block. */ @@ -1007,10 +1016,13 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c case ZSTDds_checkChecksum: assert(srcSize == 4); /* guaranteed by dctx->expected */ - { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState); - U32 const check32 = MEM_readLE32(src); - DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32); - RETURN_ERROR_IF(check32 != h32, checksum_wrong, ""); + { + if (dctx->validateChecksum) { + U32 const h32 = (U32)XXH64_digest(&dctx->xxhState); + U32 const check32 = MEM_readLE32(src); + DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32); + RETURN_ERROR_IF(check32 != h32, checksum_wrong, ""); + } dctx->expected = 0; dctx->stage = ZSTDds_getFrameHeaderSize; return 0; @@ -1019,7 +1031,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c case ZSTDds_decodeSkippableHeader: assert(src != NULL); assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE); - memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */ + ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */ dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */ dctx->stage = ZSTDds_skipFrame; return 0; @@ -1075,7 +1087,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, workspace, workspaceSize); #else size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable, - dictPtr, dictEnd - dictPtr, + dictPtr, (size_t)(dictEnd - dictPtr), workspace, workspaceSize); #endif RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, ""); @@ -1084,40 +1096,46 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, { short offcodeNCount[MaxOff+1]; unsigned offcodeMaxValue = MaxOff, offcodeLog; - size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, ""); RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); ZSTD_buildFSETable( entropy->OFTable, offcodeNCount, offcodeMaxValue, OF_base, OF_bits, - offcodeLog); + offcodeLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */0); dictPtr += offcodeHeaderSize; } { short matchlengthNCount[MaxML+1]; unsigned matchlengthMaxValue = MaxML, matchlengthLog; - size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, ""); RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); ZSTD_buildFSETable( entropy->MLTable, matchlengthNCount, matchlengthMaxValue, ML_base, ML_bits, - matchlengthLog); + matchlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); dictPtr += matchlengthHeaderSize; } { short litlengthNCount[MaxLL+1]; unsigned litlengthMaxValue = MaxLL, litlengthLog; - size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, ""); RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); ZSTD_buildFSETable( entropy->LLTable, litlengthNCount, litlengthMaxValue, LL_base, LL_bits, - litlengthLog); + litlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); dictPtr += litlengthHeaderSize; } @@ -1131,7 +1149,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, entropy->rep[i] = rep; } } - return dictPtr - (const BYTE*)dict; + return (size_t)(dictPtr - (const BYTE*)dict); } static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) @@ -1170,7 +1188,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) dctx->dictID = 0; dctx->bType = bt_reserved; ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); - memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ + ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ dctx->LLTptr = dctx->entropy.LLTable; dctx->MLTptr = dctx->entropy.MLTable; dctx->OFTptr = dctx->entropy.OFTable; @@ -1394,7 +1412,7 @@ size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize) size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format) { - return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, format); + return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, (int)format); } ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam) @@ -1411,8 +1429,12 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam) ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless); return bounds; case ZSTD_d_stableOutBuffer: - bounds.lowerBound = (int)ZSTD_obm_buffered; - bounds.upperBound = (int)ZSTD_obm_stable; + bounds.lowerBound = (int)ZSTD_bm_buffered; + bounds.upperBound = (int)ZSTD_bm_stable; + return bounds; + case ZSTD_d_forceIgnoreChecksum: + bounds.lowerBound = (int)ZSTD_d_validateChecksum; + bounds.upperBound = (int)ZSTD_d_ignoreChecksum; return bounds; default:; } @@ -1436,6 +1458,26 @@ static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value) RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \ } +size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value) +{ + switch (param) { + case ZSTD_d_windowLogMax: + *value = (int)ZSTD_highbit32((U32)dctx->maxWindowSize); + return 0; + case ZSTD_d_format: + *value = (int)dctx->format; + return 0; + case ZSTD_d_stableOutBuffer: + *value = (int)dctx->outBufferMode; + return 0; + case ZSTD_d_forceIgnoreChecksum: + *value = (int)dctx->forceIgnoreChecksum; + return 0; + default:; + } + RETURN_ERROR(parameter_unsupported, ""); +} + size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value) { RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); @@ -1451,7 +1493,11 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value return 0; case ZSTD_d_stableOutBuffer: CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value); - dctx->outBufferMode = (ZSTD_outBufferMode_e)value; + dctx->outBufferMode = (ZSTD_bufferMode_e)value; + return 0; + case ZSTD_d_forceIgnoreChecksum: + CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value); + dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value; return 0; default:; } @@ -1469,8 +1515,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset) || (reset == ZSTD_reset_session_and_parameters) ) { RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); ZSTD_clearDict(dctx); - dctx->format = ZSTD_f_zstd1; - dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + ZSTD_DCtx_resetParameters(dctx); } return 0; } @@ -1524,7 +1569,7 @@ static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const ne { if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize)) zds->oversizedDuration++; - else + else zds->oversizedDuration = 0; } @@ -1538,7 +1583,7 @@ static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* { ZSTD_outBuffer const expect = zds->expectedOutBuffer; /* No requirement when ZSTD_obm_stable is not enabled. */ - if (zds->outBufferMode != ZSTD_obm_stable) + if (zds->outBufferMode != ZSTD_bm_stable) return 0; /* Any buffer is allowed in zdss_init, this must be the same for every other call until * the context is reset. @@ -1548,7 +1593,7 @@ static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* /* The buffer must match our expectation exactly. */ if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size) return 0; - RETURN_ERROR(dstBuffer_wrong, "ZSTD_obm_stable enabled but output differs!"); + RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!"); } /* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream() @@ -1560,7 +1605,7 @@ static size_t ZSTD_decompressContinueStream( ZSTD_DStream* zds, char** op, char* oend, void const* src, size_t srcSize) { int const isSkipFrame = ZSTD_isSkipFrame(zds); - if (zds->outBufferMode == ZSTD_obm_buffered) { + if (zds->outBufferMode == ZSTD_bm_buffered) { size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart; size_t const decodedSize = ZSTD_decompressContinue(zds, zds->outBuff + zds->outStart, dstSize, src, srcSize); @@ -1573,14 +1618,14 @@ static size_t ZSTD_decompressContinueStream( } } else { /* Write directly into the output buffer */ - size_t const dstSize = isSkipFrame ? 0 : oend - *op; + size_t const dstSize = isSkipFrame ? 0 : (size_t)(oend - *op); size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize); FORWARD_IF_ERROR(decodedSize, ""); *op += decodedSize; /* Flushing is not needed. */ zds->streamStage = zdss_read; assert(*op <= oend); - assert(zds->outBufferMode == ZSTD_obm_stable); + assert(zds->outBufferMode == ZSTD_bm_stable); } return 0; } @@ -1663,14 +1708,14 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB assert(iend >= ip); if (toLoad > remainingInput) { /* not enough input to load full header */ if (remainingInput > 0) { - memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput); + ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput); zds->lhSize += remainingInput; } input->pos = input->size; return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ } assert(ip != NULL); - memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; + ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; break; } } @@ -1678,10 +1723,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN && zds->fParams.frameType != ZSTD_skippableFrame && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { - size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart); + size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart)); if (cSize <= (size_t)(iend-istart)) { /* shortcut : using single-pass mode */ - size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, ZSTD_getDDict(zds)); + size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds)); if (ZSTD_isError(decompressedSize)) return decompressedSize; DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()") ip = istart + cSize; @@ -1693,7 +1738,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB } } /* Check output buffer is large enough for ZSTD_odm_stable. */ - if (zds->outBufferMode == ZSTD_obm_stable + if (zds->outBufferMode == ZSTD_bm_stable && zds->fParams.frameType != ZSTD_skippableFrame && zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN && (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) { @@ -1723,7 +1768,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB /* Adapt buffer sizes to frame header instructions */ { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */); - size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_obm_buffered + size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize) : 0; @@ -1731,7 +1776,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB { int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize); int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds); - + if (tooSmall || tooLarge) { size_t const bufferSize = neededInBuffSize + neededOutBuffSize; DEBUGLOG(4, "inBuff : from %u to %u", @@ -1745,10 +1790,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB bufferSize > zds->staticSize - sizeof(ZSTD_DCtx), memory_allocation, ""); } else { - ZSTD_free(zds->inBuff, zds->customMem); + ZSTD_customFree(zds->inBuff, zds->customMem); zds->inBuffSize = 0; zds->outBuffSize = 0; - zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem); + zds->inBuff = (char*)ZSTD_customMalloc(bufferSize, zds->customMem); RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, ""); } zds->inBuffSize = neededInBuffSize; @@ -1760,7 +1805,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB case zdss_read: DEBUGLOG(5, "stage zdss_read"); - { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip); + { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)); DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize); if (neededInSize==0) { /* end of frame */ zds->streamStage = zdss_init; @@ -1790,7 +1835,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos, corruption_detected, "should never happen"); - loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip); + loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip)); } ip += loadedSize; zds->inPos += loadedSize; @@ -1804,7 +1849,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB } case zdss_flush: { size_t const toFlushSize = zds->outEnd - zds->outStart; - size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize); + size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize); op += flushedSize; zds->outStart += flushedSize; if (flushedSize == toFlushSize) { /* flush completed */ diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.c b/thirdparty/zstd/decompress/zstd_decompress_block.c index ad3b3d8dbd..19cbdc5c16 100644 --- a/thirdparty/zstd/decompress/zstd_decompress_block.c +++ b/thirdparty/zstd/decompress/zstd_decompress_block.c @@ -14,7 +14,7 @@ /*-******************************************************* * Dependencies *********************************************************/ -#include <string.h> /* memcpy, memmove, memset */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ #include "../common/compiler.h" /* prefetch */ #include "../common/cpu.h" /* bmi2 */ #include "../common/mem.h" /* low level memory routines */ @@ -44,7 +44,7 @@ /*_******************************************************* * Memory operations **********************************************************/ -static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); } +static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } /*-************************************************************* @@ -166,7 +166,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, dctx->litSize = litSize; dctx->litEntropy = 1; if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); + ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } @@ -191,10 +191,10 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, ""); - memcpy(dctx->litBuffer, istart+lhSize, litSize); + ZSTD_memcpy(dctx->litBuffer, istart+lhSize, litSize); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); + ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+litSize; } /* direct reference into compressed stream */ @@ -223,7 +223,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, break; } RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); - memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; return lhSize+1; @@ -236,7 +236,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, /* Default FSE distribution tables. * These are pre-calculated FSE decoding tables using default distributions as defined in specification : - * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions * They were generated programmatically with following method : * - start from default distributions, present in /lib/common/zstd_internal.h * - generate tables normally, using ZSTD_buildFSETable() @@ -364,23 +364,26 @@ static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddB * generate FSE decoding table for one symbol (ll, ml or off) * cannot fail if input is valid => * all inputs are presumed validated at this stage */ -void -ZSTD_buildFSETable(ZSTD_seqSymbol* dt, +FORCE_INLINE_TEMPLATE +void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, const U32* baseValue, const U32* nbAdditionalBits, - unsigned tableLog) + unsigned tableLog, void* wksp, size_t wkspSize) { ZSTD_seqSymbol* const tableDecode = dt+1; - U16 symbolNext[MaxSeq+1]; - U32 const maxSV1 = maxSymbolValue + 1; U32 const tableSize = 1 << tableLog; - U32 highThreshold = tableSize-1; + + U16* symbolNext = (U16*)wksp; + BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1); + U32 highThreshold = tableSize - 1; + /* Sanity Checks */ assert(maxSymbolValue <= MaxSeq); assert(tableLog <= MaxFSELog); - + assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE); + (void)wkspSize; /* Init, lay down lowprob symbols */ { ZSTD_seqSymbol_header DTableH; DTableH.tableLog = tableLog; @@ -396,16 +399,69 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt, assert(normalizedCounter[s]>=0); symbolNext[s] = (U16)normalizedCounter[s]; } } } - memcpy(dt, &DTableH, sizeof(DTableH)); + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); } /* Spread symbols */ - { U32 const tableMask = tableSize-1; + assert(tableSize <= 512); + /* Specialized symbol spreading for the case when there are + * no low probability (-1 count) symbols. When compressing + * small blocks we avoid low probability symbols to hit this + * case, since header decoding speed matters more. + */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { + U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s<maxSV1; ++s, sv += add) { + int i; + int const n = normalizedCounter[s]; + MEM_write64(spread + pos, sv); + for (i = 8; i < n; i += 8) { + MEM_write64(spread + pos + i, sv); + } + pos += n; + } + } + /* Now we spread those positions across the table. + * The benefit of doing it in two stages is that we avoid the the + * variable size inner loop, which caused lots of branch misses. + * Now we can run through all the positions without any branch misses. + * We unroll the loop twice, since that is what emperically worked best. + */ + { + size_t position = 0; + size_t s; + size_t const unroll = 2; + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableDecode[uPosition].baseValue = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); + } + } else { + U32 const tableMask = tableSize-1; U32 const step = FSE_TABLESTEP(tableSize); U32 s, position = 0; for (s=0; s<maxSV1; s++) { int i; - for (i=0; i<normalizedCounter[s]; i++) { + int const n = normalizedCounter[s]; + for (i=0; i<n; i++) { tableDecode[position].baseValue = s; position = (position + step) & tableMask; while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */ @@ -414,7 +470,8 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt, } /* Build Decoding table */ - { U32 u; + { + U32 u; for (u=0; u<tableSize; u++) { U32 const symbol = tableDecode[u].baseValue; U32 const nextState = symbolNext[symbol]++; @@ -423,7 +480,46 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt, assert(nbAdditionalBits[symbol] < 255); tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol]; tableDecode[u].baseValue = baseValue[symbol]; - } } + } + } +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U32* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize) +{ + ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue, + baseValue, nbAdditionalBits, tableLog, wksp, wkspSize); +} + +#if DYNAMIC_BMI2 +TARGET_ATTRIBUTE("bmi2") static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U32* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize) +{ + ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue, + baseValue, nbAdditionalBits, tableLog, wksp, wkspSize); +} +#endif + +void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U32* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + ZSTD_buildFSETable_body_bmi2(dt, normalizedCounter, maxSymbolValue, + baseValue, nbAdditionalBits, tableLog, wksp, wkspSize); + return; + } +#endif + (void)bmi2; + ZSTD_buildFSETable_body_default(dt, normalizedCounter, maxSymbolValue, + baseValue, nbAdditionalBits, tableLog, wksp, wkspSize); } @@ -435,7 +531,8 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb const void* src, size_t srcSize, const U32* baseValue, const U32* nbAdditionalBits, const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable, - int ddictIsCold, int nbSeq) + int ddictIsCold, int nbSeq, U32* wksp, size_t wkspSize, + int bmi2) { switch(type) { @@ -467,7 +564,7 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, ""); RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, ""); - ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog); + ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2); *DTablePtr = DTableSpace; return headerSize; } @@ -499,7 +596,8 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, if (nbSeq > 0x7F) { if (nbSeq == 0xFF) { RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, ""); - nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2; + nbSeq = MEM_readLE16(ip) + LONGNBSEQ; + ip+=2; } else { RETURN_ERROR_IF(ip >= iend, srcSize_wrong, ""); nbSeq = ((nbSeq-0x80)<<8) + *ip++; @@ -520,7 +618,9 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, ip, iend-ip, LL_base, LL_bits, LL_defaultDTable, dctx->fseEntropy, - dctx->ddictIsCold, nbSeq); + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + dctx->bmi2); RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed"); ip += llhSize; } @@ -530,7 +630,9 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, ip, iend-ip, OF_base, OF_bits, OF_defaultDTable, dctx->fseEntropy, - dctx->ddictIsCold, nbSeq); + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + dctx->bmi2); RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed"); ip += ofhSize; } @@ -540,7 +642,9 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, ip, iend-ip, ML_base, ML_bits, ML_defaultDTable, dctx->fseEntropy, - dctx->ddictIsCold, nbSeq); + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + dctx->bmi2); RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed"); ip += mlhSize; } @@ -686,12 +790,12 @@ size_t ZSTD_execSequenceEnd(BYTE* op, RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); match = dictEnd - (prefixStart-match); if (match + sequence.matchLength <= dictEnd) { - memmove(oLitEnd, match, sequence.matchLength); + ZSTD_memmove(oLitEnd, match, sequence.matchLength); return sequenceLength; } /* span extDict & currentPrefixSegment */ { size_t const length1 = dictEnd - match; - memmove(oLitEnd, match, length1); + ZSTD_memmove(oLitEnd, match, length1); op = oLitEnd + length1; sequence.matchLength -= length1; match = prefixStart; @@ -752,12 +856,12 @@ size_t ZSTD_execSequence(BYTE* op, RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); match = dictEnd + (match - prefixStart); if (match + sequence.matchLength <= dictEnd) { - memmove(oLitEnd, match, sequence.matchLength); + ZSTD_memmove(oLitEnd, match, sequence.matchLength); return sequenceLength; } /* span extDict & currentPrefixSegment */ { size_t const length1 = dictEnd - match; - memmove(oLitEnd, match, length1); + ZSTD_memmove(oLitEnd, match, length1); op = oLitEnd + length1; sequence.matchLength -= length1; match = prefixStart; @@ -948,7 +1052,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c } #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) +MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) { size_t const windowSize = dctx->fParams.windowSize; /* No dictionary used. */ @@ -969,6 +1073,7 @@ MEM_STATIC void ZSTD_assertValidSequence( seq_t const seq, BYTE const* prefixStart, BYTE const* virtualStart) { +#if DEBUGLEVEL >= 1 size_t const windowSize = dctx->fParams.windowSize; size_t const sequenceSize = seq.litLength + seq.matchLength; BYTE const* const oLitEnd = op + seq.litLength; @@ -986,6 +1091,9 @@ MEM_STATIC void ZSTD_assertValidSequence( /* Offset must be within our window. */ assert(seq.offset <= windowSize); } +#else + (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart; +#endif } #endif @@ -1080,14 +1188,14 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, #endif DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); BIT_reloadDStream(&(seqState.DStream)); + op += oneSeqSize; /* gcc and clang both don't like early returns in this loop. - * gcc doesn't like early breaks either. - * Instead save an error and report it at the end. - * When there is an error, don't increment op, so we don't - * overwrite. + * Instead break and check for an error at the end of the loop. */ - if (UNLIKELY(ZSTD_isError(oneSeqSize))) error = oneSeqSize; - else op += oneSeqSize; + if (UNLIKELY(ZSTD_isError(oneSeqSize))) { + error = oneSeqSize; + break; + } if (UNLIKELY(!--nbSeq)) break; } @@ -1104,7 +1212,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, { size_t const lastLLSize = litEnd - litPtr; RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); if (op != NULL) { - memcpy(op, litPtr, lastLLSize); + ZSTD_memcpy(op, litPtr, lastLLSize); op += lastLLSize; } } @@ -1209,7 +1317,7 @@ ZSTD_decompressSequencesLong_body( { size_t const lastLLSize = litEnd - litPtr; RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); if (op != NULL) { - memcpy(op, litPtr, lastLLSize); + ZSTD_memcpy(op, litPtr, lastLLSize); op += lastLLSize; } } diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.h b/thirdparty/zstd/decompress/zstd_decompress_block.h index bf39b7350c..b5715c168e 100644 --- a/thirdparty/zstd/decompress/zstd_decompress_block.h +++ b/thirdparty/zstd/decompress/zstd_decompress_block.h @@ -15,7 +15,7 @@ /*-******************************************************* * Dependencies *********************************************************/ -#include <stddef.h> /* size_t */ +#include "../common/zstd_deps.h" /* size_t */ #include "../zstd.h" /* DCtx, and some public functions */ #include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */ #include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */ @@ -48,12 +48,15 @@ size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, * this function must be called with valid parameters only * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.) * in which case it cannot fail. + * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is + * defined in zstd_decompress_internal.h. * Internal use only. */ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, const U32* baseValue, const U32* nbAdditionalBits, - unsigned tableLog); + unsigned tableLog, void* wksp, size_t wkspSize, + int bmi2); #endif /* ZSTD_DEC_BLOCK_H */ diff --git a/thirdparty/zstd/decompress/zstd_decompress_internal.h b/thirdparty/zstd/decompress/zstd_decompress_internal.h index 9ad96c5548..f80b471e99 100644 --- a/thirdparty/zstd/decompress/zstd_decompress_internal.h +++ b/thirdparty/zstd/decompress/zstd_decompress_internal.h @@ -27,26 +27,26 @@ /*-******************************************************* * Constants *********************************************************/ -static const U32 LL_base[MaxLL+1] = { +static UNUSED_ATTR const U32 LL_base[MaxLL+1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000 }; -static const U32 OF_base[MaxOff+1] = { +static UNUSED_ATTR const U32 OF_base[MaxOff+1] = { 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; -static const U32 OF_bits[MaxOff+1] = { +static UNUSED_ATTR const U32 OF_bits[MaxOff+1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; -static const U32 ML_base[MaxML+1] = { +static UNUSED_ATTR const U32 ML_base[MaxML+1] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, @@ -73,12 +73,16 @@ static const U32 ML_base[MaxML+1] = { #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64)) +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32)) + typedef struct { ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */ ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */ ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */ HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ U32 rep[ZSTD_REP_NUM]; + U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32]; } ZSTD_entropyDTables_t; typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, @@ -95,11 +99,6 @@ typedef enum { ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */ } ZSTD_dictUses_e; -typedef enum { - ZSTD_obm_buffered = 0, /* Buffer the output */ - ZSTD_obm_stable = 1 /* ZSTD_outBuffer is stable */ -} ZSTD_outBufferMode_e; - struct ZSTD_DCtx_s { const ZSTD_seqSymbol* LLTptr; @@ -122,6 +121,8 @@ struct ZSTD_DCtx_s XXH64_state_t xxhState; size_t headerSize; ZSTD_format_e format; + ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */ + U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */ const BYTE* litPtr; ZSTD_customMem customMem; size_t litSize; @@ -152,7 +153,7 @@ struct ZSTD_DCtx_s U32 legacyVersion; U32 hostageByte; int noForwardProgress; - ZSTD_outBufferMode_e outBufferMode; + ZSTD_bufferMode_e outBufferMode; ZSTD_outBuffer expectedOutBuffer; /* workspace */ diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h index 8c6fc6ae90..b0ecdf5538 100644 --- a/thirdparty/zstd/zstd.h +++ b/thirdparty/zstd/zstd.h @@ -72,16 +72,21 @@ extern "C" { /*------ Version ------*/ #define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MINOR 4 -#define ZSTD_VERSION_RELEASE 5 - +#define ZSTD_VERSION_RELEASE 8 #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) -ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< to check runtime library version */ + +/*! ZSTD_versionNumber() : + * Return runtime library version, the value is (MAJOR*100*100 + MINOR*100 + RELEASE). */ +ZSTDLIB_API unsigned ZSTD_versionNumber(void); #define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE #define ZSTD_QUOTE(str) #str #define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) -ZSTDLIB_API const char* ZSTD_versionString(void); /* requires v1.3.0+ */ + +/*! ZSTD_versionString() : + * Return runtime library version, like "1.4.5". Requires v1.3.0+. */ +ZSTDLIB_API const char* ZSTD_versionString(void); /* ************************************* * Default constant @@ -334,7 +339,9 @@ typedef enum { * for large inputs, by finding large matches at long distance. * It increases memory usage and window size. * Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB - * except when expressly set to a different value. */ + * except when expressly set to a different value. + * Note: will be enabled by default if ZSTD_c_windowLog >= 128 MB and + * compression strategy >= ZSTD_btopt (== compression level 16+) */ ZSTD_c_ldmHashLog=161, /* Size of the table for long distance matching, as a power of 2. * Larger values increase memory usage and compression ratio, * but decrease compression speed. @@ -365,16 +372,20 @@ typedef enum { ZSTD_c_dictIDFlag=202, /* When applicable, dictionary's ID is written into frame header (default:1) */ /* multi-threading parameters */ - /* These parameters are only useful if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD). - * They return an error otherwise. */ + /* These parameters are only active if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD). + * Otherwise, trying to set any other value than default (0) will be a no-op and return an error. + * In a situation where it's unknown if the linked library supports multi-threading or not, + * setting ZSTD_c_nbWorkers to any value >= 1 and consulting the return value provides a quick way to check this property. + */ ZSTD_c_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel. - * When nbWorkers >= 1, triggers asynchronous mode when used with ZSTD_compressStream*() : + * When nbWorkers >= 1, triggers asynchronous mode when invoking ZSTD_compressStream*() : * ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller, - * while compression work is performed in parallel, within worker threads. + * while compression is performed in parallel, within worker thread(s). * (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end : * in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call). * More workers improve speed, but also increase memory usage. - * Default value is `0`, aka "single-threaded mode" : no worker is spawned, compression is performed inside Caller's thread, all invocations are blocking */ + * Default value is `0`, aka "single-threaded mode" : no worker is spawned, + * compression is performed inside Caller's thread, and all invocations are blocking */ ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1. * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads. * 0 means default, which is dynamically determined based on compression parameters. @@ -403,6 +414,11 @@ typedef enum { * ZSTD_c_literalCompressionMode * ZSTD_c_targetCBlockSize * ZSTD_c_srcSizeHint + * ZSTD_c_enableDedicatedDictSearch + * ZSTD_c_stableInBuffer + * ZSTD_c_stableOutBuffer + * ZSTD_c_blockDelimiters + * ZSTD_c_validateSequences * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * note : never ever use experimentalParam? names directly; * also, the enums values themselves are unstable and can still change. @@ -413,7 +429,12 @@ typedef enum { ZSTD_c_experimentalParam4=1001, ZSTD_c_experimentalParam5=1002, ZSTD_c_experimentalParam6=1003, - ZSTD_c_experimentalParam7=1004 + ZSTD_c_experimentalParam7=1004, + ZSTD_c_experimentalParam8=1005, + ZSTD_c_experimentalParam9=1006, + ZSTD_c_experimentalParam10=1007, + ZSTD_c_experimentalParam11=1008, + ZSTD_c_experimentalParam12=1009 } ZSTD_cParameter; typedef struct { @@ -524,11 +545,13 @@ typedef enum { * At the time of this writing, they include : * ZSTD_d_format * ZSTD_d_stableOutBuffer + * ZSTD_d_forceIgnoreChecksum * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * note : never ever use experimentalParam? names directly */ ZSTD_d_experimentalParam1=1000, - ZSTD_d_experimentalParam2=1001 + ZSTD_d_experimentalParam2=1001, + ZSTD_d_experimentalParam3=1002 } ZSTD_dParameter; @@ -664,8 +687,9 @@ typedef enum { * - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode) * - output->pos must be <= dstCapacity, input->pos must be <= srcSize * - output->pos and input->pos will be updated. They are guaranteed to remain below their respective limit. + * - endOp must be a valid directive * - When nbWorkers==0 (default), function is blocking : it completes its job before returning to caller. - * - When nbWorkers>=1, function is non-blocking : it just acquires a copy of input, and distributes jobs to internal worker threads, flush whatever is available, + * - When nbWorkers>=1, function is non-blocking : it copies a portion of input, distributes jobs to internal worker threads, flush to output whatever is available, * and then immediately returns, just indicating that there is some data remaining to be flushed. * The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte. * - Exception : if the first call requests a ZSTD_e_end directive and provides enough dstCapacity, the function delegates to ZSTD_compress2() which is always blocking. @@ -1100,21 +1124,40 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); typedef struct ZSTD_CCtx_params_s ZSTD_CCtx_params; typedef struct { - unsigned int matchPos; /* Match pos in dst */ - /* If seqDef.offset > 3, then this is seqDef.offset - 3 - * If seqDef.offset < 3, then this is the corresponding repeat offset - * But if seqDef.offset < 3 and litLength == 0, this is the - * repeat offset before the corresponding repeat offset - * And if seqDef.offset == 3 and litLength == 0, this is the - * most recent repeat offset - 1 - */ - unsigned int offset; - unsigned int litLength; /* Literal length */ - unsigned int matchLength; /* Match length */ - /* 0 when seq not rep and seqDef.offset otherwise - * when litLength == 0 this will be <= 4, otherwise <= 3 like normal - */ - unsigned int rep; + unsigned int offset; /* The offset of the match. (NOT the same as the offset code) + * If offset == 0 and matchLength == 0, this sequence represents the last + * literals in the block of litLength size. + */ + + unsigned int litLength; /* Literal length of the sequence. */ + unsigned int matchLength; /* Match length of the sequence. */ + + /* Note: Users of this API may provide a sequence with matchLength == litLength == offset == 0. + * In this case, we will treat the sequence as a marker for a block boundary. + */ + + unsigned int rep; /* Represents which repeat offset is represented by the field 'offset'. + * Ranges from [0, 3]. + * + * Repeat offsets are essentially previous offsets from previous sequences sorted in + * recency order. For more detail, see doc/zstd_compression_format.md + * + * If rep == 0, then 'offset' does not contain a repeat offset. + * If rep > 0: + * If litLength != 0: + * rep == 1 --> offset == repeat_offset_1 + * rep == 2 --> offset == repeat_offset_2 + * rep == 3 --> offset == repeat_offset_3 + * If litLength == 0: + * rep == 1 --> offset == repeat_offset_2 + * rep == 2 --> offset == repeat_offset_3 + * rep == 3 --> offset == repeat_offset_1 - 1 + * + * Note: This field is optional. ZSTD_generateSequences() will calculate the value of + * 'rep', but repeat offsets do not necessarily need to be calculated from an external + * sequence provider's perspective. For example, ZSTD_compressSequences() does not + * use this 'rep' field at all (as of now). + */ } ZSTD_Sequence; typedef struct { @@ -1157,6 +1200,12 @@ typedef enum { } ZSTD_format_e; typedef enum { + /* Note: this enum controls ZSTD_d_forceIgnoreChecksum */ + ZSTD_d_validateChecksum = 0, + ZSTD_d_ignoreChecksum = 1 +} ZSTD_forceIgnoreChecksum_e; + +typedef enum { /* Note: this enum and the behavior it controls are effectively internal * implementation details of the compressor. They are expected to continue * to evolve and should be considered only in the context of extremely @@ -1253,14 +1302,74 @@ ZSTDLIB_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcS * or an error code (if srcSize is too small) */ ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); -/*! ZSTD_getSequences() : - * Extract sequences from the sequence store +typedef enum { + ZSTD_sf_noBlockDelimiters = 0, /* Representation of ZSTD_Sequence has no block delimiters, sequences only */ + ZSTD_sf_explicitBlockDelimiters = 1 /* Representation of ZSTD_Sequence contains explicit block delimiters */ +} ZSTD_sequenceFormat_e; + +/*! ZSTD_generateSequences() : + * Generate sequences using ZSTD_compress2, given a source buffer. + * + * Each block will end with a dummy sequence + * with offset == 0, matchLength == 0, and litLength == length of last literals. + * litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0) + * simply acts as a block delimiter. + * * zc can be used to insert custom compression params. * This function invokes ZSTD_compress2 - * @return : number of sequences extracted + * + * The output of this function can be fed into ZSTD_compressSequences() with CCtx + * setting of ZSTD_c_blockDelimiters as ZSTD_sf_explicitBlockDelimiters + * @return : number of sequences generated + */ + +ZSTDLIB_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, + size_t outSeqsSize, const void* src, size_t srcSize); + +/*! ZSTD_mergeBlockDelimiters() : + * Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals + * by merging them into into the literals of the next sequence. + * + * As such, the final generated result has no explicit representation of block boundaries, + * and the final last literals segment is not represented in the sequences. + * + * The output of this function can be fed into ZSTD_compressSequences() with CCtx + * setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters + * @return : number of sequences left after merging + */ +ZSTDLIB_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize); + +/*! ZSTD_compressSequences() : + * Compress an array of ZSTD_Sequence, generated from the original source buffer, into dst. + * If a dictionary is included, then the cctx should reference the dict. (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.) + * The entire source is compressed into a single frame. + * + * The compression behavior changes based on cctx params. In particular: + * If ZSTD_c_blockDelimiters == ZSTD_sf_noBlockDelimiters, the array of ZSTD_Sequence is expected to contain + * no block delimiters (defined in ZSTD_Sequence). Block boundaries are roughly determined based on + * the block size derived from the cctx, and sequences may be split. This is the default setting. + * + * If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain + * block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided. + * + * If ZSTD_c_validateSequences == 0, this function will blindly accept the sequences provided. Invalid sequences cause undefined + * behavior. If ZSTD_c_validateSequences == 1, then if sequence is invalid (see doc/zstd_compression_format.md for + * specifics regarding offset/matchlength requirements) then the function will bail out and return an error. + * + * In addition to the two adjustable experimental params, there are other important cctx params. + * - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN. + * - ZSTD_c_compressionLevel accordingly adjusts the strength of the entropy coder, as it would in typical compression. + * - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset + * is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md + * + * Note: Repcodes are, as of now, always re-calculated within this function, so ZSTD_Sequence::rep is unused. + * Note 2: Once we integrate ability to ingest repcodes, the explicit block delims mode must respect those repcodes exactly, + * and cannot emit an RLE block that disagrees with the repcode history + * @return : final compressed size or a ZSTD error. */ -ZSTDLIB_API size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, - size_t outSeqsSize, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize); /*************************************** @@ -1372,7 +1481,11 @@ ZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict( typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); typedef void (*ZSTD_freeFunction) (void* opaque, void* address); typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; -static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ +static +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif +ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); @@ -1385,13 +1498,36 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS ZSTD_compressionParameters cParams, ZSTD_customMem customMem); +/* ! Thread pool : + * These prototypes make it possible to share a thread pool among multiple compression contexts. + * This can limit resources for applications with multiple threads where each one uses + * a threaded compression mode (via ZSTD_c_nbWorkers parameter). + * ZSTD_createThreadPool creates a new thread pool with a given number of threads. + * Note that the lifetime of such pool must exist while being used. + * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value + * to use an internal thread pool). + * ZSTD_freeThreadPool frees a thread pool. + */ +typedef struct POOL_ctx_s ZSTD_threadPool; +ZSTDLIB_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads); +ZSTDLIB_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); +ZSTDLIB_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool); + +/* + * This API is temporary and is expected to change or disappear in the future! + */ +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* cctxParams, + ZSTD_customMem customMem); + ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_customMem customMem); - - /*************************************** * Advanced compression functions ***************************************/ @@ -1404,6 +1540,12 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictS * note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); +/*! ZSTD_getDictID_fromCDict() : + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict); + /*! ZSTD_getCParams() : * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. * `estimatedSrcSize` value is optional, select 0 if not known */ @@ -1518,6 +1660,143 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre * but compression ratio may regress significantly if guess considerably underestimates */ #define ZSTD_c_srcSizeHint ZSTD_c_experimentalParam7 +/* Controls whether the new and experimental "dedicated dictionary search + * structure" can be used. This feature is still rough around the edges, be + * prepared for surprising behavior! + * + * How to use it: + * + * When using a CDict, whether to use this feature or not is controlled at + * CDict creation, and it must be set in a CCtxParams set passed into that + * construction (via ZSTD_createCDict_advanced2()). A compression will then + * use the feature or not based on how the CDict was constructed; the value of + * this param, set in the CCtx, will have no effect. + * + * However, when a dictionary buffer is passed into a CCtx, such as via + * ZSTD_CCtx_loadDictionary(), this param can be set on the CCtx to control + * whether the CDict that is created internally can use the feature or not. + * + * What it does: + * + * Normally, the internal data structures of the CDict are analogous to what + * would be stored in a CCtx after compressing the contents of a dictionary. + * To an approximation, a compression using a dictionary can then use those + * data structures to simply continue what is effectively a streaming + * compression where the simulated compression of the dictionary left off. + * Which is to say, the search structures in the CDict are normally the same + * format as in the CCtx. + * + * It is possible to do better, since the CDict is not like a CCtx: the search + * structures are written once during CDict creation, and then are only read + * after that, while the search structures in the CCtx are both read and + * written as the compression goes along. This means we can choose a search + * structure for the dictionary that is read-optimized. + * + * This feature enables the use of that different structure. + * + * Note that some of the members of the ZSTD_compressionParameters struct have + * different semantics and constraints in the dedicated search structure. It is + * highly recommended that you simply set a compression level in the CCtxParams + * you pass into the CDict creation call, and avoid messing with the cParams + * directly. + * + * Effects: + * + * This will only have any effect when the selected ZSTD_strategy + * implementation supports this feature. Currently, that's limited to + * ZSTD_greedy, ZSTD_lazy, and ZSTD_lazy2. + * + * Note that this means that the CDict tables can no longer be copied into the + * CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be + * useable. The dictionary can only be attached or reloaded. + * + * In general, you should expect compression to be faster--sometimes very much + * so--and CDict creation to be slightly slower. Eventually, we will probably + * make this mode the default. + */ +#define ZSTD_c_enableDedicatedDictSearch ZSTD_c_experimentalParam8 + +/* ZSTD_c_stableInBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells the compressor that the ZSTD_inBuffer will ALWAYS be the same + * between calls, except for the modifications that zstd makes to pos (the + * caller must not modify pos). This is checked by the compressor, and + * compression will fail if it ever changes. This means the only flush + * mode that makes sense is ZSTD_e_end, so zstd will error if ZSTD_e_end + * is not used. The data in the ZSTD_inBuffer in the range [src, src + pos) + * MUST not be modified during compression or you will get data corruption. + * + * When this flag is enabled zstd won't allocate an input window buffer, + * because the user guarantees it can reference the ZSTD_inBuffer until + * the frame is complete. But, it will still allocate an output buffer + * large enough to fit a block (see ZSTD_c_stableOutBuffer). This will also + * avoid the memcpy() from the input buffer to the input window buffer. + * + * NOTE: ZSTD_compressStream2() will error if ZSTD_e_end is not used. + * That means this flag cannot be used with ZSTD_compressStream(). + * + * NOTE: So long as the ZSTD_inBuffer always points to valid memory, using + * this flag is ALWAYS memory safe, and will never access out-of-bounds + * memory. However, compression WILL fail if you violate the preconditions. + * + * WARNING: The data in the ZSTD_inBuffer in the range [dst, dst + pos) MUST + * not be modified during compression or you will get data corruption. This + * is because zstd needs to reference data in the ZSTD_inBuffer to find + * matches. Normally zstd maintains its own window buffer for this purpose, + * but passing this flag tells zstd to use the user provided buffer. + */ +#define ZSTD_c_stableInBuffer ZSTD_c_experimentalParam9 + +/* ZSTD_c_stableOutBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells he compressor that the ZSTD_outBuffer will not be resized between + * calls. Specifically: (out.size - out.pos) will never grow. This gives the + * compressor the freedom to say: If the compressed data doesn't fit in the + * output buffer then return ZSTD_error_dstSizeTooSmall. This allows us to + * always decompress directly into the output buffer, instead of decompressing + * into an internal buffer and copying to the output buffer. + * + * When this flag is enabled zstd won't allocate an output buffer, because + * it can write directly to the ZSTD_outBuffer. It will still allocate the + * input window buffer (see ZSTD_c_stableInBuffer). + * + * Zstd will check that (out.size - out.pos) never grows and return an error + * if it does. While not strictly necessary, this should prevent surprises. + */ +#define ZSTD_c_stableOutBuffer ZSTD_c_experimentalParam10 + +/* ZSTD_c_blockDelimiters + * Default is 0 == ZSTD_sf_noBlockDelimiters. + * + * For use with sequence compression API: ZSTD_compressSequences(). + * + * Designates whether or not the given array of ZSTD_Sequence contains block delimiters + * and last literals, which are defined as sequences with offset == 0 and matchLength == 0. + * See the definition of ZSTD_Sequence for more specifics. + */ +#define ZSTD_c_blockDelimiters ZSTD_c_experimentalParam11 + +/* ZSTD_c_validateSequences + * Default is 0 == disabled. Set to 1 to enable sequence validation. + * + * For use with sequence compression API: ZSTD_compressSequences(). + * Designates whether or not we validate sequences provided to ZSTD_compressSequences() + * during function execution. + * + * Without validation, providing a sequence that does not conform to the zstd spec will cause + * undefined behavior, and may produce a corrupted block. + * + * With validation enabled, a if sequence is invalid (see doc/zstd_compression_format.md for + * specifics regarding offset/matchlength requirements) then the function will bail out and + * return an error. + * + */ +#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12 + /*! ZSTD_CCtx_getParameter() : * Get the requested compression parameter value, selected by enum ZSTD_cParameter, * and store it into int* value. @@ -1566,8 +1845,10 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, Z /*! ZSTD_CCtxParams_setParameter() : * Similar to ZSTD_CCtx_setParameter. * Set one compression parameter, selected by enum ZSTD_cParameter. - * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams(). - * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Parameters must be applied to a ZSTD_CCtx using + * ZSTD_CCtx_setParametersUsingCCtxParams(). + * @result : a code representing success or failure (which can be tested with + * ZSTD_isError()). */ ZSTDLIB_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value); @@ -1647,6 +1928,13 @@ ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* pre */ ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); +/*! ZSTD_DCtx_getParameter() : + * Get the requested decompression parameter value, selected by enum ZSTD_dParameter, + * and store it into int* value. + * @return : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value); + /* ZSTD_d_format * experimental parameter, * allowing selection between ZSTD_format_e input compression formats @@ -1684,6 +1972,17 @@ ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowS */ #define ZSTD_d_stableOutBuffer ZSTD_d_experimentalParam2 +/* ZSTD_d_forceIgnoreChecksum + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable + * + * Tells the decompressor to skip checksum validation during decompression, regardless + * of whether checksumming was specified during compression. This offers some + * slight performance benefits, and may be useful for debugging. + * Param has values of type ZSTD_forceIgnoreChecksum_e + */ +#define ZSTD_d_forceIgnoreChecksum ZSTD_d_experimentalParam3 + /*! ZSTD_DCtx_setFormat() : * Instruct the decoder context about what kind of data to decode next. * This instruction is mandatory to decode data without a fully-formed header, @@ -1711,7 +2010,8 @@ ZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs ( ********************************************************************/ /*===== Advanced Streaming compression functions =====*/ -/**! ZSTD_initCStream_srcSize() : + +/*! ZSTD_initCStream_srcSize() : * This function is deprecated, and equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any) @@ -1728,7 +2028,7 @@ ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); -/**! ZSTD_initCStream_usingDict() : +/*! ZSTD_initCStream_usingDict() : * This function is deprecated, and is equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); @@ -1745,7 +2045,7 @@ ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); -/**! ZSTD_initCStream_advanced() : +/*! ZSTD_initCStream_advanced() : * This function is deprecated, and is approximately equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * // Pseudocode: Set each zstd parameter and leave the rest as-is. @@ -1766,7 +2066,7 @@ ZSTD_initCStream_advanced(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize); -/**! ZSTD_initCStream_usingCDict() : +/*! ZSTD_initCStream_usingCDict() : * This function is deprecated, and equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_refCDict(zcs, cdict); @@ -1776,7 +2076,7 @@ ZSTD_initCStream_advanced(ZSTD_CStream* zcs, */ ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); -/**! ZSTD_initCStream_usingCDict_advanced() : +/*! ZSTD_initCStream_usingCDict_advanced() : * This function is DEPRECATED, and is approximately equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * // Pseudocode: Set each zstd frame parameter and leave the rest as-is. @@ -1849,7 +2149,8 @@ ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); /*===== Advanced Streaming decompression functions =====*/ -/** + +/*! * This function is deprecated, and is equivalent to: * * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); @@ -1860,7 +2161,7 @@ ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); */ ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); -/** +/*! * This function is deprecated, and is equivalent to: * * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); @@ -1871,7 +2172,7 @@ ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dic */ ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); -/** +/*! * This function is deprecated, and is equivalent to: * * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); @@ -1933,7 +2234,7 @@ ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstC ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -/*- +/** Buffer-less streaming decompression (synchronous mode) A ZSTD_DCtx object is required to track streaming operations. |